Skip to content
This repository was archived by the owner on Jul 19, 2022. It is now read-only.
Open
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
100 changes: 75 additions & 25 deletions jsonxx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "jsonxx.h"

#include <algorithm>
#include <cctype>
#include <iostream>
#include <iomanip>
Expand Down Expand Up @@ -310,6 +311,8 @@ bool Object::parse(std::istream& input, Object& object) {
// TODO(hjiang): Add an option to allow duplicated keys?
if (object.value_map_.find(key) == object.value_map_.end()) {
object.value_map_[key] = v;
if (keys_are_ordered())
object.key_set_.push_back(key);
} else {
if (parser_is_permissive()) {
delete object.value_map_[key];
Expand Down Expand Up @@ -503,16 +506,30 @@ std::ostream& operator<<(std::ostream& stream, const jsonxx::Array& v) {

std::ostream& operator<<(std::ostream& stream, const jsonxx::Object& v) {
stream << "{";
jsonxx::Object::container::const_iterator
it = v.kv_map().begin(),
end = v.kv_map().end();
while (it != end) {
jsonxx::stream_string(stream, it->first);
stream << ": " << *(it->second);
++it;
if (it != end) {
stream << ", ";
}
if (jsonxx::keys_are_ordered()) {
const std::vector<std::string>& keys = v.keys();
std::string last = keys[keys.size()-1];
const std::map<std::string, jsonxx::Value*>& kv_map = v.kv_map();
for (std::string key : keys) {
printf(" %s\n", key.c_str());
jsonxx::stream_string(stream, key);
stream << ": " << *(kv_map.at(key));
if (key != last) {
stream << ", ";
}
}
} else {
jsonxx::Object::container::const_iterator
it = v.kv_map().begin(),
end = v.kv_map().end();
while (it != end) {
jsonxx::stream_string(stream, it->first);
stream << ": " << *(it->second);
++it;
if (it != end) {
stream << ", ";
}
}
}
return stream << "}";
}
Expand Down Expand Up @@ -603,9 +620,15 @@ namespace json {

case jsonxx::Value::OBJECT_:
ss << "{\n";
for(Object::container::const_iterator it=t.object_value_->kv_map().begin(),
end = t.object_value_->kv_map().end(); it != end ; ++it)
ss << tag( format, depth+1, it->first, *it->second );
if (keys_are_ordered()) {
const std::map<std::string, Value*>& kv_map = t.object_value_->kv_map();
for(std::string key : t.object_value_->keys())
ss << tag( format, depth+1, key, *kv_map.at(key) );
} else {
for(Object::container::const_iterator it=t.object_value_->kv_map().begin(),
end = t.object_value_->kv_map().end(); it != end ; ++it)
ss << tag( format, depth+1, it->first, *it->second );
}
return remove_last_comma( ss.str() ) + tab + "}" ",\n";

case jsonxx::Value::NUMBER_:
Expand Down Expand Up @@ -788,13 +811,20 @@ std::string tag( unsigned format, unsigned depth, const std::string &name, const
+ ss.str()
+ close_tag( format, 's', name ) + '\n';

case jsonxx::Value::OBJECT_:
for(Object::container::const_iterator it=t.object_value_->kv_map().begin(),
end = t.object_value_->kv_map().end(); it != end ; ++it)
ss << tag( format, depth+1, it->first, *it->second );
case jsonxx::Value::OBJECT_: {
if (keys_are_ordered()) {
const std::map<std::string, Value*>& kv_map = t.object_value_->kv_map();
for(std::string key : t.object_value_->keys())
ss << tag( format, depth+1, key, *kv_map.at(key) );
} else {
for(Object::container::const_iterator it=t.object_value_->kv_map().begin(),
end = t.object_value_->kv_map().end(); it != end ; ++it)
ss << tag( format, depth+1, it->first, *it->second );
}
return tab + open_tag( format, 'o', name, attr ) + '\n'
+ ss.str()
+ tab + close_tag( format, 'o', name ) + '\n';
}

case jsonxx::Value::NUMBER_:
// max precision
Expand Down Expand Up @@ -999,15 +1029,29 @@ void Object::import( const Object &other ) {
odd.clear();
if (this != &other) {
// default
container::const_iterator
it = other.value_map_.begin(),
end = other.value_map_.end();
for (/**/ ; it != end ; ++it) {
container::iterator found = value_map_.find(it->first);
if( found != value_map_.end() ) {
delete found->second;
if (keys_are_ordered()) {
const std::vector<std::string>& keys = other.keys();
const std::map<std::string, Value*>& kv_map = other.kv_map();
for (std::string key : keys) {
container::iterator found = value_map_.find(key);
if( found != value_map_.end() ) {
delete found->second;
} else if (keys_are_ordered()) {
key_set_.push_back(key);
}
value_map_[ key ] = new Value( *kv_map.at(key) );
}
} else {
container::const_iterator
it = other.value_map_.begin(),
end = other.value_map_.end();
for (/**/ ; it != end ; ++it) {
container::iterator found = value_map_.find(it->first);
if( found != value_map_.end() ) {
delete found->second;
}
value_map_[ it->first ] = new Value( *it->second );
}
value_map_[ it->first ] = new Value( *it->second );
}
} else {
// recursion is supported here
Expand All @@ -1019,6 +1063,8 @@ void Object::import( const std::string &key, const Value &value ) {
container::iterator found = value_map_.find(key);
if( found != value_map_.end() ) {
delete found->second;
} else if (keys_are_ordered()) {
key_set_.push_back(key);
}
value_map_[ key ] = new Value( value );
}
Expand Down Expand Up @@ -1050,6 +1096,9 @@ size_t Object::size() const {
bool Object::empty() const {
return value_map_.size() == 0;
}
const std::vector<std::string> &Object::keys() const {
return key_set_;
}
const std::map<std::string, Value*> &Object::kv_map() const {
return value_map_;
}
Expand All @@ -1062,6 +1111,7 @@ void Object::reset() {
delete i->second;
}
value_map_.clear();
key_set_.clear();
}
bool Object::parse(std::istream &input) {
return parse(input,*this);
Expand Down
6 changes: 5 additions & 1 deletion jsonxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ enum Settings {
// values
Parser = Permissive, // permissive or strict parsing
UnquotedKeys = Disabled, // support of unquoted keys
Assertions = Enabled // enabled or disabled assertions (these asserts work both in DEBUG and RELEASE builds)
Assertions = Enabled, // enabled or disabled assertions (these asserts work both in DEBUG and RELEASE builds)
OrderedKeys = Enabled
};

#ifdef _MSC_VER
Expand All @@ -72,6 +73,7 @@ enum Settings {
inline bool parser_is_strict() { return Parser == Strict; }
inline bool parser_is_permissive() { return Parser == Permissive; }
inline bool unquoted_keys_are_enabled() { return UnquotedKeys == Enabled; }
inline bool keys_are_ordered() { return OrderedKeys == Enabled; }
#ifdef _MSC_VER
#pragma warning(pop)
#endif
Expand Down Expand Up @@ -133,6 +135,7 @@ class Object {
size_t size() const;
bool empty() const;

const std::vector<std::string>& keys() const;
const std::map<std::string, Value*>& kv_map() const;
std::string json() const;
std::string xml( unsigned format = JSONx, const std::string &header = std::string(), const std::string &attrib = std::string() ) const;
Expand All @@ -159,6 +162,7 @@ class Object {
protected:
static bool parse(std::istream& input, Object& object);
container value_map_;
std::vector<std::string> key_set_;
std::string odd;
};

Expand Down