Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-20 22:39:47

0001 #include <iostream>
0002 #include "EventFilter/Utilities/interface/value.h"
0003 #include "EventFilter/Utilities/interface/writer.h"
0004 #include <utility>
0005 #include <stdexcept>
0006 #include <cstring>
0007 #include <cassert>
0008 #ifdef JSON_USE_CPPTL
0009 #include <cpptl/conststring.h>
0010 #endif
0011 #include <cstddef>  // size_t
0012 #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
0013 #include "EventFilter/Utilities/interface/json_batchallocator.h"
0014 #endif  // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
0015 
0016 #define JSON_ASSERT_UNREACHABLE assert(false)
0017 #define JSON_ASSERT(condition) assert(condition);  //  <= change this into an exception throw
0018 #define JSON_ASSERT_MESSAGE(condition, message) \
0019   if (!(condition))                             \
0020     throw std::runtime_error(message);
0021 
0022 namespace jsoncollector {
0023   namespace Json {
0024 
0025     const Value Value::null;
0026     const Int Value::minInt = Int(~(UInt(-1) / 2));
0027     const Int Value::maxInt = Int(UInt(-1) / 2);
0028     const UInt Value::maxUInt = UInt(-1);
0029 
0030     // A "safe" implementation of strdup. Allow null pointer to be passed.
0031     // Also avoid warning on msvc80.
0032     //
0033     //inline char *safeStringDup( const char *czstring )
0034     //{
0035     //   if ( czstring )
0036     //   {
0037     //      const size_t length = (unsigned int)( strlen(czstring) + 1 );
0038     //      char *newString = static_cast<char *>( malloc( length ) );
0039     //      memcpy( newString, czstring, length );
0040     //      return newString;
0041     //   }
0042     //   return 0;
0043     //}
0044     //
0045     //inline char *safeStringDup( const std::string &str )
0046     //{
0047     //   if ( !str.empty() )
0048     //   {
0049     //      const size_t length = str.length();
0050     //      char *newString = static_cast<char *>( malloc( length + 1 ) );
0051     //      memcpy( newString, str.c_str(), length );
0052     //      newString[length] = 0;
0053     //      return newString;
0054     //   }
0055     //   return 0;
0056     //}
0057 
0058     ValueAllocator::~ValueAllocator() {}
0059 
0060     class DefaultValueAllocator : public ValueAllocator {
0061     public:
0062       DefaultValueAllocator() {}
0063 
0064       ~DefaultValueAllocator() override {}
0065 
0066       char *makeMemberName(const char *memberName) const override { return duplicateStringValue(memberName); }
0067 
0068       void releaseMemberName(char *memberName) const override { releaseStringValue(memberName); }
0069 
0070       char *duplicateStringValue(const char *value, unsigned int length = unknown) const override {
0071         // invesgate this old optimization
0072         //if ( !value  ||  value[0] == 0 )
0073         //   return 0;
0074 
0075         if (length == unknown)
0076           length = (unsigned int)strlen(value);
0077         char *newString = static_cast<char *>(malloc(length + 1));
0078         memcpy(newString, value, length);
0079         newString[length] = 0;
0080         return newString;
0081       }
0082 
0083       void releaseStringValue(char *value) const override {
0084         if (value)
0085           free(value);
0086       }
0087     };
0088 
0089     static ValueAllocator const *valueAllocator() {
0090       static const DefaultValueAllocator defaultAllocator;
0091       static ValueAllocator const *valueAllocator = &defaultAllocator;
0092       return valueAllocator;
0093     }
0094 
0095     static struct DummyValueAllocatorInitializer {
0096       DummyValueAllocatorInitializer() {
0097         valueAllocator();  // ensure valueAllocator() statics are initialized before main().
0098       }
0099     } dummyValueAllocatorInitializer;
0100 
0101     // //////////////////////////////////////////////////////////////////
0102     // //////////////////////////////////////////////////////////////////
0103     // //////////////////////////////////////////////////////////////////
0104     // ValueInternals...
0105     // //////////////////////////////////////////////////////////////////
0106     // //////////////////////////////////////////////////////////////////
0107     // //////////////////////////////////////////////////////////////////
0108 
0109 #include "json_valueiterator.icc"
0110 
0111     // //////////////////////////////////////////////////////////////////
0112     // //////////////////////////////////////////////////////////////////
0113     // //////////////////////////////////////////////////////////////////
0114     // class Value::CommentInfo
0115     // //////////////////////////////////////////////////////////////////
0116     // //////////////////////////////////////////////////////////////////
0117     // //////////////////////////////////////////////////////////////////
0118 
0119     Value::CommentInfo::CommentInfo() : comment_(nullptr) {}
0120 
0121     Value::CommentInfo::~CommentInfo() {
0122       if (comment_)
0123         valueAllocator()->releaseStringValue(comment_);
0124     }
0125 
0126     void Value::CommentInfo::setComment(const char *text) {
0127       if (comment_)
0128         valueAllocator()->releaseStringValue(comment_);
0129       JSON_ASSERT(text);
0130       JSON_ASSERT_MESSAGE(text[0] == '\0' || text[0] == '/', "Comments must start with /");
0131       // It seems that /**/ style comments are acceptable as well.
0132       comment_ = valueAllocator()->duplicateStringValue(text);
0133     }
0134 
0135 // //////////////////////////////////////////////////////////////////
0136 // //////////////////////////////////////////////////////////////////
0137 // //////////////////////////////////////////////////////////////////
0138 // class Value::CZString
0139 // //////////////////////////////////////////////////////////////////
0140 // //////////////////////////////////////////////////////////////////
0141 // //////////////////////////////////////////////////////////////////
0142 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0143 
0144     // Notes: index_ indicates if the string was allocated when
0145     // a string is stored.
0146 
0147     Value::CZString::CZString(int index) : cstr_(nullptr), index_(index) {}
0148 
0149     Value::CZString::CZString(const char *cstr, DuplicationPolicy allocate)
0150         : cstr_(allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr), index_(allocate) {}
0151 
0152     Value::CZString::CZString(const CZString &other)
0153         : cstr_(other.index_ != noDuplication && other.cstr_ != nullptr ? valueAllocator()->makeMemberName(other.cstr_)
0154                                                                         : other.cstr_),
0155           index_(other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) : other.index_) {}
0156 
0157     Value::CZString::~CZString() {
0158       if (cstr_ && index_ == duplicate)
0159         valueAllocator()->releaseMemberName(const_cast<char *>(cstr_));
0160     }
0161 
0162     void Value::CZString::swap(CZString &other) {
0163       std::swap(cstr_, other.cstr_);
0164       std::swap(index_, other.index_);
0165     }
0166 
0167     Value::CZString &Value::CZString::operator=(const CZString &other) {
0168       CZString temp(other);
0169       swap(temp);
0170       return *this;
0171     }
0172 
0173     bool Value::CZString::operator<(const CZString &other) const {
0174       if (cstr_ and other.cstr_)
0175         return strcmp(cstr_, other.cstr_) < 0;
0176       return index_ < other.index_;
0177     }
0178 
0179     bool Value::CZString::operator==(const CZString &other) const {
0180       if (cstr_ and other.cstr_)
0181         return strcmp(cstr_, other.cstr_) == 0;
0182       return index_ == other.index_;
0183     }
0184 
0185     int Value::CZString::index() const { return index_; }
0186 
0187     const char *Value::CZString::c_str() const { return cstr_; }
0188 
0189     bool Value::CZString::isStaticString() const { return index_ == noDuplication; }
0190 
0191 #endif  // ifndef JSON_VALUE_USE_INTERNAL_MAP
0192 
0193     // //////////////////////////////////////////////////////////////////
0194     // //////////////////////////////////////////////////////////////////
0195     // //////////////////////////////////////////////////////////////////
0196     // class Value::Value
0197     // //////////////////////////////////////////////////////////////////
0198     // //////////////////////////////////////////////////////////////////
0199     // //////////////////////////////////////////////////////////////////
0200 
0201     /*! \internal Default constructor initialization must be equivalent to:
0202  * memset( this, 0, sizeof(Value) )
0203  * This optimization is used in ValueInternalMap fast allocator.
0204  */
0205     Value::Value(ValueType type)
0206         : type_(type),
0207           allocated_(0),
0208           comments_(nullptr)
0209 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0210           ,
0211           itemIsUsed_(0)
0212 #endif
0213     {
0214       switch (type) {
0215         case nullValue:
0216           break;
0217         case intValue:
0218         case uintValue:
0219           value_.int_ = 0;
0220           break;
0221         case realValue:
0222           value_.real_ = 0.0;
0223           break;
0224         case stringValue:
0225           value_.string_ = nullptr;
0226           break;
0227 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0228         case arrayValue:
0229         case objectValue:
0230           value_.map_ = new ObjectValues();
0231           break;
0232 #else
0233         case arrayValue:
0234           value_.array_ = arrayAllocator()->newArray();
0235           break;
0236         case objectValue:
0237           value_.map_ = mapAllocator()->newMap();
0238           break;
0239 #endif
0240         case booleanValue:
0241           value_.bool_ = false;
0242           break;
0243         default:
0244           JSON_ASSERT_UNREACHABLE;
0245       }
0246     }
0247 
0248     Value::Value(Int value)
0249         : type_(intValue),
0250           comments_(nullptr)
0251 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0252           ,
0253           itemIsUsed_(0)
0254 #endif
0255     {
0256       value_.int_ = value;
0257     }
0258 
0259     Value::Value(UInt value)
0260         : type_(uintValue),
0261           comments_(nullptr)
0262 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0263           ,
0264           itemIsUsed_(0)
0265 #endif
0266     {
0267       value_.uint_ = value;
0268     }
0269 
0270     Value::Value(double value)
0271         : type_(realValue),
0272           comments_(nullptr)
0273 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0274           ,
0275           itemIsUsed_(0)
0276 #endif
0277     {
0278       value_.real_ = value;
0279     }
0280 
0281     Value::Value(const char *value)
0282         : type_(stringValue),
0283           allocated_(true),
0284           comments_(nullptr)
0285 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0286           ,
0287           itemIsUsed_(0)
0288 #endif
0289     {
0290       value_.string_ = valueAllocator()->duplicateStringValue(value);
0291     }
0292 
0293     Value::Value(const char *beginValue, const char *endValue)
0294         : type_(stringValue),
0295           allocated_(true),
0296           comments_(nullptr)
0297 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0298           ,
0299           itemIsUsed_(0)
0300 #endif
0301     {
0302       value_.string_ = valueAllocator()->duplicateStringValue(beginValue, UInt(endValue - beginValue));
0303     }
0304 
0305     Value::Value(const std::string &value)
0306         : type_(stringValue),
0307           allocated_(true),
0308           comments_(nullptr)
0309 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0310           ,
0311           itemIsUsed_(0)
0312 #endif
0313     {
0314       value_.string_ = valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
0315     }
0316 
0317     Value::Value(const StaticString &value)
0318         : type_(stringValue),
0319           allocated_(false),
0320           comments_(nullptr)
0321 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0322           ,
0323           itemIsUsed_(0)
0324 #endif
0325     {
0326       value_.string_ = const_cast<char *>(value.c_str());
0327     }
0328 
0329 #ifdef JSON_USE_CPPTL
0330     Value::Value(const CppTL::ConstString &value)
0331         : type_(stringValue),
0332           allocated_(true),
0333           comments_(0)
0334 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0335           ,
0336           itemIsUsed_(0)
0337 #endif
0338     {
0339       value_.string_ = valueAllocator()->duplicateStringValue(value, value.length());
0340     }
0341 #endif
0342 
0343     Value::Value(bool value)
0344         : type_(booleanValue),
0345           comments_(nullptr)
0346 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0347           ,
0348           itemIsUsed_(0)
0349 #endif
0350     {
0351       value_.bool_ = value;
0352     }
0353 
0354     Value::Value(const Value &other)
0355         : type_(other.type_),
0356           comments_(nullptr)
0357 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0358           ,
0359           itemIsUsed_(0)
0360 #endif
0361     {
0362       switch (type_) {
0363         case nullValue:
0364         case intValue:
0365         case uintValue:
0366         case realValue:
0367         case booleanValue:
0368           value_ = other.value_;
0369           break;
0370         case stringValue:
0371           if (other.value_.string_) {
0372             value_.string_ = valueAllocator()->duplicateStringValue(other.value_.string_);
0373             allocated_ = true;
0374           } else
0375             value_.string_ = nullptr;
0376           break;
0377 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0378         case arrayValue:
0379         case objectValue:
0380           value_.map_ = new ObjectValues(*other.value_.map_);
0381           break;
0382 #else
0383         case arrayValue:
0384           value_.array_ = arrayAllocator()->newArrayCopy(*other.value_.array_);
0385           break;
0386         case objectValue:
0387           value_.map_ = mapAllocator()->newMapCopy(*other.value_.map_);
0388           break;
0389 #endif
0390         default:
0391           JSON_ASSERT_UNREACHABLE;
0392       }
0393       if (other.comments_) {
0394         comments_ = new CommentInfo[numberOfCommentPlacement];
0395         for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
0396           const CommentInfo &otherComment = other.comments_[comment];
0397           if (otherComment.comment_)
0398             comments_[comment].setComment(otherComment.comment_);
0399         }
0400       }
0401     }
0402 
0403     Value::~Value() {
0404       switch (type_) {
0405         case nullValue:
0406         case intValue:
0407         case uintValue:
0408         case realValue:
0409         case booleanValue:
0410           break;
0411         case stringValue:
0412           if (allocated_)
0413             valueAllocator()->releaseStringValue(value_.string_);
0414           break;
0415 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0416         case arrayValue:
0417         case objectValue:
0418           delete value_.map_;
0419           break;
0420 #else
0421         case arrayValue:
0422           arrayAllocator()->destructArray(value_.array_);
0423           break;
0424         case objectValue:
0425           mapAllocator()->destructMap(value_.map_);
0426           break;
0427 #endif
0428         default:
0429           JSON_ASSERT_UNREACHABLE;
0430       }
0431 
0432       if (comments_)
0433         delete[] comments_;
0434     }
0435 
0436     Value &Value::operator=(const Value &other) {
0437       Value temp(other);
0438       swap(temp);
0439       return *this;
0440     }
0441 
0442     void Value::swap(Value &other) {
0443       ValueType temp = type_;
0444       type_ = other.type_;
0445       other.type_ = temp;
0446       std::swap(value_, other.value_);
0447       int temp2 = allocated_;
0448       allocated_ = other.allocated_;
0449       other.allocated_ = temp2;
0450     }
0451 
0452     ValueType Value::type() const { return type_; }
0453 
0454     int Value::compare(const Value &other) {
0455       /*
0456    int typeDelta = other.type_ - type_;
0457    switch ( type_ )
0458    {
0459    case nullValue:
0460 
0461       return other.type_ == type_;
0462    case intValue:
0463       if ( other.type_.isNumeric()
0464    case uintValue:
0465    case realValue:
0466    case booleanValue:
0467       break;
0468    case stringValue,
0469       break;
0470    case arrayValue:
0471       delete value_.array_;
0472       break;
0473    case objectValue:
0474       delete value_.map_;
0475    default:
0476       JSON_ASSERT_UNREACHABLE;
0477    }
0478    */
0479       return 0;  // unreachable
0480     }
0481 
0482     bool Value::operator<(const Value &other) const {
0483       int typeDelta = type_ - other.type_;
0484       if (typeDelta)
0485         return typeDelta < 0 ? true : false;
0486       switch (type_) {
0487         case nullValue:
0488           return false;
0489         case intValue:
0490           return value_.int_ < other.value_.int_;
0491         case uintValue:
0492           return value_.uint_ < other.value_.uint_;
0493         case realValue:
0494           return value_.real_ < other.value_.real_;
0495         case booleanValue:
0496           return value_.bool_ < other.value_.bool_;
0497         case stringValue:
0498           return (value_.string_ == nullptr && other.value_.string_) ||
0499                  (other.value_.string_ && value_.string_ && strcmp(value_.string_, other.value_.string_) < 0);
0500 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0501         case arrayValue:
0502         case objectValue: {
0503           int delta = int(value_.map_->size() - other.value_.map_->size());
0504           if (delta)
0505             return delta < 0;
0506           return (*value_.map_) < (*other.value_.map_);
0507         }
0508 #else
0509         case arrayValue:
0510           return value_.array_->compare(*(other.value_.array_)) < 0;
0511         case objectValue:
0512           return value_.map_->compare(*(other.value_.map_)) < 0;
0513 #endif
0514         default:
0515           JSON_ASSERT_UNREACHABLE;
0516       }
0517       return false;  // unreachable
0518     }
0519 
0520     bool Value::operator<=(const Value &other) const { return !(other > *this); }
0521 
0522     bool Value::operator>=(const Value &other) const { return !(*this < other); }
0523 
0524     bool Value::operator>(const Value &other) const { return other < *this; }
0525 
0526     bool Value::operator==(const Value &other) const {
0527       //if ( type_ != other.type_ )
0528       // GCC 2.95.3 says:
0529       // attempt to take address of bit-field structure member `Json::Value::type_'
0530       // Beats me, but a temp solves the problem.
0531       int temp = other.type_;
0532       if (type_ != temp)
0533         return false;
0534       switch (type_) {
0535         case nullValue:
0536           return true;
0537         case intValue:
0538           return value_.int_ == other.value_.int_;
0539         case uintValue:
0540           return value_.uint_ == other.value_.uint_;
0541         case realValue:
0542           return value_.real_ == other.value_.real_;
0543         case booleanValue:
0544           return value_.bool_ == other.value_.bool_;
0545         case stringValue:
0546           return (value_.string_ == other.value_.string_) ||
0547                  (other.value_.string_ && value_.string_ && strcmp(value_.string_, other.value_.string_) == 0);
0548 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0549         case arrayValue:
0550         case objectValue:
0551           return value_.map_->size() == other.value_.map_->size() && (*value_.map_) == (*other.value_.map_);
0552 #else
0553         case arrayValue:
0554           return value_.array_->compare(*(other.value_.array_)) == 0;
0555         case objectValue:
0556           return value_.map_->compare(*(other.value_.map_)) == 0;
0557 #endif
0558         default:
0559           JSON_ASSERT_UNREACHABLE;
0560       }
0561       return false;  // unreachable
0562     }
0563 
0564     bool Value::operator!=(const Value &other) const { return !(*this == other); }
0565 
0566     const char *Value::asCString() const {
0567       JSON_ASSERT(type_ == stringValue);
0568       return value_.string_;
0569     }
0570 
0571     std::string Value::asString() const {
0572       switch (type_) {
0573         case nullValue:
0574           return "";
0575         case stringValue:
0576           return value_.string_ ? value_.string_ : "";
0577         case booleanValue:
0578           return value_.bool_ ? "true" : "false";
0579         case intValue:
0580         case uintValue:
0581         case realValue:
0582         case arrayValue:
0583         case objectValue:
0584           JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
0585         default:
0586           JSON_ASSERT_UNREACHABLE;
0587       }
0588       return "";  // unreachable
0589     }
0590 
0591 #ifdef JSON_USE_CPPTL
0592     CppTL::ConstString Value::asConstString() const { return CppTL::ConstString(asString().c_str()); }
0593 #endif
0594 
0595     Value::Int Value::asInt() const {
0596       switch (type_) {
0597         case nullValue:
0598           return 0;
0599         case intValue:
0600           return value_.int_;
0601         case uintValue:
0602           JSON_ASSERT_MESSAGE(value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
0603           return value_.uint_;
0604         case realValue:
0605           JSON_ASSERT_MESSAGE(value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
0606           return Int(value_.real_);
0607         case booleanValue:
0608           return value_.bool_ ? 1 : 0;
0609         case stringValue:
0610         case arrayValue:
0611         case objectValue:
0612           JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
0613         default:
0614           JSON_ASSERT_UNREACHABLE;
0615       }
0616       return 0;  // unreachable;
0617     }
0618 
0619     Value::UInt Value::asUInt() const {
0620       switch (type_) {
0621         case nullValue:
0622           return 0;
0623         case intValue:
0624           JSON_ASSERT_MESSAGE(value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
0625           return value_.int_;
0626         case uintValue:
0627           return value_.uint_;
0628         case realValue:
0629           JSON_ASSERT_MESSAGE(value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
0630           return UInt(value_.real_);
0631         case booleanValue:
0632           return value_.bool_ ? 1 : 0;
0633         case stringValue:
0634         case arrayValue:
0635         case objectValue:
0636           JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
0637         default:
0638           JSON_ASSERT_UNREACHABLE;
0639       }
0640       return 0;  // unreachable;
0641     }
0642 
0643     double Value::asDouble() const {
0644       switch (type_) {
0645         case nullValue:
0646           return 0.0;
0647         case intValue:
0648           return value_.int_;
0649         case uintValue:
0650           return value_.uint_;
0651         case realValue:
0652           return value_.real_;
0653         case booleanValue:
0654           return value_.bool_ ? 1.0 : 0.0;
0655         case stringValue:
0656         case arrayValue:
0657         case objectValue:
0658           JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
0659         default:
0660           JSON_ASSERT_UNREACHABLE;
0661       }
0662       return 0;  // unreachable;
0663     }
0664 
0665     bool Value::asBool() const {
0666       switch (type_) {
0667         case nullValue:
0668           return false;
0669         case intValue:
0670         case uintValue:
0671           return value_.int_ != 0;
0672         case realValue:
0673           return value_.real_ != 0.0;
0674         case booleanValue:
0675           return value_.bool_;
0676         case stringValue:
0677           return value_.string_ && value_.string_[0] != 0;
0678         case arrayValue:
0679         case objectValue:
0680           return !value_.map_->empty();
0681         default:
0682           JSON_ASSERT_UNREACHABLE;
0683       }
0684       return false;  // unreachable;
0685     }
0686 
0687     bool Value::isConvertibleTo(ValueType other) const {
0688       switch (type_) {
0689         case nullValue:
0690           return true;
0691         case intValue:
0692           return (other == nullValue && value_.int_ == 0) || other == intValue ||
0693                  (other == uintValue && value_.int_ >= 0) || other == realValue || other == stringValue ||
0694                  other == booleanValue;
0695         case uintValue:
0696           return (other == nullValue && value_.uint_ == 0) || (other == intValue && value_.uint_ <= (unsigned)maxInt) ||
0697                  other == uintValue || other == realValue || other == stringValue || other == booleanValue;
0698         case realValue:
0699           return (other == nullValue && value_.real_ == 0.0) ||
0700                  (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt) ||
0701                  (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt) || other == realValue ||
0702                  other == stringValue || other == booleanValue;
0703         case booleanValue:
0704           return (other == nullValue && value_.bool_ == false) || other == intValue || other == uintValue ||
0705                  other == realValue || other == stringValue || other == booleanValue;
0706         case stringValue:
0707           return other == stringValue || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
0708         case arrayValue:
0709           return other == arrayValue || (other == nullValue && value_.map_->empty());
0710         case objectValue:
0711           return other == objectValue || (other == nullValue && value_.map_->empty());
0712         default:
0713           JSON_ASSERT_UNREACHABLE;
0714       }
0715       return false;  // unreachable;
0716     }
0717 
0718     /// Number of values in array or object
0719     Value::UInt Value::size() const {
0720       switch (type_) {
0721         case nullValue:
0722         case intValue:
0723         case uintValue:
0724         case realValue:
0725         case booleanValue:
0726         case stringValue:
0727           return 0;
0728 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0729         case arrayValue:  // size of the array is highest index + 1
0730           if (!value_.map_->empty()) {
0731             ObjectValues::const_iterator itLast = value_.map_->end();
0732             --itLast;
0733             return (*itLast).first.index() + 1;
0734           }
0735           return 0;
0736         case objectValue:
0737           return Int(value_.map_->size());
0738 #else
0739         case arrayValue:
0740           return Int(value_.array_->size());
0741         case objectValue:
0742           return Int(value_.map_->size());
0743 #endif
0744         default:
0745           JSON_ASSERT_UNREACHABLE;
0746       }
0747       return 0;  // unreachable;
0748     }
0749 
0750     bool Value::empty() const {
0751       if (isNull() || isArray() || isObject())
0752         return size() == 0u;
0753       else
0754         return false;
0755     }
0756 
0757     bool Value::operator!() const { return isNull(); }
0758 
0759     void Value::clear() {
0760       JSON_ASSERT(type_ == nullValue || type_ == arrayValue || type_ == objectValue);
0761 
0762       switch (type_) {
0763 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0764         case arrayValue:
0765         case objectValue:
0766           value_.map_->clear();
0767           break;
0768 #else
0769         case arrayValue:
0770           value_.array_->clear();
0771           break;
0772         case objectValue:
0773           value_.map_->clear();
0774           break;
0775 #endif
0776         default:
0777           break;
0778       }
0779     }
0780 
0781     void Value::resize(UInt newSize) {
0782       JSON_ASSERT(type_ == nullValue || type_ == arrayValue);
0783       if (type_ == nullValue)
0784         *this = Value(arrayValue);
0785 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0786       UInt oldSize = size();
0787       if (newSize == 0)
0788         clear();
0789       else if (newSize > oldSize)
0790         (*this)[newSize - 1];
0791       else {
0792         for (UInt index = newSize; index < oldSize; ++index)
0793           value_.map_->erase(index);
0794         assert(size() == newSize);
0795       }
0796 #else
0797       value_.array_->resize(newSize);
0798 #endif
0799     }
0800 
0801     Value &Value::operator[](UInt index) {
0802       JSON_ASSERT(type_ == nullValue || type_ == arrayValue);
0803       if (type_ == nullValue)
0804         *this = Value(arrayValue);
0805 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0806       CZString key(index);
0807       ObjectValues::iterator it = value_.map_->lower_bound(key);
0808       if (it != value_.map_->end() && (*it).first == key)
0809         return (*it).second;
0810 
0811       ObjectValues::value_type defaultValue(key, null);
0812       it = value_.map_->insert(it, defaultValue);
0813       return (*it).second;
0814 #else
0815       return value_.array_->resolveReference(index);
0816 #endif
0817     }
0818 
0819     const Value &Value::operator[](UInt index) const {
0820       JSON_ASSERT(type_ == nullValue || type_ == arrayValue);
0821       if (type_ == nullValue)
0822         return null;
0823 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0824       CZString key(index);
0825       ObjectValues::const_iterator it = value_.map_->find(key);
0826       if (it == value_.map_->end())
0827         return null;
0828       return (*it).second;
0829 #else
0830       Value *value = value_.array_->find(index);
0831       return value ? *value : null;
0832 #endif
0833     }
0834 
0835     Value &Value::operator[](const char *key) { return resolveReference(key, false); }
0836 
0837     Value &Value::resolveReference(const char *key, bool isStatic) {
0838       JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0839       if (type_ == nullValue)
0840         *this = Value(objectValue);
0841 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0842       CZString actualKey(key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
0843       ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
0844       if (it != value_.map_->end() && (*it).first == actualKey)
0845         return (*it).second;
0846 
0847       ObjectValues::value_type defaultValue(actualKey, null);
0848       it = value_.map_->insert(it, defaultValue);
0849       Value &value = (*it).second;
0850       return value;
0851 #else
0852       return value_.map_->resolveReference(key, isStatic);
0853 #endif
0854     }
0855 
0856     Value Value::get(UInt index, const Value &defaultValue) const {
0857       const Value *value = &((*this)[index]);
0858       return value == &null ? defaultValue : *value;
0859     }
0860 
0861     bool Value::isValidIndex(UInt index) const { return index < size(); }
0862 
0863     const Value &Value::operator[](const char *key) const {
0864       JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0865       if (type_ == nullValue)
0866         return null;
0867 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0868       CZString actualKey(key, CZString::noDuplication);
0869       ObjectValues::const_iterator it = value_.map_->find(actualKey);
0870       if (it == value_.map_->end())
0871         return null;
0872       return (*it).second;
0873 #else
0874       const Value *value = value_.map_->find(key);
0875       return value ? *value : null;
0876 #endif
0877     }
0878 
0879     Value &Value::operator[](const std::string &key) { return (*this)[key.c_str()]; }
0880 
0881     const Value &Value::operator[](const std::string &key) const { return (*this)[key.c_str()]; }
0882 
0883     Value &Value::operator[](const StaticString &key) { return resolveReference(key, true); }
0884 
0885 #ifdef JSON_USE_CPPTL
0886     Value &Value::operator[](const CppTL::ConstString &key) { return (*this)[key.c_str()]; }
0887 
0888     const Value &Value::operator[](const CppTL::ConstString &key) const { return (*this)[key.c_str()]; }
0889 #endif
0890 
0891     Value &Value::append(const Value &value) { return (*this)[size()] = value; }
0892 
0893     Value Value::get(const char *key, const Value &defaultValue) const {
0894       const Value *value = &((*this)[key]);
0895       return value == &null ? defaultValue : *value;
0896     }
0897 
0898     Value Value::get(const std::string &key, const Value &defaultValue) const { return get(key.c_str(), defaultValue); }
0899 
0900     Value Value::removeMember(const char *key) {
0901       JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0902       if (type_ == nullValue)
0903         return null;
0904 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0905       CZString actualKey(key, CZString::noDuplication);
0906       ObjectValues::iterator it = value_.map_->find(actualKey);
0907       if (it == value_.map_->end())
0908         return null;
0909       Value old(it->second);
0910       value_.map_->erase(it);
0911       return old;
0912 #else
0913       Value *value = value_.map_->find(key);
0914       if (value) {
0915         Value old(*value);
0916         value_.map_.remove(key);
0917         return old;
0918       } else {
0919         return null;
0920       }
0921 #endif
0922     }
0923 
0924     Value Value::removeMember(const std::string &key) { return removeMember(key.c_str()); }
0925 
0926 #ifdef JSON_USE_CPPTL
0927     Value Value::get(const CppTL::ConstString &key, const Value &defaultValue) const {
0928       return get(key.c_str(), defaultValue);
0929     }
0930 #endif
0931 
0932     bool Value::isMember(const char *key) const {
0933       const Value *value = &((*this)[key]);
0934       return value != &null;
0935     }
0936 
0937     bool Value::isMember(const std::string &key) const { return isMember(key.c_str()); }
0938 
0939 #ifdef JSON_USE_CPPTL
0940     bool Value::isMember(const CppTL::ConstString &key) const { return isMember(key.c_str()); }
0941 #endif
0942 
0943     Value::Members Value::getMemberNames() const {
0944       JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0945       if (type_ == nullValue)
0946         return Value::Members();
0947       Members members;
0948       members.reserve(value_.map_->size());
0949 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0950       ObjectValues::const_iterator it = value_.map_->begin();
0951       ObjectValues::const_iterator itEnd = value_.map_->end();
0952       for (; it != itEnd; ++it)
0953         members.push_back(std::string((*it).first.c_str()));
0954 #else
0955       ValueInternalMap::IteratorState it;
0956       ValueInternalMap::IteratorState itEnd;
0957       value_.map_->makeBeginIterator(it);
0958       value_.map_->makeEndIterator(itEnd);
0959       for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it))
0960         members.push_back(std::string(ValueInternalMap::key(it)));
0961 #endif
0962       return members;
0963     }
0964     //
0965     //# ifdef JSON_USE_CPPTL
0966     //EnumMemberNames
0967     //Value::enumMemberNames() const
0968     //{
0969     //   if ( type_ == objectValue )
0970     //   {
0971     //      return CppTL::Enum::any(  CppTL::Enum::transform(
0972     //         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
0973     //         MemberNamesTransform() ) );
0974     //   }
0975     //   return EnumMemberNames();
0976     //}
0977     //
0978     //
0979     //EnumValues
0980     //Value::enumValues() const
0981     //{
0982     //   if ( type_ == objectValue  ||  type_ == arrayValue )
0983     //      return CppTL::Enum::anyValues( *(value_.map_),
0984     //                                     CppTL::Type<const Value &>() );
0985     //   return EnumValues();
0986     //}
0987     //
0988     //# endif
0989 
0990     bool Value::isNull() const { return type_ == nullValue; }
0991 
0992     bool Value::isBool() const { return type_ == booleanValue; }
0993 
0994     bool Value::isInt() const { return type_ == intValue; }
0995 
0996     bool Value::isUInt() const { return type_ == uintValue; }
0997 
0998     bool Value::isIntegral() const { return type_ == intValue || type_ == uintValue || type_ == booleanValue; }
0999 
1000     bool Value::isDouble() const { return type_ == realValue; }
1001 
1002     bool Value::isNumeric() const { return isIntegral() || isDouble(); }
1003 
1004     bool Value::isString() const { return type_ == stringValue; }
1005 
1006     bool Value::isArray() const { return type_ == nullValue || type_ == arrayValue; }
1007 
1008     bool Value::isObject() const { return type_ == nullValue || type_ == objectValue; }
1009 
1010     void Value::setComment(const char *comment, CommentPlacement placement) {
1011       if (!comments_)
1012         comments_ = new CommentInfo[numberOfCommentPlacement];
1013       comments_[placement].setComment(comment);
1014     }
1015 
1016     void Value::setComment(const std::string &comment, CommentPlacement placement) {
1017       setComment(comment.c_str(), placement);
1018     }
1019 
1020     bool Value::hasComment(CommentPlacement placement) const {
1021       return comments_ != nullptr && comments_[placement].comment_ != nullptr;
1022     }
1023 
1024     std::string Value::getComment(CommentPlacement placement) const {
1025       if (hasComment(placement))
1026         return comments_[placement].comment_;
1027       return "";
1028     }
1029 
1030     std::string Value::toStyledString() const {
1031       StyledWriter writer;
1032       return writer.write(*this);
1033     }
1034 
1035     Value::const_iterator Value::begin() const {
1036       switch (type_) {
1037 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1038         case arrayValue:
1039           if (value_.array_) {
1040             ValueInternalArray::IteratorState it;
1041             value_.array_->makeBeginIterator(it);
1042             return const_iterator(it);
1043           }
1044           break;
1045         case objectValue:
1046           if (value_.map_) {
1047             ValueInternalMap::IteratorState it;
1048             value_.map_->makeBeginIterator(it);
1049             return const_iterator(it);
1050           }
1051           break;
1052 #else
1053         case arrayValue:
1054         case objectValue:
1055           if (value_.map_)
1056             return const_iterator(value_.map_->begin());
1057           break;
1058 #endif
1059         default:
1060           break;
1061       }
1062       return const_iterator();
1063     }
1064 
1065     Value::const_iterator Value::end() const {
1066       switch (type_) {
1067 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1068         case arrayValue:
1069           if (value_.array_) {
1070             ValueInternalArray::IteratorState it;
1071             value_.array_->makeEndIterator(it);
1072             return const_iterator(it);
1073           }
1074           break;
1075         case objectValue:
1076           if (value_.map_) {
1077             ValueInternalMap::IteratorState it;
1078             value_.map_->makeEndIterator(it);
1079             return const_iterator(it);
1080           }
1081           break;
1082 #else
1083         case arrayValue:
1084         case objectValue:
1085           if (value_.map_)
1086             return const_iterator(value_.map_->end());
1087           break;
1088 #endif
1089         default:
1090           break;
1091       }
1092       return const_iterator();
1093     }
1094 
1095     Value::iterator Value::begin() {
1096       switch (type_) {
1097 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1098         case arrayValue:
1099           if (value_.array_) {
1100             ValueInternalArray::IteratorState it;
1101             value_.array_->makeBeginIterator(it);
1102             return iterator(it);
1103           }
1104           break;
1105         case objectValue:
1106           if (value_.map_) {
1107             ValueInternalMap::IteratorState it;
1108             value_.map_->makeBeginIterator(it);
1109             return iterator(it);
1110           }
1111           break;
1112 #else
1113         case arrayValue:
1114         case objectValue:
1115           if (value_.map_)
1116             return iterator(value_.map_->begin());
1117           break;
1118 #endif
1119         default:
1120           break;
1121       }
1122       return iterator();
1123     }
1124 
1125     Value::iterator Value::end() {
1126       switch (type_) {
1127 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1128         case arrayValue:
1129           if (value_.array_) {
1130             ValueInternalArray::IteratorState it;
1131             value_.array_->makeEndIterator(it);
1132             return iterator(it);
1133           }
1134           break;
1135         case objectValue:
1136           if (value_.map_) {
1137             ValueInternalMap::IteratorState it;
1138             value_.map_->makeEndIterator(it);
1139             return iterator(it);
1140           }
1141           break;
1142 #else
1143         case arrayValue:
1144         case objectValue:
1145           if (value_.map_)
1146             return iterator(value_.map_->end());
1147           break;
1148 #endif
1149         default:
1150           break;
1151       }
1152       return iterator();
1153     }
1154 
1155     // class PathArgument
1156     // //////////////////////////////////////////////////////////////////
1157 
1158     PathArgument::PathArgument() : kind_(kindNone) {}
1159 
1160     PathArgument::PathArgument(Value::UInt index) : index_(index), kind_(kindIndex) {}
1161 
1162     PathArgument::PathArgument(const char *key) : key_(key), kind_(kindKey) {}
1163 
1164     PathArgument::PathArgument(const std::string &key) : key_(key), kind_(kindKey) {}
1165 
1166     // class Path
1167     // //////////////////////////////////////////////////////////////////
1168 
1169     Path::Path(const std::string &path,
1170                const PathArgument &a1,
1171                const PathArgument &a2,
1172                const PathArgument &a3,
1173                const PathArgument &a4,
1174                const PathArgument &a5) {
1175       InArgs in;
1176       in.push_back(&a1);
1177       in.push_back(&a2);
1178       in.push_back(&a3);
1179       in.push_back(&a4);
1180       in.push_back(&a5);
1181       makePath(path, in);
1182     }
1183 
1184     void Path::makePath(const std::string &path, const InArgs &in) {
1185       const char *current = path.c_str();
1186       const char *end = current + path.length();
1187       InArgs::const_iterator itInArg = in.begin();
1188       while (current != end) {
1189         if (*current == '[') {
1190           ++current;
1191           if (*current == '%')
1192             addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1193           else {
1194             Value::UInt index = 0;
1195             for (; current != end && *current >= '0' && *current <= '9'; ++current)
1196               index = index * 10 + Value::UInt(*current - '0');
1197             args_.push_back(index);
1198           }
1199           if (current == end || *current++ != ']')
1200             invalidPath(path, int(current - path.c_str()));
1201         } else if (*current == '%') {
1202           addPathInArg(path, in, itInArg, PathArgument::kindKey);
1203           ++current;
1204         } else if (*current == '.') {
1205           ++current;
1206         } else {
1207           const char *beginName = current;
1208           while (current != end && !strchr("[.", *current))
1209             ++current;
1210           args_.push_back(std::string(beginName, current));
1211         }
1212       }
1213     }
1214 
1215     void Path::addPathInArg(const std::string &path,
1216                             const InArgs &in,
1217                             InArgs::const_iterator &itInArg,
1218                             PathArgument::Kind kind) {
1219       if (itInArg == in.end()) {
1220         // Error: missing argument %d
1221       } else if ((*itInArg)->kind_ != kind) {
1222         // Error: bad argument type
1223       } else {
1224         args_.push_back(**itInArg);
1225       }
1226     }
1227 
1228     void Path::invalidPath(const std::string &path, int location) {
1229       // Error: invalid path.
1230     }
1231 
1232     const Value &Path::resolve(const Value &root) const {
1233       const Value *node = &root;
1234       for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1235         const PathArgument &arg = *it;
1236         if (arg.kind_ == PathArgument::kindIndex) {
1237           if (!node->isArray() || node->isValidIndex(arg.index_)) {
1238             // Error: unable to resolve path (array value expected at position...
1239           }
1240           node = &((*node)[arg.index_]);
1241         } else if (arg.kind_ == PathArgument::kindKey) {
1242           if (!node->isObject()) {
1243             // Error: unable to resolve path (object value expected at position...)
1244           }
1245           node = &((*node)[arg.key_]);
1246           if (node == &Value::null) {
1247             // Error: unable to resolve path (object has no member named '' at position...)
1248           }
1249         }
1250       }
1251       return *node;
1252     }
1253 
1254     Value Path::resolve(const Value &root, const Value &defaultValue) const {
1255       const Value *node = &root;
1256       for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1257         const PathArgument &arg = *it;
1258         if (arg.kind_ == PathArgument::kindIndex) {
1259           if (!node->isArray() || node->isValidIndex(arg.index_))
1260             return defaultValue;
1261           node = &((*node)[arg.index_]);
1262         } else if (arg.kind_ == PathArgument::kindKey) {
1263           if (!node->isObject())
1264             return defaultValue;
1265           node = &((*node)[arg.key_]);
1266           if (node == &Value::null)
1267             return defaultValue;
1268         }
1269       }
1270       return *node;
1271     }
1272 
1273     Value &Path::make(Value &root) const {
1274       Value *node = &root;
1275       for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1276         const PathArgument &arg = *it;
1277         if (arg.kind_ == PathArgument::kindIndex) {
1278           if (!node->isArray()) {
1279             // Error: node is not an array at position ...
1280           }
1281           node = &((*node)[arg.index_]);
1282         } else if (arg.kind_ == PathArgument::kindKey) {
1283           if (!node->isObject()) {
1284             // Error: node is not an object at position...
1285           }
1286           node = &((*node)[arg.key_]);
1287         }
1288       }
1289       return *node;
1290     }
1291 
1292   }  // namespace Json
1293 }  //namespace jsoncollector