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