xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/tools/j2s4b/src/j2s4b/j2s.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *  Copyright (c) 2020, Rockchip Electronics Co., Ltd
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  */
14 
15 #include "j2s.h"
16 
17 using namespace RkCam;
18 
19 static bool j2s_template_dumping = false;
20 
21 #if 1
j2s_alloc_data(j2s_ctx * ctx,size_t size)22 __attribute__((weak)) void *j2s_alloc_data(j2s_ctx *ctx, size_t size) {
23   (void)(ctx);
24   return malloc(size);
25 }
26 
j2s_release_data(j2s_ctx * ctx,void * ptr)27 __attribute__((weak)) void j2s_release_data(j2s_ctx *ctx, void *ptr) {
28   (void)(ctx);
29   free(ptr);
30 }
31 #endif
32 
33 static cJSON *_j2s_obj_to_json(j2s_ctx *ctx, int obj_index, void *ptr);
34 
35 static cJSON *_j2s_struct_to_json(j2s_ctx *ctx, int struct_index, void *ptr);
36 
37 static int _j2s_json_to_obj(j2s_ctx *ctx, cJSON *json, cJSON *parent,
38                             int obj_index, void *ptr, bool query);
39 
40 static int _j2s_json_to_struct(j2s_ctx *ctx, cJSON *json, int struct_index,
41                                void *ptr, bool query);
42 
43 static int _j2s_struct_free(j2s_ctx *ctx, int struct_index, void *ptr);
44 
45 #define J2B_MAX_PATH_LEN (128)
46 
struct_map_create(const char * fpath)47 struct_map_t *struct_map_create(const char *fpath) {
48   char map_file_name[J2B_MAX_PATH_LEN] = {0};
49   char block_file_name[J2B_MAX_PATH_LEN] = {0};
50 
51   struct_map_t *new_struct = (struct_map_t *)malloc(sizeof(struct_map_t));
52 
53   if (!new_struct) {
54     return NULL;
55   }
56 
57   snprintf(map_file_name, J2B_MAX_PATH_LEN, "%s.map", fpath);
58   snprintf(block_file_name, J2B_MAX_PATH_LEN, "%s.block", fpath);
59 
60   new_struct->file = fopen(fpath, "wb+");
61   new_struct->map_file = fopen(map_file_name, "wb+");
62   new_struct->block_file = fopen(block_file_name, "wb+");
63 
64   if (!new_struct->file || !new_struct->map_file || !new_struct->block_file) {
65     goto error;
66     return NULL;
67   }
68 
69   new_struct->fpath = strdup(fpath);
70 
71   return new_struct;
72 
73 error:
74   if (new_struct->file)
75     fclose(new_struct->file);
76   if (new_struct->map_file)
77     fclose(new_struct->map_file);
78   if (new_struct->block_file)
79     fclose(new_struct->block_file);
80 
81   if (new_struct)
82     free(new_struct);
83 
84   return NULL;
85 }
86 
struct_map_record_root(struct_map_t * struct_map,const uint8_t * data,size_t len)87 int struct_map_record_root(struct_map_t *struct_map, const uint8_t *data,
88                            size_t len) {
89 
90   if (!struct_map || !data || !len) {
91     return -1;
92   }
93 
94   fwrite(data, 1, len, struct_map->file);
95 
96   struct_map->offset += len;
97   // block data will be merge at end of struct bin
98   struct_map->block_offset += len;
99   struct_map->root_ptr = data;
100 
101   return 0;
102 }
103 
struct_map_record(struct_map_t * struct_map,const uint8_t * data,uint64_t dst_addr,size_t len)104 int struct_map_record(struct_map_t *struct_map, const uint8_t *data,
105                       uint64_t dst_addr, size_t len) {
106 
107   map_index_t map_index;
108 
109   memset(&map_index, 0, sizeof(map_index_t));
110 
111   if (!struct_map || !data || !len) {
112     return -1;
113   }
114 
115   map_index.dst_offset = (void *)dst_addr;
116   map_index.ptr_offset = (void *)struct_map->block_offset;
117   map_index.len = len;
118 
119   fwrite(&map_index, 1, sizeof(map_index_t), struct_map->map_file);
120   fwrite(data, 1, len, struct_map->block_file);
121 
122   struct_map->map_offset += sizeof(map_index_t);
123   struct_map->block_offset += len;
124 
125   return 0;
126 }
127 
struct_map_init(struct_map_t * struct_map)128 int struct_map_init(struct_map_t *struct_map) {
129   if (!struct_map) {
130     return -1;
131   }
132   return 0;
133 }
134 
struct_map_close(struct_map_t * struct_map)135 int struct_map_close(struct_map_t *struct_map) {
136 
137   if (struct_map->file)
138     fclose(struct_map->file);
139 
140   if (struct_map->map_file)
141     fclose(struct_map->map_file);
142 
143   if (struct_map->block_file)
144     fclose(struct_map->block_file);
145 
146   return 0;
147 }
148 
149 static inline int j2s_find_struct_index(j2s_ctx *ctx, const char *name);
150 
151 static int _j2s_struct_to_bin(j2s_ctx *ctx, int struct_index, void *ptr,
152                               size_t len, struct_map_t *struct_map);
153 
j2s_find_struct_index(j2s_ctx * ctx,const char * name)154 static inline int j2s_find_struct_index(j2s_ctx *ctx, const char *name) {
155   if (!name)
156     return -1;
157 
158   for (int i = 0; i < ctx->num_struct; i++) {
159     j2s_struct *struct_obj = &ctx->structs[i];
160     if (!strcmp(struct_obj->name, name))
161       return i;
162   }
163 
164   return -1;
165 }
166 
j2s_struct_free(j2s_ctx * ctx,const char * name,void * ptr)167 int j2s_struct_free(j2s_ctx *ctx, const char *name, void *ptr) {
168   int struct_index = name ? j2s_find_struct_index(ctx, name) : ctx->root_index;
169 
170   return _j2s_struct_free(ctx, struct_index, ptr);
171 }
172 
j2s_struct_to_bin(j2s_ctx * ctx,const char * name,void * ptr,size_t len,const char * bin_path)173 int j2s_struct_to_bin(j2s_ctx *ctx, const char *name, void *ptr, size_t len,
174                       const char *bin_path) {
175   struct_map_t *struct_map = struct_map_create(bin_path);
176   if (!struct_map) {
177     return -1;
178   }
179   int struct_index = name ? j2s_find_struct_index(ctx, name) : ctx->root_index;
180 
181   _j2s_struct_to_bin(ctx, struct_index, ptr, len, struct_map);
182 
183   struct_map_close(struct_map);
184 
185   return 0;
186 }
187 
j2s_struct_to_json(j2s_ctx * ctx,const char * name,void * ptr)188 cJSON *j2s_struct_to_json(j2s_ctx *ctx, const char *name, void *ptr) {
189   int struct_index = name ? j2s_find_struct_index(ctx, name) : ctx->root_index;
190 
191   return _j2s_struct_to_json(ctx, struct_index, ptr);
192 }
193 
j2s_json_to_struct(j2s_ctx * ctx,cJSON * json,const char * name,void * ptr)194 int j2s_json_to_struct(j2s_ctx *ctx, cJSON *json, const char *name, void *ptr) {
195   int struct_index = name ? j2s_find_struct_index(ctx, name) : ctx->root_index;
196 
197   return _j2s_json_to_struct(ctx, json, struct_index, ptr, false);
198 }
199 
j2s_json_from_struct(j2s_ctx * ctx,cJSON * json,const char * name,void * ptr)200 int j2s_json_from_struct(j2s_ctx *ctx, cJSON *json, const char *name,
201                          void *ptr) {
202   int struct_index = name ? j2s_find_struct_index(ctx, name) : ctx->root_index;
203 
204   return _j2s_json_to_struct(ctx, json, struct_index, ptr, true);
205 }
206 
207 /* Enum name to value */
j2s_enum_get_value(j2s_ctx * ctx,int enum_index,const char * name)208 static inline int j2s_enum_get_value(j2s_ctx *ctx, int enum_index,
209                                      const char *name) {
210   j2s_enum *enum_obj;
211 
212   if (enum_index < 0 || !name)
213     return -1;
214 
215   enum_obj = &ctx->enums[enum_index];
216 
217   for (int i = 0; i < enum_obj->num_value; i++) {
218     j2s_enum_value *enum_value = &ctx->enum_values[enum_obj->value_index + i];
219 
220     if (!strcmp(enum_value->name, name))
221       return enum_value->value;
222   }
223 
224   ERR("unknown enum name: %s for %s\n", name, enum_obj->name);
225   return -1;
226 }
227 
228 /* Enum value to name */
j2s_enum_get_name(j2s_ctx * ctx,int enum_index,int value)229 static inline const char *j2s_enum_get_name(j2s_ctx *ctx, int enum_index,
230                                             int value) {
231   j2s_enum *enum_obj;
232 
233   if (enum_index < 0)
234     goto out;
235 
236   enum_obj = &ctx->enums[enum_index];
237 
238   for (int i = 0; i < enum_obj->num_value; i++) {
239     j2s_enum_value *enum_value = &ctx->enum_values[enum_obj->value_index + i];
240 
241     if (enum_value->value == value)
242       return enum_value->name;
243   }
244 
245   ERR("unknown enum value: %d for %s\n", value, enum_obj->name);
246 out:
247   return "INVALID";
248 }
249 
_j2s_enum_to_json(j2s_ctx * ctx,int enum_index)250 static cJSON *_j2s_enum_to_json(j2s_ctx *ctx, int enum_index) {
251   j2s_enum *enum_obj;
252   cJSON *root, *item;
253 
254   if (enum_index < 0)
255     return NULL;
256 
257   enum_obj = &ctx->enums[enum_index];
258 
259   root = RkCam::cJSON_CreateObject();
260   DASSERT(root, return NULL);
261 
262   for (int i = 0; i < enum_obj->num_value; i++) {
263     j2s_enum_value *enum_value = &ctx->enum_values[enum_obj->value_index + i];
264 
265     item = RkCam::cJSON_CreateNumber(enum_value->value);
266     if (item)
267       RkCam::cJSON_AddItemToObject(root, enum_value->name, item);
268   }
269 
270   return root;
271 }
272 
j2s_enums_to_json(j2s_ctx * ctx)273 cJSON *j2s_enums_to_json(j2s_ctx *ctx) {
274   cJSON *root, *item;
275 
276   if (!ctx->num_enum)
277     return NULL;
278 
279   root = cJSON_CreateObject();
280   DASSERT(root, return NULL);
281 
282   for (int i = 0; i < ctx->num_enum; i++) {
283     j2s_enum *enum_obj = &ctx->enums[i];
284 
285     item = _j2s_enum_to_json(ctx, i);
286     if (item)
287       cJSON_AddItemToObject(root, enum_obj->name, item);
288   }
289 
290   return root;
291 }
292 
_j2s_struct_to_template_json(j2s_ctx * ctx,int struct_index)293 static cJSON *_j2s_struct_to_template_json(j2s_ctx *ctx, int struct_index) {
294   j2s_struct *struct_obj;
295   cJSON *json;
296 
297   if (struct_index < 0)
298     return NULL;
299 
300   struct_obj = &ctx->structs[struct_index];
301   if (struct_obj->child_index < 0)
302     return NULL;
303 
304   DBG("start struct: %s\n", struct_obj->name);
305   j2s_template_dumping = true;
306   json = _j2s_struct_to_json(ctx, struct_index, NULL);
307   j2s_template_dumping = false;
308   DBG("finish struct: %s\n", struct_obj->name);
309 
310   return json;
311 }
312 
j2s_struct_to_template_json(j2s_ctx * ctx,const char * name)313 cJSON *j2s_struct_to_template_json(j2s_ctx *ctx, const char *name) {
314   int struct_index = name ? j2s_find_struct_index(ctx, name) : ctx->root_index;
315 
316   return _j2s_struct_to_template_json(ctx, struct_index);
317 }
318 
j2s_struct_size(j2s_ctx * ctx,int struct_index)319 int j2s_struct_size(j2s_ctx *ctx, int struct_index) {
320   j2s_struct *struct_obj;
321   j2s_obj *child;
322   int child_index, child_size;
323 
324   if (struct_index < 0)
325     return 0;
326 
327   struct_obj = &ctx->structs[struct_index];
328 
329   /* Find last child */
330   for (child = NULL, child_index = struct_obj->child_index; child_index >= 0;
331        child_index = child->next_index)
332     child = &ctx->objs[child_index];
333 
334   if (!child)
335     return 0;
336 
337   if (J2S_IS_POINTER(child)) {
338     child_size = (int)sizeof(void *);
339   } else if (J2S_IS_ARRAY(child)) {
340     child_size = child->elem_size * child->num_elem;
341   } else {
342     child_size = child->elem_size;
343   }
344 
345   return child_size + child->offset;
346 }
347 
j2s_type_name(j2s_type type)348 const char *j2s_type_name(j2s_type type) {
349   switch (type) {
350   case J2S_TYPE_INT_8:
351     return "int8_t";
352   case J2S_TYPE_UINT_8:
353     return "uint8_t";
354   case J2S_TYPE_INT_16:
355     return "int16_t";
356   case J2S_TYPE_UINT_16:
357     return "uint16_t";
358   case J2S_TYPE_INT_32:
359     return "int32_t";
360   case J2S_TYPE_UINT_32:
361     return "uint32_t";
362   case J2S_TYPE_INT_64:
363     return "int64_t";
364   case J2S_TYPE_UINT_64:
365     return "uint64_t";
366   case J2S_TYPE_FLOAT:
367     return "float";
368   case J2S_TYPE_DOUBLE:
369     return "double";
370   case J2S_TYPE_STRING:
371     return "char";
372   case J2S_TYPE_STRUCT:
373     return "struct";
374   default:
375     return "unknown";
376   }
377 }
378 
379 /* Get number value from a obj */
j2s_obj_get_value(j2s_ctx * ctx,int obj_index,void * ptr_)380 static inline double j2s_obj_get_value(j2s_ctx *ctx, int obj_index,
381                                        void *ptr_) {
382   j2s_obj *obj;
383   double value;
384   char *ptr = (char *)ptr_;
385 
386   if (!ptr || obj_index < 0)
387     return 0;
388 
389   obj = &ctx->objs[obj_index];
390   ptr += obj->offset;
391 
392 #define J2S_FETCH_NUM(type, ptr)                                               \
393   value = (double)*((type *)ptr);                                              \
394   return value;
395 
396   switch (obj->type) {
397   case J2S_TYPE_INT_8:
398     J2S_FETCH_NUM(int8_t, ptr);
399   case J2S_TYPE_UINT_8:
400     J2S_FETCH_NUM(uint8_t, ptr);
401   case J2S_TYPE_INT_16:
402     J2S_FETCH_NUM(int16_t, ptr);
403   case J2S_TYPE_UINT_16:
404     J2S_FETCH_NUM(uint16_t, ptr);
405   case J2S_TYPE_INT_32:
406     J2S_FETCH_NUM(int32_t, ptr);
407   case J2S_TYPE_UINT_32:
408     J2S_FETCH_NUM(uint32_t, ptr);
409   case J2S_TYPE_INT_64:
410     J2S_FETCH_NUM(int64_t, ptr);
411   case J2S_TYPE_UINT_64:
412     J2S_FETCH_NUM(uint64_t, ptr);
413   case J2S_TYPE_FLOAT:
414     J2S_FETCH_NUM(float, ptr);
415   case J2S_TYPE_DOUBLE:
416     J2S_FETCH_NUM(double, ptr);
417   default:
418     return 0;
419   }
420 }
421 
422 /* Set number value to a obj */
j2s_obj_set_value(j2s_ctx * ctx,int obj_index,double value,void * ptr_)423 static inline int j2s_obj_set_value(j2s_ctx *ctx, int obj_index, double value,
424                                     void *ptr_) {
425   j2s_obj *obj;
426   char *ptr = (char *)ptr_;
427 
428   if (!ptr || obj_index < 0)
429     return 0;
430 
431   obj = &ctx->objs[obj_index];
432   ptr += obj->offset;
433 
434 #define J2S_STORE_NUM(type, value, ptr)                                        \
435   *(type *)ptr = (type)value;                                                  \
436   return 0;
437 
438   switch (obj->type) {
439   case J2S_TYPE_INT_8:
440     J2S_STORE_NUM(int8_t, value, ptr);
441   case J2S_TYPE_UINT_8:
442     J2S_STORE_NUM(uint8_t, value, ptr);
443   case J2S_TYPE_INT_16:
444     J2S_STORE_NUM(int16_t, value, ptr);
445   case J2S_TYPE_UINT_16:
446     J2S_STORE_NUM(uint16_t, value, ptr);
447   case J2S_TYPE_INT_32:
448     J2S_STORE_NUM(int32_t, value, ptr);
449   case J2S_TYPE_UINT_32:
450     J2S_STORE_NUM(uint32_t, value, ptr);
451   case J2S_TYPE_INT_64:
452     J2S_STORE_NUM(int64_t, value, ptr);
453   case J2S_TYPE_UINT_64:
454     J2S_STORE_NUM(uint64_t, value, ptr);
455   case J2S_TYPE_FLOAT:
456     J2S_STORE_NUM(float, value, ptr);
457   case J2S_TYPE_DOUBLE:
458     J2S_STORE_NUM(double, value, ptr);
459   default:
460     return 0;
461   }
462 }
463 
464 /* Extract array to the first elem */
j2s_extract_array(j2s_obj * obj)465 static inline void j2s_extract_array(j2s_obj *obj) {
466   if (obj->flags & J2S_FLAG_DEP_ARRAY) {
467     obj->flags &= ~J2S_FLAG_DEP_ARRAY;
468     obj->num_elem = obj->elem_size / obj->base_elem_size;
469   } else {
470     obj->flags &= ~J2S_FLAG_ARRAY;
471     obj->num_elem = 1;
472   }
473 
474   obj->elem_size = obj->base_elem_size;
475 }
476 
477 /* Extract dynamic array to normal array */
j2s_extract_dynamic_array(j2s_obj * obj,int len,void * ptr_)478 static inline void *j2s_extract_dynamic_array(j2s_obj *obj, int len,
479                                               void *ptr_) {
480   char *ptr = (char *)ptr_;
481 
482   if (!j2s_template_dumping) {
483     ptr += obj->offset;
484     ptr = (char *)(*(void **)ptr);
485     if (!ptr)
486       return NULL;
487   }
488 
489   obj->offset = 0;
490   obj->len_index = -1;
491   obj->num_elem = len;
492 
493   if (obj->flags & J2S_FLAG_DEP_POINTER) {
494     obj->flags &= ~J2S_FLAG_DEP_POINTER;
495   } else {
496     obj->flags &= ~J2S_FLAG_ARRAY_POINTER;
497     obj->flags &= ~J2S_FLAG_POINTER;
498   }
499 
500   if (obj->flags & J2S_FLAG_ARRAY) {
501     obj->flags |= J2S_FLAG_DEP_ARRAY;
502   } else {
503     obj->flags |= J2S_FLAG_ARRAY;
504   }
505 
506   return ptr;
507 }
508 
j2s_get_index_json(j2s_ctx * ctx,cJSON * parent,int obj_index)509 static cJSON *j2s_get_index_json(j2s_ctx *ctx, cJSON *parent, int obj_index) {
510   j2s_obj *obj;
511   char index_name[MAX_NAME + 10];
512 
513   if (obj_index < 0)
514     return NULL;
515 
516   obj = &ctx->objs[obj_index];
517 
518   /* Handle array with index obj @<name>_index */
519   snprintf(index_name, sizeof(index_name), "@%s_index", obj->name);
520   return cJSON_GetObjectItemCaseSensitive(parent, index_name);
521 }
522 
_j2s_obj_to_json(j2s_ctx * ctx,int obj_index,void * ptr_)523 static cJSON *_j2s_obj_to_json(j2s_ctx *ctx, int obj_index, void *ptr_) {
524   j2s_obj *obj;
525   cJSON *root;
526   double value;
527   char *ptr = (char *)ptr_;
528 
529   if (obj_index < 0)
530     return NULL;
531 
532   obj = &ctx->objs[obj_index];
533 
534   DBG("handling obj: %s from %p[%d]\n", obj->name, ptr, obj->offset);
535 
536   /* Handle simple string */
537   if (J2S_IS_SIMPLE_STRING(obj)) {
538     if (j2s_template_dumping)
539       return cJSON_CreateString("");
540 
541     ptr += obj->offset;
542     if (obj->flags & J2S_FLAG_POINTER)
543       ptr = *(char **)ptr;
544     return cJSON_CreateString(ptr ? ptr : "");
545   }
546 
547   /* Handle array member */
548   if (J2S_IS_ARRAY(obj)) {
549     j2s_obj tmp_obj;
550     cJSON *item;
551 
552     root = cJSON_CreateArray();
553     DASSERT(root, return NULL);
554 
555     tmp_obj = *obj;
556 
557     /* Walk into array */
558     j2s_extract_array(obj);
559 
560     for (int i = 0; i < tmp_obj.num_elem; i++) {
561       DBG("handling array: %s %d/%d\n", obj->name, i, tmp_obj.num_elem);
562 
563       item = _j2s_obj_to_json(ctx, obj_index, ptr);
564       if (item)
565         cJSON_AddItemToArray(root, item);
566 
567       obj->offset += tmp_obj.elem_size;
568     }
569 
570     *obj = tmp_obj;
571     return root;
572   }
573 
574   /* Handle dynamic array */
575   if (J2S_IS_POINTER(obj)) {
576     j2s_obj tmp_obj;
577     int len;
578 
579     DASSERT_MSG(obj->len_index >= 0, return NULL,
580                 "dynamic array %s missing len\n", obj->name);
581 
582     if (j2s_template_dumping) {
583       len = 1;
584     } else {
585       len = j2s_obj_get_value(ctx, obj->len_index, ptr);
586     }
587 
588     if (!len)
589       return cJSON_CreateArray();
590 
591     tmp_obj = *obj;
592 
593     /* Walk into dynamic array */
594     ptr = (char *)j2s_extract_dynamic_array(obj, len, ptr);
595     DASSERT_MSG(j2s_template_dumping || ptr, return NULL,
596                 "found null pointer at %s\n", obj->name);
597 
598     DBG("handling dynamic array: %s %d*%d from %p\n", obj->name, obj->elem_size,
599         obj->num_elem, ptr);
600 
601     root = _j2s_obj_to_json(ctx, obj_index, ptr);
602 
603     *obj = tmp_obj;
604     return root;
605   }
606 
607   /* Handle struct member */
608   if (obj->type == J2S_TYPE_STRUCT)
609     return _j2s_struct_to_json(ctx, obj->struct_index, ptr + obj->offset);
610 
611   /* Handle basic member */
612   if (j2s_template_dumping) {
613     for (int i = 0; i < ctx->num_obj; i++) {
614       if (ctx->objs[i].len_index == obj_index)
615         return cJSON_CreateNumber(1);
616     }
617 
618     if (obj->enum_index >= 0) {
619       /* Use first value as default */
620       j2s_enum *enum_obj = &ctx->enums[obj->enum_index];
621       j2s_enum_value *enum_value = &ctx->enum_values[enum_obj->value_index];
622 
623       return cJSON_CreateString(enum_value->name);
624     }
625 
626     return cJSON_CreateNumber(0);
627   }
628 
629   value = j2s_obj_get_value(ctx, obj_index, ptr);
630 
631   if (obj->enum_index >= 0) {
632     /* Convert enum value to name */
633     const char *name = j2s_enum_get_name(ctx, obj->enum_index, (int)value);
634     return cJSON_CreateString(name);
635   }
636 
637   return cJSON_CreateNumber(value);
638 }
639 
_j2s_struct_to_json(j2s_ctx * ctx,int struct_index,void * ptr)640 static cJSON *_j2s_struct_to_json(j2s_ctx *ctx, int struct_index, void *ptr) {
641   j2s_struct *struct_obj;
642   j2s_obj *child;
643   cJSON *root, *item;
644   int child_index, ret = 0;
645 
646   if (struct_index < 0)
647     return NULL;
648 
649   struct_obj = &ctx->structs[struct_index];
650   if (struct_obj->child_index < 0)
651     return NULL;
652 
653   root = cJSON_CreateObject();
654   DASSERT(root, return NULL);
655 
656   DBG("start struct: %s from %p\n", struct_obj->name, ptr);
657 
658   ret = -1;
659 
660   /* Walk child list */
661   for (child_index = struct_obj->child_index; child_index >= 0;
662        child_index = child->next_index) {
663     child = &ctx->objs[child_index];
664 
665     DBG("start child: %s (%s) from %p\n", child->name, struct_obj->name, ptr);
666 
667     item = _j2s_obj_to_json(ctx, child_index, ptr);
668     DBG("finish child: %s (%s)\n", child->name, struct_obj->name);
669 
670     if (item) {
671       if (ctx->dump_desc && child_index < ctx->num_desc) {
672         /* Dump desc to template JSON as @<member> */
673         char buf[MAX_NAME + 1] = "@";
674 
675         const char *desc = ctx->descs[child_index];
676         if (desc) {
677           cJSON *json = cJSON_CreateString(desc);
678           DASSERT(json, goto out);
679 
680           strcat(buf, child->name);
681           cJSON_AddItemToObject(root, buf, json);
682         }
683       }
684 
685       cJSON_AddItemToObject(root, child->name, item);
686     }
687   }
688 
689   ret = 0;
690 out:
691   DBG("finish struct: %s\n", struct_obj->name);
692 
693   if (ret < 0) {
694     cJSON_Delete(root);
695     return NULL;
696   }
697   return root;
698 }
699 
_j2s_obj_free(j2s_ctx * ctx,int obj_index,void * ptr_)700 static int _j2s_obj_free(j2s_ctx *ctx, int obj_index, void *ptr_) {
701   j2s_obj *obj;
702   char *ptr = (char *)ptr_;
703 
704   if (obj_index < 0)
705     return -1;
706 
707   obj = &ctx->objs[obj_index];
708 
709   /* Handle simple string */
710   if (J2S_IS_SIMPLE_STRING(obj)) {
711     ptr += obj->offset;
712 
713     if (obj->flags & J2S_FLAG_ARRAY) {
714       return 0;
715     }
716 
717     if (obj->flags & J2S_FLAG_POINTER) {
718       ptr = *(char **)ptr;
719     }
720 
721     if (ptr) {
722       free(ptr);
723     }
724     return 0;
725   }
726 
727   /* Handle array member */
728   if (J2S_IS_ARRAY(obj)) {
729     j2s_obj tmp_obj;
730     tmp_obj = *obj;
731 
732     /* Walk into array */
733     j2s_extract_array(obj);
734 
735     for (int i = 0; i < tmp_obj.num_elem; i++) {
736       _j2s_obj_free(ctx, obj_index, ptr);
737       obj->offset += tmp_obj.elem_size;
738     }
739 
740     *obj = tmp_obj;
741     return 0;
742   }
743 
744   /* Handle dynamic array */
745   if (J2S_IS_POINTER(obj)) {
746     j2s_obj tmp_obj;
747     void *root_ptr = *(void **)ptr;
748     int len;
749 
750     if (obj->len_index < 0) {
751       DBG("dynamic array %s missing len\n", obj->name);
752       return -1;
753     }
754 
755     len = j2s_obj_get_value(ctx, obj->len_index, ptr);
756 
757     if (len <= 0) {
758       DBG("array size error: %s %d\n", obj->name, len);
759       return -1;
760     }
761 
762     tmp_obj = *obj;
763 
764     /* Walk into dynamic array */
765     ptr = (char *)j2s_extract_dynamic_array(obj, len, ptr);
766 
767     _j2s_obj_free(ctx, obj_index, ptr);
768 
769     if (ptr) {
770       free(ptr);
771     }
772 
773     *obj = tmp_obj;
774     return 0;
775   }
776 
777   /* Handle struct member */
778   if (obj->type == J2S_TYPE_STRUCT) {
779     return _j2s_struct_free(ctx, obj->struct_index, ptr + obj->offset);
780   }
781 
782   return 0;
783 }
784 
_j2s_struct_free(j2s_ctx * ctx,int struct_index,void * ptr)785 static int _j2s_struct_free(j2s_ctx *ctx, int struct_index, void *ptr) {
786   j2s_struct *struct_obj = NULL;
787   j2s_obj *child = NULL;
788   int child_index, ret = 0;
789 
790   if (struct_index < 0)
791     return -1;
792 
793   struct_obj = &ctx->structs[struct_index];
794   if (struct_obj->child_index < 0)
795     return -1;
796 
797   ret = -1;
798 
799   /* Walk child list */
800   for (child_index = struct_obj->child_index; child_index >= 0;
801        child_index = child->next_index) {
802     child = &ctx->objs[child_index];
803     ret = _j2s_obj_free(ctx, child_index, ptr);
804   }
805 
806   return ret;
807 }
808 
_j2s_obj_to_bin(j2s_ctx * ctx,int obj_index,void * ptr_,struct_map_t * struct_map)809 static int _j2s_obj_to_bin(j2s_ctx *ctx, int obj_index, void *ptr_,
810                            struct_map_t *struct_map) {
811   j2s_obj *obj;
812   char *ptr = (char *)ptr_;
813 
814   if (obj_index < 0 || !struct_map)
815     return -1;
816 
817   obj = &ctx->objs[obj_index];
818 
819   DBG("------->obj info[%s][%d]\n", obj->name, obj_index);
820 
821   /* Handle simple string */
822   if (J2S_IS_SIMPLE_STRING(obj)) {
823     ptr += obj->offset;
824 
825     if (obj->flags & J2S_FLAG_ARRAY) {
826       return 0;
827     }
828 
829     if (obj->flags & J2S_FLAG_POINTER) {
830       ptr = *(char **)ptr;
831     }
832 
833     if (ptr) {
834       struct_map_record(struct_map, (const uint8_t *)ptr, (uint64_t)ptr,
835                         strlen(ptr));
836     }
837     return 0;
838   }
839 
840   /* Handle array member */
841   if (J2S_IS_ARRAY(obj)) {
842     j2s_obj tmp_obj;
843     tmp_obj = *obj;
844 
845     /* Walk into array */
846     j2s_extract_array(obj);
847 
848     for (int i = 0; i < tmp_obj.num_elem; i++) {
849       _j2s_obj_to_bin(ctx, obj_index, ptr, struct_map);
850       obj->offset += tmp_obj.elem_size;
851     }
852 
853     *obj = tmp_obj;
854     return 0;
855   }
856 
857   /* Handle dynamic array */
858   if (J2S_IS_POINTER(obj)) {
859     j2s_obj tmp_obj;
860     void *root_ptr = *(void **)ptr;
861     int len;
862 
863     if (obj->len_index < 0) {
864       DBG("dynamic array %s missing len\n", obj->name);
865       return -1;
866     }
867 
868     len = j2s_obj_get_value(ctx, obj->len_index, ptr);
869 
870     if (len <= 0) {
871       DBG("array size error: %s %d\n", obj->name, len);
872       return -1;
873     }
874 
875     tmp_obj = *obj;
876 
877     /* Walk into dynamic array */
878     ptr = (char *)j2s_extract_dynamic_array(obj, len, ptr);
879 
880     _j2s_obj_to_bin(ctx, obj_index, ptr, struct_map);
881 
882     if (ptr) {
883       DBG("%s-----dynamic size:[%d]x[%d]\n", obj->name, obj->base_elem_size,
884           len);
885       struct_map_record(struct_map, (const uint8_t *)ptr, (uint64_t)ptr,
886                         obj->base_elem_size * len);
887     }
888 
889     *obj = tmp_obj;
890     return 0;
891   }
892 
893   /* Handle struct member */
894   if (obj->type == J2S_TYPE_STRUCT) {
895     return _j2s_struct_to_bin(ctx, obj->struct_index, ptr + obj->offset, 1,
896                               struct_map);
897   }
898 
899   return 0;
900 }
901 
_j2s_struct_to_bin(j2s_ctx * ctx,int struct_index,void * ptr,size_t len,struct_map_t * struct_map)902 static int _j2s_struct_to_bin(j2s_ctx *ctx, int struct_index, void *ptr,
903                               size_t len, struct_map_t *struct_map) {
904   j2s_struct *struct_obj = NULL;
905   j2s_obj *child = NULL;
906   int child_index, ret = 0;
907 
908   if (!struct_map) {
909     return -1;
910   }
911 
912   if (struct_index < 0)
913     return -1;
914 
915   struct_obj = &ctx->structs[struct_index];
916   if (struct_obj->child_index < 0)
917     return -1;
918 
919   struct_map_record_root(struct_map, (const uint8_t *)ptr, len);
920 
921   ret = -1;
922 
923   /* Walk child list */
924   for (child_index = struct_obj->child_index; child_index >= 0;
925        child_index = child->next_index) {
926     child = &ctx->objs[child_index];
927     ret = _j2s_obj_to_bin(ctx, child_index, ptr, struct_map);
928   }
929 
930   return ret;
931 }
932 
j2s_json_to_array_with_index(j2s_ctx * ctx,cJSON * json,cJSON * index_json,cJSON * parent,j2s_obj * obj,void * ptr,bool query)933 static int j2s_json_to_array_with_index(j2s_ctx *ctx, cJSON *json,
934                                         cJSON *index_json, cJSON *parent,
935                                         j2s_obj *obj, void *ptr, bool query) {
936   j2s_obj tmp_obj;
937   cJSON *index_item, *item;
938   int size, index, ret = -1;
939 
940   size = cJSON_GetArraySize(index_json);
941   if (!size)
942     return 0;
943 
944   tmp_obj = *obj;
945 
946   /* Walk into array */
947   j2s_extract_array(obj);
948 
949   if (query) {
950     cJSON *root;
951 
952     /* Clear the original array */
953     root = cJSON_CreateArray();
954     cJSON_ReplaceItemInObjectCaseSensitive(parent, obj->name, root);
955 
956     for (int i = 0; i < size; i++) {
957       index_item = cJSON_GetArrayItem(index_json, i);
958       index = cJSON_GetNumberValue(index_item);
959       obj->offset = tmp_obj.offset + index * tmp_obj.elem_size;
960       item = NULL;
961 
962       DBG("handling index array: %s %d/%d\n", obj->name, index,
963           tmp_obj.num_elem);
964 
965       /* Query item */
966       if (index < tmp_obj.num_elem)
967         item = _j2s_obj_to_json(ctx, obj - ctx->objs, ptr);
968 
969       if (!item) {
970         item = cJSON_CreateObject();
971         if (!item) {
972           ret = -1;
973           break;
974         }
975       }
976 
977       cJSON_AddItemToArray(root, item);
978     }
979   } else {
980     for (int i = 0; i < size; i++) {
981       index_item = cJSON_GetArrayItem(index_json, i);
982       index = cJSON_GetNumberValue(index_item);
983       obj->offset = tmp_obj.offset + index * tmp_obj.elem_size;
984 
985       DBG("handling index array: %s %d/%d\n", obj->name, index,
986           tmp_obj.num_elem);
987 
988       if (index >= tmp_obj.num_elem)
989         continue;
990 
991       /* Apply item */
992       item = cJSON_GetArrayItem(json, i);
993       if (!item)
994         break;
995 
996       ret = _j2s_json_to_obj(ctx, item, parent, obj - ctx->objs, ptr, false);
997       if (ret < 0)
998         break;
999     }
1000   }
1001 
1002   *obj = tmp_obj;
1003   return ret;
1004 }
1005 
_j2s_json_to_obj(j2s_ctx * ctx,cJSON * json,cJSON * parent,int obj_index,void * ptr_,bool query)1006 static int _j2s_json_to_obj(j2s_ctx *ctx, cJSON *json, cJSON *parent,
1007                             int obj_index, void *ptr_, bool query) {
1008   j2s_obj *obj;
1009   cJSON *root = json;
1010   int ret = 0;
1011   char *ptr = (char *)ptr_;
1012 
1013   if (obj_index < 0)
1014     return -1;
1015 
1016   obj = &ctx->objs[obj_index];
1017 
1018   DBG("handling obj: %s from %p[%d]\n", obj->name, ptr, obj->offset);
1019 
1020   /* Handle simple string */
1021   if (J2S_IS_SIMPLE_STRING(obj)) {
1022     ptr += obj->offset;
1023 
1024     if (query) {
1025       if (obj->flags == J2S_FLAG_POINTER)
1026         ptr = *(char **)ptr;
1027 
1028       cJSON_SetValuestring(root, ptr ? ptr : "");
1029     } else {
1030       char *str = cJSON_GetStringValue(root);
1031 
1032       if (obj->flags == J2S_FLAG_ARRAY) {
1033         strncpy(ptr, str ? str : "", obj->num_elem);
1034       } else {
1035         char **buf = (char **)ptr;
1036         if (*buf)
1037           free(*buf);
1038         int str_len = str ? strlen(str) : strlen("");
1039         size_t real_size = 0;
1040         *buf = (char *)j2s_alloc_data(ctx, str_len + 1, &real_size);
1041         j2s_alloc_map_record(ctx, buf, *buf, real_size);
1042         if (*buf) {
1043           memcpy(*buf, str, strlen(str));
1044           (*buf)[str_len] = '\0';
1045           DBG("----->self ptr offset[%zu]-[%zu]-[%s]\n",
1046               ((uint8_t *)buf - ((j2s_pool_t *)ctx->priv)->data),
1047               (uint8_t *)*buf - ((j2s_pool_t *)ctx->priv)->data, *buf);
1048         }
1049       }
1050     }
1051 
1052     return 0;
1053   }
1054 
1055   /* Handle array member */
1056   if (J2S_IS_ARRAY(obj)) {
1057     j2s_obj tmp_obj;
1058     cJSON *item, *index_json;
1059 
1060     index_json = j2s_get_index_json(ctx, parent, obj_index);
1061     if (index_json && obj->type != J2S_TYPE_STRING &&
1062         obj->flags != J2S_FLAG_ARRAY) {
1063       cJSON_DetachItemViaPointer(parent, index_json);
1064       index_json = NULL;
1065       ERR("ignoring index for dep types %s\n", obj->name);
1066     }
1067 
1068     if (index_json)
1069       return j2s_json_to_array_with_index(ctx, json, index_json, parent, obj,
1070                                           ptr, query);
1071 
1072     tmp_obj = *obj;
1073 
1074     /* Walk into array */
1075     j2s_extract_array(obj);
1076 
1077     for (int i = 0; i < tmp_obj.num_elem; i++) {
1078       DBG("handling array: %s %d/%d\n", obj->name, i, tmp_obj.num_elem);
1079 
1080       item = cJSON_GetArrayItem(root, i);
1081       if (!item)
1082         continue;
1083 
1084       ret = _j2s_json_to_obj(ctx, item, parent, obj_index, ptr, query);
1085       if (ret < 0)
1086         break;
1087 
1088       obj->offset += tmp_obj.elem_size;
1089     }
1090 
1091     *obj = tmp_obj;
1092     return ret;
1093   }
1094 
1095   /* Handle dynamic array */
1096   if (J2S_IS_POINTER(obj)) {
1097     j2s_obj tmp_obj;
1098     cJSON *len_json, *index_json;
1099     char *len_name;
1100     int len, old_len;
1101 
1102     DASSERT_MSG(obj->len_index >= 0, return -1,
1103                 "dynamic array %s missing len\n", obj->name);
1104 
1105     len_name = ctx->objs[obj->len_index].name;
1106 
1107     len_json = cJSON_GetObjectItemCaseSensitive(parent, len_name);
1108     if (!len_json && !query)
1109       ERR("missing len in json for dynamic array '%s'\n", obj->name);
1110 
1111     index_json = j2s_get_index_json(ctx, parent, obj_index);
1112 
1113     if (query && !index_json) {
1114       /* Query dynamic array len */
1115       if (len_json)
1116         cJSON_DetachItemViaPointer(parent, len_json);
1117 
1118       len_json = _j2s_obj_to_json(ctx, obj->len_index, ptr);
1119       DASSERT_MSG(len_json, return -1, "failed to query %s\n", len_name);
1120 
1121       cJSON_AddItemToObject(parent, len_name, len_json);
1122 
1123       /* Force query the whole dynamic array */
1124       cJSON_DetachItemViaPointer(parent, json);
1125       cJSON_Delete(json);
1126 
1127       json = _j2s_obj_to_json(ctx, obj_index, ptr);
1128       DASSERT_MSG(json, return -1, "failed to query %s\n", obj->name);
1129 
1130       cJSON_AddItemToObject(parent, obj->name, json);
1131       return 0;
1132     }
1133 
1134     old_len = j2s_obj_get_value(ctx, obj->len_index, ptr);
1135 
1136     if (len_json) {
1137       len = cJSON_GetArraySize(json);
1138       /* Fallback to array size */
1139       cJSON_SetNumberValue(len_json, len);
1140     } else if (index_json) {
1141       len = old_len;
1142     } else {
1143       /* Fallback to array size */
1144       len = cJSON_GetArraySize(json);
1145     }
1146 
1147     if (len != old_len) {
1148       /* Dynamic array size changed, realloc it */
1149       void **buf = (void **)(ptr + obj->offset);
1150 
1151       if (old_len && *buf)
1152         j2s_release_data(ctx, *buf);
1153 
1154       size_t real_size = 0;
1155       *buf = j2s_alloc_data(ctx, len * obj->elem_size, &real_size);
1156       j2s_alloc_map_record(ctx, buf, *buf, real_size);
1157       DBG("----->self ptr offset[%zu]-[%zu]\n",
1158           ((uint8_t *)buf - ((j2s_pool_t *)ctx->priv)->data),
1159           (uint8_t *)*buf - ((j2s_pool_t *)ctx->priv)->data);
1160 
1161       j2s_obj_set_value(ctx, obj->len_index, len, ptr);
1162 
1163       DBG("re-alloc %s from %d*%d to %d*%d = %p\n", obj->name, old_len,
1164           obj->elem_size, len, obj->elem_size, *buf);
1165     }
1166 
1167     if (!len)
1168       return 0;
1169 
1170     tmp_obj = *obj;
1171 
1172     /* Walk into dynamic array */
1173     ptr = (char *)j2s_extract_dynamic_array(obj, len, ptr);
1174     DASSERT_MSG(ptr, return -1, "found null pointer at %s\n", obj->name);
1175 
1176     DBG("handling dynamic array: %s %d*%d from %p\n", obj->name, obj->elem_size,
1177         obj->num_elem, ptr);
1178 
1179     ret = _j2s_json_to_obj(ctx, root, parent, obj_index, ptr, query);
1180 
1181     *obj = tmp_obj;
1182     return ret;
1183   }
1184 
1185   /* Handle struct member */
1186   if (obj->type == J2S_TYPE_STRUCT)
1187     return _j2s_json_to_struct(ctx, root, obj->struct_index, ptr + obj->offset,
1188                                query);
1189 
1190   /* Handle basic member */
1191   if (query) {
1192     double value = j2s_obj_get_value(ctx, obj_index, ptr);
1193 
1194     if (obj->enum_index >= 0) {
1195       /* Convert enum value to name */
1196       const char *name = j2s_enum_get_name(ctx, obj->enum_index, (int)value);
1197       cJSON_SetValuestring(root, name);
1198       return 0;
1199     }
1200 
1201     cJSON_SetNumberValue(root, value);
1202     return 0;
1203   } else {
1204     double value;
1205 
1206     if (obj->enum_index >= 0) {
1207       /* Convert enum name to value */
1208       char *name = cJSON_GetStringValue(root);
1209 
1210       value = (double)j2s_enum_get_value(ctx, obj->enum_index, name);
1211     } else {
1212       value = cJSON_GetNumberValue(root);
1213     }
1214 
1215     j2s_obj_set_value(ctx, obj_index, value, ptr);
1216     return 0;
1217   }
1218 }
1219 
_j2s_json_to_struct(j2s_ctx * ctx,cJSON * json,int struct_index,void * ptr,bool query)1220 static int _j2s_json_to_struct(j2s_ctx *ctx, cJSON *json, int struct_index,
1221                                void *ptr, bool query) {
1222   j2s_struct *struct_obj;
1223   j2s_obj *child;
1224   cJSON *item, *root = json;
1225   int child_index, ret = 0;
1226 
1227   if (struct_index < 0)
1228     return -1;
1229 
1230   struct_obj = &ctx->structs[struct_index];
1231 
1232   DBG("start struct: %s from %p\n", struct_obj->name, ptr);
1233 
1234   /* Walk child list */
1235   for (child_index = struct_obj->child_index; child_index >= 0;
1236        child_index = child->next_index) {
1237     child = &ctx->objs[child_index];
1238 
1239     item = cJSON_GetObjectItemCaseSensitive(root, child->name);
1240     if (!item)
1241       continue;
1242 
1243     DBG("start child: %s (%s) from %p\n", child->name, struct_obj->name, ptr);
1244     ret = _j2s_json_to_obj(ctx, item, root, child_index, ptr, query);
1245     DBG("finish child: %s (%s)\n", child->name, struct_obj->name);
1246     if (ret < 0)
1247       break;
1248   }
1249 
1250   DBG("finish struct: %s\n", struct_obj->name);
1251   return ret;
1252 }
1253 
j2s_restore_obj(j2s_ctx * ctx,j2s_obj * obj,int fd,void * ptr_)1254 static int j2s_restore_obj(j2s_ctx *ctx, j2s_obj *obj, int fd, void *ptr_) {
1255   char buf[MAX_NAME];
1256   void **data_ptr;
1257   int size;
1258   char *ptr = (char *)ptr_;
1259 
1260   if (!J2S_IS_POINTER(obj))
1261     return 0;
1262 
1263   data_ptr = (void **)(ptr + obj->offset);
1264 
1265   if (read(fd, buf, MAX_NAME) != MAX_NAME)
1266     return -1;
1267 
1268   if (strncmp(obj->name, buf, MAX_NAME) < 0)
1269     return -1;
1270 
1271   if (read(fd, &size, sizeof(int)) != sizeof(int))
1272     return -1;
1273 
1274   if (!size) {
1275     *data_ptr = NULL;
1276     return 0;
1277   }
1278 
1279   *data_ptr = j2s_alloc_data(ctx, size);
1280   if (!*data_ptr)
1281     return -1;
1282 
1283   if (read(fd, *data_ptr, size) != size) {
1284     j2s_release_data(ctx, *data_ptr);
1285     return -1;
1286   }
1287 
1288   DBG("restore obj: %s to %p, size %d\n", obj->name, *data_ptr, size);
1289 
1290   return size;
1291 }
1292 
j2s_store_obj(j2s_obj * obj,int fd,void * ptr_)1293 static void j2s_store_obj(j2s_obj *obj, int fd, void *ptr_) {
1294   char buf[MAX_NAME] = {0};
1295   int size;
1296   ssize_t bytes_written = 0;
1297   char *ptr = (char *)ptr_;
1298 
1299   if (!J2S_IS_POINTER(obj))
1300     return;
1301 
1302   ptr = (char *)(*(void **)(ptr + obj->offset));
1303   if (!ptr)
1304     return;
1305 
1306   if (J2S_IS_SIMPLE_STRING(obj)) {
1307     size = strlen(ptr) + 1;
1308   } else {
1309     size = obj->num_elem * obj->elem_size;
1310   }
1311 
1312   DBG("store obj: %s from %p, size %d\n", obj->name, ptr, size);
1313 
1314   strcpy(buf, obj->name);
1315   bytes_written = write(fd, buf, MAX_NAME);
1316   bytes_written = write(fd, &size, sizeof(int));
1317   bytes_written = write(fd, ptr, size);
1318 }
1319 
j2s_json_to_bin(j2s_ctx * ctx,cJSON * json,const char * name,void ** ptr,size_t struct_size,const char * ofname)1320 int j2s_json_to_bin(j2s_ctx *ctx, cJSON *json, const char *name, void **ptr,
1321                     size_t struct_size, const char *ofname) {
1322   size_t real_size = 0;
1323   size_t bin_size = 0;
1324   j2s_pool_t *j2s_pool = NULL;
1325   *ptr = j2s_alloc_data(ctx, struct_size, &real_size);
1326   j2s_json_to_struct(ctx, json, name, *ptr);
1327 
1328   void* bin_buffer = malloc(MAX_IQBIN_SIZE);
1329   if (!bin_buffer) {
1330     printf("%s %d [J2S4B] oom!\n", __func__, __LINE__);
1331     return -1;
1332   }
1333 
1334   uint8_t *current_index = (uint8_t*) bin_buffer;
1335 
1336   j2s_pool = (j2s_pool_t *)ctx->priv;
1337 
1338   size_t map_start = j2s_pool->used;
1339   memcpy(current_index, j2s_pool->data, j2s_pool->used);
1340   current_index += j2s_pool->used;
1341   memcpy(current_index, j2s_pool->maps_list, sizeof(map_index_t) * j2s_pool->map_len);
1342   current_index += sizeof(map_index_t) * j2s_pool->map_len;
1343   memcpy(current_index, &map_start, sizeof(size_t));
1344   current_index += sizeof(size_t);
1345   memcpy(current_index, &j2s_pool->map_len, sizeof(size_t));
1346   current_index += sizeof(size_t);
1347 
1348   bin_size = j2s_pool->used + sizeof(map_index_t) * j2s_pool->map_len + sizeof(size_t) * 2;
1349 
1350   BinMapLoader::suqeezBinMap(ofname, (uint8_t*)bin_buffer, bin_size);
1351 
1352   free(bin_buffer);
1353 
1354   DBG("maps [%zu][%zu][%zu]\n", sizeof(map_index_t), j2s_pool->map_len, map_start);
1355 
1356   return 0;
1357 }
1358