diff options
author | 2012-07-11 18:48:37 +0000 | |
---|---|---|
committer | 2012-07-11 18:48:37 +0000 | |
commit | 19393dff0c4e44499d0c8102e6238b8544f7b6dd (patch) | |
tree | 449bd0f391b6a59cd7ec496569ca4584339670b4 | |
parent | a2fdb338c72ce3b9ffda4c1012e485a390f913ee (diff) |
add flatten/unflatten to SkDataSet
Review URL: https://codereview.appspot.com/6374057
git-svn-id: http://skia.googlecode.com/svn/trunk@4548 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/core/SkDataSet.h | 16 | ||||
-rw-r--r-- | src/core/SkData.cpp | 70 |
2 files changed, 81 insertions, 5 deletions
diff --git a/include/core/SkDataSet.h b/include/core/SkDataSet.h index eed8c20a24..781cd6ced6 100644 --- a/include/core/SkDataSet.h +++ b/include/core/SkDataSet.h @@ -13,9 +13,22 @@ class SkStream; class SkWStream; +class SkFlattenableReadBuffer; +class SkFlattenableWriteBuffer; class SkDataSet : public SkRefCnt { public: + /** + * Returns a new empty dataset. Note: since SkDataSet is immutable, this + * "new" set may be the same one that was returned before, but each + * returned object must have its reference-count balanced regardles. + * + * SkDataSet* empty = SkDataSet::NewEmpty(); + * ... + * empty->unref(); + */ + static SkDataSet* NewEmpty(); + struct Pair { const char* fKey; SkData* fValue; @@ -60,6 +73,9 @@ public: explicit SkDataSet(SkStream*); void writeToStream(SkWStream*) const; + explicit SkDataSet(SkFlattenableReadBuffer&); + void flatten(SkFlattenableWriteBuffer&) const; + private: int32_t fCount; uint32_t fKeySize; diff --git a/src/core/SkData.cpp b/src/core/SkData.cpp index 618ee35f07..a9ca4dabf4 100644 --- a/src/core/SkData.cpp +++ b/src/core/SkData.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2011 Google Inc. * @@ -6,8 +5,6 @@ * found in the LICENSE file. */ - - #include "SkData.h" SK_DEFINE_INST_COUNT(SkData) @@ -126,6 +123,7 @@ SkData* SkData::NewWithCString(const char cstr[]) { /////////////////////////////////////////////////////////////////////////////// #include "SkDataSet.h" +#include "SkFlattenable.h" #include "SkStream.h" static SkData* dupdata(SkData* data) { @@ -137,6 +135,26 @@ static SkData* dupdata(SkData* data) { return data; } +static SkData* read_data(SkFlattenableReadBuffer& buffer) { + size_t size = buffer.readU32(); + if (0 == size) { + return SkData::NewEmpty(); + } else { + // buffer.read expects a 4-byte aligned size + size_t size4 = SkAlign4(size); + void* block = sk_malloc_throw(size4); + buffer.read(block, size4); + // we pass the "real" size to NewFromMalloc, since its needs to report + // the same size that was written. + return SkData::NewFromMalloc(block, size); + } +} + +static void write_data(SkFlattenableWriteBuffer& buffer, SkData* data) { + buffer.write32(data->size()); + buffer.writePad(data->data(), data->size()); +} + static SkData* findValue(const char key[], const SkDataSet::Pair array[], int n) { for (int i = 0; i < n; ++i) { if (!strcmp(key, array[i].fKey)) { @@ -222,15 +240,27 @@ void SkDataSet::writeToStream(SkWStream* stream) const { } } +void SkDataSet::flatten(SkFlattenableWriteBuffer& buffer) const { + buffer.write32(fCount); + if (fCount > 0) { + buffer.write32(fKeySize); + // our first key points to all the key storage + buffer.writePad(fPairs[0].fKey, fKeySize); + for (int i = 0; i < fCount; ++i) { + write_data(buffer, fPairs[i].fValue); + } + } +} + SkDataSet::SkDataSet(SkStream* stream) { fCount = stream->readU32(); if (fCount > 0) { fKeySize = stream->readU32(); fPairs = allocatePairStorage(fCount, fKeySize); char* keyStorage = (char*)(fPairs + fCount); - + stream->read(keyStorage, fKeySize); - + for (int i = 0; i < fCount; ++i) { fPairs[i].fKey = keyStorage; keyStorage += strlen(keyStorage) + 1; @@ -242,3 +272,33 @@ SkDataSet::SkDataSet(SkStream* stream) { } } +SkDataSet::SkDataSet(SkFlattenableReadBuffer& buffer) { + fCount = buffer.readU32(); + if (fCount > 0) { + fKeySize = buffer.readU32(); + // we align fKeySize, since buffer.read needs to read a mul4 amount + fPairs = allocatePairStorage(fCount, SkAlign4(fKeySize)); + char* keyStorage = (char*)(fPairs + fCount); + + buffer.read(keyStorage, SkAlign4(fKeySize)); + + for (int i = 0; i < fCount; ++i) { + fPairs[i].fKey = keyStorage; + keyStorage += strlen(keyStorage) + 1; + fPairs[i].fValue = read_data(buffer); + } + } else { + fKeySize = 0; + fPairs = NULL; + } +} + +SkDataSet* SkDataSet::NewEmpty() { + static SkDataSet* gEmptySet; + if (NULL == gEmptySet) { + gEmptySet = SkNEW_ARGS(SkDataSet, (NULL, 0)); + } + gEmptySet->ref(); + return gEmptySet; +} + |