1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkReader32.h" 9 #include "SkString.h" 10 #include "SkWriter32.h" 11 12 /* 13 * Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4 14 */ 15 16 const char* SkReader32::readString(size_t* outLen) { 17 size_t len = this->readU32(); 18 const void* ptr = this->peek(); 19 20 // skip over the string + '\0' and then pad to a multiple of 4 21 size_t alignedSize = SkAlign4(len + 1); 22 this->skip(alignedSize); 23 24 if (outLen) { 25 *outLen = len; 26 } 27 return (const char*)ptr; 28 } 29 30 size_t SkReader32::readIntoString(SkString* copy) { 31 size_t len; 32 const char* ptr = this->readString(&len); 33 if (copy) { 34 copy->set(ptr, len); 35 } 36 return len; 37 } 38 39 void SkWriter32::writeString(const char str[], size_t len) { 40 if (nullptr == str) { 41 str = ""; 42 len = 0; 43 } 44 if ((long)len < 0) { 45 len = strlen(str); 46 } 47 48 // [ 4 byte len ] [ str ... ] [1 - 4 \0s] 49 uint32_t* ptr = this->reservePad(sizeof(uint32_t) + len + 1); 50 *ptr = SkToU32(len); 51 char* chars = (char*)(ptr + 1); 52 memcpy(chars, str, len); 53 chars[len] = '\0'; 54 } 55 56 size_t SkWriter32::WriteStringSize(const char* str, size_t len) { 57 if ((long)len < 0) { 58 SkASSERT(str); 59 len = strlen(str); 60 } 61 const size_t lenBytes = 4; // we use 4 bytes to record the length 62 // add 1 since we also write a terminating 0 63 return SkAlign4(lenBytes + len + 1); 64 } 65 66 void SkWriter32::growToAtLeast(size_t size) { 67 const bool wasExternal = (fExternal != nullptr) && (fData == fExternal); 68 69 fCapacity = 4096 + SkTMax(size, fCapacity + (fCapacity / 2)); 70 fInternal.realloc(fCapacity); 71 fData = fInternal.get(); 72 73 if (wasExternal) { 74 // we were external, so copy in the data 75 memcpy(fData, fExternal, fUsed); 76 } 77 } 78 79 SkData* SkWriter32::snapshotAsData() const { 80 return SkData::NewWithCopy(fData, fUsed); 81 } 82