Skip to content

Commit 4dc9a47

Browse files
committed
Drop templated JsonEncoder class & its utilities
1 parent a56548d commit 4dc9a47

File tree

1 file changed

+3
-343
lines changed

1 file changed

+3
-343
lines changed

lib/base/json.cpp

+3-343
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
11
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
22

33
#include "base/json.hpp"
4-
#include "base/debug.hpp"
5-
#include "base/namespace.hpp"
6-
#include "base/dictionary.hpp"
74
#include "base/array.hpp"
8-
#include "base/objectlock.hpp"
9-
#include "base/convert.hpp"
10-
#include "base/utility.hpp"
11-
#include <bitset>
12-
#include <boost/exception_ptr.hpp>
13-
#include <cstdint>
14-
#include <json.hpp>
155
#include <stack>
16-
#include <utility>
17-
#include <vector>
186

197
using namespace icinga;
208

@@ -143,165 +131,11 @@ class JsonSax : public nlohmann::json_sax<nlohmann::json>
143131
void FillCurrentTarget(Value value);
144132
};
145133

146-
const char l_Null[] = "null";
147-
const char l_False[] = "false";
148-
const char l_True[] = "true";
149-
const char l_Indent[] = " ";
150-
151-
// https://github.com/nlohmann/json/issues/1512
152-
template<bool prettyPrint>
153-
class JsonEncoder
154-
{
155-
public:
156-
void Null();
157-
void Boolean(bool value);
158-
void NumberFloat(double value);
159-
void Strng(String value);
160-
void StartObject();
161-
void Key(String value);
162-
void EndObject();
163-
void StartArray();
164-
void EndArray();
165-
166-
String GetResult();
167-
168-
private:
169-
std::vector<char> m_Result;
170-
String m_CurrentKey;
171-
std::stack<std::bitset<2>> m_CurrentSubtree;
172-
173-
void AppendChar(char c);
174-
175-
template<class Iterator>
176-
void AppendChars(Iterator begin, Iterator end);
177-
178-
void AppendJson(nlohmann::json json);
179-
180-
void BeforeItem();
181-
182-
void FinishContainer(char terminator);
183-
};
184-
185-
template<bool prettyPrint>
186-
void Encode(JsonEncoder<prettyPrint>& stateMachine, const Value& value);
187-
188-
template<bool prettyPrint>
189-
inline
190-
void EncodeNamespace(JsonEncoder<prettyPrint>& stateMachine, const Namespace::Ptr& ns)
191-
{
192-
stateMachine.StartObject();
193-
194-
ObjectLock olock(ns);
195-
for (const Namespace::Pair& kv : ns) {
196-
stateMachine.Key(Utility::ValidateUTF8(kv.first));
197-
Encode(stateMachine, kv.second.Val);
198-
}
199-
200-
stateMachine.EndObject();
201-
}
202-
203-
template<bool prettyPrint>
204-
inline
205-
void EncodeDictionary(JsonEncoder<prettyPrint>& stateMachine, const Dictionary::Ptr& dict)
206-
{
207-
stateMachine.StartObject();
208-
209-
ObjectLock olock(dict);
210-
for (const Dictionary::Pair& kv : dict) {
211-
stateMachine.Key(Utility::ValidateUTF8(kv.first));
212-
Encode(stateMachine, kv.second);
213-
}
214-
215-
stateMachine.EndObject();
216-
}
217-
218-
template<bool prettyPrint>
219-
inline
220-
void EncodeArray(JsonEncoder<prettyPrint>& stateMachine, const Array::Ptr& arr)
221-
{
222-
stateMachine.StartArray();
223-
224-
ObjectLock olock(arr);
225-
for (const Value& value : arr) {
226-
Encode(stateMachine, value);
227-
}
228-
229-
stateMachine.EndArray();
230-
}
231-
232-
template<bool prettyPrint>
233-
void Encode(JsonEncoder<prettyPrint>& stateMachine, const Value& value)
234-
{
235-
switch (value.GetType()) {
236-
case ValueNumber:
237-
stateMachine.NumberFloat(value.Get<double>());
238-
break;
239-
240-
case ValueBoolean:
241-
stateMachine.Boolean(value.ToBool());
242-
break;
243-
244-
case ValueString:
245-
stateMachine.Strng(Utility::ValidateUTF8(value.Get<String>()));
246-
break;
247-
248-
case ValueObject:
249-
{
250-
const Object::Ptr& obj = value.Get<Object::Ptr>();
251-
252-
{
253-
Namespace::Ptr ns = dynamic_pointer_cast<Namespace>(obj);
254-
if (ns) {
255-
EncodeNamespace(stateMachine, ns);
256-
break;
257-
}
258-
}
259-
260-
{
261-
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(obj);
262-
if (dict) {
263-
EncodeDictionary(stateMachine, dict);
264-
break;
265-
}
266-
}
267-
268-
{
269-
Array::Ptr arr = dynamic_pointer_cast<Array>(obj);
270-
if (arr) {
271-
EncodeArray(stateMachine, arr);
272-
break;
273-
}
274-
}
275-
276-
// obj is most likely a function => "Object of type 'Function'"
277-
Encode(stateMachine, obj->ToString());
278-
break;
279-
}
280-
281-
case ValueEmpty:
282-
stateMachine.Null();
283-
break;
284-
285-
default:
286-
VERIFY(!"Invalid variant type.");
287-
}
288-
}
289-
290134
String icinga::JsonEncode(const Value& value, bool pretty_print)
291135
{
292-
if (pretty_print) {
293-
JsonEncoder<true> stateMachine;
294-
295-
Encode(stateMachine, value);
296-
297-
return stateMachine.GetResult() + "\n";
298-
} else {
299-
JsonEncoder<false> stateMachine;
300-
301-
Encode(stateMachine, value);
302-
303-
return stateMachine.GetResult();
304-
}
136+
std::ostringstream oss;
137+
JsonEncode(value, oss, pretty_print);
138+
return oss.str();
305139
}
306140

