add SkDataSet class, so SkAnnotation can be more immutable-like
Review URL: https://codereview.appspot.com/6354091

git-svn-id: http://skia.googlecode.com/svn/trunk@4542 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/DataRefTest.cpp b/tests/DataRefTest.cpp
index dc7f424..8c9d151 100644
--- a/tests/DataRefTest.cpp
+++ b/tests/DataRefTest.cpp
@@ -7,6 +7,85 @@
  */
 #include "Test.h"
 #include "SkData.h"
+#include "SkDataSet.h"
+#include "SkStream.h"
+
+template <typename T> class SkTUnref {
+public:
+    SkTUnref(T* ref) : fRef(ref) {}
+    ~SkTUnref() { fRef->unref(); }
+    
+    operator T*() { return fRef; }
+    operator const T*() { return fRef; }
+
+private:
+    T*  fRef;
+};
+
+static void unrefAll(const SkDataSet::Pair pairs[], int count) {
+    for (int i = 0; i < count; ++i) {
+        pairs[i].fValue->unref();
+    }
+}
+
+// asserts that inner is a subset of outer
+static void test_dataset_subset(skiatest::Reporter* reporter,
+                                const SkDataSet& outer, const SkDataSet& inner) {
+    SkDataSet::Iter iter(inner);
+    for (; !iter.done(); iter.next()) {
+        SkData* outerData = outer.find(iter.key());
+        REPORTER_ASSERT(reporter, outerData);
+        REPORTER_ASSERT(reporter, outerData->equals(iter.value()));
+    }
+}
+
+static void test_datasets_equal(skiatest::Reporter* reporter,
+                                const SkDataSet& ds0, const SkDataSet& ds1) {
+    REPORTER_ASSERT(reporter, ds0.count() == ds1.count());
+    
+    test_dataset_subset(reporter, ds0, ds1);
+    test_dataset_subset(reporter, ds1, ds0);
+}
+
+static void test_dataset(skiatest::Reporter* reporter, const SkDataSet& ds,
+                         int count) {
+    REPORTER_ASSERT(reporter, ds.count() == count);
+    
+    SkDataSet::Iter iter(ds);
+    int index = 0;
+    for (; !iter.done(); iter.next()) {
+        const char* name = iter.key();
+        SkData* data = iter.value();
+        SkDebugf("[%d] %s:%s\n", index, name, (const char*)data->bytes());
+        index += 1;
+    }
+    REPORTER_ASSERT(reporter, index == count);
+
+    SkDynamicMemoryWStream ostream;
+    ds.writeToStream(&ostream);
+    SkMemoryStream istream;
+    istream.setData(ostream.copyToData())->unref();
+    SkDataSet copy(&istream);
+    
+    test_datasets_equal(reporter, ds, copy);
+}
+
+static void test_dataset(skiatest::Reporter* reporter) {
+    SkDataSet set0(NULL, 0);
+    SkDataSet set1("hello", SkTUnref<SkData>(SkData::NewWithCString("world")));
+    
+    const SkDataSet::Pair pairs[] = {
+        { "one", SkData::NewWithCString("1") },
+        { "two", SkData::NewWithCString("2") },
+        { "three", SkData::NewWithCString("3") },
+    };
+    SkDataSet set3(pairs, 3);
+    unrefAll(pairs, 3);
+
+    test_dataset(reporter, set0, 0);
+    test_dataset(reporter, set1, 1);
+    test_dataset(reporter, set3, 3);
+}
 
 static void* gGlobal;
 
@@ -40,7 +119,7 @@
     REPORTER_ASSERT(reporter, 0 == *r2->bytes());
 }
 
-static void TestDataRef(skiatest::Reporter* reporter) {
+static void TestData(skiatest::Reporter* reporter) {
     const char* str = "We the people, in order to form a more perfect union.";
     const int N = 10;
 
@@ -66,7 +145,8 @@
     tmp->unref();
     
     test_cstring(reporter);
+    test_dataset(reporter);
 }
 
 #include "TestClassDef.h"
-DEFINE_TESTCLASS("DataRef", DataRefTestClass, TestDataRef)
+DEFINE_TESTCLASS("Data", DataTestClass, TestData)