diff --git a/R/RcppExports.R b/R/RcppExports.R index 4667512..0bbaefe 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -27,7 +27,7 @@ readsas <- function(filePath, debug, selectrows_, selectcols_, empty_to_na, temp #' @param dateval timestamp #' @keywords internal #' @noRd -writesas <- function(filePath, dat, compress, debug, bit32, headersize, pagesize, dateval) { - invisible(.Call(`_readsas_writesas`, filePath, dat, compress, debug, bit32, headersize, pagesize, dateval)) +writesas <- function(filePath, dat, compress, debug, bit32, headersize, pagesize, dateval, encoding32) { + invisible(.Call(`_readsas_writesas`, filePath, dat, compress, debug, bit32, headersize, pagesize, dateval, encoding32)) } diff --git a/R/writesas.R b/R/writesas.R index c028981..09a662e 100644 --- a/R/writesas.R +++ b/R/writesas.R @@ -9,12 +9,13 @@ #'@param bit32 write 32bit file #'@param varlabels optional variable labels #'@param size optional header/pagesize +#'@param encoding encoding 62 = windows, 20 = utf #' #'@useDynLib readsas, .registration=TRUE #' #'@export write.sas <- function(dat, filepath, compress = 0, debug = FALSE, bit32 = FALSE, - varlabels, size) { + varlabels, size, encoding = 20) { filepath <- path.expand(filepath) @@ -96,16 +97,15 @@ write.sas <- function(dat, filepath, compress = 0, debug = FALSE, bit32 = FALSE, # for numerics # formats <- rep("BEST", ncol(dat)) - attr(dat, "vartypes") <- as.integer(vartypes) - attr(dat, "colwidth") <- as.integer(colwidth) - attr(dat, "formats") <- formats - attr(dat, "width") <- width - attr(dat, "decim") <- decim - attr(dat, "labels") <- labels + attr(dat, "vartypes") <- as.integer(vartypes) + attr(dat, "colwidth") <- as.integer(colwidth) + attr(dat, "formats") <- formats + attr(dat, "width") <- width + attr(dat, "decim") <- decim + attr(dat, "labels") <- labels attr(dat, "varlabels") <- varlabels - writesas(filepath, dat, compress = 0, debug = debug, bit32 = bit32, - headersize = size[1], pagesize = size[2], dateval = as_datetime(Sys.time())) - + headersize = size[1], pagesize = size[2], + dateval = as_datetime(Sys.time()), encoding32 = encoding) } diff --git a/man/write.sas.Rd b/man/write.sas.Rd index e4ab0dc..f2f7e0a 100644 --- a/man/write.sas.Rd +++ b/man/write.sas.Rd @@ -11,7 +11,8 @@ write.sas( debug = FALSE, bit32 = FALSE, varlabels, - size + size, + encoding = 20 ) } \arguments{ @@ -28,6 +29,8 @@ write.sas( \item{varlabels}{optional variable labels} \item{size}{optional header/pagesize} + +\item{encoding}{encoding 62 = windows, 20 = utf} } \description{ write.sas diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 1e528cd..d0e17e4 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -27,8 +27,8 @@ BEGIN_RCPP END_RCPP } // writesas -void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, bool debug, bool bit32, int32_t headersize, int32_t pagesize, double dateval); -RcppExport SEXP _readsas_writesas(SEXP filePathSEXP, SEXP datSEXP, SEXP compressSEXP, SEXP debugSEXP, SEXP bit32SEXP, SEXP headersizeSEXP, SEXP pagesizeSEXP, SEXP datevalSEXP) { +void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, bool debug, bool bit32, int32_t headersize, int32_t pagesize, double dateval, int32_t encoding32); +RcppExport SEXP _readsas_writesas(SEXP filePathSEXP, SEXP datSEXP, SEXP compressSEXP, SEXP debugSEXP, SEXP bit32SEXP, SEXP headersizeSEXP, SEXP pagesizeSEXP, SEXP datevalSEXP, SEXP encoding32SEXP) { BEGIN_RCPP Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const char * >::type filePath(filePathSEXP); @@ -39,14 +39,15 @@ BEGIN_RCPP Rcpp::traits::input_parameter< int32_t >::type headersize(headersizeSEXP); Rcpp::traits::input_parameter< int32_t >::type pagesize(pagesizeSEXP); Rcpp::traits::input_parameter< double >::type dateval(datevalSEXP); - writesas(filePath, dat, compress, debug, bit32, headersize, pagesize, dateval); + Rcpp::traits::input_parameter< int32_t >::type encoding32(encoding32SEXP); + writesas(filePath, dat, compress, debug, bit32, headersize, pagesize, dateval, encoding32); return R_NilValue; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_readsas_readsas", (DL_FUNC) &_readsas_readsas, 6}, - {"_readsas_writesas", (DL_FUNC) &_readsas_writesas, 8}, + {"_readsas_writesas", (DL_FUNC) &_readsas_writesas, 9}, {NULL, NULL, 0} }; diff --git a/src/writesas.cpp b/src/writesas.cpp index fc0a821..b9d97af 100644 --- a/src/writesas.cpp +++ b/src/writesas.cpp @@ -41,7 +41,9 @@ using namespace Rcpp; // [[Rcpp::export]] void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, bool debug, bool bit32, int32_t headersize, int32_t pagesize, - double dateval) { + double dateval, int32_t encoding32) { + + int8_t encoding = (int8_t)encoding32; uint32_t k = dat.size(); uint64_t n = dat.nrows(); @@ -149,7 +151,7 @@ void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, double created = dateval, created2 = 0; // 8 double modified = dateval, modified2 = 0; // 16 - double thrdts = 0; + double thrdts = dateval; // possibly make headersize and pagesize variable // int32_t headersize = 65536; @@ -183,7 +185,7 @@ void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, if (bit32 == 1) U64_BYTE_CHECKER_VALUE = 50; if (U64_BYTE_CHECKER_VALUE == 51) ALIGN_2_VALUE = 4; - pkt2 = 20, pkt3 = 0; + pkt2 = 34, pkt3 = 0; writebin(ALIGN_1_CHECKER_VALUE, sas, swapit); writebin(pkt2, sas, swapit); // 34 @@ -194,8 +196,8 @@ void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, int8_t ENDIANNESS = 1; // 0 is swapit = 1 uint8_t PLATFORM = 49; // (1) 49 Unix (2) 50 Win - pkt1 = 0, pkt3 = 0; - // if (bit32 == 1) pkt1 = 50; + pkt1 = 51, pkt3 = 2; + if (bit32 == 1) pkt1 = 50; writebin(pkt1, sas, swapit); // 51 writebin(ENDIANNESS, sas, swapit); writebin(pkt3, sas, swapit); // 2 @@ -258,7 +260,7 @@ void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, writebin(pkt4, sas, swapit); // packet 10 -------------------------------------- // - int8_t encoding = 20; // utf8 + // int8_t encoding = 20; // utf8 pkt1 = 51, pkt2 = 0, pkt3 = 0, pkt4 = 20; if (bit32 == 1) pkt1 = 50; writebin(pkt1, sas, swapit); // 51 @@ -341,10 +343,12 @@ void writesas(const char * filePath, Rcpp::DataFrame dat, uint8_t compress, // large unk // something related to file password? - uint32_t pktu32 = 1157289805; + // 0000 and 4 byte from date + uint32_t pktu32 = 0; + std::memcpy(&pktu32, &created, sizeof(int32_t)); writebin(pktu32, sas, swapit); - pktu32 = 563452161; + pktu32 = 545930268; // three identical smaller unks // required so that the file is identified as SAS file writebin(pktu32, sas, swapit);