1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SkWriter32.h" 9 10struct SkWriter32::Block { 11 Block* fNext; 12 size_t fSize; 13 size_t fAllocated; 14 15 size_t available() const { return fSize - fAllocated; } 16 char* base() { return (char*)(this + 1); } 17 const char* base() const { return (const char*)(this + 1); } 18 19 uint32_t* alloc(size_t size) { 20 SkASSERT(SkAlign4(size) == size); 21 SkASSERT(this->available() >= size); 22 void* ptr = this->base() + fAllocated; 23 fAllocated += size; 24 SkASSERT(fAllocated <= fSize); 25 return (uint32_t*)ptr; 26 } 27 28 uint32_t* peek32(size_t offset) { 29 SkASSERT(offset <= fAllocated + 4); 30 void* ptr = this->base() + offset; 31 return (uint32_t*)ptr; 32 } 33 34 static Block* Create(size_t size) { 35 SkASSERT(SkAlign4(size) == size); 36 Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); 37 block->fNext = NULL; 38 block->fSize = size; 39 block->fAllocated = 0; 40 return block; 41 } 42}; 43 44/////////////////////////////////////////////////////////////////////////////// 45 46SkWriter32::~SkWriter32() { 47 this->reset(); 48} 49 50void SkWriter32::reset() { 51 Block* block = fHead; 52 while (block) { 53 Block* next = block->fNext; 54 sk_free(block); 55 block = next; 56 } 57 58 fSize = 0; 59 fHead = fTail = NULL; 60 fSingleBlock = NULL; 61} 62 63void SkWriter32::reset(void* block, size_t size) { 64 this->reset(); 65 SkASSERT(0 == ((fSingleBlock - (char*)0) & 3)); // need 4-byte alignment 66 fSingleBlock = (char*)block; 67 fSingleBlockSize = (size & ~3); 68} 69 70uint32_t* SkWriter32::reserve(size_t size) { 71 SkASSERT(SkAlign4(size) == size); 72 73 if (fSingleBlock) { 74 uint32_t* ptr = (uint32_t*)(fSingleBlock + fSize); 75 fSize += size; 76 SkASSERT(fSize <= fSingleBlockSize); 77 return ptr; 78 } 79 80 Block* block = fTail; 81 82 if (NULL == block) { 83 SkASSERT(NULL == fHead); 84 fHead = fTail = block = Block::Create(SkMax32(size, fMinSize)); 85 } else if (block->available() < size) { 86 fTail = Block::Create(SkMax32(size, fMinSize)); 87 block->fNext = fTail; 88 block = fTail; 89 } 90 91 fSize += size; 92 93 return block->alloc(size); 94} 95 96uint32_t* SkWriter32::peek32(size_t offset) { 97 SkASSERT(SkAlign4(offset) == offset); 98 SkASSERT(offset <= fSize); 99 100 if (fSingleBlock) { 101 return (uint32_t*)(fSingleBlock + offset); 102 } 103 104 Block* block = fHead; 105 SkASSERT(NULL != block); 106 107 while (offset >= block->fAllocated) { 108 offset -= block->fAllocated; 109 block = block->fNext; 110 SkASSERT(NULL != block); 111 } 112 return block->peek32(offset); 113} 114 115void SkWriter32::flatten(void* dst) const { 116 if (fSingleBlock) { 117 memcpy(dst, fSingleBlock, fSize); 118 return; 119 } 120 121 const Block* block = fHead; 122 SkDEBUGCODE(size_t total = 0;) 123 124 while (block) { 125 size_t allocated = block->fAllocated; 126 memcpy(dst, block->base(), allocated); 127 dst = (char*)dst + allocated; 128 block = block->fNext; 129 130 SkDEBUGCODE(total += allocated;) 131 SkASSERT(total <= fSize); 132 } 133 SkASSERT(total == fSize); 134} 135 136void SkWriter32::writePad(const void* src, size_t size) { 137 size_t alignedSize = SkAlign4(size); 138 char* dst = (char*)this->reserve(alignedSize); 139 memcpy(dst, src, size); 140 dst += size; 141 int n = alignedSize - size; 142 while (--n >= 0) { 143 *dst++ = 0; 144 } 145} 146 147#include "SkStream.h" 148 149size_t SkWriter32::readFromStream(SkStream* stream, size_t length) { 150 if (fSingleBlock) { 151 SkASSERT(fSingleBlockSize >= fSize); 152 size_t remaining = fSingleBlockSize - fSize; 153 if (length > remaining) { 154 length = remaining; 155 } 156 stream->read(fSingleBlock + fSize, length); 157 fSize += length; 158 return length; 159 } 160 161 char scratch[1024]; 162 const size_t MAX = sizeof(scratch); 163 size_t remaining = length; 164 165 while (remaining != 0) { 166 size_t n = remaining; 167 if (n > MAX) { 168 n = MAX; 169 } 170 size_t bytes = stream->read(scratch, n); 171 this->writePad(scratch, bytes); 172 remaining -= bytes; 173 if (bytes != n) { 174 break; 175 } 176 } 177 return length - remaining; 178} 179 180bool SkWriter32::writeToStream(SkWStream* stream) { 181 if (fSingleBlock) { 182 return stream->write(fSingleBlock, fSize); 183 } 184 185 const Block* block = fHead; 186 while (block) { 187 if (!stream->write(block->base(), block->fAllocated)) { 188 return false; 189 } 190 block = block->fNext; 191 } 192 return true; 193} 194 195/////////////////////////////////////////////////////////////////////////////// 196 197#include "SkReader32.h" 198#include "SkString.h" 199 200/* 201 * Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4 202 */ 203 204const char* SkReader32::readString(size_t* outLen) { 205 size_t len = this->readInt(); 206 const void* ptr = this->peek(); 207 208 // skip over teh string + '\0' and then pad to a multiple of 4 209 size_t alignedSize = SkAlign4(len + 1); 210 this->skip(alignedSize); 211 212 if (outLen) { 213 *outLen = len; 214 } 215 return (const char*)ptr; 216} 217 218size_t SkReader32::readIntoString(SkString* copy) { 219 size_t len; 220 const char* ptr = this->readString(&len); 221 if (copy) { 222 copy->set(ptr, len); 223 } 224 return len; 225} 226 227void SkWriter32::writeString(const char str[], size_t len) { 228 if ((long)len < 0) { 229 SkASSERT(str); 230 len = strlen(str); 231 } 232 this->write32(len); 233 // add 1 since we also write a terminating 0 234 size_t alignedLen = SkAlign4(len + 1); 235 char* ptr = (char*)this->reserve(alignedLen); 236 memcpy(ptr, str, len); 237 ptr[len] = 0; 238 // we may have left 0,1,2,3 bytes uninitialized, since we reserved align4 239 // number of bytes. That's ok, since the reader will know to skip those 240} 241 242size_t SkWriter32::WriteStringSize(const char* str, size_t len) { 243 if ((long)len < 0) { 244 SkASSERT(str); 245 len = strlen(str); 246 } 247 const size_t lenBytes = 4; // we use 4 bytes to record the length 248 // add 1 since we also write a terminating 0 249 return SkAlign4(lenBytes + len + 1); 250} 251 252 253