Skip to content

Commit

Permalink
fix StaticString test
Browse files Browse the repository at this point in the history
* support zeroes in string_
* support zeroes in writer; provide getString(char**, unsigned*)
* valueToQuotedStringN(), isCC0(), etc
* allow zeroes for cpptl ConstString
* allocated => non-static
  • Loading branch information
cdunn2001 committed Mar 3, 2015
1 parent a532835 commit c28610f
Show file tree
Hide file tree
Showing 4 changed files with 304 additions and 81 deletions.
68 changes: 45 additions & 23 deletions include/json/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,21 @@ class JSON_API StaticString {
* The type of the held value is represented by a #ValueType and
* can be obtained using type().
*
* values of an #objectValue or #arrayValue can be accessed using operator[]()
*methods.
* Non const methods will automatically create the a #nullValue element
* Values of an #objectValue or #arrayValue can be accessed using operator[]()
* methods.
* Non-const methods will automatically create the a #nullValue element
* if it does not exist.
* The sequence of an #arrayValue will be automatically resize and initialized
* The sequence of an #arrayValue will be automatically resized and initialized
* with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
*
* The get() methods can be used to obtanis default value in the case the
*required element
* does not exist.
* The get() methods can be used to obtain default value in the case the
* required element does not exist.
*
* It is possible to iterate over the list of a #objectValue values using
* the getMemberNames() method.
*
* \note Value string-length fit in size_t, but keys must fit in unsigned.
* (The reason is an implementation detail.) The readers will raise an
* \note #Value string-length fit in size_t, but keys must be < 2^30.
* (The reason is an implementation detail.) A #CharReader will raise an
* exception if a bound is exceeded to avoid security holes in your app,
* but the Value API does *not* check bounds. That is the responsibility
* of the caller.
Expand Down Expand Up @@ -170,24 +169,27 @@ class JSON_API Value {
duplicateOnCopy
};
CZString(ArrayIndex index);
CZString(char const* cstr, unsigned length, DuplicationPolicy allocate);
CZString(const CZString& other);
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other);
~CZString();
CZString& operator=(CZString other);
bool operator<(const CZString& other) const;
bool operator==(const CZString& other) const;
bool operator<(CZString const& other) const;
bool operator==(CZString const& other) const;
ArrayIndex index() const;
const char* c_str() const;
//const char* c_str() const; ///< \deprecated
char const* data() const;
unsigned length() const;
bool isStaticString() const;

private:
void swap(CZString& other);

struct StringStorage {
DuplicationPolicy policy_: 2;
unsigned length_: 30; // 1GB max
};

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

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

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

Value& resolveReference(const char* key, bool isStatic);
Value& resolveReference(const char* key);
Value& resolveReference(const char* key, const char* end);

struct CommentInfo {
CommentInfo();
Expand All @@ -518,11 +534,12 @@ Json::Value obj_value(Json::objectValue); // {}
LargestUInt uint_;
double real_;
bool bool_;
char* string_; // actually ptr to unsigned, followed by str
char* string_; // actually ptr to unsigned, followed by str, unless !allocated_
ObjectValues* map_;
} value_;
ValueType type_ : 8;
unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
// If not allocated_, string_ must be null-terminated.
CommentInfo* comments_;

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

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

protected:
Value& deref() const;
Expand Down Expand Up @@ -653,8 +675,8 @@ class JSON_API ValueConstIterator : public ValueIteratorBase {

public:
typedef const Value value_type;
typedef unsigned int size_t;
typedef int difference_type;
//typedef unsigned int size_t;
//typedef int difference_type;
typedef const Value& reference;
typedef const Value* pointer;
typedef ValueConstIterator SelfType;
Expand Down
Loading

0 comments on commit c28610f

Please sign in to comment.