php 处理jsonpp,json_internalarray.inl

// included by json_value.cpp

// everything is within Json namespace

// //

// //

// //

// class ValueInternalArray

// //

// //

// //

ValueArrayAllocator::~ValueArrayAllocator()

{

}

// //

// class DefaultValueArrayAllocator

// //

#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR

class DefaultValueArrayAllocator : public ValueArrayAllocator

{

public: // overridden from ValueArrayAllocator

virtual ~DefaultValueArrayAllocator()

{

}

virtual ValueInternalArray *newArray()

{

return new ValueInternalArray();

}

virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )

{

return new ValueInternalArray( other );

}

virtual void destructArray( ValueInternalArray *array )

{

delete array;

}

virtual void reallocateArrayPageIndex( Value **&indexes,

ValueInternalArray::PageIndex &indexCount,

ValueInternalArray::PageIndex minNewIndexCount )

{

ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;

if ( minNewIndexCount > newIndexCount )

newIndexCount = minNewIndexCount;

void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );

if ( !newIndexes )

throw std::bad_alloc();

indexCount = newIndexCount;

indexes = static_cast( newIndexes );

}

virtual void releaseArrayPageIndex( Value **indexes,

ValueInternalArray::PageIndex indexCount )

{

if ( indexes )

free( indexes );

}

virtual Value *allocateArrayPage()

{

return static_cast( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );

}

virtual void releaseArrayPage( Value *value )

{

if ( value )

free( value );

}

};

#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR

/// @todo make this thread-safe (lock when accessign batch allocator)

class DefaultValueArrayAllocator : public ValueArrayAllocator

{

public: // overridden from ValueArrayAllocator

virtual ~DefaultValueArrayAllocator()

{

}

virtual ValueInternalArray *newArray()

{

ValueInternalArray *array = arraysAllocator_.allocate();

new (array) ValueInternalArray(); // placement new

return array;

}

virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )

{

ValueInternalArray *array = arraysAllocator_.allocate();

new (array) ValueInternalArray( other ); // placement new

return array;

}

virtual void destructArray( ValueInternalArray *array )

{

if ( array )

{

array->~ValueInternalArray();

arraysAllocator_.release( array );

}

}

virtual void reallocateArrayPageIndex( Value **&indexes,

ValueInternalArray::PageIndex &indexCount,

ValueInternalArray::PageIndex minNewIndexCount )

{

ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;

if ( minNewIndexCount > newIndexCount )

newIndexCount = minNewIndexCount;

void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );

if ( !newIndexes )

throw std::bad_alloc();

indexCount = newIndexCount;

indexes = static_cast( newIndexes );

}

virtual void releaseArrayPageIndex( Value **indexes,

ValueInternalArray::PageIndex indexCount )

{

if ( indexes )

free( indexes );

}

virtual Value *allocateArrayPage()

{

return static_cast( pagesAllocator_.allocate() );

}

virtual void releaseArrayPage( Value *value )

{

if ( value )

pagesAllocator_.release( value );

}

private:

BatchAllocator arraysAllocator_;

BatchAllocator pagesAllocator_;

};

#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR

static ValueArrayAllocator *&arrayAllocator()

{

static DefaultValueArrayAllocator defaultAllocator;

static ValueArrayAllocator *arrayAllocator = &defaultAllocator;

return arrayAllocator;

}

static struct DummyArrayAllocatorInitializer {

DummyArrayAllocatorInitializer()

{

arrayAllocator(); // ensure arrayAllocator() statics are initialized before main().

}

} dummyArrayAllocatorInitializer;

// //

// class ValueInternalArray

// //

bool

ValueInternalArray::equals( const IteratorState &x,

const IteratorState &other )

{

return x.array_ == other.array_

&& x.currentItemIndex_ == other.currentItemIndex_

&& x.currentPageIndex_ == other.currentPageIndex_;

}

void

ValueInternalArray::increment( IteratorState &it )

{

JSON_ASSERT_MESSAGE( it.array_ &&

(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_

!= it.array_->size_,

"ValueInternalArray::increment(): moving iterator beyond end" );

++(it.currentItemIndex_);

if ( it.currentItemIndex_ == itemsPerPage )

{

it.currentItemIndex_ = 0;

++(it.currentPageIndex_);

}

}

void

ValueInternalArray::decrement( IteratorState &it )

{

JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_

&& it.currentItemIndex_ == 0,

"ValueInternalArray::decrement(): moving iterator beyond end" );

if ( it.currentItemIndex_ == 0 )

{

it.currentItemIndex_ = itemsPerPage-1;

--(it.currentPageIndex_);

}

else

{

--(it.currentItemIndex_);

}

}

Value &

ValueInternalArray::unsafeDereference( const IteratorState &it )

{

return (*(it.currentPageIndex_))[it.currentItemIndex_];

}

Value &

ValueInternalArray::dereference( const IteratorState &it )

