Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

1. Custom binary operators from the `lubridate` package now work with objects of class `IDate` as with a `Date` subclass, [#6839](https://github.com/Rdatatable/data.table/issues/6839). Thanks @emallickhossain for the report and @aitap for the fix.

2. `fwrite(compress="gzip")` once again produces a gzip header when the column names are missing or disabled, [@6852](https://github.com/Rdatatable/data.table/issues/6852). Thanks @maxscheiber for the report and @aitap for the fix.

## NOTES

1. Continued work to remove non-API C functions, [#6180](https://github.com/Rdatatable/data.table/issues/6180). Thanks Ivan Krylov for the PRs and for writing a clear and concise guide about the R API: https://aitap.codeberg.page/R-api/.
Expand Down
5 changes: 4 additions & 1 deletion inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -10024,10 +10024,13 @@ if (!haszlib()) {
fwrite(DT, file=f3<-tempfile(), compress="gzip") # compress to filename not ending .gz
fwrite(DT, file=f4<-tempfile(), compress="gzip", compressLevel=1) # test compressLevel
fwrite(DT, file=f5<-tempfile(), compress="gzip", compressLevel=9)
# col.names=FALSE must not disable gzip header, #6852
fwrite(DT, file=f6<-tempfile(), compress="gzip", col.names=FALSE)
test(1658.441, file.info(f3)$size, file.info(f1)$size)
test(1658.442, file.info(f4)$size >= file.info(f1)$size)
test(1658.443, file.info(f1)$size >= file.info(f5)$size)
unlink(c(f1,f2,f3,f4,f5))
test(1658.444, fread(f6, col.names = c("a", "b")), DT)
unlink(c(f1,f2,f3,f4,f5,f6))
}
DT = data.table(a=1:3, b=list(1:4, c(3.14, 100e10), c("foo", "bar", "baz")))
test(1658.45, fwrite(DT), output=c("a,b","1,1|2|3|4","2,3.14|1e+12","3,foo|bar|baz"))
Expand Down
41 changes: 30 additions & 11 deletions src/fwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,9 +829,28 @@ void fwriteMain(fwriteMainArgs args)
zbuffSize / MEGA, nth, errno, strerror(errno));
// # nocov end
}
}
len = 0;
crc = crc32(0L, Z_NULL, 0);

#endif
if (f != -1) {
// write minimal gzip header, but not on the console
static const char header[] = "\037\213\10\0\0\0\0\0\0\3";
int ret0 = WRITE(f, header, (sizeof header) - 1);
compress_len += (sizeof header) - 1;

if (ret0 == -1) {
// # nocov start
int errwrite = errno; // capture write errno now in case close fails with a different errno
CLOSE(f);
free(buffPool);
free(zbuffPool);
deflateEnd(&strm);
STOP(_("Failed to write gzip header. Write returned %d"), errwrite);
// # nocov end
}
}
}
#endif // #NOZLIB

// write header

Expand Down Expand Up @@ -873,15 +892,10 @@ void fwriteMain(fwriteMainArgs args)
*ch = '\0';
DTPRINT("%s", buff); // # notranslate
} else {
int ret0=0, ret1=0, ret2=0;
int ret1=0, ret2=0;
#ifndef NOZLIB
if (args.is_gzip) {
char* zbuff = zbuffPool;
// write minimal gzip header
char* header = "\037\213\10\0\0\0\0\0\0\3";
ret0 = WRITE(f, header, 10);
compress_len += 10;
crc = crc32(0L, Z_NULL, 0);

size_t zbuffUsed = zbuffSize;
len = (size_t)(ch - buff);
Expand All @@ -898,21 +912,26 @@ void fwriteMain(fwriteMainArgs args)
#ifndef NOZLIB
}
#endif
if (ret0 == -1 || ret1 || ret2 == -1) {
if (ret1 || ret2 == -1) {
// # nocov start
int errwrite = errno; // capture write errno now in case close fails with a different errno
CLOSE(f);
free(buffPool);
#ifndef NOZLIB
free(zbuffPool);
#endif
if (ret0 == -1) STOP(_("Failed to write gzip header. Write returned %d"), ret0);
else if (ret1) STOP(_("Failed to compress gzip. compressbuff() returned %d"), ret1);
if (ret1) STOP(_("Failed to compress gzip. compressbuff() returned %d"), ret1);
else STOP(_("%s: '%s'"), strerror(errwrite), args.filename);
// # nocov end
}
}
}
#ifndef NOZLIB
Copy link
Member

@ben-schwen ben-schwen Mar 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly #6857 is not an issue for me when deleting this block 😕

@aitap

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if args.is_gzip is not true then we never call init_stream so this is actually not surprising anymore.

else {
// was unconditionally initialized for zbuffSize, not used for header
deflateEnd(&strm);
}
#endif
if (verbose)
DTPRINT(_("Initialization done in %.3fs\n"), 1.0*(wallclock()-t0));

Expand Down
Loading