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