1 2 /* 3 * Copyright 2008 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkReader32_DEFINED 11 #define SkReader32_DEFINED 12 13 #include "SkMatrix.h" 14 #include "SkPath.h" 15 #include "SkRegion.h" 16 #include "SkRRect.h" 17 #include "SkScalar.h" 18 19 class SkString; 20 21 class SkReader32 : SkNoncopyable { 22 public: 23 SkReader32() : fCurr(NULL), fStop(NULL), fBase(NULL) {} 24 SkReader32(const void* data, size_t size) { 25 this->setMemory(data, size); 26 } 27 28 void setMemory(const void* data, size_t size) { 29 SkASSERT(ptr_align_4(data)); 30 SkASSERT(SkAlign4(size) == size); 31 32 fBase = fCurr = (const char*)data; 33 fStop = (const char*)data + size; 34 } 35 36 uint32_t size() const { return SkToU32(fStop - fBase); } 37 uint32_t offset() const { return SkToU32(fCurr - fBase); } 38 bool eof() const { return fCurr >= fStop; } 39 const void* base() const { return fBase; } 40 const void* peek() const { return fCurr; } 41 42 uint32_t available() const { return SkToU32(fStop - fCurr); } 43 bool isAvailable(uint32_t size) const { return fCurr + size <= fStop; } 44 45 void rewind() { fCurr = fBase; } 46 47 void setOffset(size_t offset) { 48 SkASSERT(SkAlign4(offset) == offset); 49 SkASSERT(offset <= this->size()); 50 fCurr = fBase + offset; 51 } 52 53 bool readBool() { return this->readInt() != 0; } 54 55 int32_t readInt() { 56 SkASSERT(ptr_align_4(fCurr)); 57 int32_t value = *(const int32_t*)fCurr; 58 fCurr += sizeof(value); 59 SkASSERT(fCurr <= fStop); 60 return value; 61 } 62 63 void* readPtr() { 64 void* ptr; 65 // we presume this "if" is resolved at compile-time 66 if (4 == sizeof(void*)) { 67 ptr = *(void**)fCurr; 68 } else { 69 memcpy(&ptr, fCurr, sizeof(void*)); 70 } 71 fCurr += sizeof(void*); 72 return ptr; 73 } 74 75 SkScalar readScalar() { 76 SkASSERT(ptr_align_4(fCurr)); 77 SkScalar value = *(const SkScalar*)fCurr; 78 fCurr += sizeof(value); 79 SkASSERT(fCurr <= fStop); 80 return value; 81 } 82 83 const void* skip(size_t size) { 84 SkASSERT(ptr_align_4(fCurr)); 85 const void* addr = fCurr; 86 fCurr += SkAlign4(size); 87 SkASSERT(fCurr <= fStop); 88 return addr; 89 } 90 91 template <typename T> const T& skipT() { 92 SkASSERT(SkAlign4(sizeof(T)) == sizeof(T)); 93 return *(const T*)this->skip(sizeof(T)); 94 } 95 96 void read(void* dst, size_t size) { 97 SkASSERT(0 == size || dst != NULL); 98 SkASSERT(ptr_align_4(fCurr)); 99 memcpy(dst, fCurr, size); 100 fCurr += SkAlign4(size); 101 SkASSERT(fCurr <= fStop); 102 } 103 104 uint8_t readU8() { return (uint8_t)this->readInt(); } 105 uint16_t readU16() { return (uint16_t)this->readInt(); } 106 int32_t readS32() { return this->readInt(); } 107 uint32_t readU32() { return this->readInt(); } 108 109 void readPath(SkPath* path) { 110 size_t size = path->readFromMemory(this->peek()); 111 SkASSERT(SkAlign4(size) == size); 112 (void)this->skip(size); 113 } 114 115 void readMatrix(SkMatrix* matrix) { 116 size_t size = matrix->readFromMemory(this->peek()); 117 SkASSERT(SkAlign4(size) == size); 118 (void)this->skip(size); 119 } 120 121 SkRRect* readRRect(SkRRect* rrect) { 122 rrect->readFromMemory(this->skip(SkRRect::kSizeInMemory)); 123 return rrect; 124 } 125 126 void readRegion(SkRegion* rgn) { 127 size_t size = rgn->readFromMemory(this->peek()); 128 SkASSERT(SkAlign4(size) == size); 129 (void)this->skip(size); 130 } 131 132 /** 133 * Read the length of a string (written by SkWriter32::writeString) into 134 * len (if len is not NULL) and return the null-ternimated address of the 135 * string within the reader's buffer. 136 */ 137 const char* readString(size_t* len = NULL); 138 139 /** 140 * Read the string (written by SkWriter32::writeString) and return it in 141 * copy (if copy is not null). Return the length of the string. 142 */ 143 size_t readIntoString(SkString* copy); 144 145 private: 146 // these are always 4-byte aligned 147 const char* fCurr; // current position within buffer 148 const char* fStop; // end of buffer 149 const char* fBase; // beginning of buffer 150 151 #ifdef SK_DEBUG 152 static bool ptr_align_4(const void* ptr) { 153 return (((const char*)ptr - (const char*)NULL) & 3) == 0; 154 } 155 #endif 156 }; 157 158 #endif 159