Skip to content

Commit 669025a

Browse files
committed
Refactor NodeJS to C string parser
1 parent 333b540 commit 669025a

1 file changed

Lines changed: 93 additions & 54 deletions

File tree

src/napi/addon.c

Lines changed: 93 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ typedef napi_value (*cws_node_fn)(napi_env, napi_callback_info);
8282
struct js_cws_config_t {
8383
struct soap *soap_internal;
8484
int err;
85+
char *str; //Alloc'd draft text for manipulating string and data. Must be free
86+
size_t str_len; // Copied string length
87+
size_t str_size; // Alloc'd string size
8588
};
8689

8790
struct cws_js_err_t {
@@ -194,7 +197,7 @@ static int cws_set_uint64_stat_list(napi_env env, napi_value exports, struct sta
194197

195198
return 0;
196199
}
197-
200+
/* DEPRECATED
198201
#define TEXT_BUF_ALLOC_MAX_SZ 2048
199202
static char *textBufAlloc(size_t len)
200203
{
@@ -206,24 +209,70 @@ static char *textBufAlloc(size_t len)
206209
return NULL;
207210
}
208211
#undef TEXT_BUF_ALLOC_MAX_SZ
212+
*/
213+
static char *textBufAlloc(size_t *sz, struct js_cws_config_t *js_cws_config, size_t len)
214+
{
215+
char *str_tmp;
216+
size_t str_sz_tmp;
217+
218+
if (len>0) {
219+
JS_WITSML21_DEBUG("textBufAlloc: Begin creation/realloc text buf of length %lu", len)
220+
if (js_cws_config->str) {
221+
if (js_cws_config->str_size>len) {
222+
*sz=js_cws_config->str_size;
223+
js_cws_config->str[len]=0;
224+
JS_WITSML21_DEBUG("textBufAlloc: Recycled buffer %p of size %lu", js_cws_config->str, js_cws_config->str_size)
225+
return js_cws_config->str;
226+
}
227+
228+
JS_WITSML21_DEBUG("textBufAlloc: Try to realloc pointer %p of size %lu...", js_cws_config->str, js_cws_config->str_size)
229+
if ((str_tmp=(char *)cws_realloc((void *)js_cws_config->str, (str_sz_tmp=(len+1))))) {
230+
js_cws_config->str_len=len;
231+
*sz=js_cws_config->str_size=str_sz_tmp;
232+
JS_WITSML21_DEBUG("textBufAlloc: realloc'd pointer has changed? = %s", (str_tmp==js_cws_config->str)?"FALSE":"TRUE")
233+
(js_cws_config->str=str_tmp)[len]=0;
234+
JS_WITSML21_DEBUG("textBufAlloc: realloc'd pointer %p of new size %lu...", js_cws_config->str, js_cws_config->str_size)
235+
return js_cws_config->str;
236+
}
237+
238+
*sz=js_cws_config->str_size; // Size <= len. Keep last size (realloc fail) and old pointer
239+
js_cws_config->str_len=0;
240+
js_cws_config->str[0]=0; // On realloc fail text buffer has empty string
241+
JS_WITSML21_DEBUG("textBufAlloc: Fail on realloc. Keep old pointer %p of size %lu", js_cws_config->str, js_cws_config->str_size)
242+
} else {
243+
JS_WITSML21_DEBUG("textBufAlloc: try to create new text buffer of length %lu", len)
244+
if ((js_cws_config->str=(char *)cws_malloc((js_cws_config->str_size=(len+1))))) {
245+
js_cws_config->str_len=len;
246+
*sz=js_cws_config->str_size;
247+
JS_WITSML21_DEBUG("textBufAlloc: try to create text buffer of length %lu. Success at %p with size %lu", len, js_cws_config->str, js_cws_config->str_size)
248+
return js_cws_config->str;
249+
}
250+
js_cws_config->str_len=0;
251+
*sz=js_cws_config->str_size=0;
252+
JS_WITSML21_DEBUG("textBufAlloc: Unable to alloc new text buffer.")
253+
}
254+
}
209255

210-
static char *js_cws_get_value_string_utf8(size_t *len, napi_env env, napi_value value)
256+
return NULL;
257+
}
258+
259+
static char *js_cws_get_value_string_utf8(size_t *len, napi_env env, napi_value value, struct js_cws_config_t *js_cws_config)
211260
{
212261
char *res;
262+
size_t sz;
213263

214264
if (napi_get_value_string_utf8(env, value, NULL, 0, len)!=napi_ok)
215265
return NULL;
216266

217-
if (!(res=textBufAlloc(*len)))
267+
if (!(res=textBufAlloc(&sz, js_cws_config, *len)))
218268
return NULL;
219269

220-
if (napi_get_value_string_utf8(env, value, res, (*len)+1, len)==napi_ok) {
221-
JS_WITSML21_DEBUG("\njs_cws_get_value_string_utf8: has NULL terminator: %d\n", res[*len]==0)
222-
JS_WITSML21_DEBUG("\njs_cws_get_value_string_utf8: value: %s\n", res)
270+
if (napi_get_value_string_utf8(env, value, res, sz, len)==napi_ok) {
271+
JS_WITSML21_DEBUG("js_cws_get_value_string_utf8: has NULL terminator: %d\n", res[*len]==0)
272+
JS_WITSML21_DEBUG("js_cws_get_value_string_utf8: value: %s\n", res)
223273
return res;
224274
}
225275

226-
free((void *)res);
227276
return NULL;
228277
}
229278

@@ -269,22 +318,31 @@ static void js_cws_config_free(struct js_cws_config_t **js_cws_config)
269318
{
270319
CWS_CONFIG *config;
271320

272-
JS_WITSML21_DEBUG("\njs_cws_config_free: Begin free if is NOT NULL %p", *js_cws_config)
321+
JS_WITSML21_DEBUG("js_cws_config_free: Begin free if is NOT NULL %p", *js_cws_config)
273322

274323
if (*js_cws_config) {
275324
config=(CWS_CONFIG *)(*js_cws_config)->soap_internal->user;
276325

277-
JS_WITSML21_DEBUG("\njs_cws_config_free: Destroying soap_internal %p", (*js_cws_config)->soap_internal)
326+
JS_WITSML21_DEBUG("js_cws_config_free: Destroying soap_internal %p", (*js_cws_config)->soap_internal)
278327
cws_internal_soap_free(&(*js_cws_config)->soap_internal);
279328

280-
JS_WITSML21_DEBUG("\njs_cws_config_free: Destroying config %p", config)
329+
JS_WITSML21_DEBUG("js_cws_config_free: Destroying config %p", config)
281330
cws_config_free(&config);
282331

283-
JS_WITSML21_DEBUG("\njs_cws_config_free: Destroying js_cws_config object %p", js_cws_config)
332+
if ((*js_cws_config)->str) {
333+
JS_WITSML21_DEBUG(
334+
"js_cws_config_free: Freeing draft string buffer %p of length %lu of size %lu",
335+
(*js_cws_config)->str, (*js_cws_config)->str_len, (*js_cws_config)->str_size
336+
)
337+
free((*js_cws_config)->str);
338+
(*js_cws_config)->str=NULL;
339+
}
340+
341+
JS_WITSML21_DEBUG("js_cws_config_free: Destroying js_cws_config object %p", js_cws_config)
284342
free((void *)*js_cws_config);
285343
*js_cws_config=NULL;
286344

287-
JS_WITSML21_DEBUG("\njs_cws_config_free: Destroyed")
345+
JS_WITSML21_DEBUG("js_cws_config_free: Destroyed")
288346
}
289347

290348
}
@@ -294,7 +352,7 @@ static struct js_cws_config_t *js_cws_config_init()
294352
CWS_CONFIG *config;
295353
struct js_cws_config_t *js_cws_config;
296354

297-
JS_WITSML21_DEBUG("\njs_cws_config_init: Initializing ...")
355+
JS_WITSML21_DEBUG("js_cws_config_init: Initializing ...")
298356
if (!(js_cws_config=(struct js_cws_config_t *)malloc(sizeof(struct js_cws_config_t))))
299357
return NULL;
300358

@@ -305,8 +363,11 @@ static struct js_cws_config_t *js_cws_config_init()
305363
goto js_cws_config_init_exit2;
306364

307365
js_cws_config->err=0;
366+
js_cws_config->str=NULL;
367+
js_cws_config->str_len=0;
368+
js_cws_config->str_size=0;
308369

309-
JS_WITSML21_DEBUG("\njs_cws_config_init: SUCCESS ... %p", js_cws_config)
370+
JS_WITSML21_DEBUG("js_cws_config_init: SUCCESS ... %p", js_cws_config)
310371

311372
return js_cws_config;
312373

@@ -466,40 +527,36 @@ napi_value c_parseFromFile(napi_env env, napi_callback_info info)
466527
)
467528

468529
JS_CWS_THROW_COND(
469-
(ERR=((filename=js_cws_get_value_string_utf8(&filenameLen, env, argv))==NULL)),
530+
(ERR=((filename=js_cws_get_value_string_utf8(&filenameLen, env, argv, js_cws_instance))==NULL)),
470531
"c_parseFromFile",
471532
"Could not parse filename. Wrong format or empty string or invalid utf-8 or no space in C string buffer",
472533
124
473534
)
474535

475-
JS_CWS_THROW_COND_GOTO(
536+
JS_CWS_THROW_COND(
476537
(ERR=readText((const char **)&text, &textLen, filename)),
477538
"readText", "Could not read xml/text",
478-
ERR, c_parseFromFile_exit1
539+
ERR
479540
)
480541

481542
JS_CWS_THROW_COND_GOTO(
482543
(ERR=c_parse_util(js_cws_instance->soap_internal, (void **)&bson_ser, text, textLen, IS_BSON)),
483544
"c_parse_util", "BSON parse error @ c_parseFromFile",
484-
ERR, c_parseFromFile_exit2
545+
ERR, c_parseFromFile_exit1
485546
)
486547

487548
JS_CWS_THROW_COND_GOTO(
488549
(ERR=js_cws_new_array_buffer(&res, env, (void *)bson_ser->bson, bson_ser->bson_size)),
489550
"js_cws_new_array_buffer", "Could not copy BSON bytes to JavaScript array buffer @ c_parseFromFile",
490-
ERR, c_parseFromFile_exit2
551+
ERR, c_parseFromFile_exit1
491552
)
492553

493554
free((void *)text);
494-
free((void *)filename);
495555

496556
return res;
497557

498-
c_parseFromFile_exit2:
499-
free((void *)text);
500-
501558
c_parseFromFile_exit1:
502-
free((void *)filename);
559+
free((void *)text);
503560

504561
return NULL;
505562
}
@@ -542,41 +599,37 @@ napi_value c_parseFromFileJSON(napi_env env, napi_callback_info info)
542599
)
543600

