Просмотр исходного кода

Changed JsonSink to match Arduino's Print class

Benoît Blanchon 11 лет назад
Родитель
Сommit
a57220debc

+ 13 - 7
JsonGeneratorTests/JsonArray.h

@@ -37,19 +37,25 @@ private:
     JsonValue items[N];
     int itemCount;
 
-    virtual void writeTo(JsonSink& sb)
+    virtual size_t writeTo(JsonSink& sb)
     {
-        sb.append("[");
-        sb.reserveRoom(1);
+        size_t n = 0;
+        
+        n += sb.append("[");
 
         for (int i = 0; i < itemCount; i++)
         {
-            if (i>0) sb.append(",");
-            items[i].writeTo(sb);
+            if (i > 0)
+            {
+                n += sb.append(",");
+            }
+
+            n += items[i].writeTo(sb);
         }
 
-        sb.releaseRoom(1);
-        sb.append("]");
+        n += sb.append("]");
+
+        return n;
     }
 };
 

+ 15 - 10
JsonGeneratorTests/JsonHashTable.h

@@ -45,24 +45,29 @@ private:
     KeyValuePair items[N];
     int itemCount;
 
-    virtual void writeTo(JsonSink& sink)
+    virtual size_t writeTo(JsonSink& sink)
     {
-        sink.append("{");
-        sink.reserveRoom(1);
+        size_t n = 0;
+
+        n += sink.append('{');
 
         for (int i = 0; i < itemCount; i++)
         {
-            if (i>0) sink.append(",");
-
             JsonValue key(items[i].key);
 
-            key.writeTo(sink);
-            sink.append(":");
-            items[i].value.writeTo(sink);
+            if (i > 0)
+            {
+                n += sink.append(',');
+            }
+
+            n += key.writeTo(sink);
+            n += sink.append(':');
+            n += items[i].value.writeTo(sink);
         }
 
-        sink.releaseRoom(1);
-        sink.append("}");
+        n += sink.append('}');
+
+        return n;
     }
 };
 

+ 3 - 3
JsonGeneratorTests/JsonObjectBase.h

@@ -12,12 +12,12 @@ class JsonObjectBase
 {
 public:
 
-    void writeTo(char* buffer, size_t bufferSize)
+    size_t writeTo(char* buffer, size_t bufferSize)
     {
         StringBuilder sb(buffer, bufferSize);
-        writeTo(sb);
+        return writeTo(sb);
     }
 
-    virtual void writeTo(JsonSink& sb) = 0;
+    virtual size_t writeTo(JsonSink& sb) = 0;
 };
 

+ 11 - 6
JsonGeneratorTests/JsonSink.h

@@ -9,11 +9,16 @@ class JsonSink
 {
 public:
 
-    virtual void append(char c) = 0;
-    virtual void append(const char* s) = 0;
-
-    virtual bool hasRoomFor(int n) = 0;
-    virtual void reserveRoom(int n) = 0;
-    virtual void releaseRoom(int n) = 0;
+    virtual size_t append(char c) = 0;
+    
+    size_t append(const char* s)
+    {
+        size_t n = 0;
+        while (*s)
+        {
+            n += append(*s++);
+        }
+        return n;
+    }
 };
 

+ 21 - 24
JsonGeneratorTests/JsonValue.cpp

@@ -8,29 +8,29 @@
 #include <cstdio>
 #include <cstring>
 
-void JsonValue::writeBooleanTo(JsonSink& sb)
+size_t JsonValue::writeBooleanTo(JsonSink& sb)
 {
-    sb.append(content.boolean ? "true" : "false");
+    return sb.append(content.boolean ? "true" : "false");
 }
 
-void JsonValue::writeNumberTo(JsonSink& sb)
+size_t JsonValue::writeNumberTo(JsonSink& sb)
 {
     char tmp[16];
 
     _snprintf(tmp, sizeof(tmp), "%lg", content.number);
 
-    sb.append(tmp);
+    return sb.append(tmp);
 }
 
-void JsonValue::writeObjectTo(JsonSink& sink)
+size_t JsonValue::writeObjectTo(JsonSink& sink)
 {
     if (content.object)
-        ((JsonObjectBase*) content.object)->writeTo(sink);
+        return ((JsonObjectBase*)content.object)->writeTo(sink);
     else
-        sink.append("null");
+        return sink.append("null");
 }
 
