180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkWriter32.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkWriter32::SkWriter32(size_t minSize, void* storage, size_t storageSize) { 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMinSize = minSize; 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSize = 0; 13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fWrittenBeforeLastBlock = 0; 14d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fHead = fTail = NULL; 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (storageSize) { 17d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->reset(storage, storageSize); 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkWriter32::~SkWriter32() { 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(); 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkWriter32::reset() { 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Block* block = fHead; 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (this->isHeadExternallyAllocated()) { 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(block); 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // don't 'free' the first block, since it is owned by the caller 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = block->fNext; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (block) { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Block* next = block->fNext; 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(block); 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = next; 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSize = 0; 40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fWrittenBeforeLastBlock = 0; 41d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fHead = fTail = NULL; 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkWriter32::reset(void* storage, size_t storageSize) { 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(); 46d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 47d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger storageSize &= ~3; // trunc down to multiple of 4 48d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (storageSize > 0 && SkIsAlign4((intptr_t)storage)) { 49d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fHead = fTail = fExternalBlock.initFromStorage(storage, storageSize); 50d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerSkWriter32::Block* SkWriter32::doReserve(size_t size) { 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkAlign4(size) == size); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Block* block = fTail; 57d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkASSERT(NULL == block || block->available() < size); 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == block) { 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL == fHead); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHead = fTail = block = Block::Create(SkMax32(size, fMinSize)); 62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(0 == fWrittenBeforeLastBlock); 63d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { 64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(fSize > 0); 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fWrittenBeforeLastBlock = fSize; 66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTail = Block::Create(SkMax32(size, fMinSize)); 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block->fNext = fTail; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = fTail; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 71d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return block; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint32_t* SkWriter32::peek32(size_t offset) { 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(this->validate();) 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkAlign4(offset) == offset); 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(offset <= fSize); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // try the fast case, where offset is within fTail 81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (offset >= fWrittenBeforeLastBlock) { 82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fTail->peek32(offset - fWrittenBeforeLastBlock); 83363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 84363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Block* block = fHead; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != block); 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (offset >= block->fAllocatedSoFar) { 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru offset -= block->fAllocatedSoFar; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = block->fNext; 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != block); 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return block->peek32(offset); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkWriter32::rewindToOffset(size_t offset) { 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (offset >= fSize) { 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == offset) { 101d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->reset(); 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(this->validate();) 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkAlign4(offset) == offset); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(offset <= fSize); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSize = offset; 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Try the fast case, where offset is within fTail 112363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (offset >= fWrittenBeforeLastBlock) { 113363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fTail->fAllocatedSoFar = offset - fWrittenBeforeLastBlock; 114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Similar to peek32, except that we free up any following blocks. 116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // We have to re-compute fWrittenBeforeLastBlock as well. 117363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 118363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger size_t globalOffset = offset; 119363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Block* block = fHead; 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != block); 121363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger while (offset >= block->fAllocatedSoFar) { 122363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger offset -= block->fAllocatedSoFar; 123363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger block = block->fNext; 124363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(NULL != block); 125363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // this has to be recomputed, since we may free up fTail 128363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fWrittenBeforeLastBlock = globalOffset - offset; 129363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 130363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // update the size on the "last" block 131363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger block->fAllocatedSoFar = offset; 132363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // end our list 133363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fTail = block; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Block* next = block->fNext; 135363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger block->fNext = NULL; 136363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // free up any trailing blocks 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = next; 138363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger while (block) { 139363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Block* next = block->fNext; 140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sk_free(block); 141363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger block = next; 142363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(this->validate();) 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkWriter32::flatten(void* dst) const { 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Block* block = fHead; 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(size_t total = 0;) 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (block) { 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t allocated = block->fAllocatedSoFar; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(dst, block->base(), allocated); 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst = (char*)dst + allocated; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = block->fNext; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(total += allocated;) 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(total <= fSize); 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(total == fSize); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint32_t* SkWriter32::reservePad(size_t size) { 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (size > 0) { 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t alignedSize = SkAlign4(size); 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* dst = (char*)this->reserve(alignedSize); 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Pad the last four bytes with zeroes in one step. 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t* padding = (uint32_t*)(dst + (alignedSize - 4)); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *padding = 0; 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (uint32_t*) dst; 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->reserve(0); 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkWriter32::writePad(const void* src, size_t size) { 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (size > 0) { 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* dst = (char*)this->reservePad(size); 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Copy the actual data. 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(dst, src, size); 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h" 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t SkWriter32::readFromStream(SkStream* stream, size_t length) { 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char scratch[1024]; 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const size_t MAX = sizeof(scratch); 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t remaining = length; 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (remaining != 0) { 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t n = remaining; 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (n > MAX) { 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = MAX; 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t bytes = stream->read(scratch, n); 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->writePad(scratch, bytes); 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru remaining -= bytes; 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bytes != n) { 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return length - remaining; 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkWriter32::writeToStream(SkWStream* stream) { 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Block* block = fHead; 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (block) { 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!stream->write(block->base(), block->fAllocatedSoFar)) { 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = block->fNext; 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkWriter32::validate() const { 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkIsAlign4(fSize)); 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t accum = 0; 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Block* block = fHead; 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (block) { 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkIsAlign4(block->fSizeOfBlock)); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SkIsAlign4(block->fAllocatedSoFar)); 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(block->fAllocatedSoFar <= block->fSizeOfBlock); 226363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL == block->fNext) { 227363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(fTail == block); 228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(fWrittenBeforeLastBlock == accum); 229363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru accum += block->fAllocatedSoFar; 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(accum <= fSize); 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru block = block->fNext; 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(accum == fSize); 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkReader32.h" 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkString.h" 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkReader32::readString(size_t* outLen) { 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len = this->readInt(); 249e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (0xFFFF == len) { 250e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (outLen) { 251e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger *outLen = 0; 252e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 253e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return NULL; 254e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const void* ptr = this->peek(); 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // skip over teh string + '\0' and then pad to a multiple of 4 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t alignedSize = SkAlign4(len + 1); 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->skip(alignedSize); 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (outLen) { 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *outLen = len; 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (const char*)ptr; 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t SkReader32::readIntoString(SkString* copy) { 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len; 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* ptr = this->readString(&len); 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (copy) { 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru copy->set(ptr, len); 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return len; 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkWriter32::writeString(const char str[], size_t len) { 277e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (NULL == str) { 278e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger // We're already requiring len < 0xFFFF, so we can use that to mark NULL. 279e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger this->write32(0xFFFF); 280e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return; 281e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((long)len < 0) { 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru len = strlen(str); 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->write32(len); 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // add 1 since we also write a terminating 0 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t alignedLen = SkAlign4(len + 1); 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* ptr = (char*)this->reserve(alignedLen); 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Write the terminating 0 and fill in the rest with zeroes 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t* padding = (uint32_t*)(ptr + (alignedLen - 4)); 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *padding = 0; 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Copy the string itself. 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(ptr, str, len); 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t SkWriter32::WriteStringSize(const char* str, size_t len) { 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((long)len < 0) { 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(str); 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru len = strlen(str); 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const size_t lenBytes = 4; // we use 4 bytes to record the length 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // add 1 since we also write a terminating 0 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkAlign4(lenBytes + len + 1); 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 307