307141
/**
@@ -460,177 +294,3 @@ void JsonSax::FillCurrentTarget(Value value)
460294
}
461295
}
462296
}
463-
464-
template<bool prettyPrint>
465-
inline
466-
void JsonEncoder<prettyPrint>::Null()
467-
{
468-
BeforeItem();
469-
AppendChars((const char*)l_Null, (const char*)l_Null + 4);
470-
}
471-
472-
template<bool prettyPrint>
473-
inline
474-
void JsonEncoder<prettyPrint>::Boolean(bool value)
475-
{
476-
BeforeItem();
477-
478-
if (value) {
479-
AppendChars((const char*)l_True, (const char*)l_True + 4);
480-
} else {
481-
AppendChars((const char*)l_False, (const char*)l_False + 5);
482-
}
483-
}
484-
485-
template<bool prettyPrint>
486-
inline
487-
void JsonEncoder<prettyPrint>::NumberFloat(double value)
488-
{
489-
BeforeItem();
490-
491-
// Make sure 0.0 is serialized as 0, so e.g. Icinga DB can parse it as int.
492-
if (value < 0) {
493-
long long i = value;
494-
495-
if (i == value) {
496-
AppendJson(i);
497-
} else {
498-
AppendJson(value);
499-
}
500-
} else {
501-
unsigned long long i = value;
502-
503-
if (i == value) {
504-
AppendJson(i);
505-
} else {
506-
AppendJson(value);
507-
}
508-
}
509-
}
510-
511-
template<bool prettyPrint>
512-
inline
513-
void JsonEncoder<prettyPrint>::Strng(String value)
514-
{
515-
BeforeItem();
516-
AppendJson(std::move(value));
517-
}
518-
519-
template<bool prettyPrint>
520-
inline
521-
void JsonEncoder<prettyPrint>::StartObject()
522-
{
523-
BeforeItem();
524-
AppendChar('{');
525-
526-
m_CurrentSubtree.push(2);
527-
}
528-
529-
template<bool prettyPrint>
530-
inline
531-
void JsonEncoder<prettyPrint>::Key(String value)
532-
{
533-
m_CurrentKey = std::move(value);
534-
}
535-
536-
template<bool prettyPrint>
537-
inline
538-
void JsonEncoder<prettyPrint>::EndObject()
539-
{
540-
FinishContainer('}');
541-
}
542-
543-
template<bool prettyPrint>
544-
inline
545-
void JsonEncoder<prettyPrint>::StartArray()
546-
{
547-
BeforeItem();
548-
AppendChar('[');
549-
550-
m_CurrentSubtree.push(0);
551-
}
552-
553-
template<bool prettyPrint>
554-
inline
555-
void JsonEncoder<prettyPrint>::EndArray()
556-
{
557-
FinishContainer(']');
558-
}
559-
560-
template<bool prettyPrint>
561-
inline
562-
String JsonEncoder<prettyPrint>::GetResult()
563-
{
564-
return String(m_Result.begin(), m_Result.end());
565-
}
566-
567-
template<bool prettyPrint>
568-
inline
569-
void JsonEncoder<prettyPrint>::AppendChar(char c)
570-
{
571-
m_Result.emplace_back(c);
572-
}
573-
574-
template<bool prettyPrint>
575-
template<class Iterator>
576-
inline
577-
void JsonEncoder<prettyPrint>::AppendChars(Iterator begin, Iterator end)
578-
{
579-
m_Result.insert(m_Result.end(), begin, end);
580-
}
581-
582-
template<bool prettyPrint>
583-
inline
584-
void JsonEncoder<prettyPrint>::AppendJson(nlohmann::json json)
585-
{
586-
nlohmann::detail::serializer<nlohmann::json>(nlohmann::detail::output_adapter<char>(m_Result), ' ').dump(std::move(json), prettyPrint, true, 0);
587-
}
588-
589-
template<bool prettyPrint>
590-
inline
591-
void JsonEncoder<prettyPrint>::BeforeItem()
592-
{
593-
if (!m_CurrentSubtree.empty()) {
594-
auto& node (m_CurrentSubtree.top());
595-
596-
if (node[0]) {
597-
AppendChar(',');
598-
} else {
599-
node[0] = true;
600-
}
601-
602-
if (prettyPrint) {
603-
AppendChar('\n');
604-
605-
for (auto i (m_CurrentSubtree.size()); i; --i) {
606-
AppendChars((const char*)l_Indent, (const char*)l_Indent + 4);
607-
}
608-
}
609-
610-
if (node[1]) {
611-
AppendJson(std::move(m_CurrentKey));
612-
AppendChar(':');
613-
614-
if (prettyPrint) {
615-
AppendChar(' ');
616-
}
617-
}
618-
}
619-
}
620-
621-
template<bool prettyPrint>
622-
inline
623-
void JsonEncoder<prettyPrint>::FinishContainer(char terminator)
624-
{
625-
if (prettyPrint && m_CurrentSubtree.top()[0]) {
626-
AppendChar('\n');
627-
628-
for (auto i (m_CurrentSubtree.size() - 1u); i; --i) {
629-
AppendChars((const char*)l_Indent, (const char*)l_Indent + 4);
630-
}
631-
}
632-
633-
AppendChar(terminator);
634-
635-
m_CurrentSubtree.pop();
636-
}

0 commit comments

Comments
 (0)