544601
JS_CWS_THROW_COND(
545-
(ERR=((filename=js_cws_get_value_string_utf8(&filenameLen, env, argv))==NULL)),
602+
(ERR=((filename=js_cws_get_value_string_utf8(&filenameLen, env, argv, js_cws_instance))==NULL)),
546603
"c_parseFromFileJSON",
547604
"Could not parse filename. Wrong format or empty string or invalid utf-8 or no space in C string buffer",
548605
144
549606
)
550607

551-
JS_CWS_THROW_COND_GOTO(
608+
JS_CWS_THROW_COND(
552609
(ERR=readText((const char **)&text, &textLen, filename)),
553610
"readText", "Could not read xml/text @ c_parseFromFileJSON",
554-
ERR, c_parseFromFileJSON_exit1
611+
ERR
555612
)
556613

557614
JS_CWS_THROW_COND_GOTO(
558615
(ERR=c_parse_util(js_cws_instance->soap_internal, (void **)&json_ser, text, textLen, IS_JSON)),
559616
"c_parse_util", "BSON parse error @ c_parseFromFileJSON",
560-
ERR, c_parseFromFileJSON_exit2
617+
ERR, c_parseFromFileJSON_exit1
561618
)
562619

563620
JS_CWS_THROW_COND_GOTO(
564621
(ERR=(napi_create_string_utf8(env, json_ser->json, json_ser->json_len, &res)!=napi_ok)),
565622
"napi_create_string_utf8",
566623
"napi_create_string_utf8 @ c_parseFromFileJSON. Error on parsing JSON string",
567-
145, c_parseFromFileJSON_exit2
624+
145, c_parseFromFileJSON_exit1
568625
)
569626

570627
free((void *)text);
571-
free((void *)filename);
572628

573629
return res;
574630

575-
c_parseFromFileJSON_exit2:
576-
free((void *)text);
577-
578631
c_parseFromFileJSON_exit1:
579-
free((void *)filename);
632+
free((void *)text);
580633

581634
return NULL;
582635
}
@@ -611,26 +664,19 @@ napi_value c_saveToFile(napi_env env, napi_callback_info info)
611664
CHECK_HAS_ERROR("c_saveToFile", "Could not save BSON serialized to file for this object. Object not found or error on parsing", 154)
612665