-void JsonValue::writeStringTo(JsonSink& sink)
+size_t JsonValue::writeStringTo(JsonSink& sink)
 {
     auto s = content.string;
 
@@ -39,54 +39,51 @@ void JsonValue::writeStringTo(JsonSink& sink)
         return sink.append("null");
     }
 
-    if (!sink.hasRoomFor(2))
-    {
-        return;
-    }
+    size_t n = 0;
 
-    sink.append('\"');
-    sink.reserveRoom(1);
+    n += sink.append('\"');
 
     while (*s)
     {
         switch (*s)
         {
         case '"':
-            sink.append("\\\"");
+            n += sink.append("\\\"");
             break;
 
         case '\\':
-            sink.append("\\\\");
+            n += sink.append("\\\\");
             break;
 
         case '\b':
-            sink.append("\\b");
+            n += sink.append("\\b");
             break;
 
         case '\f':
-            sink.append("\\f");
+            n += sink.append("\\f");
             break;
 
         case '\n':
-            sink.append("\\n");
+            n += sink.append("\\n");
             break;
 
         case '\r':
-            sink.append("\\r");
+            n += sink.append("\\r");
             break;
 
         case '\t':
-            sink.append("\\t");
+            n += sink.append("\\t");
             break;
 
         default:
-            sink.append(*s);
+            n += sink.append(*s);
             break;
         }
 
         s++;
     }
 
-    sink.releaseRoom(1);
-    sink.append('\"');
+    n += sink.append('\"');
+
+    return n;
 }

+ 7 - 7
JsonGeneratorTests/JsonValue.h

@@ -41,10 +41,10 @@ public:
         content.object = &value;
     }
 
-    void writeTo(JsonSink& sink)
+    size_t writeTo(JsonSink& sink)
     {
         // handmade polymorphism
-        (this->*implementation)(sink);
+        return (this->*implementation)(sink);
     }
     
 private:
@@ -59,10 +59,10 @@ private:
 
     Content content;
 
-    void (JsonValue::*implementation)(JsonSink& sb);
+    size_t (JsonValue::*implementation)(JsonSink& sb);
 
-    void writeBooleanTo(JsonSink& sb);
-    void writeNumberTo(JsonSink& sb);
-    void writeObjectTo(JsonSink& sb);
-    void writeStringTo(JsonSink& sb);
+    size_t writeBooleanTo(JsonSink& sb);
+    size_t writeNumberTo(JsonSink& sb);
+    size_t writeObjectTo(JsonSink& sb);
+    size_t writeStringTo(JsonSink& sb);
 };

+ 2 - 2
JsonGeneratorTests/JsonValueTests.cpp

@@ -51,10 +51,10 @@ namespace JsonGeneratorTests
         TEST_METHOD(OverCapacity)
         {
             append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
-            assertResultIs("\"ABCDEFGHIJKLMNOPQ\"");
+            assertResultIs("\"ABCDEFGHIJKLMNOPQR");
 
             append("");
-            assertResultIs("\"ABCDEFGHIJKLMNOPQ\"");
+            assertResultIs("\"ABCDEFGHIJKLMNOPQR");
         }
 
         TEST_METHOD(SpecialChars)

+ 3 - 15
JsonGeneratorTests/StringBuilder.cpp

@@ -5,23 +5,11 @@
 
 #include "StringBuilder.h"
 
-void StringBuilder::append(const char* s)
+size_t StringBuilder::append(char c)
 {
-    char* tail = buffer + length;
-
-    while (*s && length<capacity)
-    {
-        buffer[length++] = *s++;
-    }
-
-    buffer[length] = 0;
-}
-
-
-void StringBuilder::append(char c)
-{
-    if (length >= capacity) return;
+    if (length >= capacity) return 0;
 
     buffer[length++] = c;
     buffer[length] = 0;
+    return 1;
 }

+ 2 - 17
JsonGeneratorTests/StringBuilder.h

@@ -16,23 +16,8 @@ public:
         buffer[0] = 0;
     }
 
-    virtual void append(char c);
-    virtual void append(const char* s);
-
-    virtual bool hasRoomFor(int n)
-    {
-        return capacity - length >= n;
-    }
-
-    virtual void reserveRoom(int n)
-    {
-        capacity -= n;
-    }
-
-    virtual void releaseRoom(int n)
-    {
-        capacity += n;
-    }
+    virtual size_t append(char c);
+    size_t append(const char* c);
 
 private:
     char* buffer;