add flatten/unflatten to SkDataSet
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 11 Jul 2012 18:48:37 +0000 (18:48 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 11 Jul 2012 18:48:37 +0000 (18:48 +0000)
Review URL: https://codereview.appspot.com/6374057

git-svn-id: http://skia.googlecode.com/svn/trunk@4548 2bbb7eff-a529-9590-31e7-b0007b416f81

include/core/SkDataSet.h
src/core/SkData.cpp

index eed8c20..781cd6c 100644 (file)
 
 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;
index 618ee35..a9ca4da 100644 (file)
@@ -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;
+}
+