1 // SoftEther VPN Source Code - Developer Edition Master Branch
2 // Mayaqua Kernel
3
4
5 // Pack.c
6 // Data package code
7
8 #include "Pack.h"
9
10 #include "Encrypt.h"
11 #include "Internat.h"
12 #include "Mayaqua.h"
13 #include "Memory.h"
14 #include "Network.h"
15 #include "Str.h"
16
17 // Get a list of the element names in the PACK
GetPackElementNames(PACK * p)18 TOKEN_LIST *GetPackElementNames(PACK *p)
19 {
20 TOKEN_LIST *ret;
21 UINT i;
22 // Validate arguments
23 if (p == NULL)
24 {
25 return NULL;
26 }
27
28 ret = ZeroMalloc(sizeof(TOKEN_LIST));
29
30 ret->NumTokens = LIST_NUM(p->elements);
31 ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
32
33 for (i = 0;i < ret->NumTokens;i++)
34 {
35 ELEMENT *e = LIST_DATA(p->elements, i);
36
37 ret->Token[i] = CopyStr(e->name);
38 }
39
40 return ret;
41 }
42
43 // Convert the BUF to a PACK
BufToPack(BUF * b)44 PACK *BufToPack(BUF *b)
45 {
46 PACK *p;
47 // Validate arguments
48 if (b == NULL)
49 {
50 return NULL;
51 }
52
53 p = NewPack();
54 if (ReadPack(b, p) == false)
55 {
56 FreePack(p);
57 return NULL;
58 }
59
60 return p;
61 }
62
63 // Convert the PACK to the BUF
PackToBuf(PACK * p)64 BUF *PackToBuf(PACK *p)
65 {
66 BUF *b;
67 // Validate arguments
68 if (p == NULL)
69 {
70 return NULL;
71 }
72
73 b = NewBuf();
74 WritePack(b, p);
75
76 return b;
77 }
78
79 // Read the PACK
ReadPack(BUF * b,PACK * p)80 bool ReadPack(BUF *b, PACK *p)
81 {
82 UINT i, num;
83 // Validate arguments
84 if (b == NULL || p == NULL)
85 {
86 return false;
87 }
88
89 // The number of ELEMENTs
90 num = ReadBufInt(b);
91 if (num > MAX_ELEMENT_NUM)
92 {
93 // Number exceeds
94 return false;
95 }
96
97 // Read the ELEMENT
98 for (i = 0;i < num;i++)
99 {
100 ELEMENT *e;
101 e = ReadElement(b);
102 if (AddElement(p, e) == false)
103 {
104 // Adding error
105 return false;
106 }
107 }
108
109 return true;
110 }
111
112 // Write down the PACK
WritePack(BUF * b,PACK * p)113 void WritePack(BUF *b, PACK *p)
114 {
115 UINT i;
116 // Validate arguments
117 if (b == NULL || p == NULL)
118 {
119 return;
120 }
121
122 // The number of ELEMENTs
123 WriteBufInt(b, LIST_NUM(p->elements));
124
125 // Write the ELEMENT
126 for (i = 0;i < LIST_NUM(p->elements);i++)
127 {
128 ELEMENT *e = LIST_DATA(p->elements, i);
129 WriteElement(b, e);
130 }
131 }
132
133 // Read the ELEMENT
ReadElement(BUF * b)134 ELEMENT *ReadElement(BUF *b)
135 {
136 UINT i;
137 char name[MAX_ELEMENT_NAME_LEN + 1];
138 UINT type, num_value;
139 VALUE **values;
140 ELEMENT *e;
141 // Validate arguments
142 if (b == NULL)
143 {
144 return NULL;
145 }
146
147 // Name
148 if (ReadBufStr(b, name, sizeof(name)) == false)
149 {
150 return NULL;
151 }
152
153 // Type of item
154 type = ReadBufInt(b);
155
156 // Number of items
157 num_value = ReadBufInt(b);
158 if (num_value > MAX_VALUE_NUM)
159 {
160 // Number exceeds
161 return NULL;
162 }
163
164 // VALUE
165 values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
166 for (i = 0;i < num_value;i++)
167 {
168 values[i] = ReadValue(b, type);
169 }
170
171 // Create a ELEMENT
172 e = NewElement(name, type, num_value, values);
173
174 Free(values);
175
176 return e;
177 }
178
179 // Write the ELEMENT
WriteElement(BUF * b,ELEMENT * e)180 void WriteElement(BUF *b, ELEMENT *e)
181 {
182 UINT i;
183 // Validate arguments
184 if (b == NULL || e == NULL)
185 {
186 return;
187 }
188
189 // Name
190 WriteBufStr(b, e->name);
191 // Type of item
192 WriteBufInt(b, e->type);
193 // Number of items
194 WriteBufInt(b, e->num_value);
195 // VALUE
196 for (i = 0;i < e->num_value;i++)
197 {
198 VALUE *v = e->values[i];
199 WriteValue(b, v, e->type);
200 }
201 }
202
203 // Read the VALUE
ReadValue(BUF * b,UINT type)204 VALUE *ReadValue(BUF *b, UINT type)
205 {
206 UINT len;
207 BYTE *u;
208 void *data;
209 char *str;
210 wchar_t *unistr;
211 UINT unistr_size;
212 UINT size;
213 UINT u_size;
214 VALUE *v = NULL;
215 // Validate arguments
216 if (b == NULL)
217 {
218 return NULL;
219 }
220
221 // Data item
222 switch (type)
223 {
224 case VALUE_INT: // Integer
225 v = NewIntValue(ReadBufInt(b));
226 break;
227 case VALUE_INT64:
228 v = NewInt64Value(ReadBufInt64(b));
229 break;
230 case VALUE_DATA: // Data
231 size = ReadBufInt(b);
232 if (size > MAX_VALUE_SIZE)
233 {
234 // Size over
235 break;
236 }
237 data = Malloc(size);
238 if (ReadBuf(b, data, size) != size)
239 {
240 // Read failure
241 Free(data);
242 break;
243 }
244 v = NewDataValue(data, size);
245 Free(data);
246 break;
247 case VALUE_STR: // ANSI string
248 len = ReadBufInt(b);
249 if (len > (MAX_VALUE_SIZE - 1))
250 {
251 // Size over
252 break;
253 }
254 str = Malloc(len + 1);
255 // String body
256 if (ReadBuf(b, str, len) != len)
257 {
258 // Read failure
259 Free(str);
260 break;
261 }
262 str[len] = 0;
263 v = NewStrValue(str);
264 Free(str);
265 break;
266 case VALUE_UNISTR: // Unicode string
267 u_size = ReadBufInt(b);
268 if (u_size > MAX_VALUE_SIZE)
269 {
270 // Size over
271 break;
272 }
273 // Reading an UTF-8 string
274 u = ZeroMalloc(u_size + 1);
275 if (ReadBuf(b, u, u_size) != u_size)
276 {
277 // Read failure
278 Free(u);
279 break;
280 }
281 // Convert to a Unicode string
282 unistr_size = CalcUtf8ToUni(u, u_size);
283 if (unistr_size == 0)
284 {
285 Free(u);
286 break;
287 }
288 unistr = Malloc(unistr_size);
289 Utf8ToUni(unistr, unistr_size, u, u_size);
290 Free(u);
291 v = NewUniStrValue(unistr);
292 Free(unistr);
293 break;
294 }
295
296 return v;
297 }
298
299 // Write the VALUE
WriteValue(BUF * b,VALUE * v,UINT type)300 void WriteValue(BUF *b, VALUE *v, UINT type)
301 {
302 UINT len;
303 BYTE *u;
304 UINT u_size;
305 // Validate arguments
306 if (b == NULL || v == NULL)
307 {
308 return;
309 }
310
311 // Data item
312 switch (type)
313 {
314 case VALUE_INT: // Integer
315 WriteBufInt(b, v->IntValue);
316 break;
317 case VALUE_INT64: // 64 bit integer
318 WriteBufInt64(b, v->Int64Value);
319 break;
320 case VALUE_DATA: // Data
321 // Size
322 WriteBufInt(b, v->Size);
323 // Body
324 WriteBuf(b, v->Data, v->Size);
325 break;
326 case VALUE_STR: // ANSI string
327 len = StrLen(v->Str);
328 // Length
329 WriteBufInt(b, len);
330 // String body
331 WriteBuf(b, v->Str, len);
332 break;
333 case VALUE_UNISTR: // Unicode string
334 // Convert to UTF-8
335 u_size = CalcUniToUtf8(v->UniStr) + 1;
336 u = ZeroMalloc(u_size);
337 UniToUtf8(u, u_size, v->UniStr);
338 // Size
339 WriteBufInt(b, u_size);
340 // UTF-8 string body
341 WriteBuf(b, u, u_size);
342 Free(u);
343 break;
344 }
345 }
346
347 // Get data size
GetDataValueSize(ELEMENT * e,UINT index)348 UINT GetDataValueSize(ELEMENT *e, UINT index)
349 {
350 // Validate arguments
351 if (e == NULL)
352 {
353 return 0;
354 }
355 if (e->values == NULL)
356 {
357 return 0;
358 }
359 if (index >= e->num_value)
360 {
361 return 0;
362 }
363 if (e->values[index] == NULL)
364 {
365 return 0;
366 }
367
368 return e->values[index]->Size;
369 }
370
371 // Get the data
GetDataValue(ELEMENT * e,UINT index)372 void *GetDataValue(ELEMENT *e, UINT index)
373 {
374 // Validate arguments
375 if (e == NULL)
376 {
377 return NULL;
378 }
379 if (e->values == NULL)
380 {
381 return NULL;
382 }
383 if (index >= e->num_value)
384 {
385 return NULL;
386 }
387 if (e->values[index] == NULL)
388 {
389 return NULL;
390 }
391
392 return e->values[index]->Data;
393 }
394
395 // Get the Unicode string type
GetUniStrValue(ELEMENT * e,UINT index)396 wchar_t *GetUniStrValue(ELEMENT *e, UINT index)
397 {
398 // Validate arguments
399 if (e == NULL)
400 {
401 return 0;
402 }
403 if (index >= e->num_value)
404 {
405 return 0;
406 }
407 if (e->values[index] == NULL)
408 {
409 return NULL;
410 }
411
412 return e->values[index]->UniStr;
413 }
414
415 // Get the ANSI string type
GetStrValue(ELEMENT * e,UINT index)416 char *GetStrValue(ELEMENT *e, UINT index)
417 {
418 // Validate arguments
419 if (e == NULL)
420 {
421 return 0;
422 }
423 if (index >= e->num_value)
424 {
425 return 0;
426 }
427 if (e->values[index] == NULL)
428 {
429 return NULL;
430 }
431
432 return e->values[index]->Str;
433 }
434
435 // Get the 64 bit integer value
GetInt64Value(ELEMENT * e,UINT index)436 UINT64 GetInt64Value(ELEMENT *e, UINT index)
437 {
438 // Validate arguments
439 if (e == NULL)
440 {
441 return 0;
442 }
443 if (index >= e->num_value)
444 {
445 return 0;
446 }
447 if (e->values[index] == NULL)
448 {
449 return 0;
450 }
451
452 return e->values[index]->Int64Value;
453 }
454
455 // Get the integer value
GetIntValue(ELEMENT * e,UINT index)456 UINT GetIntValue(ELEMENT *e, UINT index)
457 {
458 // Validate arguments
459 if (e == NULL)
460 {
461 return 0;
462 }
463 if (index >= e->num_value)
464 {
465 return 0;
466 }
467 if (e->values[index] == NULL)
468 {
469 return 0;
470 }
471
472 return e->values[index]->IntValue;
473 }
474
475 // Function of sort for PACK
ComparePackName(void * p1,void * p2)476 int ComparePackName(void *p1, void *p2)
477 {
478 ELEMENT *o1, *o2;
479 if (p1 == NULL || p2 == NULL)
480 {
481 return 0;
482 }
483 o1 = *(ELEMENT **)p1;
484 o2 = *(ELEMENT **)p2;
485 if (o1 == NULL || o2 == NULL)
486 {
487 return 0;
488 }
489
490 return StrCmpi(o1->name, o2->name);
491 }
492
493 // Delete the VALUE
FreeValue(VALUE * v,UINT type)494 void FreeValue(VALUE *v, UINT type)
495 {
496 // Validate arguments
497 if (v == NULL)
498 {
499 return;
500 }
501
502 switch (type)
503 {
504 case VALUE_INT:
505 case VALUE_INT64:
506 break;
507 case VALUE_DATA:
508 Free(v->Data);
509 break;
510 case VALUE_STR:
511 Free(v->Str);
512 break;
513 case VALUE_UNISTR:
514 Free(v->UniStr);
515 break;
516 }
517
518 // Memory release
519 Free(v);
520 }
521
522 // Create a VALUE of Unicode String type
NewUniStrValue(wchar_t * str)523 VALUE *NewUniStrValue(wchar_t *str)
524 {
525 VALUE *v;
526 // Validate arguments
527 if (str == NULL)
528 {
529 return NULL;
530 }
531
532 // Memory allocation
533 v = Malloc(sizeof(VALUE));
534
535 // String copy
536 v->Size = UniStrSize(str);
537 v->UniStr = Malloc(v->Size);
538 UniStrCpy(v->UniStr, v->Size, str);
539
540 UniTrim(v->UniStr);
541
542 return v;
543 }
544
545 // Creation of the VALUE of ANSI string type
NewStrValue(char * str)546 VALUE *NewStrValue(char *str)
547 {
548 VALUE *v;
549 // Validate arguments
550 if (str == NULL)
551 {
552 return NULL;
553 }
554
555 // Memory allocation
556 v = Malloc(sizeof(VALUE));
557
558 // String copy
559 v->Size = StrLen(str) + 1;
560 v->Str = Malloc(v->Size);
561 StrCpy(v->Str, v->Size, str);
562
563 Trim(v->Str);
564
565 return v;
566 }
567
568 // Create the VALUE of the data type
NewDataValue(void * data,UINT size)569 VALUE *NewDataValue(void *data, UINT size)
570 {
571 VALUE *v;
572 // Validate arguments
573 if (data == NULL)
574 {
575 return NULL;
576 }
577
578 // Memory allocation
579 v = Malloc(sizeof(VALUE));
580
581 // Data copy
582 v->Size = size;
583 v->Data = Malloc(v->Size);
584 Copy(v->Data, data, size);
585
586 return v;
587 }
588
589 // Create the VALUE of 64 bit integer type
NewInt64Value(UINT64 i)590 VALUE *NewInt64Value(UINT64 i)
591 {
592 VALUE *v;
593
594 v = Malloc(sizeof(VALUE));
595 v->Int64Value = i;
596 v->Size = sizeof(UINT64);
597
598 return v;
599 }
600
601 // Create the VALUE of integer type
NewIntValue(UINT i)602 VALUE *NewIntValue(UINT i)
603 {
604 VALUE *v;
605
606 // Memory allocation
607 v = Malloc(sizeof(VALUE));
608 v->IntValue = i;
609 v->Size = sizeof(UINT);
610
611 return v;
612 }
613
614 // Delete the ELEMENT
FreeElement(ELEMENT * e)615 void FreeElement(ELEMENT *e)
616 {
617 UINT i;
618 // Validate arguments
619 if (e == NULL)
620 {
621 return;
622 }
623
624 for (i = 0;i < e->num_value;i++)
625 {
626 FreeValue(e->values[i], e->type);
627 }
628 Free(e->values);
629
630 Free(e);
631 }
632
633 // Create a ELEMENT
NewElement(char * name,UINT type,UINT num_value,VALUE ** values)634 ELEMENT *NewElement(char *name, UINT type, UINT num_value, VALUE **values)
635 {
636 ELEMENT *e;
637 UINT i;
638 // Validate arguments
639 if (name == NULL || num_value == 0 || values == NULL)
640 {
641 return NULL;
642 }
643
644 // Memory allocation
645 e = ZeroMalloc(sizeof(ELEMENT));
646 StrCpy(e->name, sizeof(e->name), name);
647 e->num_value = num_value;
648 e->type = type;
649
650 // Copy of the pointer list to the element
651 e->values = (VALUE **)ZeroMalloc(sizeof(VALUE *) * num_value);
652 for (i = 0;i < e->num_value;i++)
653 {
654 e->values[i] = values[i];
655 }
656
657 return e;
658 }
659
660 // Search and retrieve a ELEMENT from the PACK
GetElement(PACK * p,char * name,UINT type)661 ELEMENT *GetElement(PACK *p, char *name, UINT type)
662 {
663 ELEMENT t;
664 ELEMENT *e;
665 // Validate arguments
666 if (p == NULL || name == NULL)
667 {
668 return NULL;
669 }
670
671 // Search
672 StrCpy(t.name, sizeof(t.name), name);
673 e = Search(p->elements, &t);
674
675 if (e == NULL)
676 {
677 return NULL;
678 }
679
680 // Type checking
681 if (type != INFINITE)
682 {
683 if (e->type != type)
684 {
685 return NULL;
686 }
687 }
688
689 return e;
690 }
691
692 // Check whether the specified element exists
IsElement(PACK * p,char * name)693 bool IsElement(PACK *p, char *name)
694 {
695 ELEMENT t;
696 ELEMENT *e;
697 // Validate arguments
698 if (p == NULL || name == NULL)
699 {
700 return false;
701 }
702
703 // Search
704 StrCpy(t.name, sizeof(t.name), name);
705 e = Search(p->elements, &t);
706
707 if (e == NULL)
708 {
709 return false;
710 }
711
712 return true;
713 }
714
715 // Remove the ELEMENT from the PACK
DelElement(PACK * p,char * name)716 void DelElement(PACK *p, char *name)
717 {
718 ELEMENT *e;
719 // Validate arguments
720 if (p == NULL || name == NULL)
721 {
722 return;
723 }
724
725 e = GetElement(p, name, INFINITE);
726 if (e != NULL)
727 {
728 Delete(p->elements, e);
729
730 FreeElement(e);
731 }
732 }
733
734 // Add an ELEMENT to the PACK
AddElement(PACK * p,ELEMENT * e)735 bool AddElement(PACK *p, ELEMENT *e)
736 {
737 // Validate arguments
738 if (p == NULL || e == NULL)
739 {
740 return false;
741 }
742
743 // Size Check
744 if (LIST_NUM(p->elements) >= MAX_ELEMENT_NUM)
745 {
746 // Can not add any more
747 FreeElement(e);
748 return false;
749 }
750
751 // Check whether there is another item which have same name
752 if (GetElement(p, e->name, INFINITE))
753 {
754 // Exists
755 FreeElement(e);
756 return false;
757 }
758
759 if (e->num_value == 0)
760 {
761 // VALUE without any items can not be added
762 FreeElement(e);
763 return false;
764 }
765
766 // Set JsonHint_GroupName
767 StrCpy(e->JsonHint_GroupName, sizeof(e->JsonHint_GroupName), p->CurrentJsonHint_GroupName);
768
769 // Adding
770 Add(p->elements, e);
771 return true;
772 }
773
774 // Release of the PACK object
FreePack(PACK * p)775 void FreePack(PACK *p)
776 {
777 UINT i;
778 ELEMENT **elements;
779 // Validate arguments
780 if (p == NULL)
781 {
782 return;
783 }
784
785 elements = ToArray(p->elements);
786 for (i = 0;i < LIST_NUM(p->elements);i++)
787 {
788 FreeElement(elements[i]);
789 }
790 Free(elements);
791
792 if (p->json_subitem_names != NULL)
793 {
794 FreeStrList(p->json_subitem_names);
795 }
796
797 ReleaseList(p->elements);
798 Free(p);
799 }
800
801 // Create a PACK object
NewPack()802 PACK *NewPack()
803 {
804 PACK *p;
805
806 // Memory allocation
807 p = ZeroMallocEx(sizeof(PACK), true);
808
809 // Creating a List
810 p->elements = NewListFast(ComparePackName);
811
812 return p;
813 }
814
815 // Get the K from the PACK
PackGetK(PACK * p,char * name)816 K *PackGetK(PACK *p, char *name)
817 {
818 K *k;
819 BUF *b;
820 // Validate arguments
821 if (p == NULL || name == NULL)
822 {
823 return NULL;
824 }
825
826 b = PackGetBuf(p, name);
827 if (b == NULL)
828 {
829 return NULL;
830 }
831
832 k = BufToK(b, true, false, NULL);
833
834 if (k == NULL)
835 {
836 k = BufToK(b, true, true, NULL);
837 }
838
839 FreeBuf(b);
840
841 return k;
842 }
843
844 // Get the X from the PACK
PackGetX(PACK * p,char * name)845 X *PackGetX(PACK *p, char *name)
846 {
847 X *x;
848 BUF *b;
849 // Validate arguments
850 if (p == NULL || name == NULL)
851 {
852 return NULL;
853 }
854
855 b = PackGetBuf(p, name);
856 if (b == NULL)
857 {
858 return NULL;
859 }
860
861 x = BufToX(b, false);
862
863 if (x == NULL)
864 {
865 x = BufToX(b, true);
866 }
867
868 FreeBuf(b);
869
870 return x;
871 }
872
873 // Add the K to the PACK
PackAddK(PACK * p,char * name,K * k)874 ELEMENT *PackAddK(PACK *p, char *name, K *k)
875 {
876 BUF *b;
877 ELEMENT *e = NULL;
878 // Validate arguments
879 if (p == NULL || name == NULL || k == NULL)
880 {
881 return NULL;
882 }
883
884 b = KToBuf(k, false, NULL);
885 if (b == NULL)
886 {
887 return NULL;
888 }
889
890 e = PackAddBuf(p, name, b);
891 FreeBuf(b);
892
893 return e;
894 }
895
896 // Add an X into the PACK
PackAddX(PACK * p,char * name,X * x)897 ELEMENT *PackAddX(PACK *p, char *name, X *x)
898 {
899 BUF *b;
900 ELEMENT *e = NULL;
901 // Validate arguments
902 if (p == NULL || name == NULL || x == NULL)
903 {
904 return NULL;
905 }
906
907 b = XToBuf(x, false);
908 if (b == NULL)
909 {
910 return NULL;
911 }
912
913 e = PackAddBuf(p, name, b);
914 FreeBuf(b);
915
916 return e;
917 }
918
919 // Get a buffer from the PACK
PackGetBuf(PACK * p,char * name)920 BUF *PackGetBuf(PACK *p, char *name)
921 {
922 return PackGetBufEx(p, name, 0);
923 }
PackGetBufEx(PACK * p,char * name,UINT index)924 BUF *PackGetBufEx(PACK *p, char *name, UINT index)
925 {
926 UINT size;
927 void *tmp;
928 BUF *b;
929 // Validate arguments
930 if (p == NULL || name == NULL)
931 {
932 return NULL;
933 }
934
935 size = PackGetDataSizeEx(p, name, index);
936 tmp = MallocEx(size, true);
937 if (PackGetDataEx(p, name, tmp, index) == false)
938 {
939 Free(tmp);
940 return NULL;
941 }
942
943 b = NewBuf();
944 WriteBuf(b, tmp, size);
945 SeekBuf(b, 0, 0);
946
947 Free(tmp);
948
949 return b;
950 }
951
952 // Get the data from the PACK
PackGetData(PACK * p,char * name,void * data)953 bool PackGetData(PACK *p, char *name, void *data)
954 {
955 return PackGetDataEx(p, name, data, 0);
956 }
PackGetDataEx(PACK * p,char * name,void * data,UINT index)957 bool PackGetDataEx(PACK *p, char *name, void *data, UINT index)
958 {
959 ELEMENT *e;
960 // Validate arguments
961 if (p == NULL || name == NULL)
962 {
963 return false;
964 }
965
966 e = GetElement(p, name, VALUE_DATA);
967 if (e == NULL)
968 {
969 return false;
970 }
971 Copy(data, GetDataValue(e, index), GetDataValueSize(e, index));
972 return true;
973 }
PackGetData2(PACK * p,char * name,void * data,UINT size)974 bool PackGetData2(PACK *p, char *name, void *data, UINT size)
975 {
976 return PackGetDataEx2(p, name, data, size, 0);
977 }
PackGetDataEx2(PACK * p,char * name,void * data,UINT size,UINT index)978 bool PackGetDataEx2(PACK *p, char *name, void *data, UINT size, UINT index)
979 {
980 ELEMENT *e;
981 // Validate arguments
982 if (p == NULL || name == NULL)
983 {
984 return false;
985 }
986
987 e = GetElement(p, name, VALUE_DATA);
988 if (e == NULL)
989 {
990 return false;
991 }
992 if (GetDataValueSize(e, index) != size)
993 {
994 return false;
995 }
996 Copy(data, GetDataValue(e, index), GetDataValueSize(e, index));
997 return true;
998 }
999
1000 // Get the data size from the PACK
PackGetDataSize(PACK * p,char * name)1001 UINT PackGetDataSize(PACK *p, char *name)
1002 {
1003 return PackGetDataSizeEx(p, name, 0);
1004 }
PackGetDataSizeEx(PACK * p,char * name,UINT index)1005 UINT PackGetDataSizeEx(PACK *p, char *name, UINT index)
1006 {
1007 ELEMENT *e;
1008 // Validate arguments
1009 if (p == NULL || name == NULL)
1010 {
1011 return 0;
1012 }
1013
1014 e = GetElement(p, name, VALUE_DATA);
1015 if (e == NULL)
1016 {
1017 return 0;
1018 }
1019 return GetDataValueSize(e, index);
1020 }
1021
1022 // Get an integer from the PACK
PackGetInt64(PACK * p,char * name)1023 UINT64 PackGetInt64(PACK *p, char *name)
1024 {
1025 return PackGetInt64Ex(p, name, 0);
1026 }
PackGetInt64Ex(PACK * p,char * name,UINT index)1027 UINT64 PackGetInt64Ex(PACK *p, char *name, UINT index)
1028 {
1029 ELEMENT *e;
1030 // Validate arguments
1031 if (p == NULL || name == NULL)
1032 {
1033 return 0;
1034 }
1035
1036 e = GetElement(p, name, VALUE_INT64);
1037 if (e == NULL)
1038 {
1039 return 0;
1040 }
1041 return GetInt64Value(e, index);
1042 }
1043
1044 // Get the index number from the PACK
PackGetIndexCount(PACK * p,char * name)1045 UINT PackGetIndexCount(PACK *p, char *name)
1046 {
1047 ELEMENT *e;
1048 // Validate arguments
1049 if (p == NULL || name == NULL)
1050 {
1051 return 0;
1052 }
1053
1054 e = GetElement(p, name, INFINITE);
1055 if (e == NULL)
1056 {
1057 return 0;
1058 }
1059
1060 return e->num_value;
1061 }
1062
1063 // Get the number from the PACK
PackGetNum(PACK * p,char * name)1064 UINT PackGetNum(PACK *p, char *name)
1065 {
1066 return MIN(PackGetInt(p, name), 65536);
1067 }
1068
1069 // Get a bool type from the PACK
PackGetBool(PACK * p,char * name)1070 bool PackGetBool(PACK *p, char *name)
1071 {
1072 return PackGetInt(p, name) == 0 ? false : true;
1073 }
PackGetBoolEx(PACK * p,char * name,UINT index)1074 bool PackGetBoolEx(PACK *p, char *name, UINT index)
1075 {
1076 return PackGetIntEx(p, name, index) == 0 ? false : true;
1077 }
1078
1079 // Set CurrentJsonHint_GroupName to PACK
PackSetCurrentJsonGroupName(PACK * p,char * json_group_name)1080 void PackSetCurrentJsonGroupName(PACK *p, char *json_group_name)
1081 {
1082 if (p == NULL)
1083 {
1084 return;
1085 }
1086
1087 if (json_group_name == NULL)
1088 {
1089 ClearStr(p->CurrentJsonHint_GroupName, sizeof(p->CurrentJsonHint_GroupName));
1090 }
1091 else
1092 {
1093 StrCpy(p->CurrentJsonHint_GroupName, sizeof(p->CurrentJsonHint_GroupName), json_group_name);
1094
1095 if (p->json_subitem_names == NULL)
1096 {
1097 p->json_subitem_names = NewStrList();
1098 }
1099
1100 AddStrToStrListDistinct(p->json_subitem_names, json_group_name);
1101 }
1102 }
1103
1104 // Add a bool type into the PACK
PackAddBool(PACK * p,char * name,bool b)1105 ELEMENT *PackAddBool(PACK *p, char *name, bool b)
1106 {
1107 ELEMENT *e = PackAddInt(p, name, b ? 1 : 0);
1108 if (e != NULL)
1109 {
1110 e->JsonHint_IsBool = true;
1111 }
1112 return e;
1113 }
PackAddBoolEx(PACK * p,char * name,bool b,UINT index,UINT total)1114 ELEMENT *PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total)
1115 {
1116 ELEMENT *e = PackAddIntEx(p, name, b ? 1 : 0, index, total);
1117 if (e != NULL)
1118 {
1119 e->JsonHint_IsBool = true;
1120 }
1121 return e;
1122 }
1123
1124 // Add the IPV6_ADDR to the PACK
PackAddIp6AddrEx(PACK * p,char * name,IPV6_ADDR * addr,UINT index,UINT total)1125 ELEMENT *PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total)
1126 {
1127 // Validate arguments
1128 if (p == NULL || name == NULL || addr == NULL)
1129 {
1130 return NULL;
1131 }
1132
1133 return PackAddDataEx(p, name, addr, sizeof(IPV6_ADDR), index, total);
1134 }
PackAddIp6Addr(PACK * p,char * name,IPV6_ADDR * addr)1135 ELEMENT *PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr)
1136 {
1137 return PackAddIp6AddrEx(p, name, addr, 0, 1);
1138 }
1139
1140 // Get an IPV6_ADDR from the PACK
PackGetIp6AddrEx(PACK * p,char * name,IPV6_ADDR * addr,UINT index)1141 bool PackGetIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index)
1142 {
1143 // Validate arguments
1144 if (p == NULL || name == NULL || addr == NULL)
1145 {
1146 Zero(addr, sizeof(IPV6_ADDR));
1147 return false;
1148 }
1149
1150 return PackGetDataEx2(p, name, addr, sizeof(IPV6_ADDR), index);
1151 }
PackGetIp6Addr(PACK * p,char * name,IPV6_ADDR * addr)1152 bool PackGetIp6Addr(PACK *p, char *name, IPV6_ADDR *addr)
1153 {
1154 return PackGetIp6AddrEx(p, name, addr, 0);
1155 }
1156
1157 // Add the IP to the PACK
PackAddIp32Ex(PACK * p,char * name,UINT ip32,UINT index,UINT total)1158 void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total)
1159 {
1160 PackAddIp32Ex2(p, name, ip32, index, total, false);
1161 }
PackAddIp32Ex2(PACK * p,char * name,UINT ip32,UINT index,UINT total,bool is_single)1162 void PackAddIp32Ex2(PACK *p, char *name, UINT ip32, UINT index, UINT total, bool is_single)
1163 {
1164 IP ip;
1165 // Validate arguments
1166 if (p == NULL || name == NULL)
1167 {
1168 return;
1169 }
1170
1171 UINTToIP(&ip, ip32);
1172
1173 PackAddIpEx2(p, name, &ip, index, total, is_single);
1174 }
PackAddIp32(PACK * p,char * name,UINT ip32)1175 void PackAddIp32(PACK *p, char *name, UINT ip32)
1176 {
1177 PackAddIp32Ex2(p, name, ip32, 0, 1, true);
1178 }
PackAddIpEx(PACK * p,char * name,IP * ip,UINT index,UINT total)1179 void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total)
1180 {
1181 PackAddIpEx2(p, name, ip, index, total, false);
1182 }
PackAddIpEx2(PACK * p,char * name,IP * ip,UINT index,UINT total,bool is_single)1183 void PackAddIpEx2(PACK *p, char *name, IP *ip, UINT index, UINT total, bool is_single)
1184 {
1185 UINT i;
1186 char tmp[MAX_PATH];
1187 ELEMENT *e;
1188 // Validate arguments
1189 if (p == NULL || name == NULL || ip == NULL)
1190 {
1191 return;
1192 }
1193 if (total >= 2)
1194 {
1195 is_single = false;
1196 }
1197
1198 Format(tmp, sizeof(tmp), "%s@ipv6_bool", name);
1199 e = PackAddBoolEx(p, tmp, IsIP6(ip), index, total);
1200 if (e != NULL && is_single) e->JsonHint_IsArray = false;
1201 if (e != NULL) e->JsonHint_IsIP = true;
1202
1203 Format(tmp, sizeof(tmp), "%s@ipv6_array", name);
1204 e = PackAddDataEx(p, tmp, ip->address, sizeof(ip->address), index, total);
1205 if (e != NULL && is_single) e->JsonHint_IsArray = false;
1206 if (e != NULL) e->JsonHint_IsIP = true;
1207
1208 Format(tmp, sizeof(tmp), "%s@ipv6_scope_id", name);
1209 e = PackAddIntEx(p, tmp, ip->ipv6_scope_id, index, total);
1210 if (e != NULL && is_single) e->JsonHint_IsArray = false;
1211 if (e != NULL) e->JsonHint_IsIP = true;
1212
1213 i = IPToUINT(ip);
1214
1215 if (IsBigEndian())
1216 {
1217 i = Swap32(i);
1218 }
1219
1220 e = PackAddIntEx(p, name, i, index, total);
1221 if (e != NULL && is_single) e->JsonHint_IsArray = false;
1222 if (e != NULL) e->JsonHint_IsIP = true;
1223 }
PackAddIp(PACK * p,char * name,IP * ip)1224 void PackAddIp(PACK *p, char *name, IP *ip)
1225 {
1226 PackAddIpEx2(p, name, ip, 0, 1, true);
1227 }
1228
1229 // Get an IP from the PACK
PackGetIp32Ex(PACK * p,char * name,UINT index)1230 UINT PackGetIp32Ex(PACK *p, char *name, UINT index)
1231 {
1232 IP ip;
1233 // Validate arguments
1234 if (p == NULL || name == NULL)
1235 {
1236 return 0;
1237 }
1238
1239 if (PackGetIpEx(p, name, &ip, index) == false)
1240 {
1241 return 0;
1242 }
1243
1244 return IPToUINT(&ip);
1245 }
PackGetIp32(PACK * p,char * name)1246 UINT PackGetIp32(PACK *p, char *name)
1247 {
1248 return PackGetIp32Ex(p, name, 0);
1249 }
PackGetIpEx(PACK * p,char * name,IP * ip,UINT index)1250 bool PackGetIpEx(PACK *p, char *name, IP *ip, UINT index)
1251 {
1252 UINT i;
1253 char tmp[MAX_PATH];
1254 // Validate arguments
1255 if (p == NULL || ip == NULL || name == NULL)
1256 {
1257 return false;
1258 }
1259
1260 Format(tmp, sizeof(tmp), "%s@ipv6_bool", name);
1261 if (PackGetBoolEx(p, tmp, index))
1262 {
1263 UCHAR data[16];
1264 UINT scope_id;
1265
1266 Zero(data, sizeof(data));
1267
1268 Format(tmp, sizeof(tmp), "%s@ipv6_array", name);
1269 PackGetDataEx2(p, tmp, data, sizeof(data), index);
1270
1271 Format(tmp, sizeof(tmp), "%s@ipv6_scope_id", name);
1272 scope_id = PackGetIntEx(p, tmp, index);
1273
1274 SetIP6(ip, data);
1275 ip->ipv6_scope_id = scope_id;
1276 }
1277 else
1278 {
1279 if (GetElement(p, name, VALUE_INT) == NULL)
1280 {
1281 Zero(ip, sizeof(IP));
1282 return false;
1283 }
1284
1285 i = PackGetIntEx(p, name, index);
1286
1287 if (IsBigEndian())
1288 {
1289 i = Swap32(i);
1290 }
1291
1292 UINTToIP(ip, i);
1293 }
1294
1295 return true;
1296 }
PackGetIp(PACK * p,char * name,IP * ip)1297 bool PackGetIp(PACK *p, char *name, IP *ip)
1298 {
1299 return PackGetIpEx(p, name, ip, 0);
1300 }
1301
1302 // Check whether the specified value is existing on the Pack
PackIsValueExists(PACK * p,char * name)1303 bool PackIsValueExists(PACK *p, char *name)
1304 {
1305 // Validate arguments
1306 if (p == NULL || name == NULL)
1307 {
1308 return false;
1309 }
1310
1311 return IsElement(p, name);
1312 }
1313
1314 // Get an integer from the PACK
PackGetInt(PACK * p,char * name)1315 UINT PackGetInt(PACK *p, char *name)
1316 {
1317 return PackGetIntEx(p, name, 0);
1318 }
PackGetIntEx(PACK * p,char * name,UINT index)1319 UINT PackGetIntEx(PACK *p, char *name, UINT index)
1320 {
1321 ELEMENT *e;
1322 // Validate arguments
1323 if (p == NULL || name == NULL)
1324 {
1325 return 0;
1326 }
1327
1328 e = GetElement(p, name, VALUE_INT);
1329 if (e == NULL)
1330 {
1331 return 0;
1332 }
1333 return GetIntValue(e, index);
1334 }
1335
1336 // Get an Unicode string from the PACK
PackGetUniStr(PACK * p,char * name,wchar_t * unistr,UINT size)1337 bool PackGetUniStr(PACK *p, char *name, wchar_t *unistr, UINT size)
1338 {
1339 return PackGetUniStrEx(p, name, unistr, size, 0);
1340 }
PackGetUniStrEx(PACK * p,char * name,wchar_t * unistr,UINT size,UINT index)1341 bool PackGetUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT size, UINT index)
1342 {
1343 ELEMENT *e;
1344 // Validate arguments
1345 if (p == NULL || name == NULL || unistr == NULL || size == 0)
1346 {
1347 return false;
1348 }
1349
1350 unistr[0] = 0;
1351
1352 e = GetElement(p, name, VALUE_UNISTR);
1353 if (e == NULL)
1354 {
1355 return false;
1356 }
1357 UniStrCpy(unistr, size, GetUniStrValue(e, index));
1358 return true;
1359 }
1360
1361 // Compare strings in the PACK
PackCmpStr(PACK * p,char * name,char * str)1362 bool PackCmpStr(PACK *p, char *name, char *str)
1363 {
1364 char tmp[MAX_SIZE];
1365
1366 if (PackGetStr(p, name, tmp, sizeof(tmp)) == false)
1367 {
1368 return false;
1369 }
1370
1371 if (StrCmpi(tmp, str) == 0)
1372 {
1373 return true;
1374 }
1375
1376 return false;
1377 }
1378
1379 // Get a string from the PACK
PackGetStr(PACK * p,char * name,char * str,UINT size)1380 bool PackGetStr(PACK *p, char *name, char *str, UINT size)
1381 {
1382 return PackGetStrEx(p, name, str, size, 0);
1383 }
PackGetStrEx(PACK * p,char * name,char * str,UINT size,UINT index)1384 bool PackGetStrEx(PACK *p, char *name, char *str, UINT size, UINT index)
1385 {
1386 ELEMENT *e;
1387 // Validate arguments
1388 if (p == NULL || name == NULL || str == NULL || size == 0)
1389 {
1390 return false;
1391 }
1392
1393 str[0] = 0;
1394
1395 e = GetElement(p, name, VALUE_STR);
1396 if (e == NULL)
1397 {
1398 return false;
1399 }
1400
1401 StrCpy(str, size, GetStrValue(e, index));
1402 return true;
1403 }
1404
1405 // Get the string size from the PACK
PackGetStrSize(PACK * p,char * name)1406 UINT PackGetStrSize(PACK *p, char *name)
1407 {
1408 return PackGetStrSizeEx(p, name, 0);
1409 }
PackGetStrSizeEx(PACK * p,char * name,UINT index)1410 UINT PackGetStrSizeEx(PACK *p, char *name, UINT index)
1411 {
1412 ELEMENT *e;
1413 // Validate arguments
1414 if (p == NULL || name == NULL)
1415 {
1416 return 0;
1417 }
1418
1419 e = GetElement(p, name, VALUE_STR);
1420 if (e == NULL)
1421 {
1422 return 0;
1423 }
1424 return GetDataValueSize(e, index);
1425 }
1426
1427 // Add the buffer to the PACK (array)
PackAddBufEx(PACK * p,char * name,BUF * b,UINT index,UINT total)1428 ELEMENT *PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total)
1429 {
1430 // Validate arguments
1431 if (p == NULL || name == NULL || b == NULL || total == 0)
1432 {
1433 return NULL;
1434 }
1435
1436 return PackAddDataEx(p, name, b->Buf, b->Size, index, total);
1437 }
1438
1439 // Add the data to the PACK (array)
PackAddDataEx(PACK * p,char * name,void * data,UINT size,UINT index,UINT total)1440 ELEMENT *PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total)
1441 {
1442 VALUE *v;
1443 ELEMENT *e;
1444 // Validate arguments
1445 if (p == NULL || data == NULL || name == NULL || total == 0)
1446 {
1447 return NULL;
1448 }
1449
1450 v = NewDataValue(data, size);
1451 e = GetElement(p, name, VALUE_DATA);
1452 if (e != NULL)
1453 {
1454 if (e->num_value >= total)
1455 {
1456 FreeValue(e->values[index], VALUE_DATA);
1457 e->values[index] = v;
1458 }
1459 else
1460 {
1461 FreeValue(v, VALUE_DATA);
1462 }
1463 }
1464 else
1465 {
1466 e = ZeroMallocEx(sizeof(ELEMENT), true);
1467 StrCpy(e->name, sizeof(e->name), name);
1468 e->num_value = total;
1469 e->type = VALUE_DATA;
1470 e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1471 e->values[index] = v;
1472 if (AddElement(p, e) == false)
1473 {
1474 return NULL;
1475 }
1476 }
1477
1478 e->JsonHint_IsArray = true;
1479
1480 return e;
1481 }
1482
1483 // Add the buffer to the PACK
PackAddBuf(PACK * p,char * name,BUF * b)1484 ELEMENT *PackAddBuf(PACK *p, char *name, BUF *b)
1485 {
1486 // Validate arguments
1487 if (p == NULL || name == NULL || b == NULL)
1488 {
1489 return NULL;
1490 }
1491
1492 return PackAddData(p, name, b->Buf, b->Size);
1493 }
1494
1495 // Add the data to the PACK
PackAddData(PACK * p,char * name,void * data,UINT size)1496 ELEMENT *PackAddData(PACK *p, char *name, void *data, UINT size)
1497 {
1498 VALUE *v;
1499 ELEMENT *e;
1500 // Validate arguments
1501 if (p == NULL || data == NULL || name == NULL)
1502 {
1503 return NULL;
1504 }
1505
1506 v = NewDataValue(data, size);
1507 e = NewElement(name, VALUE_DATA, 1, &v);
1508 if (AddElement(p, e) == false)
1509 {
1510 return NULL;
1511 }
1512
1513 return e;
1514 }
1515
1516 // Add a 64 bit integer (array) to the PACK
PackAddInt64Ex(PACK * p,char * name,UINT64 i,UINT index,UINT total)1517 ELEMENT *PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total)
1518 {
1519 VALUE *v;
1520 ELEMENT *e;
1521 // Validate arguments
1522 if (p == NULL || name == NULL || total == 0)
1523 {
1524 return NULL;
1525 }
1526
1527 v = NewInt64Value(i);
1528 e = GetElement(p, name, VALUE_INT64);
1529 if (e != NULL)
1530 {
1531 if (e->num_value >= total)
1532 {
1533 FreeValue(e->values[index], VALUE_INT64);
1534 e->values[index] = v;
1535 }
1536 else
1537 {
1538 FreeValue(v, VALUE_INT64);
1539 }
1540 }
1541 else
1542 {
1543 e = ZeroMallocEx(sizeof(ELEMENT), true);
1544 StrCpy(e->name, sizeof(e->name), name);
1545 e->num_value = total;
1546 e->type = VALUE_INT64;
1547 e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1548 e->values[index] = v;
1549
1550 if (AddElement(p, e) == false)
1551 {
1552 return NULL;
1553 }
1554 }
1555
1556 e->JsonHint_IsArray = true;
1557
1558 return e;
1559 }
1560
1561 // Add an integer to the PACK (array)
PackAddIntEx(PACK * p,char * name,UINT i,UINT index,UINT total)1562 ELEMENT *PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total)
1563 {
1564 VALUE *v;
1565 ELEMENT *e;
1566 // Validate arguments
1567 if (p == NULL || name == NULL || total == 0)
1568 {
1569 return NULL;
1570 }
1571
1572 v = NewIntValue(i);
1573 e = GetElement(p, name, VALUE_INT);
1574 if (e != NULL)
1575 {
1576 if (e->num_value >= total)
1577 {
1578 FreeValue(e->values[index], VALUE_INT);
1579 e->values[index] = v;
1580 }
1581 else
1582 {
1583 FreeValue(v, VALUE_INT);
1584 }
1585 }
1586 else
1587 {
1588 e = ZeroMallocEx(sizeof(ELEMENT), true);
1589 StrCpy(e->name, sizeof(e->name), name);
1590 e->num_value = total;
1591 e->type = VALUE_INT;
1592 e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1593 e->values[index] = v;
1594
1595 if (AddElement(p, e) == false)
1596 {
1597 return NULL;
1598 }
1599 }
1600
1601 e->JsonHint_IsArray = true;
1602
1603 return e;
1604 }
1605
1606 // Add 64 bit integer time value to the PACK
PackAddTime64(PACK * p,char * name,UINT64 i)1607 ELEMENT *PackAddTime64(PACK *p, char *name, UINT64 i)
1608 {
1609 ELEMENT *e = PackAddInt64(p, name, i);
1610 if (e != NULL)
1611 {
1612 e->JsonHint_IsDateTime = true;
1613 }
1614 return e;
1615 }
PackAddTime64Ex(PACK * p,char * name,UINT64 i,UINT index,UINT total)1616 ELEMENT *PackAddTime64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total)
1617 {
1618 ELEMENT *e = PackAddInt64Ex(p, name, i, index, total);
1619 if (e != NULL)
1620 {
1621 e->JsonHint_IsDateTime = true;
1622 }
1623 return e;
1624 }
1625
1626
1627 // Add a 64 bit integer to the PACK
PackAddInt64(PACK * p,char * name,UINT64 i)1628 ELEMENT *PackAddInt64(PACK *p, char *name, UINT64 i)
1629 {
1630 VALUE *v;
1631 ELEMENT *e;
1632 // Validate arguments
1633 if (p == NULL || name == NULL)
1634 {
1635 return NULL;
1636 }
1637
1638 v = NewInt64Value(i);
1639 e = NewElement(name, VALUE_INT64, 1, &v);
1640 if (AddElement(p, e) == false)
1641 {
1642 return NULL;
1643 }
1644 return e;
1645 }
1646
1647 // Add the number of items to the PACK
PackAddNum(PACK * p,char * name,UINT num)1648 ELEMENT *PackAddNum(PACK *p, char *name, UINT num)
1649 {
1650 return PackAddInt(p, name, num);
1651 }
1652
1653 // Add an integer to the PACK
PackAddInt(PACK * p,char * name,UINT i)1654 ELEMENT *PackAddInt(PACK *p, char *name, UINT i)
1655 {
1656 VALUE *v;
1657 ELEMENT *e = NULL;
1658 // Validate arguments
1659 if (p == NULL || name == NULL)
1660 {
1661 return NULL;
1662 }
1663
1664 v = NewIntValue(i);
1665 e = NewElement(name, VALUE_INT, 1, &v);
1666 if (AddElement(p, e) == false)
1667 {
1668 return NULL;
1669 }
1670 return e;
1671 }
1672
1673 // Add a Unicode string (array) to the PACK
PackAddUniStrEx(PACK * p,char * name,wchar_t * unistr,UINT index,UINT total)1674 ELEMENT *PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total)
1675 {
1676 VALUE *v;
1677 ELEMENT *e;
1678 // Validate arguments
1679 if (p == NULL || name == NULL || unistr == NULL || total == 0)
1680 {
1681 return NULL;
1682 }
1683
1684 v = NewUniStrValue(unistr);
1685 e = GetElement(p, name, VALUE_UNISTR);
1686 if (e != NULL)
1687 {
1688 if (e->num_value >= total)
1689 {
1690 FreeValue(e->values[index], VALUE_UNISTR);
1691 e->values[index] = v;
1692 }
1693 else
1694 {
1695 FreeValue(v, VALUE_UNISTR);
1696 }
1697 }
1698 else
1699 {
1700 e = ZeroMallocEx(sizeof(ELEMENT), true);
1701 StrCpy(e->name, sizeof(e->name), name);
1702 e->num_value = total;
1703 e->type = VALUE_UNISTR;
1704 e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1705 e->values[index] = v;
1706 if (AddElement(p, e) == false)
1707 {
1708 return NULL;
1709 }
1710 }
1711
1712 e->JsonHint_IsArray = true;
1713
1714 return e;
1715 }
1716
1717 // Add a Unicode string to the PACK
PackAddUniStr(PACK * p,char * name,wchar_t * unistr)1718 ELEMENT *PackAddUniStr(PACK *p, char *name, wchar_t *unistr)
1719 {
1720 VALUE *v;
1721 ELEMENT *e = NULL;
1722 // Validate arguments
1723 if (p == NULL || name == NULL || unistr == NULL)
1724 {
1725 return NULL;
1726 }
1727
1728 v = NewUniStrValue(unistr);
1729 e = NewElement(name, VALUE_UNISTR, 1, &v);
1730 if (AddElement(p, e) == false)
1731 {
1732 return NULL;
1733 }
1734 return e;
1735 }
1736
1737 // Add a string to the PACK (array)
PackAddStrEx(PACK * p,char * name,char * str,UINT index,UINT total)1738 ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total)
1739 {
1740 VALUE *v;
1741 ELEMENT *e;
1742 // Validate arguments
1743 if (p == NULL || name == NULL || str == NULL || total == 0)
1744 {
1745 return NULL;
1746 }
1747
1748 v = NewStrValue(str);
1749 e = GetElement(p, name, VALUE_STR);
1750 if (e != NULL)
1751 {
1752 if (e->num_value >= total)
1753 {
1754 FreeValue(e->values[index], VALUE_STR);
1755 e->values[index] = v;
1756 }
1757 else
1758 {
1759 FreeValue(v, VALUE_STR);
1760 }
1761 }
1762 else
1763 {
1764 e = ZeroMallocEx(sizeof(ELEMENT), true);
1765 StrCpy(e->name, sizeof(e->name), name);
1766 e->num_value = total;
1767 e->type = VALUE_STR;
1768 e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
1769 e->values[index] = v;
1770 if (AddElement(p, e) == false)
1771 {
1772 return NULL;
1773 }
1774 }
1775
1776 e->JsonHint_IsArray = true;
1777
1778 return e;
1779 }
1780
1781 // Add a string to the PACK
PackAddStr(PACK * p,char * name,char * str)1782 ELEMENT *PackAddStr(PACK *p, char *name, char *str)
1783 {
1784 VALUE *v;
1785 ELEMENT *e = NULL;
1786 // Validate arguments
1787 if (p == NULL || name == NULL || str == NULL)
1788 {
1789 return NULL;
1790 }
1791
1792 v = NewStrValue(str);
1793 e = NewElement(name, VALUE_STR, 1, &v);
1794 if (AddElement(p, e) == false)
1795 {
1796 return NULL;
1797 }
1798 return e;
1799 }
1800
1801 // Add an element of PACK array to JSON Array
PackArrayElementToJsonArray(JSON_ARRAY * ja,PACK * p,ELEMENT * e,UINT index)1802 void PackArrayElementToJsonArray(JSON_ARRAY *ja, PACK *p, ELEMENT *e, UINT index)
1803 {
1804 if (ja == NULL || p == NULL || e == NULL || index >= e->num_value)
1805 {
1806 return;
1807 }
1808
1809 switch (e->type)
1810 {
1811 case VALUE_INT:
1812 if (e->JsonHint_IsIP)
1813 {
1814 if (InStr(e->name, "@") == false)
1815 {
1816 IP ip;
1817 if (PackGetIpEx(p, e->name, &ip, index))
1818 {
1819 char ip_str[64];
1820 IPToStr(ip_str, sizeof(ip_str), &ip);
1821 JsonArrayAddStr(ja, ip_str);
1822 }
1823 }
1824 }
1825 else if (e->JsonHint_IsBool)
1826 {
1827 JsonArrayAddBool(ja, PackGetBoolEx(p, e->name, index));
1828 }
1829 else
1830 {
1831 JsonArrayAddNumber(ja, PackGetIntEx(p, e->name, index));
1832 }
1833 break;
1834 case VALUE_INT64:
1835 if (e->JsonHint_IsIP == false)
1836 {
1837 if (e->JsonHint_IsDateTime == false)
1838 {
1839 JsonArrayAddNumber(ja, PackGetInt64Ex(p, e->name, index));
1840 }
1841 else
1842 {
1843 char dtstr[64];
1844
1845 SystemTime64ToJsonStr(dtstr, sizeof(dtstr), PackGetInt64Ex(p, e->name, index));
1846 JsonArrayAddStr(ja, dtstr);
1847 }
1848 }
1849 break;
1850 case VALUE_DATA:
1851 if (e->JsonHint_IsIP == false)
1852 {
1853 BUF *buf = PackGetBufEx(p, e->name, index);
1854 if (buf != NULL)
1855 {
1856 JsonArrayAddData(ja, buf->Buf, buf->Size);
1857 FreeBuf(buf);
1858 }
1859 else
1860 {
1861 UCHAR zero = 0;
1862 JsonArrayAddData(ja, &zero, 0);
1863 }
1864 }
1865 break;
1866 case VALUE_STR:
1867 if (e->JsonHint_IsIP == false)
1868 {
1869 if (e->values[index] != NULL)
1870 {
1871 JsonArrayAddStr(ja, e->values[index]->Str);
1872 }
1873 else
1874 {
1875 JsonArrayAddStr(ja, "");
1876 }
1877 }
1878 break;
1879 case VALUE_UNISTR:
1880 if (e->JsonHint_IsIP == false)
1881 {
1882 if (e->values[index] != NULL)
1883 {
1884 JsonArrayAddUniStr(ja, e->values[index]->UniStr);
1885 }
1886 else
1887 {
1888 JsonArrayAddUniStr(ja, L"");
1889 }
1890 }
1891 break;
1892 }
1893 }
1894
1895 // Add an element of PACK to JSON Object
PackElementToJsonObject(JSON_OBJECT * o,PACK * p,ELEMENT * e,UINT index)1896 void PackElementToJsonObject(JSON_OBJECT *o, PACK *p, ELEMENT *e, UINT index)
1897 {
1898 char *suffix;
1899 char name[MAX_PATH];
1900 if (o == NULL || p == NULL || e == NULL)
1901 {
1902 return;
1903 }
1904
1905 suffix = DetermineJsonSuffixForPackElement(e);
1906
1907 if (suffix == NULL)
1908 {
1909 return;
1910 }
1911
1912 StrCpy(name, sizeof(name), e->name);
1913 StrCat(name, sizeof(name), suffix);
1914
1915 switch (e->type)
1916 {
1917 case VALUE_INT:
1918 if (e->JsonHint_IsIP)
1919 {
1920 if (InStr(e->name, "@") == false)
1921 {
1922 IP ip;
1923 if (PackGetIpEx(p, e->name, &ip, index))
1924 {
1925 char ip_str[64];
1926 IPToStr(ip_str, sizeof(ip_str), &ip);
1927 JsonSetStr(o, name, ip_str);
1928 }
1929 }
1930 }
1931 else if (e->JsonHint_IsBool)
1932 {
1933 JsonSetBool(o, name, PackGetBoolEx(p, e->name, index));
1934 }
1935 else
1936 {
1937 JsonSetNumber(o, name, PackGetIntEx(p, e->name, index));
1938 }
1939 break;
1940 case VALUE_INT64:
1941 if (e->JsonHint_IsIP == false)
1942 {
1943 if (e->JsonHint_IsDateTime == false)
1944 {
1945 JsonSetNumber(o, name, PackGetInt64Ex(p, e->name, index));
1946 }
1947 else
1948 {
1949 char dtstr[64];
1950
1951 SystemTime64ToJsonStr(dtstr, sizeof(dtstr), PackGetInt64Ex(p, e->name, index));
1952 JsonSetStr(o, name, dtstr);
1953 }
1954 }
1955 break;
1956 case VALUE_DATA:
1957 if (e->JsonHint_IsIP == false)
1958 {
1959 BUF *buf = PackGetBufEx(p, e->name, index);
1960 if (buf != NULL)
1961 {
1962 JsonSetData(o, name, buf->Buf, buf->Size);
1963 FreeBuf(buf);
1964 }
1965 else
1966 {
1967 UCHAR zero = 0;
1968 JsonSetData(o, name, &zero, 0);
1969 }
1970 }
1971 break;
1972 case VALUE_STR:
1973 if (e->JsonHint_IsIP == false)
1974 {
1975 if (e->values[index] != NULL)
1976 {
1977 JsonSetStr(o, name, e->values[index]->Str);
1978 }
1979 else
1980 {
1981 JsonSetStr(o, name, "");
1982 }
1983 }
1984 break;
1985 case VALUE_UNISTR:
1986 if (e->JsonHint_IsIP == false)
1987 {
1988 if (e->values[index] != NULL)
1989 {
1990 JsonSetUniStr(o, name, e->values[index]->UniStr);
1991 }
1992 else
1993 {
1994 JsonSetUniStr(o, name, L"");
1995 }
1996 }
1997 break;
1998 }
1999 }
2000
2001 // Determine JSON element suffix for PACK element
DetermineJsonSuffixForPackElement(ELEMENT * e)2002 char *DetermineJsonSuffixForPackElement(ELEMENT *e)
2003 {
2004 switch (e->type)
2005 {
2006 case VALUE_INT:
2007 if (e->JsonHint_IsIP)
2008 {
2009 if (InStr(e->name, "@") == false)
2010 {
2011 return "_ip";
2012 }
2013 }
2014 else if (e->JsonHint_IsBool)
2015 {
2016 return "_bool";
2017 }
2018 else
2019 {
2020 return "_u32";
2021 }
2022 break;
2023 case VALUE_INT64:
2024 if (e->JsonHint_IsIP == false)
2025 {
2026 if (e->JsonHint_IsDateTime == false)
2027 {
2028 return "_u64";
2029 }
2030 else
2031 {
2032 return "_dt";
2033 }
2034 }
2035 break;
2036 case VALUE_DATA:
2037 if (e->JsonHint_IsIP == false)
2038 {
2039 return "_bin";
2040 }
2041 break;
2042 case VALUE_STR:
2043 if (e->JsonHint_IsIP == false)
2044 {
2045 return "_str";
2046 }
2047 break;
2048 case VALUE_UNISTR:
2049 if (e->JsonHint_IsIP == false)
2050 {
2051 return "_utf";
2052 }
2053 break;
2054 }
2055
2056 return NULL;
2057 }
2058
2059 // Convert JSON to PACK
JsonToPack(JSON_VALUE * v)2060 PACK *JsonToPack(JSON_VALUE *v)
2061 {
2062 PACK *p = NULL;
2063 JSON_OBJECT *jo;
2064 if (v == NULL)
2065 {
2066 return NULL;
2067 }
2068
2069 p = NewPack();
2070
2071 jo = JsonValueGetObject(v);
2072
2073 if (jo != NULL)
2074 {
2075 UINT i;
2076 for (i = 0;i < jo->count;i++)
2077 {
2078 char *name = jo->names[i];
2079 JSON_VALUE *value = jo->values[i];
2080
2081 if (value->type == JSON_TYPE_ARRAY)
2082 {
2083 UINT j;
2084 JSON_ARRAY *ja = value->value.array;
2085
2086 for (j = 0;j < ja->count;j++)
2087 {
2088 if (ja->items[j]->type != JSON_TYPE_OBJECT)
2089 {
2090 JsonTryParseValueAddToPack(p, ja->items[j], name, j, ja->count, false);
2091 }
2092 else
2093 {
2094 JSON_VALUE *v = ja->items[j];
2095 JSON_OBJECT *o = v->value.object;
2096 UINT k;
2097
2098 for (k = 0;k < o->count;k++)
2099 {
2100 char *name2 = o->names[k];
2101 JSON_VALUE *value2 = o->values[k];
2102
2103 PackSetCurrentJsonGroupName(p, name);
2104 JsonTryParseValueAddToPack(p, value2, name2, j, ja->count, false);
2105 PackSetCurrentJsonGroupName(p, NULL);
2106 }
2107 }
2108 }
2109 }
2110 else
2111 {
2112 JsonTryParseValueAddToPack(p, value, name, 0, 1, true);
2113 }
2114 }
2115 }
2116
2117 return p;
2118 }
2119
ElementNullSafe(ELEMENT * p)2120 ELEMENT *ElementNullSafe(ELEMENT *p)
2121 {
2122 static ELEMENT dummy;
2123 if (p == NULL)
2124 {
2125 Zero(&dummy, sizeof(dummy));
2126 return &dummy;
2127 }
2128 return p;
2129 }
2130
JsonTryParseValueAddToPack(PACK * p,JSON_VALUE * v,char * v_name,UINT index,UINT total,bool is_single)2131 bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index, UINT total, bool is_single)
2132 {
2133 char name[MAX_PATH];
2134 bool ok = true;
2135 if (p == NULL || v == NULL)
2136 {
2137 return false;
2138 }
2139
2140 if (TrimEndWith(name, sizeof(name), v_name, "_bool"))
2141 {
2142 if (v->type == JSON_TYPE_BOOL)
2143 {
2144 ElementNullSafe(PackAddBoolEx(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single;
2145 ok = true;
2146 }
2147 else if (v->type == JSON_TYPE_NUMBER)
2148 {
2149 ElementNullSafe(PackAddBoolEx(p, name, MAKEBOOL(v->value.number), index, total))->JsonHint_IsArray = !is_single;
2150 ok = true;
2151 }
2152 else if (v->type == JSON_TYPE_STRING)
2153 {
2154 ElementNullSafe(PackAddBoolEx(p, name, ToBool(v->value.string), index, total))->JsonHint_IsArray = !is_single;
2155 ok = true;
2156 }
2157 }
2158 else if (TrimEndWith(name, sizeof(name), v_name, "_u32"))
2159 {
2160 if (v->type == JSON_TYPE_BOOL)
2161 {
2162 ElementNullSafe(PackAddIntEx(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single;
2163 ok = true;
2164 }
2165 else if (v->type == JSON_TYPE_NUMBER)
2166 {
2167 ElementNullSafe(PackAddIntEx(p, name, (UINT)v->value.number, index, total))->JsonHint_IsArray = !is_single;
2168 ok = true;
2169 }
2170 else if (v->type == JSON_TYPE_STRING)
2171 {
2172 ElementNullSafe(PackAddIntEx(p, name, ToInt(v->value.string), index, total))->JsonHint_IsArray = !is_single;
2173 ok = true;
2174 }
2175 }
2176 else if (TrimEndWith(name, sizeof(name), v_name, "_u64"))
2177 {
2178 if (v->type == JSON_TYPE_BOOL)
2179 {
2180 ElementNullSafe(PackAddInt64Ex(p, name, MAKEBOOL(v->value.boolean), index, total))->JsonHint_IsArray = !is_single;
2181 ok = true;
2182 }
2183 else if (v->type == JSON_TYPE_NUMBER)
2184 {
2185 ElementNullSafe(PackAddInt64Ex(p, name, v->value.number, index, total))->JsonHint_IsArray = !is_single;
2186 ok = true;
2187 }
2188 else if (v->type == JSON_TYPE_STRING)
2189 {
2190 ElementNullSafe(PackAddInt64Ex(p, name, ToInt64(v->value.string), index, total))->JsonHint_IsArray = !is_single;
2191 ok = true;
2192 }
2193 }
2194 else if (TrimEndWith(name, sizeof(name), v_name, "_str"))
2195 {
2196 if (v->type == JSON_TYPE_BOOL)
2197 {
2198 ElementNullSafe(PackAddStrEx(p, name, MAKEBOOL(v->value.boolean) ? "true" : "false", index, total))->JsonHint_IsArray = !is_single;
2199 ok = true;
2200 }
2201 else if (v->type == JSON_TYPE_NUMBER)
2202 {
2203 char tmp[64];
2204 ToStr64(tmp, v->value.number);
2205 ElementNullSafe(PackAddStrEx(p, name, tmp, index, total))->JsonHint_IsArray = !is_single;
2206 ok = true;
2207 }
2208 else if (v->type == JSON_TYPE_STRING)
2209 {
2210 ElementNullSafe(PackAddStrEx(p, name, v->value.string, index, total))->JsonHint_IsArray = !is_single;
2211 ok = true;
2212 }
2213 }
2214 else if (TrimEndWith(name, sizeof(name), v_name, "_utf"))
2215 {
2216 if (v->type == JSON_TYPE_BOOL)
2217 {
2218 ElementNullSafe(PackAddUniStrEx(p, name, MAKEBOOL(v->value.boolean) ? L"true" : L"false", index, total))->JsonHint_IsArray = !is_single;
2219 ok = true;
2220 }
2221 else if (v->type == JSON_TYPE_NUMBER)
2222 {
2223 char tmp[64];
2224 wchar_t tmp2[64];
2225 ToStr64(tmp, v->value.number);
2226 StrToUni(tmp2, sizeof(tmp2), tmp);
2227 ElementNullSafe(PackAddUniStrEx(p, name, tmp2, index, total))->JsonHint_IsArray = !is_single;
2228 ok = true;
2229 }
2230 else if (v->type == JSON_TYPE_STRING)
2231 {
2232 wchar_t *uni = CopyUtfToUni(v->value.string);
2233 ElementNullSafe(PackAddUniStrEx(p, name, uni, index, total))->JsonHint_IsArray = !is_single;
2234 Free(uni);
2235 ok = true;
2236 }
2237 }
2238 else if (TrimEndWith(name, sizeof(name), v_name, "_bin"))
2239 {
2240 if (v->type == JSON_TYPE_STRING)
2241 {
2242 UINT len = StrLen(v->value.string);
2243 UCHAR *data = ZeroMalloc(len * 4 + 64);
2244 UINT size = B64_Decode(data, v->value.string, len);
2245 ElementNullSafe(PackAddDataEx(p, name, data, size, index, total))->JsonHint_IsArray = !is_single;
2246 Free(data);
2247 ok = true;
2248 }
2249 }
2250 else if (TrimEndWith(name, sizeof(name), v_name, "_dt"))
2251 {
2252 if (v->type == JSON_TYPE_NUMBER)
2253 {
2254 ElementNullSafe(PackAddInt64Ex(p, name, v->value.number, index, total))->JsonHint_IsArray = !is_single;
2255 ok = true;
2256 }
2257 else if (v->type == JSON_TYPE_STRING)
2258 {
2259 UINT64 time = DateTimeStrRFC3339ToSystemTime64(v->value.string);
2260 ELEMENT *e = PackAddInt64Ex(p, name, time, index, total);
2261 if (e != NULL)
2262 {
2263 e->JsonHint_IsArray = !is_single;
2264 e->JsonHint_IsDateTime = true;
2265 }
2266 ok = true;
2267 }
2268 }
2269 else if (TrimEndWith(name, sizeof(name), v_name, "_ip"))
2270 {
2271 if (v->type == JSON_TYPE_STRING)
2272 {
2273 IP ip;
2274 if (StrToIP(&ip, v->value.string))
2275 {
2276 PackAddIpEx2(p, name, &ip, index, total, is_single);
2277 ok = true;
2278 }
2279 }
2280 }
2281
2282 return ok;
2283 }
2284
2285 // Convert JSON string to PACK
JsonStrToPack(char * str)2286 PACK *JsonStrToPack(char *str)
2287 {
2288 JSON_VALUE *v = StrToJson(str);
2289 PACK *ret;
2290
2291 if (v == NULL)
2292 {
2293 return NULL;
2294 }
2295
2296 ret = JsonToPack(v);
2297
2298 JsonFree(v);
2299
2300 return ret;
2301 }
2302
2303 // Convert PACK to JSON string
PackToJsonStr(PACK * p)2304 char *PackToJsonStr(PACK *p)
2305 {
2306 char *ret;
2307 JSON_VALUE *json = PackToJson(p);
2308
2309 ret = JsonToStr(json);
2310
2311 JsonFree(json);
2312
2313 return ret;
2314 }
2315
2316 // Convert PACK to JSON
PackToJson(PACK * p)2317 JSON_VALUE *PackToJson(PACK *p)
2318 {
2319 JSON_VALUE *v;
2320 JSON_OBJECT *o;
2321 UINT i, j, k;
2322 LIST *json_group_id_list;
2323 if (p == NULL)
2324 {
2325 return JsonNewObject();
2326 }
2327
2328 json_group_id_list = NewStrList();
2329
2330 for (i = 0;i < LIST_NUM(p->elements);i++)
2331 {
2332 ELEMENT *e = LIST_DATA(p->elements, i);
2333
2334 if (e->num_value >= 2 || e->JsonHint_IsArray)
2335 {
2336 if (IsEmptyStr(e->JsonHint_GroupName) == false)
2337 {
2338 AddStrToStrListDistinct(json_group_id_list, e->JsonHint_GroupName);
2339 }
2340 }
2341 }
2342
2343 for (i = 0;i < LIST_NUM(p->json_subitem_names);i++)
2344 {
2345 char *group_name = LIST_DATA(p->json_subitem_names, i);
2346
2347 if (IsEmptyStr(group_name) == false)
2348 {
2349 AddStrToStrListDistinct(json_group_id_list, group_name);
2350 }
2351 }
2352
2353 v = JsonNewObject();
2354 o = JsonValueGetObject(v);
2355
2356 for (k = 0;k < LIST_NUM(json_group_id_list);k++)
2357 {
2358 char *group_name = LIST_DATA(json_group_id_list, k);
2359 UINT array_count = INFINITE;
2360 bool ok = true;
2361
2362 for (i = 0;i < LIST_NUM(p->elements);i++)
2363 {
2364 ELEMENT *e = LIST_DATA(p->elements, i);
2365
2366 if (e->num_value >= 2 || e->JsonHint_IsArray)
2367 {
2368 if (StrCmpi(e->JsonHint_GroupName, group_name) == 0)
2369 {
2370 if (array_count == INFINITE)
2371 {
2372 array_count = e->num_value;
2373 }
2374 else
2375 {
2376 if (array_count != e->num_value)
2377 {
2378 ok = false;
2379 }
2380 }
2381 }
2382 }
2383 }
2384
2385 if (array_count == INFINITE)
2386 {
2387 array_count = 0;
2388 }
2389
2390 if (ok)
2391 {
2392 JSON_VALUE **json_objects = ZeroMalloc(sizeof(void *) * array_count);
2393 JSON_VALUE *jav = JsonNewArray();
2394 JSON_ARRAY *ja = JsonArray(jav);
2395
2396 JsonSet(o, group_name, jav);
2397
2398 for (j = 0;j < array_count;j++)
2399 {
2400 json_objects[j] = JsonNewObject();
2401
2402 JsonArrayAdd(ja, json_objects[j]);
2403 }
2404
2405 for (i = 0;i < LIST_NUM(p->elements);i++)
2406 {
2407 ELEMENT *e = LIST_DATA(p->elements, i);
2408
2409 if (e->num_value >= 2 || e->JsonHint_IsArray)
2410 {
2411 if (StrCmpi(e->JsonHint_GroupName, group_name) == 0)
2412 {
2413 for (j = 0;j < e->num_value;j++)
2414 {
2415 PackElementToJsonObject(JsonValueGetObject(json_objects[j]),
2416 p, e, j);
2417 }
2418 }
2419 }
2420 }
2421
2422 Free(json_objects);
2423 }
2424 }
2425
2426 for (i = 0;i < LIST_NUM(p->elements);i++)
2427 {
2428 ELEMENT *e = LIST_DATA(p->elements, i);
2429
2430 if (e->num_value >= 2 || e->JsonHint_IsArray)
2431 {
2432 if (IsEmptyStr(e->JsonHint_GroupName))
2433 {
2434 char *suffix = DetermineJsonSuffixForPackElement(e);
2435
2436 if (suffix != NULL)
2437 {
2438 JSON_VALUE *jav = JsonNewArray();
2439 JSON_ARRAY *ja = JsonArray(jav);
2440 char name[MAX_PATH];
2441
2442 for (j = 0;j < e->num_value;j++)
2443 {
2444 PackArrayElementToJsonArray(ja, p, e, j);
2445 }
2446
2447 StrCpy(name, sizeof(name), e->name);
2448 StrCat(name, sizeof(name), suffix);
2449
2450 JsonSet(o, name, jav);
2451 }
2452 }
2453 }
2454 else if (e->num_value == 1)
2455 {
2456 PackElementToJsonObject(o, p, e, 0);
2457 }
2458 }
2459
2460 ReleaseStrList(json_group_id_list);
2461
2462 return v;
2463 }
2464
2465
2466
2467
2468