Added prop svn:eol-style native. Stripped carriage-returns on unix. Hopefully, this will work for Windows too now.

This commit is contained in:
Christopher Dunn 2007-06-13 15:48:30 +00:00
parent a44cffb342
commit b2f720456e
9 changed files with 4595 additions and 4595 deletions

View File

@ -1,125 +1,125 @@
#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
# define JSONCPP_BATCHALLOCATOR_H_INCLUDED # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
# include <stdlib.h> # include <stdlib.h>
# include <assert.h> # include <assert.h>
# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
namespace Json { namespace Json {
/* Fast memory allocator. /* Fast memory allocator.
* *
* This memory allocator allocates memory for a batch of object (specified by * This memory allocator allocates memory for a batch of object (specified by
* the page size, the number of object in each page). * the page size, the number of object in each page).
* *
* It does not allow the destruction of a single object. All the allocated objects * It does not allow the destruction of a single object. All the allocated objects
* can be destroyed at once. The memory can be either released or reused for future * can be destroyed at once. The memory can be either released or reused for future
* allocation. * allocation.
* *
* The in-place new operator must be used to construct the object using the pointer * The in-place new operator must be used to construct the object using the pointer
* returned by allocate. * returned by allocate.
*/ */
template<typename AllocatedType template<typename AllocatedType
,const unsigned int objectPerAllocation> ,const unsigned int objectPerAllocation>
class BatchAllocator class BatchAllocator
{ {
public: public:
typedef AllocatedType Type; typedef AllocatedType Type;
BatchAllocator( unsigned int objectsPerPage = 255 ) BatchAllocator( unsigned int objectsPerPage = 255 )
: freeHead_( 0 ) : freeHead_( 0 )
, objectsPerPage_( objectsPerPage ) , objectsPerPage_( objectsPerPage )
{ {
// printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() ); // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space. assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
assert( objectsPerPage >= 16 ); assert( objectsPerPage >= 16 );
batches_ = allocateBatch( 0 ); // allocated a dummy page batches_ = allocateBatch( 0 ); // allocated a dummy page
currentBatch_ = batches_; currentBatch_ = batches_;
} }
~BatchAllocator() ~BatchAllocator()
{ {
for ( BatchInfo *batch = batches_; batch; ) for ( BatchInfo *batch = batches_; batch; )
{ {
BatchInfo *nextBatch = batch->next_; BatchInfo *nextBatch = batch->next_;
free( batch ); free( batch );
batch = nextBatch; batch = nextBatch;
} }
} }
/// allocate space for an array of objectPerAllocation object. /// allocate space for an array of objectPerAllocation object.
/// @warning it is the responsability of the caller to call objects constructors. /// @warning it is the responsability of the caller to call objects constructors.
AllocatedType *allocate() AllocatedType *allocate()
{ {
if ( freeHead_ ) // returns node from free list. if ( freeHead_ ) // returns node from free list.
{ {
AllocatedType *object = freeHead_; AllocatedType *object = freeHead_;
freeHead_ = *(AllocatedType **)object; freeHead_ = *(AllocatedType **)object;
return object; return object;
} }
if ( currentBatch_->used_ == currentBatch_->end_ ) if ( currentBatch_->used_ == currentBatch_->end_ )
{ {
currentBatch_ = currentBatch_->next_; currentBatch_ = currentBatch_->next_;
while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ ) while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
currentBatch_ = currentBatch_->next_; currentBatch_ = currentBatch_->next_;
if ( !currentBatch_ ) // no free batch found, allocate a new one if ( !currentBatch_ ) // no free batch found, allocate a new one
{ {
currentBatch_ = allocateBatch( objectsPerPage_ ); currentBatch_ = allocateBatch( objectsPerPage_ );
currentBatch_->next_ = batches_; // insert at the head of the list currentBatch_->next_ = batches_; // insert at the head of the list
batches_ = currentBatch_; batches_ = currentBatch_;
} }
} }
AllocatedType *allocated = currentBatch_->used_; AllocatedType *allocated = currentBatch_->used_;
currentBatch_->used_ += objectPerAllocation; currentBatch_->used_ += objectPerAllocation;
return allocated; return allocated;
} }
/// Release the object. /// Release the object.
/// @warning it is the responsability of the caller to actually destruct the object. /// @warning it is the responsability of the caller to actually destruct the object.
void release( AllocatedType *object ) void release( AllocatedType *object )
{ {
assert( object != 0 ); assert( object != 0 );
*(AllocatedType **)object = freeHead_; *(AllocatedType **)object = freeHead_;
freeHead_ = object; freeHead_ = object;
} }
private: private:
struct BatchInfo struct BatchInfo
{ {
BatchInfo *next_; BatchInfo *next_;
AllocatedType *used_; AllocatedType *used_;
AllocatedType *end_; AllocatedType *end_;
AllocatedType buffer_[objectPerAllocation]; AllocatedType buffer_[objectPerAllocation];
}; };
// disabled copy constructor and assignement operator. // disabled copy constructor and assignement operator.
BatchAllocator( const BatchAllocator & ); BatchAllocator( const BatchAllocator & );
void operator =( const BatchAllocator &); void operator =( const BatchAllocator &);
static BatchInfo *allocateBatch( unsigned int objectsPerPage ) static BatchInfo *allocateBatch( unsigned int objectsPerPage )
{ {
const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
+ sizeof(AllocatedType) * objectPerAllocation * objectsPerPage; + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) ); BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
batch->next_ = 0; batch->next_ = 0;
batch->used_ = batch->buffer_; batch->used_ = batch->buffer_;
batch->end_ = batch->buffer_ + objectsPerPage; batch->end_ = batch->buffer_ + objectsPerPage;
return batch; return batch;
} }
BatchInfo *batches_; BatchInfo *batches_;
BatchInfo *currentBatch_; BatchInfo *currentBatch_;
/// Head of a single linked list within the allocated space of freeed object /// Head of a single linked list within the allocated space of freeed object
AllocatedType *freeHead_; AllocatedType *freeHead_;
unsigned int objectsPerPage_; unsigned int objectsPerPage_;
}; };
} // namespace Json } // namespace Json
# endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED

View File

