@@ -19,36 +19,17 @@ SEXP mk_error(const int xc) {
1919
2020SEXP nano_encode (SEXP object ) {
2121
22- R_xlen_t i , xlen = Rf_xlength (object );
23- const char * s ;
24- unsigned char * buf ;
25- size_t sz , np , outlen = 0 ;
22+ R_xlen_t xlen = Rf_xlength (object );
23+ size_t sz ;
2624 SEXP out ;
2725
2826 if (!Rf_isVectorAtomic (object ))
2927 error_return ("'data' is not an atomic vector type" );
30- switch (TYPEOF (object )) {
31- case REALSXP :
32- sz = xlen * sizeof (double );
33- out = Rf_allocVector (RAWSXP , sz );
34- memcpy (RAW (out ), REAL (object ), sz );
35- break ;
36- case INTSXP :
37- sz = xlen * sizeof (int );
38- out = Rf_allocVector (RAWSXP , sz );
39- memcpy (RAW (out ), INTEGER (object ), sz );
40- break ;
41- case LGLSXP :
42- sz = xlen * sizeof (int );
43- out = Rf_allocVector (RAWSXP , sz );
44- memcpy (RAW (out ), LOGICAL (object ), sz );
45- break ;
46- case CPLXSXP :
47- sz = xlen * sizeof (double ) * 2 ;
48- out = Rf_allocVector (RAWSXP , sz );
49- memcpy (RAW (out ), COMPLEX (object ), sz );
50- break ;
51- case STRSXP :
28+ if (TYPEOF (object ) == STRSXP ) {
29+ const char * s ;
30+ unsigned char * buf ;
31+ size_t np , outlen = 0 ;
32+ R_xlen_t i ;
5233 for (i = 0 ; i < xlen ; i ++ )
5334 outlen += strlen (Rf_translateCharUTF8 (STRING_ELT (object , i ))) + 1 ;
5435 PROTECT (out = Rf_allocVector (RAWSXP , outlen ));
@@ -59,12 +40,34 @@ SEXP nano_encode(SEXP object) {
5940 np += strlen (s ) + 1 ;
6041 }
6142 UNPROTECT (1 );
62- break ;
63- case RAWSXP :
64- out = object ;
65- break ;
66- default :
67- error_return ("vector type for 'data' is unimplemented" );
43+ } else {
44+ switch (TYPEOF (object )) {
45+ case REALSXP :
46+ sz = xlen * sizeof (double );
47+ out = Rf_allocVector (RAWSXP , sz );
48+ memcpy (RAW (out ), REAL (object ), sz );
49+ break ;
50+ case INTSXP :
51+ sz = xlen * sizeof (int );
52+ out = Rf_allocVector (RAWSXP , sz );
53+ memcpy (RAW (out ), INTEGER (object ), sz );
54+ break ;
55+ case LGLSXP :
56+ sz = xlen * sizeof (int );
57+ out = Rf_allocVector (RAWSXP , sz );
58+ memcpy (RAW (out ), LOGICAL (object ), sz );
59+ break ;
60+ case CPLXSXP :
61+ sz = xlen * sizeof (double ) * 2 ;
62+ out = Rf_allocVector (RAWSXP , sz );
63+ memcpy (RAW (out ), COMPLEX (object ), sz );
64+ break ;
65+ case RAWSXP :
66+ out = object ;
67+ break ;
68+ default :
69+ error_return ("vector type for 'data' is unimplemented" );
70+ }
6871 }
6972
7073 return out ;
@@ -100,65 +103,68 @@ SEXP rawOneString(unsigned char *bytes, R_xlen_t nbytes, R_xlen_t *np) {
100103SEXP nano_decode (unsigned char * buf , const size_t sz , const int mod , const int kpr ) {
101104
102105 int tryErr = 0 ;
103- SEXP raw , data , expr , onechar ;
104- R_xlen_t i , m , nbytes = sz , np = 0 ;
106+ SEXP raw , data ;
105107
106- switch (mod ) {
107- case 1 :
108+ if (mod == 1 ) {
108109 PROTECT (raw = Rf_allocVector (RAWSXP , sz ));
109110 memcpy (RAW (raw ), buf , sz );
111+ SEXP expr ;
110112 PROTECT (expr = Rf_lang2 (nano_UnserSymbol , raw ));
111113 data = R_tryEval (expr , R_BaseEnv , & tryErr );
112- UNPROTECT (1 );
113114 if (tryErr ) {
114115 data = raw ;
115116 raw = R_NilValue ;
116117 }
117- break ;
118- case 2 :
118+ UNPROTECT ( 2 ) ;
119+ } else if ( mod == 2 ) {
119120 PROTECT (data = Rf_allocVector (STRSXP , sz ));
121+ R_xlen_t i , m , nbytes = sz , np = 0 ;
120122 for (i = 0 , m = 0 ; i < sz ; i ++ ) {
121- onechar = rawOneString (buf , nbytes , & np );
123+ SEXP onechar = rawOneString (buf , nbytes , & np );
122124 if (onechar == R_NilValue ) break ;
123125 SET_STRING_ELT (data , i , onechar );
124126 if (Rf_xlength (onechar ) > 0 ) m ++ ;
125127 }
126128 SETLENGTH (data , m );
127- break ;
128- case 3 :
129- PROTECT (data = Rf_allocVector (CPLXSXP , sz / (sizeof (double ) * 2 )));
130- memcpy (COMPLEX (data ), buf , sz );
131- break ;
132- case 4 :
133- PROTECT (data = Rf_allocVector (REALSXP , sz / sizeof (double )));
134- memcpy (REAL (data ), buf , sz );
135- break ;
136- case 5 :
137- PROTECT (data = Rf_allocVector (INTSXP , sz / sizeof (int )));
138- memcpy (INTEGER (data ), buf , sz );
139- break ;
140- case 6 :
141- PROTECT (data = Rf_allocVector (LGLSXP , sz / sizeof (int )));
142- memcpy (LOGICAL (data ), buf , sz );
143- break ;
144- case 7 :
145- PROTECT (data = Rf_allocVector (REALSXP , sz / sizeof (double )));
146- memcpy (REAL (data ), buf , sz );
147- break ;
148- case 8 :
149- PROTECT (data = Rf_allocVector (RAWSXP , sz ));
150- memcpy (RAW (data ), buf , sz );
151- break ;
152- default :
153- PROTECT (data = R_NilValue );
129+ UNPROTECT (1 );
130+ } else {
131+ switch (mod ) {
132+ case 3 :
133+ data = Rf_allocVector (CPLXSXP , sz / (sizeof (double ) * 2 ));
134+ memcpy (COMPLEX (data ), buf , sz );
135+ break ;
136+ case 4 :
137+ data = Rf_allocVector (REALSXP , sz / sizeof (double ));
138+ memcpy (REAL (data ), buf , sz );
139+ break ;
140+ case 5 :
141+ data = Rf_allocVector (INTSXP , sz / sizeof (int ));
142+ memcpy (INTEGER (data ), buf , sz );
143+ break ;
144+ case 6 :
145+ data = Rf_allocVector (LGLSXP , sz / sizeof (int ));
146+ memcpy (LOGICAL (data ), buf , sz );
147+ break ;
148+ case 7 :
149+ data = Rf_allocVector (REALSXP , sz / sizeof (double ));
150+ memcpy (REAL (data ), buf , sz );
151+ break ;
152+ case 8 :
153+ data = Rf_allocVector (RAWSXP , sz );
154+ memcpy (RAW (data ), buf , sz );
155+ break ;
156+ default :
157+ data = R_NilValue ;
158+ }
154159 }
155160
156161 if (kpr ) {
157162 SEXP out ;
158163 const char * names [] = {"raw" , "data" , "" };
164+ PROTECT (data );
159165 switch (mod ) {
160166 case 1 :
161- PROTECT (data );
167+ PROTECT (raw );
162168 break ;
163169 case 8 :
164170 PROTECT (raw = data );
@@ -175,7 +181,6 @@ SEXP nano_decode(unsigned char *buf, const size_t sz, const int mod, const int k
175181 return out ;
176182 }
177183
178- UNPROTECT (1 );
179184 return data ;
180185
181186}
0 commit comments