{

JSON_ASSERT_MESSAGE( it.array_ &&

(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_

< it.array_->size_,

"ValueInternalArray::dereference(): dereferencing invalid iterator" );

return unsafeDereference( it );

}

void

ValueInternalArray::makeBeginIterator( IteratorState &it ) const

{

it.array_ = const_cast( this );

it.currentItemIndex_ = 0;

it.currentPageIndex_ = pages_;

}

void

ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const

{

it.array_ = const_cast( this );

it.currentItemIndex_ = index % itemsPerPage;

it.currentPageIndex_ = pages_ + index / itemsPerPage;

}

void

ValueInternalArray::makeEndIterator( IteratorState &it ) const

{

makeIterator( it, size_ );

}

ValueInternalArray::ValueInternalArray()

: pages_( 0 )

, size_( 0 )

, pageCount_( 0 )

{

}

ValueInternalArray::ValueInternalArray( const ValueInternalArray &other )

: pages_( 0 )

, pageCount_( 0 )

, size_( other.size_ )

{

PageIndex minNewPages = other.size_ / itemsPerPage;

arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );

JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,

"ValueInternalArray::reserve(): bad reallocation" );

IteratorState itOther;

other.makeBeginIterator( itOther );

Value *value;

for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) )

{

if ( index % itemsPerPage == 0 )

{

PageIndex pageIndex = index / itemsPerPage;

value = arrayAllocator()->allocateArrayPage();

pages_[pageIndex] = value;

}

new (value) Value( dereference( itOther ) );

}

}

ValueInternalArray &

ValueInternalArray::operator =( const ValueInternalArray &other )

{

ValueInternalArray temp( other );

swap( temp );

return *this;

}

ValueInternalArray::~ValueInternalArray()

{

// destroy all constructed items

IteratorState it;

IteratorState itEnd;

makeBeginIterator( it);

makeEndIterator( itEnd );

for ( ; !equals(it,itEnd); increment(it) )

{

Value *value = &dereference(it);

value->~Value();

}

// release all pages

PageIndex lastPageIndex = size_ / itemsPerPage;

for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex )

arrayAllocator()->releaseArrayPage( pages_[pageIndex] );

// release pages index

arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ );

}

void

ValueInternalArray::swap( ValueInternalArray &other )

{

Value **tempPages = pages_;

pages_ = other.pages_;

other.pages_ = tempPages;

ArrayIndex tempSize = size_;

size_ = other.size_;

other.size_ = tempSize;

PageIndex tempPageCount = pageCount_;

pageCount_ = other.pageCount_;

other.pageCount_ = tempPageCount;

}

void

ValueInternalArray::clear()

{

ValueInternalArray dummy;

swap( dummy );

}

void

ValueInternalArray::resize( ArrayIndex newSize )

{

if ( newSize == 0 )

clear();

else if ( newSize < size_ )

{

IteratorState it;

IteratorState itEnd;

makeIterator( it, newSize );

makeIterator( itEnd, size_ );

for ( ; !equals(it,itEnd); increment(it) )

{

Value *value = &dereference(it);

value->~Value();

}

PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage;

PageIndex lastPageIndex = size_ / itemsPerPage;

for ( ; pageIndex < lastPageIndex; ++pageIndex )

arrayAllocator()->releaseArrayPage( pages_[pageIndex] );

size_ = newSize;

}

else if ( newSize > size_ )

resolveReference( newSize );

}

void

ValueInternalArray::makeIndexValid( ArrayIndex index )

{

// Need to enlarge page index ?

if ( index >= pageCount_ * itemsPerPage )

{

PageIndex minNewPages = (index + 1) / itemsPerPage;

arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );

JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" );

}

// Need to allocate new pages ?

ArrayIndex nextPageIndex =

(size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage

: size_;

if ( nextPageIndex <= index )

{

PageIndex pageIndex = nextPageIndex / itemsPerPage;

PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;

for ( ; pageToAllocate-- > 0; ++pageIndex )

pages_[pageIndex] = arrayAllocator()->allocateArrayPage();

}

// Initialize all new entries

IteratorState it;

IteratorState itEnd;

makeIterator( it, size_ );

size_ = index + 1;

makeIterator( itEnd, size_ );

for ( ; !equals(it,itEnd); increment(it) )

{

Value *value = &dereference(it);

new (value) Value(); // Construct a default value using placement new

}

}

Value &

ValueInternalArray::resolveReference( ArrayIndex index )

{

if ( index >= size_ )

makeIndexValid( index );

return pages_[index/itemsPerPage][index%itemsPerPage];

}

Value *

ValueInternalArray::find( ArrayIndex index ) const

{

if ( index >= size_ )

return 0;

return &(pages_[index/itemsPerPage][index%itemsPerPage]);

}

ValueInternalArray::ArrayIndex

ValueInternalArray::size() const

{

return size_;

}

int

ValueInternalArray::distance( const IteratorState &x, const IteratorState &y )

{

return indexOf(y) - indexOf(x);

}

ValueInternalArray::ArrayIndex

ValueInternalArray::indexOf( const IteratorState &iterator )

{

if ( !iterator.array_ )

return ArrayIndex(-1);

return ArrayIndex(

(iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage

+ iterator.currentItemIndex_ );

}

int

ValueInternalArray::compare( const ValueInternalArray &other ) const

{

int sizeDiff( size_ - other.size_ );

if ( sizeDiff != 0 )

return sizeDiff;

for ( ArrayIndex index =0; index < size_; ++index )

{

int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare(

other.pages_[index/itemsPerPage][index%itemsPerPage] );

if ( diff != 0 )

return diff;

}

return 0;

}

一键复制

编辑

Web IDE

原始数据

按行查看

历史

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值