@@ -156,26 +156,30 @@ void Value::CommentInfo::setComment(const char* text, size_t len) {
156156// //////////////////////////////////////////////////////////////////
157157// //////////////////////////////////////////////////////////////////
158158
159- // Notes: index_ indicates if the string was allocated when
159+ // Notes: policy_ indicates if the string was allocated when
160160// a string is stored.
161+ //
162+ // TODO: Check for length > 1GB, in Reader.
161163
162164Value::CZString::CZString (ArrayIndex index) : cstr_(0 ), index_(index) {}
163165
164- Value::CZString::CZString (const char * cstr, DuplicationPolicy allocate)
165- : cstr_(allocate == duplicate ? duplicateStringValue(cstr) : cstr),
166- index_ (allocate) {}
166+ Value::CZString::CZString (char const * str, unsigned length, DuplicationPolicy allocate)
167+ : cstr_(allocate == duplicate ? duplicateStringValue(str) : str),
168+ storage_ ({allocate, length})
169+ {}
167170
168171Value::CZString::CZString (const CZString& other)
169- : cstr_(other.index_ != noDuplication && other.cstr_ != 0
172+ : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
170173 ? duplicateStringValue(other.cstr_)
171174 : other.cstr_),
172- index_ (other.cstr_
173- ? static_cast <ArrayIndex> (other.index_ == noDuplication
175+ storage_({ (other.cstr_
176+ ? (other.storage_ . policy_ == noDuplication
174177 ? noDuplication : duplicate)
175- : other.index_) {}
178+ : other.storage_ .policy_ ), other.storage_ .length_ })
179+ {}
176180
177181Value::CZString::~CZString () {
178- if (cstr_ && index_ == duplicate)
182+ if (cstr_ && storage_. policy_ == duplicate)
179183 releaseStringValue (const_cast <char *>(cstr_));
180184}
181185
@@ -190,22 +194,34 @@ Value::CZString& Value::CZString::operator=(CZString other) {
190194}
191195
192196bool Value::CZString::operator <(const CZString& other) const {
193- if (cstr_)
194- return strcmp (cstr_, other.cstr_ ) < 0 ;
195- return index_ < other.index_ ;
197+ if (!cstr_) return index_ < other.index_ ;
198+ // return strcmp(cstr_, other.cstr_) < 0;
199+ // Assume both are strings.
200+ unsigned this_len = this ->storage_ .length_ ;
201+ unsigned other_len = other.storage_ .length_ ;
202+ unsigned min_len = std::min (this_len, other_len);
203+ int comp = memcmp (this ->cstr_ , other.cstr_ , min_len);
204+ if (comp < 0 ) return true ;
205+ if (comp > 0 ) return false ;
206+ return (this_len < other_len);
196207}
197208
198209bool Value::CZString::operator ==(const CZString& other) const {
199- if (cstr_)
200- return strcmp (cstr_, other.cstr_ ) == 0 ;
201- return index_ == other.index_ ;
210+ if (!cstr_) return index_ == other.index_ ;
211+ // return strcmp(cstr_, other.cstr_) == 0;
212+ // Assume both are strings.
213+ unsigned this_len = this ->storage_ .length_ ;
214+ unsigned other_len = other.storage_ .length_ ;
215+ if (this_len != other_len) return false ;
216+ int comp = memcmp (this ->cstr_ , other.cstr_ , this_len);
217+ return comp == 0 ;
202218}
203219
204220ArrayIndex Value::CZString::index () const { return index_; }
205221
206222const char * Value::CZString::c_str () const { return cstr_; }
207223
208- bool Value::CZString::isStaticString () const { return index_ == noDuplication; }
224+ bool Value::CZString::isStaticString () const { return storage_. policy_ == noDuplication; }
209225
210226// //////////////////////////////////////////////////////////////////
211227// //////////////////////////////////////////////////////////////////
@@ -833,7 +849,7 @@ Value& Value::resolveReference(const char* key, bool isStatic) {
833849 if (type_ == nullValue)
834850 *this = Value (objectValue);
835851 CZString actualKey (
836- key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
852+ key, strlen (key), isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
837853 ObjectValues::iterator it = value_.map_ ->lower_bound (actualKey);
838854 if (it != value_.map_ ->end () && (*it).first == actualKey)
839855 return (*it).second ;
@@ -857,7 +873,7 @@ const Value& Value::operator[](const char* key) const {
857873 " in Json::Value::operator[](char const*)const: requires objectValue" );
858874 if (type_ == nullValue)
859875 return null;
860- CZString actualKey (key, CZString::noDuplication);
876+ CZString actualKey (key, strlen (key), CZString::noDuplication);
861877 ObjectValues::const_iterator it = value_.map_ ->find (actualKey);
862878 if (it == value_.map_ ->end ())
863879 return null;
@@ -902,7 +918,7 @@ bool Value::removeMember(const char* key, Value* removed) {
902918 if (type_ != objectValue) {
903919 return false ;
904920 }
905- CZString actualKey (key, CZString::noDuplication);
921+ CZString actualKey (key, strlen (key), CZString::noDuplication);
906922 ObjectValues::iterator it = value_.map_ ->find (actualKey);
907923 if (it == value_.map_ ->end ())
908924 return false ;
0 commit comments