Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/SimpleJson/DefaultTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ template<typename _KeyWriter, typename _ValWriter>
using JsonWriterDictT =
JsonWriterDictImpl<_KeyWriter, _ValWriter, ToStringType, IMContainerType>;

template<typename _KeyWriter, typename _ValWriter>
using JsonWriterOrdDictT =
JsonWriterOrdDictImpl<_KeyWriter, _ValWriter, ToStringType>;

template<typename _KeyWriter, typename _ValWriter>
using JsonWriterStaticDictT =
JsonWriterStaticDictImpl<_KeyWriter, _ValWriter, ToStringType, IMContainerType>;
Expand Down
102 changes: 101 additions & 1 deletion include/SimpleJson/DictWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

#pragma once

#include <algorithm>
#include <functional>
#include <vector>

#include "Internal/SimpleObjects.hpp"

#include "Utils.hpp"
Expand Down Expand Up @@ -88,6 +92,89 @@ struct JsonWriterDictBase

}; // struct JsonWriterDictBase

template<
typename _KeyWriter,
typename _ObjWriter,
typename _ToStringType,
typename _DictTraits>
struct JsonWriterDynOrderedDictBase
{

template<typename _OutputIt>
inline static void Write(_OutputIt destIt,
const typename _DictTraits::DictBase& obj,
const WriterConfig& config,
const WriterStates& state)
{
using _KeyType = typename _DictTraits::key_type;
std::vector<std::reference_wrapper<const _KeyType> > keys;

// Get all keys and sort them
keys.reserve(obj.size());
for(auto it = obj.cbegin(); it != obj.cend(); ++it)
{
keys.emplace_back(_DictTraits::GetKey(*it));
}
std::sort(keys.begin(), keys.end(), std::less<_KeyType>());

// Write the dict by the sorted keys
*destIt++ = '{';

WriterStates stateNextLevel = state;
++(stateNextLevel.m_nestLevel);
size_t len = obj.size();

if (config.m_indent.size() > 0 && obj.size() > 0)
{
Internal::RepeatOutput(destIt, config.m_lineEnd, 1);
}

for(auto it = keys.cbegin(); it != keys.cend(); ++it, --len)
{
const auto& key = it->get();

if (config.m_indent.size() > 0)
{
Internal::RepeatOutput(destIt,
config.m_indent, stateNextLevel.m_nestLevel);
}

_KeyWriter::Write(destIt, key, config, stateNextLevel);

if (config.m_indent.size() > 0)
{
*destIt++ = ' ';
*destIt++ = ':';
*destIt++ = ' ';
}
else
{
*destIt++ = ':';
}

const auto& val = obj[key];
_ObjWriter::Write(destIt, val, config, stateNextLevel);

if (len != 1)
{
*destIt++ = ',';
}

if (config.m_indent.size() > 0)
{
Internal::RepeatOutput(destIt, config.m_lineEnd, 1);
}
}

if (config.m_indent.size() > 0 && obj.size() > 0)
{
Internal::RepeatOutput(destIt, config.m_indent, state.m_nestLevel);
}
*destIt++ = '}';
}

}; // struct JsonWriterDynOrderedDictBase

template<typename _ToStringType>
struct DynamicDictTraits
{
Expand Down Expand Up @@ -156,6 +243,19 @@ struct JsonWriterDictImpl :
{
}; // struct JsonWriterDictImpl

template<
typename _KeyWriter,
typename _ObjWriter,
typename _ToStringType>
struct JsonWriterOrdDictImpl :
public JsonWriterDynOrderedDictBase<
_KeyWriter,
_ObjWriter,
_ToStringType,
DynamicDictTraits<_ToStringType> >
{
}; // struct JsonWriterOrdDictImpl

template<
typename _KeyWriter,
typename _ObjWriter,
Expand All @@ -169,6 +269,6 @@ struct JsonWriterStaticDictImpl :
_ContainerType,
StaticDictTraits<_ToStringType> >
{
}; // struct JsonWriterDictImpl
}; // struct JsonWriterStaticDictImpl

} // namespace SimpleJson
2 changes: 1 addition & 1 deletion include/SimpleJson/Internal/NumberParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ namespace SIMPLEJSON_CUSTOMIZED_NAMESPACE
inline _LowType StdNumberDownCast(const _HighType& highVal)
{
if (std::numeric_limits<_LowType>::lowest() <= highVal &&
highVal <= std::numeric_limits<_LowType>::max())
highVal <= (std::numeric_limits<_LowType>::max)())
{
return static_cast<_LowType>(highVal);
}
Expand Down
11 changes: 10 additions & 1 deletion include/SimpleJson/ObjectWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ struct JsonWriterObjectImpl
using KeyWriter = _KeyWriter;
using DictWriter =
JsonWriterDictImpl<KeyWriter, Self, _ToStringType, _ContainerType>;
using OrdDictWriter =
JsonWriterOrdDictImpl<KeyWriter, Self, _ToStringType>;
using StaticDictWriter =
JsonWriterStaticDictImpl<KeyWriter, Self, _ToStringType, _ContainerType>;

