diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index d21def39f..a2a8541ae 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -9589,6 +9589,12 @@ test(1737.3, fwrite(list(1.2,B="foo")), output=",B1.2,foo") test(1737.4, fwrite(list("A,Name"=1.2,B="fo,o")), output="\"A,Name\",B1.2,\"fo,o\"") test(1737.5, fwrite(list(1.2,B=c("foo","bar"))), error="Column 2's length (2) is not the same as column 1's length (1)") +# fwrite ITime +DT = data.table(A=as.ITime(c("23:59:58","23:59:59","12:00:00","00:00:01",NA,"00:00:00"))) +test(1738.1, capture.output(fwrite(DT)), c("A","23:59:58","23:59:59","12:00:00","00:00:01","","00:00:00")) +test(1739.2, capture.output(fwrite(DT)), capture.output(write.csv(DT,row.names=FALSE,quote=FALSE, na=""))) + + ########################## # TODO: Tests involving GForce functions needs to be run with optimisation level 1 and 2, so that both functions are tested all the time. diff --git a/src/data.table.h b/src/data.table.h index d6c9be488..b2b82381f 100644 --- a/src/data.table.h +++ b/src/data.table.h @@ -34,6 +34,10 @@ // init.c void setSizes(); SEXP char_integer64; +SEXP char_ITime; +SEXP char_IDate; +SEXP char_Date; +SEXP char_POSIXct; // dogroups.c SEXP keepattr(SEXP to, SEXP from); diff --git a/src/fwrite.c b/src/fwrite.c index c0e44ffce..742210c85 100644 --- a/src/fwrite.c +++ b/src/fwrite.c @@ -284,16 +284,45 @@ static inline void writeString(SEXP x, char **thisCh) *thisCh = ch; } -static inline Rboolean isInteger64(SEXP x) { +static inline Rboolean INHERITS(SEXP x, SEXP str) { + // Thread safe inherits() by pre-calling install() via mkChar() up front in init.c + // and passing those in here as 'str' for simple and fast non-API pointer compare. + // Not sure inherits() is in R API anyway + // The thread-safety aspect here is only really needed for list columns where the + // class of vector items is tested. Since the column classes themselves are pre-stored + // in (for example) isInteger64[] and isITime[]. SEXP class; - if (TYPEOF(x)==REALSXP && isString(class = getAttrib(x, R_ClassSymbol))) { - for (int i=0; i