1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #ifndef ENGINE_SHARED_JSONWRITER_H |
4 | #define ENGINE_SHARED_JSONWRITER_H |
5 | |
6 | #include <base/types.h> |
7 | |
8 | #include <stack> |
9 | #include <string> |
10 | |
11 | /** |
12 | * JSON writer with abstract writing function. |
13 | */ |
14 | class CJsonWriter |
15 | { |
16 | enum EJsonStateKind |
17 | { |
18 | STATE_OBJECT, |
19 | STATE_ARRAY, |
20 | STATE_ATTRIBUTE, |
21 | }; |
22 | |
23 | struct SState |
24 | { |
25 | EJsonStateKind m_Kind; |
26 | bool m_Empty = true; |
27 | |
28 | SState(EJsonStateKind Kind) : |
29 | m_Kind(Kind) |
30 | { |
31 | } |
32 | }; |
33 | |
34 | std::stack<SState> m_States; |
35 | int m_Indentation; |
36 | |
37 | bool CanWriteDatatype(); |
38 | void WriteInternalEscaped(const char *pStr); |
39 | void WriteIndent(bool EndElement); |
40 | void PushState(EJsonStateKind NewState); |
41 | SState *TopState(); |
42 | EJsonStateKind PopState(); |
43 | void CompleteDataType(); |
44 | |
45 | protected: |
46 | // String must be zero-terminated when Length is -1. |
47 | virtual void WriteInternal(const char *pStr, int Length = -1) = 0; |
48 | |
49 | public: |
50 | CJsonWriter(); |
51 | virtual ~CJsonWriter() = default; |
52 | |
53 | // The root is created by beginning the first datatype (object, array, value). |
54 | // The writer must not be used after ending the root, which must be unique. |
55 | |
56 | // Begin writing a new object |
57 | void BeginObject(); |
58 | // End current object |
59 | void EndObject(); |
60 | |
61 | // Begin writing a new array |
62 | void BeginArray(); |
63 | // End current array |
64 | void EndArray(); |
65 | |
66 | // Write attribute with the given name inside the current object. |
67 | // Names inside one object should be unique, but this is not checked here. |
68 | // Must be used to begin writing anything inside objects and only there. |
69 | // Must be followed by a datatype for the attribute value. |
70 | void WriteAttribute(const char *pName); |
71 | |
72 | // Functions for writing value literals: |
73 | // - As array values in arrays. |
74 | // - As attribute values after beginning an attribute inside an object. |
75 | // - As root value (only once). |
76 | void WriteStrValue(const char *pValue); |
77 | void WriteIntValue(int Value); |
78 | void WriteBoolValue(bool Value); |
79 | void WriteNullValue(); |
80 | }; |
81 | |
82 | /** |
83 | * Writes JSON to a file. |
84 | */ |
85 | class CJsonFileWriter : public CJsonWriter |
86 | { |
87 | IOHANDLE m_IO; |
88 | |
89 | protected: |
90 | void WriteInternal(const char *pStr, int Length = -1) override; |
91 | |
92 | public: |
93 | /** |
94 | * Create a new writer object without writing anything to the file yet. |
95 | * The file will automatically be closed by the destructor. |
96 | */ |
97 | CJsonFileWriter(IOHANDLE IO); |
98 | ~CJsonFileWriter(); |
99 | }; |
100 | |
101 | /** |
102 | * Writes JSON to an std::string. |
103 | */ |
104 | class CJsonStringWriter : public CJsonWriter |
105 | { |
106 | std::string m_OutputString; |
107 | bool m_RetrievedOutput = false; |
108 | |
109 | protected: |
110 | void WriteInternal(const char *pStr, int Length = -1) override; |
111 | |
112 | public: |
113 | CJsonStringWriter() = default; |
114 | ~CJsonStringWriter() = default; |
115 | std::string &&GetOutputString(); |
116 | }; |
117 | |
118 | #endif |
119 | |