Expand All @@ -113,7 +115,14 @@ struct JsonWriterObjectImpl
ListWriter::Write(destIt, obj.AsList(), config, state);
break;
case Internal::Obj::ObjCategory::Dict:
DictWriter::Write(destIt, obj.AsDict(), config, state);
if (config.m_orderDict)
{
OrdDictWriter::Write(destIt, obj.AsDict(), config, state);
}
else
{
DictWriter::Write(destIt, obj.AsDict(), config, state);
}
break;
case Internal::Obj::ObjCategory::StaticDict:
StaticDictWriter::Write(destIt, obj.AsStaticDict(), config, state);
Expand Down
14 changes: 14 additions & 0 deletions include/SimpleJson/SimpleJson.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.


#pragma once


#include "DefaultTypes.hpp"

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand All @@ -27,11 +31,21 @@ struct FindObjWriter<Internal::Obj::Object>
using type = JsonWriterObject;
}; // struct FindObjWriter

template<>
struct FindObjWriter<Internal::Obj::BaseObj> :
public FindObjWriter<Internal::Obj::Object>
{}; // struct FindObjWriter

template<>
struct FindObjWriter<Internal::Obj::HashableObject> :
public FindObjWriter<Internal::Obj::Object>
{}; // struct FindObjWriter

template<>
struct FindObjWriter<Internal::Obj::HashableBaseObj> :
public FindObjWriter<Internal::Obj::Object>
{}; // struct FindObjWriter

template<>
struct FindObjWriter<Internal::Obj::Null>
{
Expand Down
4 changes: 3 additions & 1 deletion include/SimpleJson/WriterConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ struct WriterConfig
{
WriterConfig() :
m_indent(""),
m_lineEnd("\n")
m_lineEnd("\n"),
m_orderDict(false)
{}

~WriterConfig() = default;

std::string m_indent;
std::string m_lineEnd;
bool m_orderDict;

}; // struct WriterConfig

Expand Down
3 changes: 3 additions & 0 deletions test/src/TestBoolParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
3 changes: 3 additions & 0 deletions test/src/TestDictParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
3 changes: 3 additions & 0 deletions test/src/TestGenericParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
3 changes: 3 additions & 0 deletions test/src/TestInputStateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/InputStateMachine.hpp>
#include <SimpleJson/Internal/SimpleObjects.hpp>

Expand Down
69 changes: 69 additions & 0 deletions test/src/TestJsonWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down Expand Up @@ -362,3 +365,69 @@ GTEST_TEST(TestJsonWriter, ObjectWriter)
EXPECT_EQ(res, "{\"string\":\"string\"}");
}
}

GTEST_TEST(TestJsonWriter, OrderedDictWriter)
{
using _Str = Internal::Obj::String;
using _Dict = Internal::Obj::Dict;

WriterConfig config;
config.m_orderDict = true;

{
std::string expOut =
"{\"0\":0,\"1\":1,\"2\":2,\"a\":\"a\",\"b\":\"b\",\"c\":\"c\"}";
_Dict dict;
dict[_Str("a")] = _Str("a");
dict[_Str("b")] = _Str("b");
dict[_Str("c")] = _Str("c");
dict[_Str("0")] = Internal::Obj::Int64(0);
dict[_Str("1")] = Internal::Obj::Int64(1);
dict[_Str("2")] = Internal::Obj::Int64(2);

const Internal::Obj::BaseObj& obj = dict;
std::string res = DumpStr(obj, config);
EXPECT_EQ(res, expOut);

res.clear();
JsonWriterOrdDictT<JsonWriterKey, JsonWriterObject>::Write(
std::back_inserter(res),
dict,
config, WriterStates()
);
EXPECT_EQ(res, expOut);
}

config.m_indent = "\t";

{
std::string expOut =
"{\n\
\"0\" : 0,\n\
\"1\" : 1,\n\
\"2\" : 2,\n\
\"a\" : \"a\",\n\
\"b\" : \"b\",\n\
\"c\" : \"c\"\n\
}";
_Dict dict;
dict[_Str("a")] = _Str("a");
dict[_Str("b")] = _Str("b");
dict[_Str("c")] = _Str("c");
dict[_Str("0")] = Internal::Obj::Int64(0);
dict[_Str("1")] = Internal::Obj::Int64(1);
dict[_Str("2")] = Internal::Obj::Int64(2);

const Internal::Obj::BaseObj& obj = dict;
std::string res = DumpStr(obj, config);
EXPECT_EQ(res, expOut);

res.clear();
JsonWriterOrdDictT<JsonWriterKey, JsonWriterObject>::Write(
std::back_inserter(res),
dict,
config, WriterStates()
);
EXPECT_EQ(res, expOut);
}
}
3 changes: 3 additions & 0 deletions test/src/TestListParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
3 changes: 3 additions & 0 deletions test/src/TestNullParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
3 changes: 3 additions & 0 deletions test/src/TestNumericParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
3 changes: 3 additions & 0 deletions test/src/TestSpecialParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
3 changes: 3 additions & 0 deletions test/src/TestStaticDict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <gtest/gtest.h>

#ifdef _MSC_VER
#include <windows.h>
#endif // _MSC_VER
#include <SimpleJson/SimpleJson.hpp>

#ifndef SIMPLEJSON_CUSTOMIZED_NAMESPACE
Expand Down
Loading