10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkWriter32.h"
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstruct SkWriter32::Block {
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Block*  fNext;
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t  fSize;
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t  fAllocated;
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t  available() const { return fSize - fAllocated; }
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char*   base() { return (char*)(this + 1); }
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* base() const { return (const char*)(this + 1); }
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    uint32_t* alloc(size_t size) {
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkAlign4(size) == size);
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(this->available() >= size);
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void* ptr = this->base() + fAllocated;
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fAllocated += size;
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fAllocated <= fSize);
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return (uint32_t*)ptr;
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    uint32_t* peek32(size_t offset) {
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(offset <= fAllocated + 4);
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void* ptr = this->base() + offset;
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return (uint32_t*)ptr;
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    static Block* Create(size_t size) {
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(SkAlign4(size) == size);
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block->fNext = NULL;
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block->fSize = size;
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block->fAllocated = 0;
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return block;
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkWriter32::~SkWriter32() {
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->reset();
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkWriter32::reset() {
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Block* block = fHead;
4535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    while (block) {
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Block* next = block->fNext;
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_free(block);
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block = next;
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fSize = 0;
5235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    fHead = fTail = NULL;
5335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    fSingleBlock = NULL;
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkWriter32::reset(void* block, size_t size) {
5735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    this->reset();
5835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkASSERT(0 == ((fSingleBlock - (char*)0) & 3));   // need 4-byte alignment
5935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    fSingleBlock = (char*)block;
6035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    fSingleBlockSize = (size & ~3);
6135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger}
6235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
6335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergeruint32_t* SkWriter32::reserve(size_t size) {
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(SkAlign4(size) == size);
6535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
6635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (fSingleBlock) {
6735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        uint32_t* ptr = (uint32_t*)(fSingleBlock + fSize);
6835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fSize += size;
6935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkASSERT(fSize <= fSingleBlockSize);
7035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return ptr;
7135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
7235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Block* block = fTail;
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (NULL == block) {
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(NULL == fHead);
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fHead = fTail = block = Block::Create(SkMax32(size, fMinSize));
7835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    } else if (block->available() < size) {
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTail = Block::Create(SkMax32(size, fMinSize));
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block->fNext = fTail;
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block = fTail;
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fSize += size;
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return block->alloc(size);
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergeruint32_t* SkWriter32::peek32(size_t offset) {
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(SkAlign4(offset) == offset);
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(offset <= fSize);
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (fSingleBlock) {
9435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return (uint32_t*)(fSingleBlock + offset);
9535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
9635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Block* block = fHead;
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(NULL != block);
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    while (offset >= block->fAllocated) {
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        offset -= block->fAllocated;
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block = block->fNext;
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(NULL != block);
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return block->peek32(offset);
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergervoid SkWriter32::flatten(void* dst) const {
10935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (fSingleBlock) {
11035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        memcpy(dst, fSingleBlock, fSize);
11135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return;
11235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
11335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const Block* block = fHead;
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(size_t total = 0;)
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    while (block) {
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        size_t allocated = block->fAllocated;
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(dst, block->base(), allocated);
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst = (char*)dst + allocated;
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block = block->fNext;
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDEBUGCODE(total += allocated;)
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(total <= fSize);
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(total == fSize);
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkWriter32::writePad(const void* src, size_t size) {
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t alignedSize = SkAlign4(size);
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char* dst = (char*)this->reserve(alignedSize);
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(dst, src, size);
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    dst += size;
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int n = alignedSize - size;
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (--n >= 0) {
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst++ = 0;
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h"
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkWriter32::readFromStream(SkStream* stream, size_t length) {
14335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (fSingleBlock) {
14435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkASSERT(fSingleBlockSize >= fSize);
14535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        size_t remaining = fSingleBlockSize - fSize;
14635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (length > remaining) {
14735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            length = remaining;
14835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
14935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        stream->read(fSingleBlock + fSize, length);
15035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        fSize += length;
15135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return length;
15235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
15335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char scratch[1024];
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const size_t MAX = sizeof(scratch);
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t remaining = length;
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (remaining != 0) {
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        size_t n = remaining;
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (n > MAX) {
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            n = MAX;
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        size_t bytes = stream->read(scratch, n);
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->writePad(scratch, bytes);
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        remaining -= bytes;
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (bytes != n) {
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return length - remaining;
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkWriter32::writeToStream(SkWStream* stream) {
17435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (fSingleBlock) {
17535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        return stream->write(fSingleBlock, fSize);
17635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
17735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const Block* block = fHead;
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (block) {
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (!stream->write(block->base(), block->fAllocated)) {
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        block = block->fNext;
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkReader32.h"
1910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerconst char* SkReader32::readString(size_t* outLen) {
1930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // we need to read at least 1-4 bytes
1940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkASSERT(this->isAvailable(4));
1950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    const uint8_t* base = (const uint8_t*)this->peek();
1960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    const uint8_t* ptr = base;
1970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t len = *ptr++;
1990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (0xFF == len) {
2000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        len = (ptr[0] << 8) | ptr[1];
2010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        ptr += 2;
2020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkASSERT(len < 0xFFFF);
2030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // skip what we've read, and 0..3 pad bytes
2060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // add 1 for the terminating 0 that writeString() included
2070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t alignedSize = SkAlign4(len + (ptr - base) + 1);
2080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    this->skip(alignedSize);
2090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (outLen) {
2110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *outLen = len;
2120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return (const char*)ptr;
2140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergervoid SkWriter32::writeString(const char str[], size_t len) {
2170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if ((long)len < 0) {
2180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkASSERT(str);
2190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        len = strlen(str);
2200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t lenBytes = 1;
2220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (len >= 0xFF) {
2230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        lenBytes = 3;
2240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkASSERT(len < 0xFFFF);
2250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // add 1 since we also write a terminating 0
2270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t alignedLen = SkAlign4(lenBytes + len + 1);
2280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    uint8_t* ptr = (uint8_t*)this->reserve(alignedLen);
2290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (1 == lenBytes) {
2300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = SkToU8(len);
2310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    } else {
2320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = 0xFF;
2330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = SkToU8(len >> 8);
2340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *ptr++ = len & 0xFF;
2350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    memcpy(ptr, str, len);
2370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    ptr[len] = 0;
2380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // we may have left 0,1,2,3 bytes uninitialized, since we reserved align4
2390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // number of bytes. That's ok, since the reader will know to skip those
2400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergersize_t SkWriter32::WriteStringSize(const char* str, size_t len) {
2430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if ((long)len < 0) {
2440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkASSERT(str);
2450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        len = strlen(str);
2460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    size_t lenBytes = 1;
2480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (len >= 0xFF) {
2490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        lenBytes = 3;
2500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkASSERT(len < 0xFFFF);
2510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // add 1 since we also write a terminating 0
2530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    return SkAlign4(lenBytes + len + 1);
2540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
2550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
257