//export ReadMsgpackFrame // // ReadMsgpackFrame reads the msgpack frame at byteOffset in rawStream, decodes the // 2-5 bytes of a msgpack binary array (either bin8, bin16, or bin32), and returns // and the decoded-into-R object and the next byteOffset to use. // func ReadMsgpackFrame(rawStream C.SEXP, byteOffset C.SEXP) C.SEXP { var start int if C.TYPEOF(byteOffset) == C.REALSXP { start = int(C.get_real_elt(byteOffset, 0)) } else if C.TYPEOF(byteOffset) == C.INTSXP { start = int(C.get_int_elt(byteOffset, 0)) } else { C.ReportErrorToR_NoReturn(C.CString("read.msgpack.frame(x, byteOffset) requires byteOffset to be a numeric byte-offset number.")) } // rawStream must be a RAWSXP if C.TYPEOF(rawStream) != C.RAWSXP { C.ReportErrorToR_NoReturn(C.CString("read.msgpack.frame(x, byteOffset) requires x be a RAW vector of bytes.")) } n := int(C.Rf_xlength(rawStream)) if n == 0 { return C.R_NilValue } if start >= n { C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("read.msgpack.frame(x, byteOffset) error: byteOffset(%d) is beyond the length of x (x has len %d).", start, n))) } var decoder [5]byte C.memcpy(unsafe.Pointer(&decoder[0]), unsafe.Pointer(C.get_raw_elt_ptr(rawStream, C.ulonglong(start))), C.size_t(5)) headerSz, _, totalSz, err := DecodeMsgpackBinArrayHeader(decoder[:]) if err != nil { C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("ReadMsgpackFrame error trying to decode msgpack frame: %s", err))) } if start+totalSz > n { C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("read.msgpack.frame(x, byteOffset) error: byteOffset(%d) plus the frames size(%d) goes beyond the length of x (x has len %d).", start, totalSz, n))) } bytes := make([]byte, totalSz) C.memcpy(unsafe.Pointer(&bytes[0]), unsafe.Pointer(C.get_raw_elt_ptr(rawStream, C.ulonglong(start))), C.size_t(totalSz)) rObject := decodeMsgpackToR(bytes[headerSz:]) C.Rf_protect(rObject) returnList := C.allocVector(C.VECSXP, C.R_xlen_t(2)) C.Rf_protect(returnList) C.SET_VECTOR_ELT(returnList, C.R_xlen_t(0), C.Rf_ScalarReal(C.double(float64(start+totalSz)))) C.SET_VECTOR_ELT(returnList, C.R_xlen_t(1), rObject) C.Rf_unprotect_ptr(rObject) C.Rf_unprotect_ptr(returnList) return returnList }
//export ReadNewlineDelimJson // // ReadNewlineDelimJson reads a json object at byteOffset in rawStream, expects // it to be newline terminated, and returns the // decoded-into-R object and the next byteOffset to use (the byte just after // the terminating newline). // func ReadNewlineDelimJson(rawStream C.SEXP, byteOffset C.SEXP) C.SEXP { C.Rf_protect(rawStream) var start int if C.TYPEOF(byteOffset) == C.REALSXP { start = int(C.get_real_elt(byteOffset, 0)) } else if C.TYPEOF(byteOffset) == C.INTSXP { start = int(C.get_int_elt(byteOffset, 0)) } else { C.ReportErrorToR_NoReturn(C.CString("read.ndjson(x, byteOffset) requires byteOffset to be a numeric byte-offset number.")) } // rawStream must be a RAWSXP if C.TYPEOF(rawStream) != C.RAWSXP { C.ReportErrorToR_NoReturn(C.CString("read.ndjson(x, byteOffset) requires x be a RAW vector of bytes.")) } n := int(C.Rf_xlength(rawStream)) if n == 0 { return C.R_NilValue } if start >= n { C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("read.ndjson(x, byteOffset) error: byteOffset(%d) is at or beyond the length of x (x has len %d).", start, n))) } // INVAR: start < n // find the next newline or end of raw array next := int(C.next_newline_pos(rawStream, C.ulonglong(start+1), C.ulonglong(n))) totalSz := next - start bytes := make([]byte, totalSz) fromPtr := unsafe.Pointer(C.get_raw_elt_ptr(rawStream, C.ulonglong(start))) C.memcpy(unsafe.Pointer(&bytes[0]), fromPtr, C.size_t(totalSz)) rObject := decodeJsonToR(bytes) C.Rf_protect(rObject) returnList := C.allocVector(C.VECSXP, C.R_xlen_t(2)) C.Rf_protect(returnList) C.SET_VECTOR_ELT(returnList, C.R_xlen_t(0), C.Rf_ScalarReal(C.double(float64(start+totalSz)))) C.SET_VECTOR_ELT(returnList, C.R_xlen_t(1), rObject) C.Rf_unprotect_ptr(rObject) C.Rf_unprotect_ptr(returnList) C.Rf_unprotect_ptr(rawStream) return returnList }