1#include <base/dbg.h>
2#include <base/str.h>
3
4#include <engine/shared/json.h>
5
6const struct _json_value *json_object_get(const json_value *pObject, const char *pIndex)
7{
8 unsigned int i;
9
10 if(pObject->type != json_object)
11 return &json_value_none;
12
13 for(i = 0; i < pObject->u.object.length; ++i)
14 if(!str_comp(a: pObject->u.object.values[i].name, b: pIndex))
15 return pObject->u.object.values[i].value;
16
17 return &json_value_none;
18}
19
20const struct _json_value *json_array_get(const json_value *pArray, int Index)
21{
22 if(pArray->type != json_array || Index >= (int)pArray->u.array.length)
23 return &json_value_none;
24
25 return pArray->u.array.values[Index];
26}
27
28int json_array_length(const json_value *pArray)
29{
30 return pArray->u.array.length;
31}
32
33const char *json_string_get(const json_value *pString)
34{
35 return pString->u.string.ptr;
36}
37
38int json_int_get(const json_value *pInteger)
39{
40 return pInteger->u.integer;
41}
42
43int json_boolean_get(const json_value *pBoolean)
44{
45 return pBoolean->u.boolean != 0;
46}
47
48static char EscapeJsonChar(char c)
49{
50 switch(c)
51 {
52 case '\"': return '\"';
53 case '\\': return '\\';
54 case '\b': return 'b';
55 case '\n': return 'n';
56 case '\r': return 'r';
57 case '\t': return 't';
58 // Don't escape '\f', who uses that. :)
59 default: return 0;
60 }
61}
62
63char *EscapeJson(char *pBuffer, int BufferSize, const char *pString)
64{
65 dbg_assert(BufferSize > 0, "can't null-terminate the string");
66 // Subtract the space for null termination early.
67 BufferSize--;
68
69 char *pResult = pBuffer;
70 while(BufferSize && *pString)
71 {
72 char c = *pString;
73 pString++;
74 char Escaped = EscapeJsonChar(c);
75 if(Escaped)
76 {
77 if(BufferSize < 2)
78 {
79 break;
80 }
81 *pBuffer++ = '\\';
82 *pBuffer++ = Escaped;
83 BufferSize -= 2;
84 }
85 // Assuming ASCII/UTF-8, "if control character".
86 else if((unsigned char)c < 0x20)
87 {
88 // \uXXXX
89 if(BufferSize < 6)
90 {
91 break;
92 }
93 str_format(buffer: pBuffer, buffer_size: BufferSize, format: "\\u%04x", c);
94 pBuffer += 6;
95 BufferSize -= 6;
96 }
97 else
98 {
99 *pBuffer++ = c;
100 BufferSize--;
101 }
102 }
103 *pBuffer = 0;
104 return pResult;
105}
106
107const char *JsonBool(bool Bool)
108{
109 if(Bool)
110 {
111 return "true";
112 }
113 else
114 {
115 return "false";
116 }
117}
118