From f18c086bd33d2f418a2c7ca27a9926bb0b91aa87 Mon Sep 17 00:00:00 2001 From: mike Date: Sat, 13 Apr 2024 06:13:07 +1000 Subject: [PATCH] Fix reading of gz file size for endian issue. Fixes #39 --- DESCRIPTION | 2 +- NEWS.md | 3 +++ src/R-yyjson-parse.c | 12 +++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3f5b55d..6cffb6d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: yyjsonr Type: Package Title: Fast 'JSON', 'NDJSON' and 'GeoJSON' Parser and Generator -Version: 0.1.20 +Version: 0.1.20.9000 Authors@R: c( person("Mike", "Cheng", role = c("aut", "cre", 'cph'), email = "mikefc@coolbutuseless.com"), diff --git a/NEWS.md b/NEWS.md index 1eb6154..c4a9f91 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,7 @@ +# yyjsonr 0.1.20.9000 2024-04-12 + +* Get size of gzipped file in an endian-neutral way. Issue #39 # yyjsonr 0.1.20 2024-04-10 diff --git a/src/R-yyjson-parse.c b/src/R-yyjson-parse.c index c75ee93..e17e3e3 100644 --- a/src/R-yyjson-parse.c +++ b/src/R-yyjson-parse.c @@ -1953,6 +1953,8 @@ SEXP parse_from_gzfile_(SEXP filename_, SEXP parse_opts_) { // Read tail end of .gz file to get length. // If uncompressed length > 4GB this method will fail as there are // only 4-bytes reserved for the field! + // Stored as a little-endian 32bit int. Reading this byte-by-byte + // to avoid an endianness issue on 32bit powerpc (Issue #39) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FILE *fp = fopen(filename, "rb"); if (fp == NULL) { @@ -1960,12 +1962,12 @@ SEXP parse_from_gzfile_(SEXP filename_, SEXP parse_opts_) { } fseek(fp, -4, SEEK_END); - int32_t uncompressed_len; - size_t nbytes = fread(&uncompressed_len, 1, 4, fp); + int32_t uncompressed_len = 0; + uncompressed_len += fgetc(fp); + uncompressed_len += fgetc(fp) << 8; + uncompressed_len += fgetc(fp) << 16; + uncompressed_len += fgetc(fp) << 24; fclose(fp); - if (nbytes != 4) { - error("Couldn't read size from end of file: %s", filename); - } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Allocate a buffer to hold the uncompressed file.