@ -1,448 +1,448 @@
// included by json_value.cpp // included by json_value.cpp
// everything is within Json namespace // everything is within Json namespace
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class ValueInternalArray // class ValueInternalArray
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueArrayAllocator::~ValueArrayAllocator() ValueArrayAllocator::~ValueArrayAllocator()
{ {
} }
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class DefaultValueArrayAllocator // class DefaultValueArrayAllocator
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
class DefaultValueArrayAllocator : public ValueArrayAllocator class DefaultValueArrayAllocator : public ValueArrayAllocator
{ {
public: // overridden from ValueArrayAllocator public: // overridden from ValueArrayAllocator
virtual ~DefaultValueArrayAllocator() virtual ~DefaultValueArrayAllocator()
{ {
} }
virtual ValueInternalArray *newArray() virtual ValueInternalArray *newArray()
{ {
return new ValueInternalArray(); return new ValueInternalArray();
} }
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
{ {
return new ValueInternalArray( other ); return new ValueInternalArray( other );
} }
virtual void destructArray( ValueInternalArray *array ) virtual void destructArray( ValueInternalArray *array )
{ {
delete array; delete array;
} }
virtual void reallocateArrayPageIndex( Value **&indexes, virtual void reallocateArrayPageIndex( Value **&indexes,
ValueInternalArray::PageIndex &indexCount, ValueInternalArray::PageIndex &indexCount,
ValueInternalArray::PageIndex minNewIndexCount ) ValueInternalArray::PageIndex minNewIndexCount )
{ {
ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
if ( minNewIndexCount > newIndexCount ) if ( minNewIndexCount > newIndexCount )
newIndexCount = minNewIndexCount; newIndexCount = minNewIndexCount;
void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
if ( !newIndexes ) if ( !newIndexes )
throw std::bad_alloc(); throw std::bad_alloc();
indexCount = newIndexCount; indexCount = newIndexCount;
indexes = static_cast<Value **>( newIndexes ); indexes = static_cast<Value **>( newIndexes );
} }
virtual void releaseArrayPageIndex( Value **indexes, virtual void releaseArrayPageIndex( Value **indexes,
ValueInternalArray::PageIndex indexCount ) ValueInternalArray::PageIndex indexCount )
{ {
if ( indexes ) if ( indexes )
free( indexes ); free( indexes );
} }
virtual Value *allocateArrayPage() virtual Value *allocateArrayPage()
{ {
return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) ); return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
} }
virtual void releaseArrayPage( Value *value ) virtual void releaseArrayPage( Value *value )
{ {
if ( value ) if ( value )
free( value ); free( value );
} }
}; };
#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
/// @todo make this thread-safe (lock when accessign batch allocator) /// @todo make this thread-safe (lock when accessign batch allocator)
class DefaultValueArrayAllocator : public ValueArrayAllocator class DefaultValueArrayAllocator : public ValueArrayAllocator
{ {
public: // overridden from ValueArrayAllocator public: // overridden from ValueArrayAllocator
virtual ~DefaultValueArrayAllocator() virtual ~DefaultValueArrayAllocator()
{ {
} }
virtual ValueInternalArray *newArray() virtual ValueInternalArray *newArray()
{ {
ValueInternalArray *array = arraysAllocator_.allocate(); ValueInternalArray *array = arraysAllocator_.allocate();
new (array) ValueInternalArray(); // placement new new (array) ValueInternalArray(); // placement new
return array; return array;
} }
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
{ {
ValueInternalArray *array = arraysAllocator_.allocate(); ValueInternalArray *array = arraysAllocator_.allocate();
new (array) ValueInternalArray( other ); // placement new new (array) ValueInternalArray( other ); // placement new
return array; return array;
} }
virtual void destructArray( ValueInternalArray *array ) virtual void destructArray( ValueInternalArray *array )
{ {
if ( array ) if ( array )
{ {
array->~ValueInternalArray(); array->~ValueInternalArray();
arraysAllocator_.release( array ); arraysAllocator_.release( array );
} }
} }
virtual void reallocateArrayPageIndex( Value **&indexes, virtual void reallocateArrayPageIndex( Value **&indexes,
ValueInternalArray::PageIndex &indexCount, ValueInternalArray::PageIndex &indexCount,
ValueInternalArray::PageIndex minNewIndexCount ) ValueInternalArray::PageIndex minNewIndexCount )
{ {
ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
if ( minNewIndexCount > newIndexCount ) if ( minNewIndexCount > newIndexCount )
newIndexCount = minNewIndexCount; newIndexCount = minNewIndexCount;
void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
if ( !newIndexes ) if ( !newIndexes )
throw std::bad_alloc(); throw std::bad_alloc();
indexCount = newIndexCount; indexCount = newIndexCount;
indexes = static_cast<Value **>( newIndexes ); indexes = static_cast<Value **>( newIndexes );
} }
virtual void releaseArrayPageIndex( Value **indexes, virtual void releaseArrayPageIndex( Value **indexes,
ValueInternalArray::PageIndex indexCount ) ValueInternalArray::PageIndex indexCount )
{ {
if ( indexes ) if ( indexes )
free( indexes ); free( indexes );
} }
virtual Value *allocateArrayPage() virtual Value *allocateArrayPage()
{ {
return static_cast<Value *>( pagesAllocator_.allocate() ); return static_cast<Value *>( pagesAllocator_.allocate() );
} }
virtual void releaseArrayPage( Value *value ) virtual void releaseArrayPage( Value *value )
{ {
if ( value ) if ( value )
pagesAllocator_.release( value ); pagesAllocator_.release( value );
} }
private: private:
BatchAllocator<ValueInternalArray,1> arraysAllocator_; BatchAllocator<ValueInternalArray,1> arraysAllocator_;
BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_; BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_;
}; };
#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
static ValueArrayAllocator *&arrayAllocator() static ValueArrayAllocator *&arrayAllocator()
{ {
static DefaultValueArrayAllocator defaultAllocator; static DefaultValueArrayAllocator defaultAllocator;
static ValueArrayAllocator *arrayAllocator = &defaultAllocator; static ValueArrayAllocator *arrayAllocator = &defaultAllocator;
return arrayAllocator; return arrayAllocator;
} }
static struct DummyArrayAllocatorInitializer { static struct DummyArrayAllocatorInitializer {
DummyArrayAllocatorInitializer() DummyArrayAllocatorInitializer()
{ {
arrayAllocator(); // ensure arrayAllocator() statics are initialized before main(). arrayAllocator(); // ensure arrayAllocator() statics are initialized before main().
} }
} dummyArrayAllocatorInitializer; } dummyArrayAllocatorInitializer;
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class ValueInternalArray // class ValueInternalArray
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
bool bool
ValueInternalArray::equals( const IteratorState &x, ValueInternalArray::equals( const IteratorState &x,
const IteratorState &other ) const IteratorState &other )
{ {
return x.array_ == other.array_ return x.array_ == other.array_
&& x.currentItemIndex_ == other.currentItemIndex_ && x.currentItemIndex_ == other.currentItemIndex_
&& x.currentPageIndex_ == other.currentPageIndex_; && x.currentPageIndex_ == other.currentPageIndex_;
} }
void void
ValueInternalArray::increment( IteratorState &it ) ValueInternalArray::increment( IteratorState &it )
{ {
JSON_ASSERT_MESSAGE( it.array_ && JSON_ASSERT_MESSAGE( it.array_ &&
(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
!= it.array_->size_, != it.array_->size_,
"ValueInternalArray::increment(): moving iterator beyond end" ); "ValueInternalArray::increment(): moving iterator beyond end" );
++(it.currentItemIndex_); ++(it.currentItemIndex_);
if ( it.currentItemIndex_ == itemsPerPage ) if ( it.currentItemIndex_ == itemsPerPage )
{ {
it.currentItemIndex_ = 0; it.currentItemIndex_ = 0;
++(it.currentPageIndex_); ++(it.currentPageIndex_);
} }
} }
void void
ValueInternalArray::decrement( IteratorState &it ) ValueInternalArray::decrement( IteratorState &it )
{ {
JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_ JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_
&& it.currentItemIndex_ == 0, && it.currentItemIndex_ == 0,
"ValueInternalArray::decrement(): moving iterator beyond end" ); "ValueInternalArray::decrement(): moving iterator beyond end" );
if ( it.currentItemIndex_ == 0 ) if ( it.currentItemIndex_ == 0 )
{ {
it.currentItemIndex_ = itemsPerPage-1; it.currentItemIndex_ = itemsPerPage-1;
--(it.currentPageIndex_); --(it.currentPageIndex_);
} }
else else
{ {
--(it.currentItemIndex_); --(it.currentItemIndex_);
} }
} }
Value & Value &
ValueInternalArray::unsafeDereference( const IteratorState &it ) ValueInternalArray::unsafeDereference( const IteratorState &it )
{ {
return (*(it.currentPageIndex_))[it.currentItemIndex_]; return (*(it.currentPageIndex_))[it.currentItemIndex_];
} }
Value & Value &
ValueInternalArray::dereference( const IteratorState &it ) ValueInternalArray::dereference( const IteratorState &it )
{ {
JSON_ASSERT_MESSAGE( it.array_ && JSON_ASSERT_MESSAGE( it.array_ &&
(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
< it.array_->size_, < it.array_->size_,
"ValueInternalArray::dereference(): dereferencing invalid iterator" ); "ValueInternalArray::dereference(): dereferencing invalid iterator" );
return unsafeDereference( it ); return unsafeDereference( it );
} }
void void
ValueInternalArray::makeBeginIterator( IteratorState &it ) const ValueInternalArray::makeBeginIterator( IteratorState &it ) const
{ {
it.array_ = const_cast<ValueInternalArray *>( this ); it.array_ = const_cast<ValueInternalArray *>( this );
it.currentItemIndex_ = 0; it.currentItemIndex_ = 0;
it.currentPageIndex_ = pages_; it.currentPageIndex_ = pages_;
} }
void void
ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const
{ {
it.array_ = const_cast<ValueInternalArray *>( this ); it.array_ = const_cast<ValueInternalArray *>( this );
it.currentItemIndex_ = index % itemsPerPage; it.currentItemIndex_ = index % itemsPerPage;
it.currentPageIndex_ = pages_ + index / itemsPerPage; it.currentPageIndex_ = pages_ + index / itemsPerPage;
} }
void void
ValueInternalArray::makeEndIterator( IteratorState &it ) const ValueInternalArray::makeEndIterator( IteratorState &it ) const
{ {
makeIterator( it, size_ ); makeIterator( it, size_ );
} }
ValueInternalArray::ValueInternalArray() ValueInternalArray::ValueInternalArray()
: pages_( 0 ) : pages_( 0 )
, size_( 0 ) , size_( 0 )
, pageCount_( 0 ) , pageCount_( 0 )
{ {
} }
ValueInternalArray::ValueInternalArray( const ValueInternalArray &other ) ValueInternalArray::ValueInternalArray( const ValueInternalArray &other )
: pages_( 0 ) : pages_( 0 )
, pageCount_( 0 ) , pageCount_( 0 )
, size_( other.size_ ) , size_( other.size_ )
{ {
PageIndex minNewPages = other.size_ / itemsPerPage; PageIndex minNewPages = other.size_ / itemsPerPage;
arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,
"ValueInternalArray::reserve(): bad reallocation" ); "ValueInternalArray::reserve(): bad reallocation" );
IteratorState itOther; IteratorState itOther;
other.makeBeginIterator( itOther ); other.makeBeginIterator( itOther );
Value *value; Value *value;
for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) ) for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) )
{ {
if ( index % itemsPerPage == 0 ) if ( index % itemsPerPage == 0 )
{ {
PageIndex pageIndex = index / itemsPerPage; PageIndex pageIndex = index / itemsPerPage;
value = arrayAllocator()->allocateArrayPage(); value = arrayAllocator()->allocateArrayPage();
pages_[pageIndex] = value; pages_[pageIndex] = value;
} }
new (value) Value( dereference( itOther ) ); new (value) Value( dereference( itOther ) );
} }
} }
ValueInternalArray & ValueInternalArray &
ValueInternalArray::operator =( const ValueInternalArray &other ) ValueInternalArray::operator =( const ValueInternalArray &other )
{ {
ValueInternalArray temp( other ); ValueInternalArray temp( other );
swap( temp ); swap( temp );
return *this; return *this;
} }
ValueInternalArray::~ValueInternalArray() ValueInternalArray::~ValueInternalArray()
{ {
// destroy all constructed items // destroy all constructed items
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
makeBeginIterator( it); makeBeginIterator( it);
makeEndIterator( itEnd ); makeEndIterator( itEnd );
for ( ; !equals(it,itEnd); increment(it) ) for ( ; !equals(it,itEnd); increment(it) )
{ {
Value *value = &dereference(it); Value *value = &dereference(it);
value->~Value(); value->~Value();
} }
// release all pages // release all pages
PageIndex lastPageIndex = size_ / itemsPerPage; PageIndex lastPageIndex = size_ / itemsPerPage;
for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex ) for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex )
arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); arrayAllocator()->releaseArrayPage( pages_[pageIndex] );
// release pages index // release pages index
arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ ); arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ );
} }
void void
ValueInternalArray::swap( ValueInternalArray &other ) ValueInternalArray::swap( ValueInternalArray &other )
{ {
Value **tempPages = pages_; Value **tempPages = pages_;
pages_ = other.pages_; pages_ = other.pages_;
other.pages_ = tempPages; other.pages_ = tempPages;
ArrayIndex tempSize = size_; ArrayIndex tempSize = size_;
size_ = other.size_; size_ = other.size_;
other.size_ = tempSize; other.size_ = tempSize;
PageIndex tempPageCount = pageCount_; PageIndex tempPageCount = pageCount_;
pageCount_ = other.pageCount_; pageCount_ = other.pageCount_;
other.pageCount_ = tempPageCount; other.pageCount_ = tempPageCount;
} }
void void
ValueInternalArray::clear() ValueInternalArray::clear()
{ {
ValueInternalArray dummy; ValueInternalArray dummy;
swap( dummy ); swap( dummy );
} }
void void
ValueInternalArray::resize( ArrayIndex newSize ) ValueInternalArray::resize( ArrayIndex newSize )
{ {
if ( newSize == 0 ) if ( newSize == 0 )
clear(); clear();
else if ( newSize < size_ ) else if ( newSize < size_ )
{ {
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
makeIterator( it, newSize ); makeIterator( it, newSize );
makeIterator( itEnd, size_ ); makeIterator( itEnd, size_ );
for ( ; !equals(it,itEnd); increment(it) ) for ( ; !equals(it,itEnd); increment(it) )
{ {
Value *value = &dereference(it); Value *value = &dereference(it);
value->~Value(); value->~Value();
} }
PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage; PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage;
PageIndex lastPageIndex = size_ / itemsPerPage; PageIndex lastPageIndex = size_ / itemsPerPage;
for ( ; pageIndex < lastPageIndex; ++pageIndex ) for ( ; pageIndex < lastPageIndex; ++pageIndex )
arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); arrayAllocator()->releaseArrayPage( pages_[pageIndex] );
size_ = newSize; size_ = newSize;
} }
else if ( newSize > size_ ) else if ( newSize > size_ )
resolveReference( newSize ); resolveReference( newSize );
} }
void void
ValueInternalArray::makeIndexValid( ArrayIndex index ) ValueInternalArray::makeIndexValid( ArrayIndex index )
{ {
// Need to enlarge page index ? // Need to enlarge page index ?
if ( index >= pageCount_ * itemsPerPage ) if ( index >= pageCount_ * itemsPerPage )
{ {
PageIndex minNewPages = (index + 1) / itemsPerPage; PageIndex minNewPages = (index + 1) / itemsPerPage;
arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" ); JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" );
} }
// Need to allocate new pages ? // Need to allocate new pages ?
ArrayIndex nextPageIndex = ArrayIndex nextPageIndex =
(size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage (size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage
: size_; : size_;
if ( nextPageIndex <= index ) if ( nextPageIndex <= index )
{ {
PageIndex pageIndex = nextPageIndex / itemsPerPage; PageIndex pageIndex = nextPageIndex / itemsPerPage;
PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1; PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
for ( ; pageToAllocate-- > 0; ++pageIndex ) for ( ; pageToAllocate-- > 0; ++pageIndex )
pages_[pageIndex] = arrayAllocator()->allocateArrayPage(); pages_[pageIndex] = arrayAllocator()->allocateArrayPage();
} }
// Initialize all new entries // Initialize all new entries
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
makeIterator( it, size_ ); makeIterator( it, size_ );
size_ = index + 1; size_ = index + 1;
makeIterator( itEnd, size_ ); makeIterator( itEnd, size_ );
for ( ; !equals(it,itEnd); increment(it) ) for ( ; !equals(it,itEnd); increment(it) )
{ {
Value *value = &dereference(it); Value *value = &dereference(it);
new (value) Value(); // Construct a default value using placement new new (value) Value(); // Construct a default value using placement new
} }
} }
Value & Value &
ValueInternalArray::resolveReference( ArrayIndex index ) ValueInternalArray::resolveReference( ArrayIndex index )
{ {
if ( index >= size_ ) if ( index >= size_ )
makeIndexValid( index ); makeIndexValid( index );
return pages_[index/itemsPerPage][index%itemsPerPage]; return pages_[index/itemsPerPage][index%itemsPerPage];
} }
Value * Value *
ValueInternalArray::find( ArrayIndex index ) const ValueInternalArray::find( ArrayIndex index ) const
{ {
if ( index >= size_ ) if ( index >= size_ )
return 0; return 0;
return &(pages_[index/itemsPerPage][index%itemsPerPage]); return &(pages_[index/itemsPerPage][index%itemsPerPage]);
} }
ValueInternalArray::ArrayIndex ValueInternalArray::ArrayIndex
ValueInternalArray::size() const ValueInternalArray::size() const
{ {
return size_; return size_;
} }
int int
ValueInternalArray::distance( const IteratorState &x, const IteratorState &y ) ValueInternalArray::distance( const IteratorState &x, const IteratorState &y )
{ {
return indexOf(y) - indexOf(x); return indexOf(y) - indexOf(x);
} }
ValueInternalArray::ArrayIndex ValueInternalArray::ArrayIndex
ValueInternalArray::indexOf( const IteratorState &iterator ) ValueInternalArray::indexOf( const IteratorState &iterator )
{ {
if ( !iterator.array_ ) if ( !iterator.array_ )
return ArrayIndex(-1); return ArrayIndex(-1);
return ArrayIndex( return ArrayIndex(
(iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage (iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage
+ iterator.currentItemIndex_ ); + iterator.currentItemIndex_ );
} }
int int
ValueInternalArray::compare( const ValueInternalArray &other ) const ValueInternalArray::compare( const ValueInternalArray &other ) const
{ {
int sizeDiff( size_ - other.size_ ); int sizeDiff( size_ - other.size_ );
if ( sizeDiff != 0 ) if ( sizeDiff != 0 )
return sizeDiff; return sizeDiff;
for ( ArrayIndex index =0; index < size_; ++index ) for ( ArrayIndex index =0; index < size_; ++index )
{ {
int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare( int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare(
other.pages_[index/itemsPerPage][index%itemsPerPage] ); other.pages_[index/itemsPerPage][index%itemsPerPage] );
if ( diff != 0 ) if ( diff != 0 )
return diff; return diff;
} }
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,257 +1,257 @@
// included by json_value.cpp // included by json_value.cpp
// everything is within Json namespace // everything is within Json namespace
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class ValueIteratorBase // class ValueIteratorBase
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueIteratorBase::ValueIteratorBase() ValueIteratorBase::ValueIteratorBase()
{ {
} }
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current ) ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current )
: current_( current ) : current_( current )
{ {
} }
#else #else
ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state ) ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state )
: isArray_( true ) : isArray_( true )
{ {
iterator_.array_ = state; iterator_.array_ = state;
} }
ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state ) ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state )
: isArray_( false ) : isArray_( false )
{ {
iterator_.map_ = state; iterator_.map_ = state;
} }
#endif #endif
Value & Value &
ValueIteratorBase::deref() const ValueIteratorBase::deref() const
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
return current_->second; return current_->second;
#else #else
if ( isArray_ ) if ( isArray_ )
return ValueInternalArray::dereference( iterator_.array_ ); return ValueInternalArray::dereference( iterator_.array_ );
return ValueInternalMap::value( iterator_.map_ ); return ValueInternalMap::value( iterator_.map_ );
#endif #endif
} }
void void
ValueIteratorBase::increment() ValueIteratorBase::increment()
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
++current_; ++current_;
#else #else
if ( isArray_ ) if ( isArray_ )
ValueInternalArray::increment( iterator_.array_ ); ValueInternalArray::increment( iterator_.array_ );
ValueInternalMap::increment( iterator_.map_ ); ValueInternalMap::increment( iterator_.map_ );
#endif #endif
} }
void void
ValueIteratorBase::decrement() ValueIteratorBase::decrement()
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
--current_; --current_;
#else #else
if ( isArray_ ) if ( isArray_ )
ValueInternalArray::decrement( iterator_.array_ ); ValueInternalArray::decrement( iterator_.array_ );
ValueInternalMap::decrement( iterator_.map_ ); ValueInternalMap::decrement( iterator_.map_ );
#endif #endif
} }
ValueIteratorBase::difference_type ValueIteratorBase::difference_type
ValueIteratorBase::computeDistance( const SelfType &other ) const ValueIteratorBase::computeDistance( const SelfType &other ) const
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
# ifdef JSON_USE_CPPTL_SMALLMAP # ifdef JSON_USE_CPPTL_SMALLMAP
return current_ - other.current_; return current_ - other.current_;
# else # else
return difference_type( std::distance( current_, other.current_ ) ); return difference_type( std::distance( current_, other.current_ ) );
# endif # endif
#else #else
if ( isArray_ ) if ( isArray_ )
return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ ); return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ );
return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ ); return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ );
#endif #endif
} }
bool bool
ValueIteratorBase::isEqual( const SelfType &other ) const ValueIteratorBase::isEqual( const SelfType &other ) const
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
return current_ == other.current_; return current_ == other.current_;
#else #else
if ( isArray_ ) if ( isArray_ )
return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ ); return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ );
return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ ); return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ );
#endif #endif
} }
void void
ValueIteratorBase::copy( const SelfType &other ) ValueIteratorBase::copy( const SelfType &other )
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
current_ = other.current_; current_ = other.current_;
#else #else
if ( isArray_ ) if ( isArray_ )
iterator_.array_ = other.iterator_.array_; iterator_.array_ = other.iterator_.array_;
iterator_.map_ = other.iterator_.map_; iterator_.map_ = other.iterator_.map_;
#endif #endif
} }
Value Value
ValueIteratorBase::key() const ValueIteratorBase::key() const
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
const Value::CZString czstring = (*current_).first; const Value::CZString czstring = (*current_).first;
if ( czstring.c_str() ) if ( czstring.c_str() )
{ {
if ( czstring.isStaticString() ) if ( czstring.isStaticString() )
return Value( StaticString( czstring.c_str() ) ); return Value( StaticString( czstring.c_str() ) );
return Value( czstring.c_str() ); return Value( czstring.c_str() );
} }
return Value( czstring.index() ); return Value( czstring.index() );
#else #else
if ( isArray_ ) if ( isArray_ )
return Value( ValueInternalArray::indexOf( iterator_.array_ ) ); return Value( ValueInternalArray::indexOf( iterator_.array_ ) );
bool isStatic; bool isStatic;
const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic ); const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic );
if ( isStatic ) if ( isStatic )
return Value( StaticString( memberName ) ); return Value( StaticString( memberName ) );
return Value( memberName ); return Value( memberName );
#endif #endif
} }
Value::UInt Value::UInt
ValueIteratorBase::index() const ValueIteratorBase::index() const
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
const Value::CZString czstring = (*current_).first; const Value::CZString czstring = (*current_).first;
if ( !czstring.c_str() ) if ( !czstring.c_str() )
return czstring.index(); return czstring.index();
return Value::UInt( -1 ); return Value::UInt( -1 );
#else #else
if ( isArray_ ) if ( isArray_ )
return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) ); return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) );
return Value::UInt( -1 ); return Value::UInt( -1 );
#endif #endif
} }
const char * const char *
ValueIteratorBase::memberName() const ValueIteratorBase::memberName() const
{ {
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
const char *name = (*current_).first.c_str(); const char *name = (*current_).first.c_str();
return name ? name : ""; return name ? name : "";
#else #else
if ( !isArray_ ) if ( !isArray_ )
return ValueInternalMap::key( iterator_.map_ ); return ValueInternalMap::key( iterator_.map_ );
return ""; return "";
#endif #endif
} }
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class ValueConstIterator // class ValueConstIterator
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueConstIterator::ValueConstIterator() ValueConstIterator::ValueConstIterator()
{ {
} }
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator &current ) ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator &current )
: ValueIteratorBase( current ) : ValueIteratorBase( current )
{ {
} }
#else #else
ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state ) ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state )
: ValueIteratorBase( state ) : ValueIteratorBase( state )
{ {
} }
ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state ) ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state )
: ValueIteratorBase( state ) : ValueIteratorBase( state )
{ {
} }
#endif #endif
ValueConstIterator & ValueConstIterator &
ValueConstIterator::operator =( const ValueIteratorBase &other ) ValueConstIterator::operator =( const ValueIteratorBase &other )
{ {
copy( other ); copy( other );
return *this; return *this;
} }
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class ValueIterator // class ValueIterator
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueIterator::ValueIterator() ValueIterator::ValueIterator()
{ {
} }
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueIterator::ValueIterator( const Value::ObjectValues::iterator &current ) ValueIterator::ValueIterator( const Value::ObjectValues::iterator &current )
: ValueIteratorBase( current ) : ValueIteratorBase( current )
{ {
} }
#else #else
ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state ) ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state )
: ValueIteratorBase( state ) : ValueIteratorBase( state )
{ {
} }
ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state ) ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state )
: ValueIteratorBase( state ) : ValueIteratorBase( state )
{ {
} }
#endif #endif
ValueIterator::ValueIterator( const ValueConstIterator &other ) ValueIterator::ValueIterator( const ValueConstIterator &other )
: ValueIteratorBase( other ) : ValueIteratorBase( other )
{ {
} }
ValueIterator::ValueIterator( const ValueIterator &other ) ValueIterator::ValueIterator( const ValueIterator &other )
: ValueIteratorBase( other ) : ValueIteratorBase( other )
{ {
} }
ValueIterator & ValueIterator &
ValueIterator::operator =( const SelfType &other ) ValueIterator::operator =( const SelfType &other )
{ {
copy( other ); copy( other );
return *this; return *this;
} }

