change string read/write to store length as full 32-bit value. This simplifies
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 21 Jun 2011 15:43:11 +0000 (15:43 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 21 Jun 2011 15:43:11 +0000 (15:43 +0000)
the internal logic, and allows SkFlattenable to rely on this when distinguishing
between 0 and indices (which will soon be negative) and string-lengths.

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

include/core/SkReader32.h
src/core/SkWriter32.cpp

index 654ebd5..5981380 100644 (file)
 #ifndef SkReader32_DEFINED
 #define SkReader32_DEFINED
 
-#include "SkTypes.h"
-
 #include "SkScalar.h"
 #include "SkPoint.h"
 #include "SkRect.h"
 
+class SkString;
+
 class SkReader32 : SkNoncopyable {
 public:
     SkReader32() : fCurr(NULL), fStop(NULL), fBase(NULL) {}
@@ -103,12 +103,18 @@ public:
     uint32_t readU32() { return this->readInt(); }
 
     /**
-     *  Read the length of a string written by SkWriter32::writeString()
-     *  (if len is not NULL) and return the null-ternimated address of the
-     *  string.
+     *  Read the length of a string (written by SkWriter32::writeString) into
+     *  len (if len is not NULL) and return the null-ternimated address of the
+     *  string within the reader's buffer.
      */
     const char* readString(size_t* len = NULL);
 
+    /**
+     *  Read the string (written by SkWriter32::writeString) and return it in
+     *  copy (if copy is not null). Return the length of the string.
+     */
+    size_t readIntoString(SkString* copy);
+
 private:
     // these are always 4-byte aligned
     const char* fCurr;  // current position within buffer
index 9a60b8e..8842086 100644 (file)
@@ -188,23 +188,20 @@ bool SkWriter32::writeToStream(SkWStream* stream) {
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkReader32.h"
+#include "SkString.h"
+
+/*
+ *  Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4
+ */
 
 const char* SkReader32::readString(size_t* outLen) {
     // we need to read at least 1-4 bytes
     SkASSERT(this->isAvailable(4));
-    const uint8_t* base = (const uint8_t*)this->peek();
-    const uint8_t* ptr = base;
-
-    size_t len = *ptr++;
-    if (0xFF == len) {
-        len = (ptr[0] << 8) | ptr[1];
-        ptr += 2;
-        SkASSERT(len < 0xFFFF);
-    }
-    
-    // skip what we've read, and 0..3 pad bytes
-    // add 1 for the terminating 0 that writeString() included
-    size_t alignedSize = SkAlign4(len + (ptr - base) + 1);
+    size_t len = this->readInt();
+    const void* ptr = this->peek();
+
+    // skip over teh string + '\0' and then pad to a multiple of 4
+    size_t alignedSize = SkAlign4(len + 1);
     this->skip(alignedSize);
 
     if (outLen) {
@@ -213,26 +210,24 @@ const char* SkReader32::readString(size_t* outLen) {
     return (const char*)ptr;
 }
 
+size_t SkReader32::readIntoString(SkString* copy) {
+    size_t len;
+    const char* ptr = this->readString(&len);
+    if (copy) {
+        copy->set(ptr, len);
+    }
+    return len;
+}
+
 void SkWriter32::writeString(const char str[], size_t len) {
     if ((long)len < 0) {
         SkASSERT(str);
         len = strlen(str);
     }
-    size_t lenBytes = 1;
-    if (len >= 0xFF) {
-        lenBytes = 3;
-        SkASSERT(len < 0xFFFF);
-    }
+    this->write32(len);
     // add 1 since we also write a terminating 0
-    size_t alignedLen = SkAlign4(lenBytes + len + 1);
-    uint8_t* ptr = (uint8_t*)this->reserve(alignedLen);
-    if (1 == lenBytes) {
-        *ptr++ = SkToU8(len);
-    } else {
-        *ptr++ = 0xFF;
-        *ptr++ = SkToU8(len >> 8);
-        *ptr++ = len & 0xFF;
-    }
+    size_t alignedLen = SkAlign4(len + 1);
+    char* ptr = (char*)this->reserve(alignedLen);
     memcpy(ptr, str, len);
     ptr[len] = 0;
     // we may have left 0,1,2,3 bytes uninitialized, since we reserved align4
@@ -244,11 +239,7 @@ size_t SkWriter32::WriteStringSize(const char* str, size_t len) {
         SkASSERT(str);
         len = strlen(str);
     }
-    size_t lenBytes = 1;
-    if (len >= 0xFF) {
-        lenBytes = 3;
-        SkASSERT(len < 0xFFFF);
-    }
+    const size_t lenBytes = 4;    // we use 4 bytes to record the length
     // add 1 since we also write a terminating 0
     return SkAlign4(lenBytes + len + 1);
 }