aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-11 18:48:37 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-11 18:48:37 +0000
commit19393dff0c4e44499d0c8102e6238b8544f7b6dd (patch)
tree449bd0f391b6a59cd7ec496569ca4584339670b4
parenta2fdb338c72ce3b9ffda4c1012e485a390f913ee (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.h16
-rw-r--r--src/core/SkData.cpp70
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;
+}
+