View File

@ -1,487 +1,487 @@
#include <json/writer.h> #include <json/writer.h>
#include <utility> #include <utility>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#if _MSC_VER >= 1400 // VC++ 8.0 #if _MSC_VER >= 1400 // VC++ 8.0
#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
#endif #endif
namespace Json { namespace Json {
static void uintToString( unsigned int value, static void uintToString( unsigned int value,
char *&current ) char *&current )
{ {
*--current = 0; *--current = 0;
do do
{ {
*--current = (value % 10) + '0'; *--current = (value % 10) + '0';
value /= 10; value /= 10;
} }
while ( value != 0 ); while ( value != 0 );
} }
std::string valueToString( Value::Int value ) std::string valueToString( Value::Int value )
{ {
char buffer[32]; char buffer[32];
char *current = buffer + sizeof(buffer); char *current = buffer + sizeof(buffer);
bool isNegative = value < 0; bool isNegative = value < 0;
if ( isNegative ) if ( isNegative )
value = -value; value = -value;
uintToString( Value::UInt(value), current ); uintToString( Value::UInt(value), current );
if ( isNegative ) if ( isNegative )
*--current = '-'; *--current = '-';
assert( current >= buffer ); assert( current >= buffer );
return current; return current;
} }
std::string valueToString( Value::UInt value ) std::string valueToString( Value::UInt value )
{ {
char buffer[32]; char buffer[32];
char *current = buffer + sizeof(buffer); char *current = buffer + sizeof(buffer);
uintToString( value, current ); uintToString( value, current );
assert( current >= buffer ); assert( current >= buffer );
return current; return current;
} }
std::string valueToString( double value ) std::string valueToString( double value )
{ {
char buffer[32]; char buffer[32];
#ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning. #ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
sprintf_s(buffer, sizeof(buffer), "%.16g", value); sprintf_s(buffer, sizeof(buffer), "%.16g", value);
#else #else
sprintf(buffer, "%.16g", value); sprintf(buffer, "%.16g", value);
#endif #endif
return buffer; return buffer;
} }
std::string valueToString( bool value ) std::string valueToString( bool value )
{ {
return value ? "true" : "false"; return value ? "true" : "false";
} }
std::string valueToQuotedString( const char *value ) std::string valueToQuotedString( const char *value )
{ {
// Not sure how to handle unicode... // Not sure how to handle unicode...
if (std::strpbrk(value, "\"\\\b\f\n\r\t") == NULL) if (std::strpbrk(value, "\"\\\b\f\n\r\t") == NULL)
return std::string("\"") + value + "\""; return std::string("\"") + value + "\"";
// We have to walk value and escape any special characters. // We have to walk value and escape any special characters.
// Appending to std::string is not efficient, but this should be rare. // Appending to std::string is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.) // (Note: forward slashes are *not* rare, but I am not escaping them.)
unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL
std::string result; std::string result;
result.reserve(maxsize); // to avoid lots of mallocs result.reserve(maxsize); // to avoid lots of mallocs
result += "\""; result += "\"";
for (const char* c=value; *c != 0; ++c){ for (const char* c=value; *c != 0; ++c){
switch(*c){ switch(*c){
case '\"': case '\"':
result += "\\\""; result += "\\\"";
break; break;
case '\\': case '\\':
result += "\\\\"; result += "\\\\";
break; break;
case '\b': case '\b':
result += "\\b"; result += "\\b";
break; break;
case '\f': case '\f':
result += "\\f"; result += "\\f";
break; break;
case '\n': case '\n':
result += "\\n"; result += "\\n";
break; break;
case '\r': case '\r':
result += "\\r"; result += "\\r";
break; break;
case '\t': case '\t':
result += "\\t"; result += "\\t";
break; break;
case '/': case '/':
// Even though \/ is considered a legal escape in JSON, a bare // Even though \/ is considered a legal escape in JSON, a bare
// slash is also legal, so I see no reason to escape it. // slash is also legal, so I see no reason to escape it.
// (I hope I am not misunderstanding something.) // (I hope I am not misunderstanding something.)
default: default:
result += *c; result += *c;
} }
} }
result += "\""; result += "\"";
return result; return result;
} }
// Class Writer // Class Writer
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
Writer::~Writer() Writer::~Writer()
{ {
} }
// Class FastWriter // Class FastWriter
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
FastWriter::FastWriter() FastWriter::FastWriter()
: yamlCompatiblityEnabled_( false ) : yamlCompatiblityEnabled_( false )
{ {
} }
void void
FastWriter::enableYAMLCompatibility() FastWriter::enableYAMLCompatibility()
{ {
yamlCompatiblityEnabled_ = true; yamlCompatiblityEnabled_ = true;
} }
std::string std::string
FastWriter::write( const Value &root ) FastWriter::write( const Value &root )
{ {
document_ = ""; document_ = "";
writeValue( root ); writeValue( root );
document_ += "\n"; document_ += "\n";
return document_; return document_;
} }
void void
FastWriter::writeValue( const Value &value ) FastWriter::writeValue( const Value &value )
{ {
switch ( value.type() ) switch ( value.type() )
{ {
case nullValue: case nullValue:
document_ += "null"; document_ += "null";
break; break;
case intValue: case intValue:
document_ += valueToString( value.asInt() ); document_ += valueToString( value.asInt() );
break; break;
case uintValue: case uintValue:
document_ += valueToString( value.asUInt() ); document_ += valueToString( value.asUInt() );
break; break;
case realValue: case realValue:
document_ += valueToString( value.asDouble() ); document_ += valueToString( value.asDouble() );
break; break;
case stringValue: case stringValue:
document_ += valueToQuotedString( value.asCString() ); document_ += valueToQuotedString( value.asCString() );
break; break;
case booleanValue: case booleanValue:
document_ += valueToString( value.asBool() ); document_ += valueToString( value.asBool() );
break; break;
case arrayValue: case arrayValue:
{ {
document_ += "["; document_ += "[";
int size = value.size(); int size = value.size();
for ( int index =0; index < size; ++index ) for ( int index =0; index < size; ++index )
{ {
if ( index > 0 ) if ( index > 0 )
document_ += ","; document_ += ",";
writeValue( value[index] ); writeValue( value[index] );
} }
document_ += "]"; document_ += "]";
} }
break; break;
case objectValue: case objectValue:
{ {
Value::Members members( value.getMemberNames() ); Value::Members members( value.getMemberNames() );
document_ += "{"; document_ += "{";
for ( Value::Members::iterator it = members.begin(); for ( Value::Members::iterator it = members.begin();
it != members.end(); it != members.end();
++it ) ++it )
{ {
const std::string &name = *it; const std::string &name = *it;
if ( it != members.begin() ) if ( it != members.begin() )
document_ += ","; document_ += ",";
document_ += valueToQuotedString( name.c_str() ); document_ += valueToQuotedString( name.c_str() );
document_ += yamlCompatiblityEnabled_ ? ": " document_ += yamlCompatiblityEnabled_ ? ": "
: ":"; : ":";
writeValue( value[name] ); writeValue( value[name] );
} }
document_ += "}"; document_ += "}";
} }
break; break;
} }
} }
// Class StyledWriter // Class StyledWriter
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
StyledWriter::StyledWriter() StyledWriter::StyledWriter()
: rightMargin_( 74 ) : rightMargin_( 74 )
, indentSize_( 3 ) , indentSize_( 3 )
{ {
} }
std::string std::string
StyledWriter::write( const Value &root ) StyledWriter::write( const Value &root )
{ {
document_ = ""; document_ = "";
addChildValues_ = false; addChildValues_ = false;
indentString_ = ""; indentString_ = "";
writeCommentBeforeValue( root ); writeCommentBeforeValue( root );
writeValue( root ); writeValue( root );
writeCommentAfterValueOnSameLine( root ); writeCommentAfterValueOnSameLine( root );
document_ += "\n"; document_ += "\n";
return document_; return document_;
} }
void void
StyledWriter::writeValue( const Value &value ) StyledWriter::writeValue( const Value &value )
{ {
switch ( value.type() ) switch ( value.type() )
{ {
case nullValue: case nullValue:
pushValue( "null" ); pushValue( "null" );
break; break;
case intValue: case intValue:
pushValue( valueToString( value.asInt() ) ); pushValue( valueToString( value.asInt() ) );
break; break;
case uintValue: case uintValue:
pushValue( valueToString( value.asUInt() ) ); pushValue( valueToString( value.asUInt() ) );
break; break;
case realValue: case realValue:
pushValue( valueToString( value.asDouble() ) ); pushValue( valueToString( value.asDouble() ) );
break; break;
case stringValue: case stringValue:
pushValue( valueToQuotedString( value.asCString() ) ); pushValue( valueToQuotedString( value.asCString() ) );
break; break;
case booleanValue: case booleanValue:
pushValue( valueToString( value.asBool() ) ); pushValue( valueToString( value.asBool() ) );
break; break;
case arrayValue: case arrayValue:
writeArrayValue( value); writeArrayValue( value);
break; break;
case objectValue: case objectValue:
{ {
Value::Members members( value.getMemberNames() ); Value::Members members( value.getMemberNames() );
if ( members.empty() ) if ( members.empty() )
pushValue( "{}" ); pushValue( "{}" );
else else
{ {
writeWithIndent( "{" ); writeWithIndent( "{" );
indent(); indent();
Value::Members::iterator it = members.begin(); Value::Members::iterator it = members.begin();
while ( true ) while ( true )
{ {
const std::string &name = *it; const std::string &name = *it;
const Value &childValue = value[name]; const Value &childValue = value[name];
writeCommentBeforeValue( childValue ); writeCommentBeforeValue( childValue );
writeWithIndent( valueToQuotedString( name.c_str() ) ); writeWithIndent( valueToQuotedString( name.c_str() ) );
document_ += " : "; document_ += " : ";
writeValue( childValue ); writeValue( childValue );
if ( ++it == members.end() ) if ( ++it == members.end() )
{ {
writeCommentAfterValueOnSameLine( childValue ); writeCommentAfterValueOnSameLine( childValue );
break; break;
} }
document_ += ","; document_ += ",";
writeCommentAfterValueOnSameLine( childValue ); writeCommentAfterValueOnSameLine( childValue );
} }
unindent(); unindent();
writeWithIndent( "}" ); writeWithIndent( "}" );
} }
} }
break; break;
} }
} }
void void
StyledWriter::writeArrayValue( const Value &value ) StyledWriter::writeArrayValue( const Value &value )
{ {
unsigned size = value.size(); unsigned size = value.size();
if ( size == 0 ) if ( size == 0 )
pushValue( "[]" ); pushValue( "[]" );
else else
{ {
bool isArrayMultiLine = isMultineArray( value ); bool isArrayMultiLine = isMultineArray( value );
if ( isArrayMultiLine ) if ( isArrayMultiLine )
{ {
writeWithIndent( "[" ); writeWithIndent( "[" );
indent(); indent();
bool hasChildValue = !childValues_.empty(); bool hasChildValue = !childValues_.empty();
unsigned index =0; unsigned index =0;
while ( true ) while ( true )
{ {
const Value &childValue = value[index]; const Value &childValue = value[index];
writeCommentBeforeValue( childValue ); writeCommentBeforeValue( childValue );
if ( hasChildValue ) if ( hasChildValue )
writeWithIndent( childValues_[index] ); writeWithIndent( childValues_[index] );
else else
{ {
writeIndent(); writeIndent();
writeValue( childValue ); writeValue( childValue );
} }
if ( ++index == size ) if ( ++index == size )
{ {
writeCommentAfterValueOnSameLine( childValue ); writeCommentAfterValueOnSameLine( childValue );
break; break;
} }
document_ += ","; document_ += ",";
writeCommentAfterValueOnSameLine( childValue ); writeCommentAfterValueOnSameLine( childValue );
} }
unindent(); unindent();
writeWithIndent( "]" ); writeWithIndent( "]" );
} }
else // output on a single line else // output on a single line
{ {
assert( childValues_.size() == size ); assert( childValues_.size() == size );
document_ += "[ "; document_ += "[ ";
for ( unsigned index =0; index < size; ++index ) for ( unsigned index =0; index < size; ++index )
{ {
if ( index > 0 ) if ( index > 0 )
document_ += ", "; document_ += ", ";
document_ += childValues_[index]; document_ += childValues_[index];
} }
document_ += " ]"; document_ += " ]";
} }
} }
} }
bool bool
StyledWriter::isMultineArray( const Value &value ) StyledWriter::isMultineArray( const Value &value )
{ {
int size = value.size(); int size = value.size();
bool isMultiLine = size*3 >= rightMargin_ ; bool isMultiLine = size*3 >= rightMargin_ ;
childValues_.clear(); childValues_.clear();
for ( int index =0; index < size && !isMultiLine; ++index ) for ( int index =0; index < size && !isMultiLine; ++index )
{ {
const Value &childValue = value[index]; const Value &childValue = value[index];
isMultiLine = isMultiLine || isMultiLine = isMultiLine ||
( (childValue.isArray() || childValue.isObject()) && ( (childValue.isArray() || childValue.isObject()) &&
childValue.size() > 0 ); childValue.size() > 0 );
} }
if ( !isMultiLine ) // check if line length > max line length if ( !isMultiLine ) // check if line length > max line length
{ {
childValues_.reserve( size ); childValues_.reserve( size );
addChildValues_ = true; addChildValues_ = true;
int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]' int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
for ( int index =0; index < size && !isMultiLine; ++index ) for ( int index =0; index < size && !isMultiLine; ++index )
{ {
writeValue( value[index] ); writeValue( value[index] );
lineLength += int( childValues_[index].length() ); lineLength += int( childValues_[index].length() );
isMultiLine = isMultiLine && hasCommentForValue( value[index] ); isMultiLine = isMultiLine && hasCommentForValue( value[index] );
} }
addChildValues_ = false; addChildValues_ = false;
isMultiLine = isMultiLine || lineLength >= rightMargin_; isMultiLine = isMultiLine || lineLength >= rightMargin_;
} }
return isMultiLine; return isMultiLine;
} }
void void
StyledWriter::pushValue( const std::string &value ) StyledWriter::pushValue( const std::string &value )
{ {
if ( addChildValues_ ) if ( addChildValues_ )
childValues_.push_back( value ); childValues_.push_back( value );
else else
document_ += value; document_ += value;
} }
void void
StyledWriter::writeIndent() StyledWriter::writeIndent()
{ {
if ( !document_.empty() ) if ( !document_.empty() )
{ {
char last = document_[document_.length()-1]; char last = document_[document_.length()-1];
if ( last == ' ' ) // already indented if ( last == ' ' ) // already indented
return; return;
if ( last != '\n' ) // Comments may add new-line if ( last != '\n' ) // Comments may add new-line
document_ += '\n'; document_ += '\n';
} }
document_ += indentString_; document_ += indentString_;
} }
void void
StyledWriter::writeWithIndent( const std::string &value ) StyledWriter::writeWithIndent( const std::string &value )
{ {
writeIndent(); writeIndent();
document_ += value; document_ += value;
} }
void void
StyledWriter::indent() StyledWriter::indent()
{ {
indentString_ += std::string( indentSize_, ' ' ); indentString_ += std::string( indentSize_, ' ' );
} }
void void
StyledWriter::unindent() StyledWriter::unindent()
{ {
assert( int(indentString_.size()) >= indentSize_ ); assert( int(indentString_.size()) >= indentSize_ );
indentString_.resize( indentString_.size() - indentSize_ ); indentString_.resize( indentString_.size() - indentSize_ );
} }
void void
StyledWriter::writeCommentBeforeValue( const Value &root ) StyledWriter::writeCommentBeforeValue( const Value &root )
{ {
if ( !root.hasComment( commentBefore ) ) if ( !root.hasComment( commentBefore ) )
return; return;
document_ += normalizeEOL( root.getComment( commentBefore ) ); document_ += normalizeEOL( root.getComment( commentBefore ) );
document_ += "\n"; document_ += "\n";
} }
void void
StyledWriter::writeCommentAfterValueOnSameLine( const Value &root ) StyledWriter::writeCommentAfterValueOnSameLine( const Value &root )
{ {
if ( root.hasComment( commentAfterOnSameLine ) ) if ( root.hasComment( commentAfterOnSameLine ) )
document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) ); document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
if ( root.hasComment( commentAfter ) ) if ( root.hasComment( commentAfter ) )
{ {
document_ += "\n"; document_ += "\n";
document_ += normalizeEOL( root.getComment( commentAfter ) ); document_ += normalizeEOL( root.getComment( commentAfter ) );
document_ += "\n"; document_ += "\n";
} }
} }
bool bool
StyledWriter::hasCommentForValue( const Value &value ) StyledWriter::hasCommentForValue( const Value &value )
{ {
return value.hasComment( commentBefore ) return value.hasComment( commentBefore )
|| value.hasComment( commentAfterOnSameLine ) || value.hasComment( commentAfterOnSameLine )
|| value.hasComment( commentAfter ); || value.hasComment( commentAfter );
} }
std::string std::string
StyledWriter::normalizeEOL( const std::string &text ) StyledWriter::normalizeEOL( const std::string &text )
{ {
std::string normalized; std::string normalized;
normalized.reserve( text.length() ); normalized.reserve( text.length() );
const char *begin = text.c_str(); const char *begin = text.c_str();
const char *end = begin + text.length(); const char *end = begin + text.length();
const char *current = begin; const char *current = begin;
while ( current != end ) while ( current != end )
{ {
char c = *current++; char c = *current++;
if ( c == '\r' ) // mac or dos EOL if ( c == '\r' ) // mac or dos EOL
{ {
if ( *current == '\n' ) // convert dos EOL if ( *current == '\n' ) // convert dos EOL
++current; ++current;
normalized += '\n'; normalized += '\n';
} }
else // handle unix EOL & other char else // handle unix EOL & other char
normalized += c; normalized += c;
} }
return normalized; return normalized;
} }
std::ostream& operator<<( std::ostream &sout, const Value &root ) std::ostream& operator<<( std::ostream &sout, const Value &root )
{ {
Json::StyledWriter writer; Json::StyledWriter writer;
sout << writer.write(root); sout << writer.write(root);
return sout; return sout;
} }
} // namespace Json } // namespace Json

