Skip to content

Commit c28610f

Browse files
committed
fix StaticString test
* support zeroes in string_ * support zeroes in writer; provide getString(char**, unsigned*) * valueToQuotedStringN(), isCC0(), etc * allow zeroes for cpptl ConstString * allocated => non-static
1 parent a532835 commit c28610f

4 files changed

Lines changed: 304 additions & 81 deletions

File tree

include/json/value.h

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,21 @@ class JSON_API StaticString {
9999
* The type of the held value is represented by a #ValueType and
100100
* can be obtained using type().
101101
*
102-
* values of an #objectValue or #arrayValue can be accessed using operator[]()
103-
*methods.
104-
* Non const methods will automatically create the a #nullValue element
102+
* Values of an #objectValue or #arrayValue can be accessed using operator[]()
103+
* methods.
104+
* Non-const methods will automatically create the a #nullValue element
105105
* if it does not exist.
106-
* The sequence of an #arrayValue will be automatically resize and initialized
106+
* The sequence of an #arrayValue will be automatically resized and initialized
107107
* with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
108108
*
109-
* The get() methods can be used to obtanis default value in the case the
110-
*required element
111-
* does not exist.
109+
* The get() methods can be used to obtain default value in the case the
110+
* required element does not exist.
112111
*
113112
* It is possible to iterate over the list of a #objectValue values using
114113
* the getMemberNames() method.
115114
*
116-
* \note Value string-length fit in size_t, but keys must fit in unsigned.
117-
* (The reason is an implementation detail.) The readers will raise an
115+
* \note #Value string-length fit in size_t, but keys must be < 2^30.
116+
* (The reason is an implementation detail.) A #CharReader will raise an
118117
* exception if a bound is exceeded to avoid security holes in your app,
119118
* but the Value API does *not* check bounds. That is the responsibility
120119
* of the caller.
@@ -170,24 +169,27 @@ class JSON_API Value {
170169
duplicateOnCopy
171170
};
172171
CZString(ArrayIndex index);
173-
CZString(char const* cstr, unsigned length, DuplicationPolicy allocate);
174-
CZString(const CZString& other);
172+
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
173+
CZString(CZString const& other);
175174
~CZString();
176175
CZString& operator=(CZString other);
177-
bool operator<(const CZString& other) const;
178-
bool operator==(const CZString& other) const;
176+
bool operator<(CZString const& other) const;
177+
bool operator==(CZString const& other) const;
179178
ArrayIndex index() const;
180-
const char* c_str() const;
179+
//const char* c_str() const; ///< \deprecated
180+
char const* data() const;
181+
unsigned length() const;
181182
bool isStaticString() const;
182183

183184
private:
184185
void swap(CZString& other);
186+
185187
struct StringStorage {
186188
DuplicationPolicy policy_: 2;
187189
unsigned length_: 30; // 1GB max
188190
};
189191

190-
const char* cstr_;
192+
char const* cstr_; // actually, a prefixed string, unless policy is noDup
191193
union {
192194
ArrayIndex index_;
193195
StringStorage storage_;
@@ -233,9 +235,14 @@ Json::Value obj_value(Json::objectValue); // {}
233235
* Like other value string constructor but do not duplicate the string for
234236
* internal storage. The given string must remain alive after the call to this
235237
* constructor.
238+
* \note This works only for null-terminated strings. (We cannot change the
239+
* size of this class, so we have nowhere to store the length,
240+
* which might be computed later for various operations.)
241+
*
236242
* Example of usage:
237243
* \code
238-
* Json::Value aValue( StaticString("some text") );
244+
* static StaticString foo("some text");
245+
* Json::Value aValue(foo);
239246
* \endcode
240247
*/
241248
Value(const StaticString& value);
@@ -268,6 +275,11 @@ Json::Value obj_value(Json::objectValue); // {}
268275

269276
const char* asCString() const; ///! Embedded zeroes could cause you trouble!
270277
std::string asString() const; ///! Embedded zeroes are possible.
278+
/** Get raw char* of string-value.
279+
* \return false if !string. (Seg-fault if str or end are NULL.)
280+
*/
281+
bool getString(
282+
char const** str, char const** end) const;
271283
#ifdef JSON_USE_CPPTL
272284
CppTL::ConstString asConstString() const;
273285
#endif
@@ -374,8 +386,6 @@ Json::Value obj_value(Json::objectValue); // {}
374386
/** \brief Access an object value by name, create a null member if it does not
375387
exist.
376388
377-
* \param key may contain embedded nulls.
378-
*
379389
* If the object has no entry for that name, then the member name used to store
380390
* the new entry is not duplicated.
381391
* Example of use:
@@ -409,6 +419,10 @@ Json::Value obj_value(Json::objectValue); // {}
409419
/// and operator[]const
410420
/// \note As stated elsewhere, behavior is undefined if (end-key) >= 2^30
411421
Value const* find(char const* key, char const* end) const;
422+
/// Most general and efficient version of object-mutators.
423+
/// \note As stated elsewhere, behavior is undefined if (end-key) >= 2^30
424+
/// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
425+
Value const* demand(char const* key, char const* end);
412426
/// \brief Remove and return the named member.
413427
///
414428
/// Do nothing if it did not exist.
@@ -442,6 +456,7 @@ Json::Value obj_value(Json::objectValue); // {}
442456
bool removeIndex(ArrayIndex i, Value* removed);
443457

444458
/// Return true if the object has a member named key.
459+
/// \note 'key' must be null-terminated.
445460
bool isMember(const char* key) const;
446461
/// Return true if the object has a member named key.
447462
/// \param key may contain embedded nulls.
@@ -493,7 +508,8 @@ Json::Value obj_value(Json::objectValue); // {}
493508
private:
494509
void initBasic(ValueType type, bool allocated = false);
495510

496-
Value& resolveReference(const char* key, bool isStatic);
511+
Value& resolveReference(const char* key);
512+
Value& resolveReference(const char* key, const char* end);
497513

498514
struct CommentInfo {
499515
CommentInfo();
@@ -518,11 +534,12 @@ Json::Value obj_value(Json::objectValue); // {}
518534
LargestUInt uint_;
519535
double real_;
520536
bool bool_;
521-
char* string_; // actually ptr to unsigned, followed by str
537+
char* string_; // actually ptr to unsigned, followed by str, unless !allocated_
522538
ObjectValues* map_;
523539
} value_;
524540
ValueType type_ : 8;
525541
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
542+
// If not allocated_, string_ must be null-terminated.
526543
CommentInfo* comments_;
527544

528545
// [start, limit) byte offsets in the source JSON text from which this Value
@@ -624,7 +641,12 @@ class JSON_API ValueIteratorBase {
624641

625642
/// Return the member name of the referenced Value. "" if it is not an
626643
/// objectValue.
627-
const char* memberName() const;
644+
/// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
645+
char const* memberName() const;
646+
/// Return the member name of the referenced Value, or NULL if it is not an
647+
/// objectValue.
648+
/// Better version than memberName(). Allows embedded nulls.
649+
char const* memberName(char const** end) const;
628650

629651
protected:
630652
Value& deref() const;
@@ -653,8 +675,8 @@ class JSON_API ValueConstIterator : public ValueIteratorBase {
653675

654676
public:
655677
typedef const Value value_type;
656-
typedef unsigned int size_t;
657-
typedef int difference_type;
678+
//typedef unsigned int size_t;
679+
//typedef int difference_type;
658680
typedef const Value& reference;
659681
typedef const Value* pointer;
660682
typedef ValueConstIterator SelfType;

0 commit comments

Comments
 (0)