@@ -13,8 +13,9 @@ static SEXP nano_eval_prot (void *call) {
1313}
1414
1515static void nano_cleanup (void * data , Rboolean jump ) {
16- if (jump )
17- free (data );
16+ if (jump ) {
17+ nng_msg_free ((nng_msg * ) data );
18+ }
1819}
1920
2021static void nano_eval_safe (void * call ) {
@@ -23,28 +24,12 @@ static void nano_eval_safe (void *call) {
2324
2425static void nano_write_bytes (R_outpstream_t stream , void * src , int len ) {
2526
26- nano_buf * buf = (nano_buf * ) stream -> data ;
27-
28- size_t req = buf -> cur + (size_t ) len ;
29- if (req > buf -> len ) {
30- if (req > R_XLEN_T_MAX ) {
31- if (buf -> len ) free (buf -> buf );
32- Rf_error ("serialization exceeds max length of raw vector" );
33- }
34- do {
35- buf -> len += buf -> len > NANONEXT_SERIAL_THR ? NANONEXT_SERIAL_THR : buf -> len ;
36- } while (buf -> len < req );
37- unsigned char * nbuf = realloc (buf -> buf , buf -> len );
38- if (nbuf == NULL ) {
39- free (buf -> buf );
40- Rf_error ("memory allocation failed" );
41- }
42- buf -> buf = nbuf ;
27+ nng_msg * msg = (nng_msg * ) stream -> data ;
28+ if (nng_msg_append (msg , src , (size_t ) len )) {
29+ nng_msg_free (msg );
30+ Rf_error ("serialization failed" );
4331 }
4432
45- memcpy (buf -> buf + buf -> cur , src , len );
46- buf -> cur += len ;
47-
4833}
4934
5035static void nano_read_bytes (R_inpstream_t stream , void * dst , int len ) {
@@ -111,10 +96,10 @@ static SEXP nano_serialize_hook(SEXP x, SEXP hook_func) {
11196
11297 SEXP out , call ;
11398 PROTECT (call = Rf_lcons (NANO_VECTOR (hook_func )[i ], Rf_cons (x , R_NilValue )));
114- out = R_UnwindProtect (nano_eval_prot , call , nano_cleanup , nano_bundle .buf , NULL );
99+ out = R_UnwindProtect (nano_eval_prot , call , nano_cleanup , nano_bundle .msg , NULL );
115100 UNPROTECT (1 );
116101 if (TYPEOF (out ) != RAWSXP ) {
117- free (nano_bundle .buf );
102+ nng_msg_free (nano_bundle .msg );
118103 Rf_error ("Serialization function for `%s` did not return a raw vector" , NANO_STR_N (klass , i ));
119104 }
120105
@@ -259,28 +244,28 @@ SEXP nano_raw_char(const unsigned char *buf, const size_t sz) {
259244
260245}
261246
262- void nano_serialize (nano_buf * buf , SEXP object , SEXP hook , int header ) {
247+ void nano_serialize (nng_msg * msg , SEXP object , SEXP hook , int header ) {
263248
264- NANO_ALLOC (buf , NANONEXT_INIT_BUFSIZE );
265249 struct R_outpstream_st output_stream ;
266250
267251 if (header || special_marker ) {
268- buf -> buf [0 ] = 0x7 ;
269- buf -> buf [3 ] = (uint8_t ) special_marker ;
270- if (header )
271- memcpy (buf -> buf + 4 , & header , sizeof (int ));
272- buf -> cur += 8 ;
252+ unsigned char magic [4 ] = {0x7 , 0x0 , 0x0 , (uint8_t ) special_marker };
253+ if (nng_msg_append (msg , magic , sizeof (magic )) ||
254+ nng_msg_append (msg , & header , sizeof (int ))) {
255+ nng_msg_free (msg );
256+ Rf_error ("serialization failed" );
257+ }
273258 }
274259
275260 if (hook != R_NilValue ) {
276261 nano_bundle .klass = NANO_VECTOR (hook )[0 ];
277262 nano_bundle .outpstream = & output_stream ;
278- nano_bundle .buf = buf -> buf ;
263+ nano_bundle .msg = msg ;
279264 }
280265
281266 R_InitOutPStream (
282267 & output_stream ,
283- (R_pstream_data_t ) buf ,
268+ (R_pstream_data_t ) msg ,
284269 R_pstream_binary_format ,
285270 NANONEXT_SERIAL_VER ,
286271 NULL ,
@@ -429,10 +414,62 @@ SEXP nano_decode(unsigned char *buf, const size_t sz, const uint8_t mod, SEXP ho
429414
430415}
431416
432- void nano_encode (nano_buf * enc , const SEXP object ) {
417+ void nano_encode (nng_msg * msg , const SEXP object ) {
433418
434419 switch (TYPEOF (object )) {
435- case STRSXP : ;
420+ case STRSXP : {
421+ R_xlen_t xlen = XLENGTH (object );
422+ if (xlen == 1 ) {
423+ const char * s = NANO_STRING (object );
424+ size_t slen = strlen (s ) + 1 ;
425+ if (nng_msg_append (msg , s , slen ))
426+ goto fail ;
427+ } else {
428+ for (R_xlen_t i = 0 ; i < xlen ; i ++ ) {
429+ const char * s = NANO_STR_N (object , i );
430+ size_t slen = strlen (s ) + 1 ;
431+ if (nng_msg_append (msg , s , slen ))
432+ goto fail ;
433+ }
434+ }
435+ break ;
436+ }
437+ case REALSXP :
438+ if (nng_msg_append (msg , DATAPTR_RO (object ), XLENGTH (object ) * sizeof (double )))
439+ goto fail ;
440+ break ;
441+ case INTSXP :
442+ case LGLSXP :
443+ if (nng_msg_append (msg , DATAPTR_RO (object ), XLENGTH (object ) * sizeof (int )))
444+ goto fail ;
445+ break ;
446+ case CPLXSXP :
447+ if (nng_msg_append (msg , DATAPTR_RO (object ), XLENGTH (object ) * 2 * sizeof (double )))
448+ goto fail ;
449+ break ;
450+ case RAWSXP :
451+ if (nng_msg_append (msg , DATAPTR_RO (object ), XLENGTH (object )))
452+ goto fail ;
453+ break ;
454+ case NILSXP :
455+ break ;
456+ default :
457+ nng_msg_free (msg );
458+ Rf_error ("`data` must be an atomic vector type or NULL to send in mode 'raw'" );
459+ }
460+
461+ return ;
462+
463+ fail :
464+ nng_msg_free (msg );
465+ Rf_error ("encode failed" );
466+
467+ }
468+
469+ void nano_encode_buf (nano_buf * enc , const SEXP object ) {
470+
471+ switch (TYPEOF (object )) {
472+ case STRSXP : {
436473 const char * s ;
437474 R_xlen_t xlen = XLENGTH (object );
438475 if (xlen == 1 ) {
@@ -452,6 +489,7 @@ void nano_encode(nano_buf *enc, const SEXP object) {
452489 enc -> cur += slen ;
453490 }
454491 break ;
492+ }
455493 case REALSXP :
456494 NANO_INIT (enc , (unsigned char * ) DATAPTR_RO (object ), XLENGTH (object ) * sizeof (double ));
457495 break ;
0 commit comments