Skip to content

Commit 2b9abc3

Browse files
committed
Merge pull request open-source-parsers#195 from cdunn2001/len-in-czstring
Store length in CZString
2 parents 5d79275 + e6b46e4 commit 2b9abc3

2 files changed

Lines changed: 45 additions & 21 deletions

File tree

include/json/value.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class JSON_API Value {
164164
duplicateOnCopy
165165
};
166166
CZString(ArrayIndex index);
167-
CZString(const char* cstr, DuplicationPolicy allocate);
167+
CZString(char const* cstr, unsigned length, DuplicationPolicy allocate);
168168
CZString(const CZString& other);
169169
~CZString();
170170
CZString& operator=(CZString other);
@@ -176,8 +176,16 @@ class JSON_API Value {
176176

177177
private:
178178
void swap(CZString& other);
179+
struct StringStorage {
180+
DuplicationPolicy policy_: 2;
181+
unsigned length_: 30; // 1GB max
182+
};
183+
179184
const char* cstr_;
180-
ArrayIndex index_;
185+
union {
186+
ArrayIndex index_;
187+
StringStorage storage_;
188+
};
181189
};
182190

183191
public:

src/lib_json/json_value.cpp

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

162164
Value::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

168171
Value::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

177181
Value::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

192196
bool 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

198209
bool 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

204220
ArrayIndex Value::CZString::index() const { return index_; }
205221

206222
const 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

Comments
 (0)