mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2024-12-27 11:21:02 +08:00
Removed experimental ValueAllocator, it caused static initialization/destruction order issues (bug #2934500). The DefaultValueAllocator has been inlined in code.
This commit is contained in:
parent
d38ba2a2cb
commit
afd9cef928
6
NEWS.txt
6
NEWS.txt
@ -12,4 +12,10 @@
|
|||||||
Notes: you need to setup the environment by running vcvars32.bat
|
Notes: you need to setup the environment by running vcvars32.bat
|
||||||
(e.g. MSVC 2008 command prompt in start menu) before running scons.
|
(e.g. MSVC 2008 command prompt in start menu) before running scons.
|
||||||
|
|
||||||
|
* Value
|
||||||
|
|
||||||
|
- Removed experimental ValueAllocator, it caused static
|
||||||
|
initialization/destruction order issues (bug #2934500).
|
||||||
|
The DefaultValueAllocator has been inlined in code.
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ namespace Json {
|
|||||||
class ValueIterator;
|
class ValueIterator;
|
||||||
class ValueConstIterator;
|
class ValueConstIterator;
|
||||||
#ifdef JSON_VALUE_USE_INTERNAL_MAP
|
#ifdef JSON_VALUE_USE_INTERNAL_MAP
|
||||||
class ValueAllocator;
|
|
||||||
class ValueMapAllocator;
|
class ValueMapAllocator;
|
||||||
class ValueInternalLink;
|
class ValueInternalLink;
|
||||||
class ValueInternalArray;
|
class ValueInternalArray;
|
||||||
|
@ -513,26 +513,7 @@ namespace Json {
|
|||||||
Args args_;
|
Args args_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
|
|
||||||
*
|
|
||||||
* - makeMemberName() and releaseMemberName() are called to respectively duplicate and
|
|
||||||
* free an Json::objectValue member name.
|
|
||||||
* - duplicateStringValue() and releaseStringValue() are called similarly to
|
|
||||||
* duplicate and free a Json::stringValue value.
|
|
||||||
*/
|
|
||||||
class ValueAllocator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum { unknown = (unsigned)-1 };
|
|
||||||
|
|
||||||
virtual ~ValueAllocator();
|
|
||||||
|
|
||||||
virtual char *makeMemberName( const char *memberName ) = 0;
|
|
||||||
virtual void releaseMemberName( char *memberName ) = 0;
|
|
||||||
virtual char *duplicateStringValue( const char *value,
|
|
||||||
unsigned int length = unknown ) = 0;
|
|
||||||
virtual void releaseStringValue( char *value ) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef JSON_VALUE_USE_INTERNAL_MAP
|
#ifdef JSON_VALUE_USE_INTERNAL_MAP
|
||||||
/** \brief Allocator to customize Value internal map.
|
/** \brief Allocator to customize Value internal map.
|
||||||
|
@ -415,7 +415,7 @@ ValueInternalMap::setNewItem( const char *key,
|
|||||||
ValueInternalLink *link,
|
ValueInternalLink *link,
|
||||||
BucketIndex index )
|
BucketIndex index )
|
||||||
{
|
{
|
||||||
char *duplicatedKey = valueAllocator()->makeMemberName( key );
|
char *duplicatedKey = makeMemberName( key );
|
||||||
++itemCount_;
|
++itemCount_;
|
||||||
link->keys_[index] = duplicatedKey;
|
link->keys_[index] = duplicatedKey;
|
||||||
link->items_[index].setItemUsed();
|
link->items_[index].setItemUsed();
|
||||||
|
@ -24,91 +24,39 @@ const Int Value::minInt = Int( ~(UInt(-1)/2) );
|
|||||||
const Int Value::maxInt = Int( UInt(-1)/2 );
|
const Int Value::maxInt = Int( UInt(-1)/2 );
|
||||||
const UInt Value::maxUInt = UInt(-1);
|
const UInt Value::maxUInt = UInt(-1);
|
||||||
|
|
||||||
// A "safe" implementation of strdup. Allow null pointer to be passed.
|
/// Unknown size marker
|
||||||
// Also avoid warning on msvc80.
|
enum { unknown = (unsigned)-1 };
|
||||||
//
|
|
||||||
//inline char *safeStringDup( const char *czstring )
|
|
||||||
//{
|
|
||||||
// if ( czstring )
|
|
||||||
// {
|
|
||||||
// const size_t length = (unsigned int)( strlen(czstring) + 1 );
|
|
||||||
// char *newString = static_cast<char *>( malloc( length ) );
|
|
||||||
// memcpy( newString, czstring, length );
|
|
||||||
// return newString;
|
|
||||||
// }
|
|
||||||
// return 0;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//inline char *safeStringDup( const std::string &str )
|
|
||||||
//{
|
|
||||||
// if ( !str.empty() )
|
|
||||||
// {
|
|
||||||
// const size_t length = str.length();
|
|
||||||
// char *newString = static_cast<char *>( malloc( length + 1 ) );
|
|
||||||
// memcpy( newString, str.c_str(), length );
|
|
||||||
// newString[length] = 0;
|
|
||||||
// return newString;
|
|
||||||
// }
|
|
||||||
// return 0;
|
|
||||||
//}
|
|
||||||
|
|
||||||
ValueAllocator::~ValueAllocator()
|
|
||||||
|
/** Duplicates the specified string value.
|
||||||
|
* @param value Pointer to the string to duplicate. Must be zero-terminated if
|
||||||
|
* length is "unknown".
|
||||||
|
* @param length Length of the value. if equals to unknown, then it will be
|
||||||
|
* computed using strlen(value).
|
||||||
|
* @return Pointer on the duplicate instance of string.
|
||||||
|
*/
|
||||||
|
static inline char *
|
||||||
|
duplicateStringValue( const char *value,
|
||||||
|
unsigned int length = unknown )
|
||||||
{
|
{
|
||||||
|
if ( length == unknown )
|
||||||
|
length = (unsigned int)strlen(value);
|
||||||
|
char *newString = static_cast<char *>( malloc( length + 1 ) );
|
||||||
|
memcpy( newString, value, length );
|
||||||
|
newString[length] = 0;
|
||||||
|
return newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultValueAllocator : public ValueAllocator
|
|
||||||
|
/** Free the string duplicated by duplicateStringValue().
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
releaseStringValue( char *value )
|
||||||
{
|
{
|
||||||
public:
|
if ( value )
|
||||||
virtual ~DefaultValueAllocator()
|
free( value );
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual char *makeMemberName( const char *memberName )
|
|
||||||
{
|
|
||||||
return duplicateStringValue( memberName );
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void releaseMemberName( char *memberName )
|
|
||||||
{
|
|
||||||
releaseStringValue( memberName );
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual char *duplicateStringValue( const char *value,
|
|
||||||
unsigned int length = unknown )
|
|
||||||
{
|
|
||||||
//@todo invesgate this old optimization
|
|
||||||
//if ( !value || value[0] == 0 )
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
if ( length == unknown )
|
|
||||||
length = (unsigned int)strlen(value);
|
|
||||||
char *newString = static_cast<char *>( malloc( length + 1 ) );
|
|
||||||
memcpy( newString, value, length );
|
|
||||||
newString[length] = 0;
|
|
||||||
return newString;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void releaseStringValue( char *value )
|
|
||||||
{
|
|
||||||
if ( value )
|
|
||||||
free( value );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static ValueAllocator *&valueAllocator()
|
|
||||||
{
|
|
||||||
static DefaultValueAllocator defaultAllocator;
|
|
||||||
static ValueAllocator *valueAllocator = &defaultAllocator;
|
|
||||||
return valueAllocator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct DummyValueAllocatorInitializer {
|
|
||||||
DummyValueAllocatorInitializer()
|
|
||||||
{
|
|
||||||
valueAllocator(); // ensure valueAllocator() statics are initialized before main().
|
|
||||||
}
|
|
||||||
} dummyValueAllocatorInitializer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// //////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////
|
||||||
@ -143,7 +91,7 @@ Value::CommentInfo::CommentInfo()
|
|||||||
Value::CommentInfo::~CommentInfo()
|
Value::CommentInfo::~CommentInfo()
|
||||||
{
|
{
|
||||||
if ( comment_ )
|
if ( comment_ )
|
||||||
valueAllocator()->releaseStringValue( comment_ );
|
releaseStringValue( comment_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -151,11 +99,11 @@ void
|
|||||||
Value::CommentInfo::setComment( const char *text )
|
Value::CommentInfo::setComment( const char *text )
|
||||||
{
|
{
|
||||||
if ( comment_ )
|
if ( comment_ )
|
||||||
valueAllocator()->releaseStringValue( comment_ );
|
releaseStringValue( comment_ );
|
||||||
JSON_ASSERT( text );
|
JSON_ASSERT( text );
|
||||||
JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
|
JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
|
||||||
// It seems that /**/ style comments are acceptable as well.
|
// It seems that /**/ style comments are acceptable as well.
|
||||||
comment_ = valueAllocator()->duplicateStringValue( text );
|
comment_ = duplicateStringValue( text );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -178,7 +126,7 @@ Value::CZString::CZString( int index )
|
|||||||
}
|
}
|
||||||
|
|
||||||
Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
|
Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
|
||||||
: cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr)
|
: cstr_( allocate == duplicate ? duplicateStringValue(cstr)
|
||||||
: cstr )
|
: cstr )
|
||||||
, index_( allocate )
|
, index_( allocate )
|
||||||
{
|
{
|
||||||
@ -186,7 +134,7 @@ Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
|
|||||||
|
|
||||||
Value::CZString::CZString( const CZString &other )
|
Value::CZString::CZString( const CZString &other )
|
||||||
: cstr_( other.index_ != noDuplication && other.cstr_ != 0
|
: cstr_( other.index_ != noDuplication && other.cstr_ != 0
|
||||||
? valueAllocator()->makeMemberName( other.cstr_ )
|
? duplicateStringValue( other.cstr_ )
|
||||||
: other.cstr_ )
|
: other.cstr_ )
|
||||||
, index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
|
, index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
|
||||||
: other.index_ )
|
: other.index_ )
|
||||||
@ -196,7 +144,7 @@ Value::CZString::CZString( const CZString &other )
|
|||||||
Value::CZString::~CZString()
|
Value::CZString::~CZString()
|
||||||
{
|
{
|
||||||
if ( cstr_ && index_ == duplicate )
|
if ( cstr_ && index_ == duplicate )
|
||||||
valueAllocator()->releaseMemberName( const_cast<char *>( cstr_ ) );
|
releaseStringValue( const_cast<char *>( cstr_ ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -348,7 +296,7 @@ Value::Value( const char *value )
|
|||||||
, itemIsUsed_( 0 )
|
, itemIsUsed_( 0 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
value_.string_ = valueAllocator()->duplicateStringValue( value );
|
value_.string_ = duplicateStringValue( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -361,8 +309,8 @@ Value::Value( const char *beginValue,
|
|||||||
, itemIsUsed_( 0 )
|
, itemIsUsed_( 0 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
value_.string_ = valueAllocator()->duplicateStringValue( beginValue,
|
value_.string_ = duplicateStringValue( beginValue,
|
||||||
UInt(endValue - beginValue) );
|
UInt(endValue - beginValue) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -374,8 +322,8 @@ Value::Value( const std::string &value )
|
|||||||
, itemIsUsed_( 0 )
|
, itemIsUsed_( 0 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(),
|
value_.string_ = duplicateStringValue( value.c_str(),
|
||||||
(unsigned int)value.length() );
|
(unsigned int)value.length() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,7 +348,7 @@ Value::Value( const CppTL::ConstString &value )
|
|||||||
, itemIsUsed_( 0 )
|
, itemIsUsed_( 0 )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() );
|
value_.string_ = duplicateStringValue( value, value.length() );
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@ -434,7 +382,7 @@ Value::Value( const Value &other )
|
|||||||
case stringValue:
|
case stringValue:
|
||||||
if ( other.value_.string_ )
|
if ( other.value_.string_ )
|
||||||
{
|
{
|
||||||
value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ );
|
value_.string_ = duplicateStringValue( other.value_.string_ );
|
||||||
allocated_ = true;
|
allocated_ = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -481,7 +429,7 @@ Value::~Value()
|
|||||||
break;
|
break;
|
||||||
case stringValue:
|
case stringValue:
|
||||||
if ( allocated_ )
|
if ( allocated_ )
|
||||||
valueAllocator()->releaseStringValue( value_.string_ );
|
releaseStringValue( value_.string_ );
|
||||||
break;
|
break;
|
||||||
#ifndef JSON_VALUE_USE_INTERNAL_MAP
|
#ifndef JSON_VALUE_USE_INTERNAL_MAP
|
||||||
case arrayValue:
|
case arrayValue:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user