diff options
Diffstat (limited to 'src/core/SkWriter32.cpp')
-rw-r--r-- | src/core/SkWriter32.cpp | 101 |
1 files changed, 84 insertions, 17 deletions
diff --git a/src/core/SkWriter32.cpp b/src/core/SkWriter32.cpp index 636af360c4..a94a92fd88 100644 --- a/src/core/SkWriter32.cpp +++ b/src/core/SkWriter32.cpp @@ -9,40 +9,40 @@ struct SkWriter32::Block { Block* fNext; - size_t fSize; // total space allocated (after this) - size_t fAllocated; // space used so far + size_t fSizeOfBlock; // total space allocated (after this) + size_t fAllocatedSoFar; // space used so far - size_t available() const { return fSize - fAllocated; } + size_t available() const { return fSizeOfBlock - fAllocatedSoFar; } char* base() { return (char*)(this + 1); } const char* base() const { return (const char*)(this + 1); } uint32_t* alloc(size_t size) { SkASSERT(SkAlign4(size) == size); SkASSERT(this->available() >= size); - void* ptr = this->base() + fAllocated; - fAllocated += size; - SkASSERT(fAllocated <= fSize); + void* ptr = this->base() + fAllocatedSoFar; + fAllocatedSoFar += size; + SkASSERT(fAllocatedSoFar <= fSizeOfBlock); return (uint32_t*)ptr; } uint32_t* peek32(size_t offset) { - SkASSERT(offset <= fAllocated + 4); + SkASSERT(offset <= fAllocatedSoFar + 4); void* ptr = this->base() + offset; return (uint32_t*)ptr; } void rewind() { fNext = NULL; - fAllocated = 0; - // keep fSize as is + fAllocatedSoFar = 0; + // keep fSizeOfBlock as is } static Block* Create(size_t size) { SkASSERT(SkAlign4(size) == size); Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); block->fNext = NULL; - block->fSize = size; - block->fAllocated = 0; + block->fSizeOfBlock = size; + block->fAllocatedSoFar = 0; return block; } @@ -50,8 +50,8 @@ struct SkWriter32::Block { SkASSERT(SkIsAlign4((intptr_t)storage)); Block* block = (Block*)storage; block->fNext = NULL; - block->fSize = size - sizeof(Block); - block->fAllocated = 0; + block->fSizeOfBlock = size - sizeof(Block); + block->fAllocatedSoFar = 0; return block; } @@ -140,6 +140,8 @@ uint32_t* SkWriter32::reserve(size_t size) { } uint32_t* SkWriter32::peek32(size_t offset) { + SkDEBUGCODE(this->validate();) + SkASSERT(SkAlign4(offset) == offset); SkASSERT(offset <= fSize); @@ -150,14 +152,55 @@ uint32_t* SkWriter32::peek32(size_t offset) { Block* block = fHead; SkASSERT(NULL != block); - while (offset >= block->fAllocated) { - offset -= block->fAllocated; + while (offset >= block->fAllocatedSoFar) { + offset -= block->fAllocatedSoFar; block = block->fNext; SkASSERT(NULL != block); } return block->peek32(offset); } +void SkWriter32::rewindToOffset(size_t offset) { + if (0 == offset) { + this->reset(NULL, 0); + return; + } + + SkDEBUGCODE(this->validate();) + + SkASSERT(SkAlign4(offset) == offset); + SkASSERT(offset <= fSize); + fSize = offset; + + if (fSingleBlock) { + return; + } + + // Similar to peek32, except that we free up any following blocks + Block* block = fHead; + SkASSERT(NULL != block); + + while (offset >= block->fAllocatedSoFar) { + offset -= block->fAllocatedSoFar; + block = block->fNext; + SkASSERT(NULL != block); + } + + fTail = block; + block->fAllocatedSoFar = offset; + + // free up any following blocks + SkASSERT(block); + block = block->fNext; + while (block) { + Block* next = block->fNext; + sk_free(block); + block = next; + } + + SkDEBUGCODE(this->validate();) +} + void SkWriter32::flatten(void* dst) const { if (fSingleBlock) { memcpy(dst, fSingleBlock, fSize); @@ -168,7 +211,7 @@ void SkWriter32::flatten(void* dst) const { SkDEBUGCODE(size_t total = 0;) while (block) { - size_t allocated = block->fAllocated; + size_t allocated = block->fAllocatedSoFar; memcpy(dst, block->base(), allocated); dst = (char*)dst + allocated; block = block->fNext; @@ -232,7 +275,7 @@ bool SkWriter32::writeToStream(SkWStream* stream) { const Block* block = fHead; while (block) { - if (!stream->write(block->base(), block->fAllocated)) { + if (!stream->write(block->base(), block->fAllocatedSoFar)) { return false; } block = block->fNext; @@ -240,6 +283,30 @@ bool SkWriter32::writeToStream(SkWStream* stream) { return true; } +#ifdef SK_DEBUG +void SkWriter32::validate() const { + SkASSERT(SkIsAlign4(fSize)); + SkASSERT(SkIsAlign4(fSingleBlockSize)); + + if (fSingleBlock) { + SkASSERT(fSize <= fSingleBlockSize); + return; + } + + size_t accum = 0; + const Block* block = fHead; + while (block) { + SkASSERT(SkIsAlign4(block->fSizeOfBlock)); + SkASSERT(SkIsAlign4(block->fAllocatedSoFar)); + SkASSERT(block->fAllocatedSoFar <= block->fSizeOfBlock); + accum += block->fAllocatedSoFar; + SkASSERT(accum <= fSize); + block = block->fNext; + } + SkASSERT(accum == fSize); +} +#endif + /////////////////////////////////////////////////////////////////////////////// #include "SkReader32.h" |