diff --git a/R/read_npy.R b/R/read_npy.R index 0262218..9b3fbe4 100644 --- a/R/read_npy.R +++ b/R/read_npy.R @@ -230,52 +230,14 @@ convert_bytes_to_array <- function(bytes, what, shape, size, endian) { (seq_along(bytes) - 1L) %/% size * size bytes <- bytes[ind] } - res <- switch( + res <- .Call( + C_type_convert, + bytes, what, - float = .Call( - C_type_convert_float, - bytes, - size, - shape, - PACKAGE = "grumpy" - ), - int = .Call( - C_type_convert_int, - bytes, - size, - shape, - PACKAGE = "grumpy" - ), - uint = .Call( - C_type_convert_uint, - bytes, - size, - shape, - PACKAGE = "grumpy" - ), - bool = .Call( - C_type_convert_bool, - bytes, - size, - shape, - PACKAGE = "grumpy" - ), - string = .Call( - C_type_convert_string, - bytes, - size, - shape, - PACKAGE = "grumpy" - ), - unicode = .Call( - C_type_convert_unicode, - bytes, - size, - shape, - endian, - PACKAGE = "grumpy" - ), - stop("Unsupported data type: ", what, call. = FALSE) + size, + shape, + endian, + PACKAGE = "grumpy" ) return(res) diff --git a/src/grumpy.c b/src/grumpy.c index c1854af..d602205 100644 --- a/src/grumpy.c +++ b/src/grumpy.c @@ -2,12 +2,7 @@ #include "type_conversion.h" static const R_CallMethodDef callMethods[] = { - {"type_convert_int", (DL_FUNC) &type_convert_int, 3}, - {"type_convert_uint", (DL_FUNC) &type_convert_uint, 3}, - {"type_convert_float", (DL_FUNC) &type_convert_float, 3}, - {"type_convert_bool", (DL_FUNC) &type_convert_bool, 3}, - {"type_convert_string", (DL_FUNC) &type_convert_string, 3}, - {"type_convert_unicode", (DL_FUNC) &type_convert_unicode, 4}, + {"type_convert", (DL_FUNC) &type_convert, 5}, {NULL, NULL, 0} }; diff --git a/src/type_conversion.c b/src/type_conversion.c index a8901a5..8b7fc9e 100644 --- a/src/type_conversion.c +++ b/src/type_conversion.c @@ -1,7 +1,36 @@ #include "type_conversion.h" #include -SEXP type_convert_int(SEXP input, SEXP _n_bytes, SEXP dims) { + +SEXP type_convert(SEXP input, SEXP what, SEXP _n_bytes, SEXP dims, SEXP _endian) { + const char *type = CHAR(STRING_ELT(what, 0)); + SEXP result; + + if (strcmp(type, "float") == 0) + result = type_convert_float(input, _n_bytes); + else if (strcmp(type, "int") == 0) + result = type_convert_int(input, _n_bytes); + else if (strcmp(type, "uint") == 0) + result = type_convert_uint(input, _n_bytes); + else if (strcmp(type, "bool") == 0) + result = type_convert_bool(input, _n_bytes); + else if (strcmp(type, "string") == 0) + result = type_convert_string(input, _n_bytes); + else if (strcmp(type, "unicode") == 0) + result = type_convert_unicode(input, _n_bytes, _endian); + else + error("Unsupported data type: %s", type); + + PROTECT(result); + if (!isNull(dims) && xlength(dims) > 0) { + Rf_dimgets(result, dims); + } + UNPROTECT(1); + + return result; +} + +SEXP type_convert_int(SEXP input, SEXP _n_bytes) { const int n_bytes = INTEGER(_n_bytes)[0]; const R_xlen_t length = xlength(input); @@ -35,16 +64,11 @@ SEXP type_convert_int(SEXP input, SEXP _n_bytes, SEXP dims) { } } - /* Set dim attribute if dims is not NULL / NA */ - if (!isNull(dims) && xlength(dims) > 0) { - Rf_dimgets(data, dims); - } - UNPROTECT(1); return(data); } -SEXP type_convert_uint(SEXP input, SEXP _n_bytes, SEXP dims) { +SEXP type_convert_uint(SEXP input, SEXP _n_bytes) { const int n_bytes = INTEGER(_n_bytes)[0]; const R_xlen_t length = xlength(input); @@ -78,16 +102,11 @@ SEXP type_convert_uint(SEXP input, SEXP _n_bytes, SEXP dims) { } } - /* Set dim attribute if dims is not NULL / NA */ - if (!isNull(dims) && xlength(dims) > 0) { - Rf_dimgets(data, dims); - } - UNPROTECT(1); return(data); } -SEXP type_convert_float(SEXP input, SEXP _n_bytes, SEXP dims){ +SEXP type_convert_float(SEXP input, SEXP _n_bytes) { const int n_bytes = INTEGER(_n_bytes)[0]; const R_xlen_t length = xlength(input); @@ -121,16 +140,11 @@ SEXP type_convert_float(SEXP input, SEXP _n_bytes, SEXP dims){ error("%d byte floating point values are not currently supported\n", n_bytes); } - /* Set dim attribute if dims is not NULL / NA */ - if (!isNull(dims) && xlength(dims) > 0) { - Rf_dimgets(data, dims); - } - UNPROTECT(1); return(data); } -SEXP type_convert_bool(SEXP input, SEXP _n_bytes, SEXP dims) { +SEXP type_convert_bool(SEXP input, SEXP _n_bytes) { const R_xlen_t length = xlength(input); const void* raw_buffer = RAW(input); @@ -148,16 +162,11 @@ SEXP type_convert_bool(SEXP input, SEXP _n_bytes, SEXP dims) { p_data[i] = ((const int8_t *)raw_buffer)[i]; } - /* Set dim attribute if dims is not NULL / NA */ - if (!isNull(dims) && xlength(dims) > 0) { - Rf_dimgets(data, dims); - } - UNPROTECT(1); return(data); } -SEXP type_convert_string(SEXP input, SEXP _n_bytes, SEXP dims) { +SEXP type_convert_string(SEXP input, SEXP _n_bytes) { const int n_bytes = INTEGER(_n_bytes)[0]; const R_xlen_t length = xlength(input); @@ -191,16 +200,11 @@ SEXP type_convert_string(SEXP input, SEXP _n_bytes, SEXP dims) { SET_STRING_ELT(data, i, mkCharCE(field, CE_BYTES)); } - /* Set dim attribute if dims is not NULL / NA */ - if (!isNull(dims) && xlength(dims) > 0) { - Rf_dimgets(data, dims); - } - UNPROTECT(1); return(data); } -SEXP type_convert_unicode(SEXP input, SEXP _n_bytes, SEXP dims, SEXP _endian) { +SEXP type_convert_unicode(SEXP input, SEXP _n_bytes, SEXP _endian) { // n_bytes is the total bytes per string element (num_codepoints * 4). // Bytes are passed as-is from the file; we select UTF-32LE or UTF-32BE @@ -259,11 +263,6 @@ SEXP type_convert_unicode(SEXP input, SEXP _n_bytes, SEXP dims, SEXP _endian) { } Riconv_close(cd); - /* Set dim attribute if dims is not NULL / NA */ - if (!isNull(dims) && xlength(dims) > 0) { - Rf_dimgets(data, dims); - } - UNPROTECT(1); return(data); } \ No newline at end of file diff --git a/src/type_conversion.h b/src/type_conversion.h index 98ce97f..882ed6d 100644 --- a/src/type_conversion.h +++ b/src/type_conversion.h @@ -3,9 +3,10 @@ #include "bit64_conversion.h" #include "float16_conversion.h" -SEXP type_convert_int(SEXP input, SEXP _n_bytes, SEXP dims); -SEXP type_convert_uint(SEXP input, SEXP _n_bytes, SEXP dims); -SEXP type_convert_float(SEXP input, SEXP _n_bytes, SEXP dims); -SEXP type_convert_bool(SEXP input, SEXP _n_bytes, SEXP dims); -SEXP type_convert_string(SEXP input, SEXP _n_bytes, SEXP dims); -SEXP type_convert_unicode(SEXP input, SEXP _n_bytes, SEXP dims, SEXP _endian); +SEXP type_convert(SEXP input, SEXP what, SEXP _n_bytes, SEXP dims, SEXP _endian); +SEXP type_convert_int(SEXP input, SEXP _n_bytes); +SEXP type_convert_uint(SEXP input, SEXP _n_bytes); +SEXP type_convert_float(SEXP input, SEXP _n_bytes); +SEXP type_convert_bool(SEXP input, SEXP _n_bytes); +SEXP type_convert_string(SEXP input, SEXP _n_bytes); +SEXP type_convert_unicode(SEXP input, SEXP _n_bytes, SEXP _endian);