View File

@ -1,211 +1,211 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="7.10" Version="7.10"
Name="lib_json" Name="lib_json"
ProjectGUID="{B84F7231-16CE-41D8-8C08-7B523FF4225B}" ProjectGUID="{B84F7231-16CE-41D8-8C08-7B523FF4225B}"
Keyword="Win32Proj"> Keyword="Win32Proj">
<Platforms> <Platforms>
<Platform <Platform
Name="Win32"/> Name="Win32"/>
</Platforms> </Platforms>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="../../build/vs71/debug/lib_json" OutputDirectory="../../build/vs71/debug/lib_json"
IntermediateDirectory="../../build/vs71/debug/lib_json" IntermediateDirectory="../../build/vs71/debug/lib_json"
ConfigurationType="4" ConfigurationType="4"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="../../include" AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB" PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
StringPooling="TRUE" StringPooling="TRUE"
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="TRUE"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="TRUE"
ForceConformanceInForLoopScope="FALSE" ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE" RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/> DebugInformationFormat="4"/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
OutputFile="$(OutDir)/json_vc71_libmtd.lib"/> OutputFile="$(OutDir)/json_vc71_libmtd.lib"/>
<Tool <Tool
Name="VCMIDLTool"/> Name="VCMIDLTool"/>
<Tool <Tool
Name="VCPostBuildEventTool"/> Name="VCPostBuildEventTool"/>
<Tool <Tool
Name="VCPreBuildEventTool"/> Name="VCPreBuildEventTool"/>
<Tool <Tool
Name="VCPreLinkEventTool"/> Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool"/> Name="VCResourceCompilerTool"/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCWebServiceProxyGeneratorTool"/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCXMLDataGeneratorTool"/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCManagedWrapperGeneratorTool"/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
OutputDirectory="../../build/vs71/release/lib_json" OutputDirectory="../../build/vs71/release/lib_json"
IntermediateDirectory="../../build/vs71/release/lib_json" IntermediateDirectory="../../build/vs71/release/lib_json"
ConfigurationType="4" ConfigurationType="4"
CharacterSet="2" CharacterSet="2"
WholeProgramOptimization="TRUE"> WholeProgramOptimization="TRUE">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
GlobalOptimizations="TRUE" GlobalOptimizations="TRUE"
EnableIntrinsicFunctions="TRUE" EnableIntrinsicFunctions="TRUE"
AdditionalIncludeDirectories="../../include" AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB" PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="TRUE"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="TRUE"
ForceConformanceInForLoopScope="FALSE" ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE" RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
AssemblerOutput="4" AssemblerOutput="4"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/> DebugInformationFormat="3"/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
OutputFile="$(OutDir)/json_vc71_libmt.lib"/> OutputFile="$(OutDir)/json_vc71_libmt.lib"/>
<Tool <Tool
Name="VCMIDLTool"/> Name="VCMIDLTool"/>
<Tool <Tool
Name="VCPostBuildEventTool"/> Name="VCPostBuildEventTool"/>
<Tool <Tool
Name="VCPreBuildEventTool"/> Name="VCPreBuildEventTool"/>
<Tool <Tool
Name="VCPreLinkEventTool"/> Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool"/> Name="VCResourceCompilerTool"/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCWebServiceProxyGeneratorTool"/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCXMLDataGeneratorTool"/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCManagedWrapperGeneratorTool"/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
<Configuration <Configuration
Name="dummy|Win32" Name="dummy|Win32"
OutputDirectory="$(ConfigurationName)" OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2" ConfigurationType="2"
CharacterSet="2" CharacterSet="2"
WholeProgramOptimization="TRUE"> WholeProgramOptimization="TRUE">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
GlobalOptimizations="TRUE" GlobalOptimizations="TRUE"
EnableIntrinsicFunctions="TRUE" EnableIntrinsicFunctions="TRUE"
AdditionalIncludeDirectories="../../include" AdditionalIncludeDirectories="../../include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB" PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="4" RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="TRUE"
DisableLanguageExtensions="TRUE" DisableLanguageExtensions="TRUE"
ForceConformanceInForLoopScope="FALSE" ForceConformanceInForLoopScope="FALSE"
RuntimeTypeInfo="TRUE" RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
AssemblerOutput="4" AssemblerOutput="4"
WarningLevel="3" WarningLevel="3"
Detect64BitPortabilityProblems="TRUE" Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/> DebugInformationFormat="3"/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
SubSystem="2" SubSystem="2"
OptimizeReferences="2" OptimizeReferences="2"
EnableCOMDATFolding="2" EnableCOMDATFolding="2"
TargetMachine="1"/> TargetMachine="1"/>
<Tool <Tool
Name="VCMIDLTool"/> Name="VCMIDLTool"/>
<Tool <Tool
Name="VCPostBuildEventTool"/> Name="VCPostBuildEventTool"/>
<Tool <Tool
Name="VCPreBuildEventTool"/> Name="VCPreBuildEventTool"/>
<Tool <Tool
Name="VCPreLinkEventTool"/> Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool"/> Name="VCResourceCompilerTool"/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCWebServiceProxyGeneratorTool"/>
<Tool <Tool
Name="VCXMLDataGeneratorTool"/> Name="VCXMLDataGeneratorTool"/>
<Tool <Tool
Name="VCWebDeploymentTool"/> Name="VCWebDeploymentTool"/>
<Tool <Tool
Name="VCManagedWrapperGeneratorTool"/> Name="VCManagedWrapperGeneratorTool"/>
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
</Configurations> </Configurations>
<References> <References>
</References> </References>
<Files> <Files>
<File <File
RelativePath="..\..\include\json\autolink.h"> RelativePath="..\..\include\json\autolink.h">
</File> </File>
<File <File
RelativePath="..\..\include\json\config.h"> RelativePath="..\..\include\json\config.h">
</File> </File>
<File <File
RelativePath="..\..\include\json\forwards.h"> RelativePath="..\..\include\json\forwards.h">
</File> </File>
<File <File
RelativePath="..\..\include\json\json.h"> RelativePath="..\..\include\json\json.h">
</File> </File>
<File <File
RelativePath=".\json_batchallocator.h"> RelativePath=".\json_batchallocator.h">
</File> </File>
<File <File
RelativePath=".\json_internalarray.inl"> RelativePath=".\json_internalarray.inl">
</File> </File>
<File <File
RelativePath=".\json_internalmap.inl"> RelativePath=".\json_internalmap.inl">
</File> </File>
<File <File
RelativePath=".\json_reader.cpp"> RelativePath=".\json_reader.cpp">
</File> </File>
<File <File
RelativePath=".\json_value.cpp"> RelativePath=".\json_value.cpp">
</File> </File>
<File <File
RelativePath=".\json_valueiterator.inl"> RelativePath=".\json_valueiterator.inl">
</File> </File>
<File <File
RelativePath=".\json_writer.cpp"> RelativePath=".\json_writer.cpp">
</File> </File>
<File <File
RelativePath="..\..\include\json\reader.h"> RelativePath="..\..\include\json\reader.h">
</File> </File>
<File <File
RelativePath="..\..\include\json\value.h"> RelativePath="..\..\include\json\value.h">
</File> </File>
<File <File
RelativePath="..\..\include\json\writer.h"> RelativePath="..\..\include\json\writer.h">
</File> </File>
</Files> </Files>
<Globals> <Globals>
</Globals> </Globals>
</VisualStudioProject> </VisualStudioProject>

View File

@ -1,8 +1,8 @@
Import( 'env buildLibrary' ) Import( 'env buildLibrary' )
buildLibrary( env, Split( """ buildLibrary( env, Split( """
json_reader.cpp json_reader.cpp
json_value.cpp json_value.cpp
json_writer.cpp json_writer.cpp
""" ), """ ),
'json' ) 'json' )