613666
JS_CWS_THROW_COND(
614-
(filename=js_cws_get_value_string_utf8(&filenameLen, env, argv))==NULL,
667+
(filename=js_cws_get_value_string_utf8(&filenameLen, env, argv, js_cws_instance))==NULL,
615668
"c_saveToFile",
616669
"Could not parse filename. Wrong format or empty string or invalid utf-8 or no space in C string buffer",
617670
155
618671
)
619672

620-
JS_CWS_THROW_COND_GOTO(
673+
JS_CWS_THROW_COND(
621674
(err=writeToFile(js_cws_instance->soap_internal, filename)),
622675
"writeToFile", "Could not save BSON file @ c_saveToFile",
623-
err, c_saveToFile_exit1
676+
err
624677
)
625678

626-
free(filename);
627-
628679
JS_CWS_RETURN_UNDEFINED
629-
630-
c_saveToFile_exit1:
631-
free(filename);
632-
633-
return NULL;
634680
}
635681

636682
napi_value c_saveToFileJSON(napi_env env, napi_callback_info info)
@@ -663,26 +709,19 @@ napi_value c_saveToFileJSON(napi_env env, napi_callback_info info)
663709
CHECK_HAS_ERROR("c_saveToFileJSON", "Could not save JSON serialized to file for this object. Object not found or error on parsing", 154)
664710

665711
JS_CWS_THROW_COND(
666-
(filename=js_cws_get_value_string_utf8(&filenameLen, env, argv))==NULL,
712+
(filename=js_cws_get_value_string_utf8(&filenameLen, env, argv, js_cws_instance))==NULL,
667713
"c_saveToFileJSON",
668714
"Could not parse filename. Wrong format or empty string or invalid utf-8 or no space in C string buffer",
669715
165
670716
)
671717

672-
JS_CWS_THROW_COND_GOTO(
718+
JS_CWS_THROW_COND(
673719
(err=writeToFileJSON(js_cws_instance->soap_internal, filename)),
674720
"writeToFileJSON", "Could not save JSON file @ writeToFileJSON",
675-
err, writeToFileJSON_exit1
721+
err
676722
)
677723

678-
free(filename);
679-
680724
JS_CWS_RETURN_UNDEFINED
681-
682-
writeToFileJSON_exit1:
683-
free(filename);
684-
685-
return NULL;
686725
}
687726

688727
napi_value c_getInstanceName(napi_env env, napi_callback_info info)

0 commit comments

Comments
 (0)