1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkWriter32.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,105 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkReader32.h" 1.12 +#include "SkString.h" 1.13 +#include "SkWriter32.h" 1.14 + 1.15 +/* 1.16 + * Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4 1.17 + */ 1.18 + 1.19 +const char* SkReader32::readString(size_t* outLen) { 1.20 + size_t len = this->readInt(); 1.21 + const void* ptr = this->peek(); 1.22 + 1.23 + // skip over the string + '\0' and then pad to a multiple of 4 1.24 + size_t alignedSize = SkAlign4(len + 1); 1.25 + this->skip(alignedSize); 1.26 + 1.27 + if (outLen) { 1.28 + *outLen = len; 1.29 + } 1.30 + return (const char*)ptr; 1.31 +} 1.32 + 1.33 +size_t SkReader32::readIntoString(SkString* copy) { 1.34 + size_t len; 1.35 + const char* ptr = this->readString(&len); 1.36 + if (copy) { 1.37 + copy->set(ptr, len); 1.38 + } 1.39 + return len; 1.40 +} 1.41 + 1.42 +void SkWriter32::writeString(const char str[], size_t len) { 1.43 + if (NULL == str) { 1.44 + str = ""; 1.45 + len = 0; 1.46 + } 1.47 + if ((long)len < 0) { 1.48 + len = strlen(str); 1.49 + } 1.50 + 1.51 + // [ 4 byte len ] [ str ... ] [1 - 4 \0s] 1.52 + uint32_t* ptr = this->reservePad(sizeof(uint32_t) + len + 1); 1.53 + *ptr = len; 1.54 + char* chars = (char*)(ptr + 1); 1.55 + memcpy(chars, str, len); 1.56 + chars[len] = '\0'; 1.57 +} 1.58 + 1.59 +size_t SkWriter32::WriteStringSize(const char* str, size_t len) { 1.60 + if ((long)len < 0) { 1.61 + SkASSERT(str); 1.62 + len = strlen(str); 1.63 + } 1.64 + const size_t lenBytes = 4; // we use 4 bytes to record the length 1.65 + // add 1 since we also write a terminating 0 1.66 + return SkAlign4(lenBytes + len + 1); 1.67 +} 1.68 + 1.69 +void SkWriter32::growToAtLeast(size_t size) { 1.70 + const bool wasExternal = (fExternal != NULL) && (fData == fExternal); 1.71 + 1.72 + fCapacity = 4096 + SkTMax(size, fCapacity + (fCapacity / 2)); 1.73 + fInternal.realloc(fCapacity); 1.74 + fData = fInternal.get(); 1.75 + 1.76 + if (wasExternal) { 1.77 + // we were external, so copy in the data 1.78 + memcpy(fData, fExternal, fUsed); 1.79 + } 1.80 + // Invalidate the snapshot, we know it is no longer useful. 1.81 + fSnapshot.reset(NULL); 1.82 +} 1.83 + 1.84 +SkData* SkWriter32::snapshotAsData() const { 1.85 + // get a non const version of this, we are only conceptually const 1.86 + SkWriter32& mutable_this = *const_cast<SkWriter32*>(this); 1.87 + // we use size change detection to invalidate the cached data 1.88 + if ((fSnapshot.get() != NULL) && (fSnapshot->size() != fUsed)) { 1.89 + mutable_this.fSnapshot.reset(NULL); 1.90 + } 1.91 + if (fSnapshot.get() == NULL) { 1.92 + uint8_t* buffer = NULL; 1.93 + if ((fExternal != NULL) && (fData == fExternal)) { 1.94 + // We need to copy to an allocated buffer before returning. 1.95 + buffer = (uint8_t*)sk_malloc_throw(fUsed); 1.96 + memcpy(buffer, fData, fUsed); 1.97 + } else { 1.98 + buffer = mutable_this.fInternal.detach(); 1.99 + // prepare us to do copy on write, by pretending the data buffer 1.100 + // is external and size limited 1.101 + mutable_this.fData = buffer; 1.102 + mutable_this.fCapacity = fUsed; 1.103 + mutable_this.fExternal = buffer; 1.104 + } 1.105 + mutable_this.fSnapshot.reset(SkData::NewFromMalloc(buffer, fUsed)); 1.106 + } 1.107 + return SkRef(fSnapshot.get()); // Take an extra ref for the caller. 1.108 +}