Merge branch 'master' into findType

This commit is contained in:
Jordan Bayles 2025-01-10 15:26:30 -08:00 committed by GitHub
commit 1342e8a6fb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 125 additions and 7 deletions

View File

@ -39,6 +39,10 @@
#endif #endif
#endif #endif
#if __cplusplus >= 201703L
#define JSONCPP_HAS_STRING_VIEW 1
#endif
#include <array> #include <array>
#include <exception> #include <exception>
#include <map> #include <map>
@ -46,6 +50,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#ifdef JSONCPP_HAS_STRING_VIEW
#include <string_view>
#endif
// Disable warning C4251: <data member>: <type> needs to have dll-interface to // Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by... // be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
@ -342,6 +350,9 @@ public:
*/ */
Value(const StaticString& value); Value(const StaticString& value);
Value(const String& value); Value(const String& value);
#ifdef JSONCPP_HAS_STRING_VIEW
Value(std::string_view value);
#endif
Value(bool value); Value(bool value);
Value(std::nullptr_t ptr) = delete; Value(std::nullptr_t ptr) = delete;
Value(const Value& other); Value(const Value& other);
@ -384,6 +395,12 @@ public:
* \return false if !string. (Seg-fault if str or end are NULL.) * \return false if !string. (Seg-fault if str or end are NULL.)
*/ */
bool getString(char const** begin, char const** end) const; bool getString(char const** begin, char const** end) const;
#ifdef JSONCPP_HAS_STRING_VIEW
/** Get string_view of string-value.
* \return false if !string. (Seg-fault if str is NULL.)
*/
bool getString(std::string_view* str) const;
#endif
Int asInt() const; Int asInt() const;
UInt asUInt() const; UInt asUInt() const;
#if defined(JSON_HAS_INT64) #if defined(JSON_HAS_INT64)
@ -470,6 +487,15 @@ public:
bool insert(ArrayIndex index, const Value& newValue); bool insert(ArrayIndex index, const Value& newValue);
bool insert(ArrayIndex index, Value&& newValue); bool insert(ArrayIndex index, Value&& newValue);
#ifdef JSONCPP_HAS_STRING_VIEW
/// Access an object value by name, create a null member if it does not exist.
/// \param key may contain embedded nulls.
Value& operator[](std::string_view key);
/// Access an object value by name, returns null if there is no member with
/// that name.
/// \param key may contain embedded nulls.
const Value& operator[](std::string_view key) const;
#else
/// Access an object value by name, create a null member if it does not exist. /// Access an object value by name, create a null member if it does not exist.
/// \note Because of our implementation, keys are limited to 2^30 -1 chars. /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
/// Exceeding that will cause an exception. /// Exceeding that will cause an exception.
@ -484,6 +510,7 @@ public:
/// that name. /// that name.
/// \param key may contain embedded nulls. /// \param key may contain embedded nulls.
const Value& operator[](const String& key) const; const Value& operator[](const String& key) const;
#endif
/** \brief Access an object value by name, create a null member if it does not /** \brief Access an object value by name, create a null member if it does not
* exist. * exist.
* *
@ -497,18 +524,24 @@ public:
* \endcode * \endcode
*/ */
Value& operator[](const StaticString& key); Value& operator[](const StaticString& key);
#ifdef JSONCPP_HAS_STRING_VIEW
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
Value get(std::string_view key, const Value& defaultValue) const;
#else
/// Return the member named key if it exist, defaultValue otherwise. /// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy /// \note deep copy
Value get(const char* key, const Value& defaultValue) const; Value get(const char* key, const Value& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
/// \param key may contain embedded nulls.
Value get(const String& key, const Value& defaultValue) const;
#endif
/// Return the member named key if it exist, defaultValue otherwise. /// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy /// \note deep copy
/// \note key may contain embedded nulls. /// \note key may contain embedded nulls.
Value get(const char* begin, const char* end, Value get(const char* begin, const char* end,
const Value& defaultValue) const; const Value& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
/// \param key may contain embedded nulls.
Value get(const String& key, const Value& defaultValue) const;
/// Most general and efficient version of isMember()const, get()const, /// Most general and efficient version of isMember()const, get()const,
/// and operator[]const /// and operator[]const
/// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
@ -548,20 +581,28 @@ public:
/// Do nothing if it did not exist. /// Do nothing if it did not exist.
/// \pre type() is objectValue or nullValue /// \pre type() is objectValue or nullValue
/// \post type() is unchanged /// \post type() is unchanged
#if JSONCPP_HAS_STRING_VIEW
void removeMember(std::string_view key);
#else
void removeMember(const char* key); void removeMember(const char* key);
/// Same as removeMember(const char*) /// Same as removeMember(const char*)
/// \param key may contain embedded nulls. /// \param key may contain embedded nulls.
void removeMember(const String& key); void removeMember(const String& key);
/// Same as removeMember(const char* begin, const char* end, Value* removed), #endif
/// but 'key' is null-terminated.
bool removeMember(const char* key, Value* removed);
/** \brief Remove the named map member. /** \brief Remove the named map member.
* *
* Update 'removed' iff removed. * Update 'removed' iff removed.
* \param key may contain embedded nulls. * \param key may contain embedded nulls.
* \return true iff removed (no exceptions) * \return true iff removed (no exceptions)
*/ */
#if JSONCPP_HAS_STRING_VIEW
bool removeMember(std::string_view key, Value* removed);
#else
bool removeMember(String const& key, Value* removed); bool removeMember(String const& key, Value* removed);
/// Same as removeMember(const char* begin, const char* end, Value* removed),
/// but 'key' is null-terminated.
bool removeMember(const char* key, Value* removed);
#endif
/// Same as removeMember(String const& key, Value* removed) /// Same as removeMember(String const& key, Value* removed)
bool removeMember(const char* begin, const char* end, Value* removed); bool removeMember(const char* begin, const char* end, Value* removed);
/** \brief Remove the indexed array element. /** \brief Remove the indexed array element.
@ -572,12 +613,18 @@ public:
*/ */
bool removeIndex(ArrayIndex index, Value* removed); bool removeIndex(ArrayIndex index, Value* removed);
#ifdef JSONCPP_HAS_STRING_VIEW
/// Return true if the object has a member named key.
/// \param key may contain embedded nulls.
bool isMember(std::string_view key) const;
#else
/// Return true if the object has a member named key. /// Return true if the object has a member named key.
/// \note 'key' must be null-terminated. /// \note 'key' must be null-terminated.
bool isMember(const char* key) const; bool isMember(const char* key) const;
/// Return true if the object has a member named key. /// Return true if the object has a member named key.
/// \param key may contain embedded nulls. /// \param key may contain embedded nulls.
bool isMember(const String& key) const; bool isMember(const String& key) const;
#endif
/// Same as isMember(String const& key)const /// Same as isMember(String const& key)const
bool isMember(const char* begin, const char* end) const; bool isMember(const char* begin, const char* end) const;

View File

@ -17,6 +17,10 @@
#include <sstream> #include <sstream>
#include <utility> #include <utility>
#ifdef JSONCPP_HAS_STRING_VIEW
#include <string_view>
#endif
// Provide implementation equivalent of std::snprintf for older _MSC compilers // Provide implementation equivalent of std::snprintf for older _MSC compilers
#if defined(_MSC_VER) && _MSC_VER < 1900 #if defined(_MSC_VER) && _MSC_VER < 1900
#include <stdarg.h> #include <stdarg.h>
@ -420,6 +424,14 @@ Value::Value(const String& value) {
value.data(), static_cast<unsigned>(value.length())); value.data(), static_cast<unsigned>(value.length()));
} }
#ifdef JSONCPP_HAS_STRING_VIEW
Value::Value(std::string_view value) {
initBasic(stringValue, true);
value_.string_ = duplicateAndPrefixStringValue(
value.data(), static_cast<unsigned>(value.length()));
}
#endif
Value::Value(const StaticString& value) { Value::Value(const StaticString& value) {
initBasic(stringValue); initBasic(stringValue);
value_.string_ = const_cast<char*>(value.c_str()); value_.string_ = const_cast<char*>(value.c_str());
@ -627,6 +639,21 @@ bool Value::getString(char const** begin, char const** end) const {
return true; return true;
} }
#ifdef JSONCPP_HAS_STRING_VIEW
bool Value::getString(std::string_view* str) const {
if (type() != stringValue)
return false;
if (value_.string_ == nullptr)
return false;
const char* begin;
unsigned length;
decodePrefixedString(this->isAllocated(), this->value_.string_, &length,
&begin);
*str = std::string_view(begin, length);
return true;
}
#endif
String Value::asString() const { String Value::asString() const {
switch (type()) { switch (type()) {
case nullValue: case nullValue:
@ -1146,6 +1173,17 @@ Value* Value::demand(char const* begin, char const* end) {
"objectValue or nullValue"); "objectValue or nullValue");
return &resolveReference(begin, end); return &resolveReference(begin, end);
} }
#ifdef JSONCPP_HAS_STRING_VIEW
const Value& Value::operator[](std::string_view key) const {
Value const* found = find(key.data(), key.data() + key.length());
if (!found)
return nullSingleton();
return *found;
}
Value& Value::operator[](std::string_view key) {
return resolveReference(key.data(), key.data() + key.length());
}
#else
const Value& Value::operator[](const char* key) const { const Value& Value::operator[](const char* key) const {
Value const* found = find(key, key + strlen(key)); Value const* found = find(key, key + strlen(key));
if (!found) if (!found)
@ -1166,6 +1204,7 @@ Value& Value::operator[](const char* key) {
Value& Value::operator[](const String& key) { Value& Value::operator[](const String& key) {
return resolveReference(key.data(), key.data() + key.length()); return resolveReference(key.data(), key.data() + key.length());
} }
#endif
Value& Value::operator[](const StaticString& key) { Value& Value::operator[](const StaticString& key) {
return resolveReference(key.c_str()); return resolveReference(key.c_str());
@ -1205,12 +1244,18 @@ Value Value::get(char const* begin, char const* end,
Value const* found = find(begin, end); Value const* found = find(begin, end);
return !found ? defaultValue : *found; return !found ? defaultValue : *found;
} }
#ifdef JSONCPP_HAS_STRING_VIEW
Value Value::get(std::string_view key, const Value& defaultValue) const {
return get(key.data(), key.data() + key.length(), defaultValue);
}
#else
Value Value::get(char const* key, Value const& defaultValue) const { Value Value::get(char const* key, Value const& defaultValue) const {
return get(key, key + strlen(key), defaultValue); return get(key, key + strlen(key), defaultValue);
} }
Value Value::get(String const& key, Value const& defaultValue) const { Value Value::get(String const& key, Value const& defaultValue) const {
return get(key.data(), key.data() + key.length(), defaultValue); return get(key.data(), key.data() + key.length(), defaultValue);
} }
#endif
bool Value::removeMember(const char* begin, const char* end, Value* removed) { bool Value::removeMember(const char* begin, const char* end, Value* removed) {
if (type() != objectValue) { if (type() != objectValue) {
@ -1226,12 +1271,31 @@ bool Value::removeMember(const char* begin, const char* end, Value* removed) {
value_.map_->erase(it); value_.map_->erase(it);
return true; return true;
} }
#ifdef JSONCPP_HAS_STRING_VIEW
bool Value::removeMember(std::string_view key, Value* removed) {
return removeMember(key.data(), key.data() + key.length(), removed);
}
#else
bool Value::removeMember(const char* key, Value* removed) { bool Value::removeMember(const char* key, Value* removed) {
return removeMember(key, key + strlen(key), removed); return removeMember(key, key + strlen(key), removed);
} }
bool Value::removeMember(String const& key, Value* removed) { bool Value::removeMember(String const& key, Value* removed) {
return removeMember(key.data(), key.data() + key.length(), removed); return removeMember(key.data(), key.data() + key.length(), removed);
} }
#endif
#ifdef JSONCPP_HAS_STRING_VIEW
void Value::removeMember(std::string_view key) {
JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
"in Json::Value::removeMember(): requires objectValue");
if (type() == nullValue)
return;
CZString actualKey(key.data(), unsigned(key.length()),
CZString::noDuplication);
value_.map_->erase(actualKey);
}
#else
void Value::removeMember(const char* key) { void Value::removeMember(const char* key) {
JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
"in Json::Value::removeMember(): requires objectValue"); "in Json::Value::removeMember(): requires objectValue");
@ -1242,6 +1306,7 @@ void Value::removeMember(const char* key) {
value_.map_->erase(actualKey); value_.map_->erase(actualKey);
} }
void Value::removeMember(const String& key) { removeMember(key.c_str()); } void Value::removeMember(const String& key) { removeMember(key.c_str()); }
#endif
bool Value::removeIndex(ArrayIndex index, Value* removed) { bool Value::removeIndex(ArrayIndex index, Value* removed) {
if (type() != arrayValue) { if (type() != arrayValue) {
@ -1271,12 +1336,18 @@ bool Value::isMember(char const* begin, char const* end) const {
Value const* value = find(begin, end); Value const* value = find(begin, end);
return nullptr != value; return nullptr != value;
} }
#ifdef JSONCPP_HAS_STRING_VIEW
bool Value::isMember(std::string_view key) const {
return isMember(key.data(), key.data() + key.length());
}
#else
bool Value::isMember(char const* key) const { bool Value::isMember(char const* key) const {
return isMember(key, key + strlen(key)); return isMember(key, key + strlen(key));
} }
bool Value::isMember(String const& key) const { bool Value::isMember(String const& key) const {
return isMember(key.data(), key.data() + key.length()); return isMember(key.data(), key.data() + key.length());
} }
#endif
Value::Members Value::getMemberNames() const { Value::Members Value::getMemberNames() const {
JSON_ASSERT_MESSAGE( JSON_ASSERT_MESSAGE(