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 SkWriter32_DEFINED 11 #define SkWriter32_DEFINED 12 13 #include "SkTypes.h" 14 15 #include "SkScalar.h" 16 #include "SkPoint.h" 17 #include "SkRect.h" 18 19 class SkStream; 20 class SkWStream; 21 22 class SkWriter32 : SkNoncopyable { 23 public: SkWriter32(size_t minSize)24 SkWriter32(size_t minSize) 25 : fMinSize(minSize), 26 fSize(0), 27 fSingleBlock(NULL), 28 fSingleBlockSize(0), 29 fHead(NULL), 30 fTail(NULL) { 31 } 32 ~SkWriter32(); 33 34 /** 35 * Returns the single block backing the writer, or NULL if the memory is 36 * to be dynamically allocated. 37 */ getSingleBlock()38 void* getSingleBlock() const { return fSingleBlock; } 39 40 /** 41 * Specify the single block to back the writer, rathern than dynamically 42 * allocating the memory. If block == NULL, then the writer reverts to 43 * dynamic allocation (and resets). 44 */ 45 void reset(void* block, size_t size); 46 writeBool(bool value)47 bool writeBool(bool value) { 48 this->writeInt(value); 49 return value; 50 } 51 writeInt(int32_t value)52 void writeInt(int32_t value) { 53 *(int32_t*)this->reserve(sizeof(value)) = value; 54 } 55 write8(int32_t value)56 void write8(int32_t value) { 57 *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF; 58 } 59 write16(int32_t value)60 void write16(int32_t value) { 61 *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF; 62 } 63 write32(int32_t value)64 void write32(int32_t value) { 65 *(int32_t*)this->reserve(sizeof(value)) = value; 66 } 67 writeScalar(SkScalar value)68 void writeScalar(SkScalar value) { 69 *(SkScalar*)this->reserve(sizeof(value)) = value; 70 } 71 writePoint(const SkPoint & pt)72 void writePoint(const SkPoint& pt) { 73 *(SkPoint*)this->reserve(sizeof(pt)) = pt; 74 } 75 writeRect(const SkRect & rect)76 void writeRect(const SkRect& rect) { 77 *(SkRect*)this->reserve(sizeof(rect)) = rect; 78 } 79 80 // write count bytes (must be a multiple of 4) writeMul4(const void * values,size_t size)81 void writeMul4(const void* values, size_t size) { 82 this->write(values, size); 83 } 84 85 /** 86 * Write size bytes from values. size must be a multiple of 4, though 87 * values need not be 4-byte aligned. 88 */ write(const void * values,size_t size)89 void write(const void* values, size_t size) { 90 SkASSERT(SkAlign4(size) == size); 91 // if we could query how much is avail in the current block, we might 92 // copy that much, and then alloc the rest. That would reduce the waste 93 // in the current block 94 memcpy(this->reserve(size), values, size); 95 } 96 97 void writePad(const void* src, size_t size); 98 99 /** 100 * Writes a string to the writer, which can be retrieved with 101 * SkReader32::readString(). 102 * The length can be specified, or if -1 is passed, it will be computed by 103 * calling strlen(). The length must be < 0xFFFF 104 */ 105 void writeString(const char* str, size_t len = (size_t)-1); 106 107 /** 108 * Computes the size (aligned to multiple of 4) need to write the string 109 * in a call to writeString(). If the length is not specified, it will be 110 * computed by calling strlen(). 111 */ 112 static size_t WriteStringSize(const char* str, size_t len = (size_t)-1); 113 114 // return the current offset (will always be a multiple of 4) size()115 uint32_t size() const { return fSize; } 116 void reset(); 117 uint32_t* reserve(size_t size); // size MUST be multiple of 4 118 119 // return the address of the 4byte int at the specified offset (which must 120 // be a multiple of 4. This does not allocate any new space, so the returned 121 // address is only valid for 1 int. 122 uint32_t* peek32(size_t offset); 123 124 // copy into a single buffer (allocated by caller). Must be at least size() 125 void flatten(void* dst) const; 126 127 // read from the stream, and write up to length bytes. Return the actual 128 // number of bytes written. 129 size_t readFromStream(SkStream*, size_t length); 130 131 bool writeToStream(SkWStream*); 132 133 private: 134 size_t fMinSize; 135 uint32_t fSize; 136 137 char* fSingleBlock; 138 uint32_t fSingleBlockSize; 139 140 struct Block; 141 Block* fHead; 142 Block* fTail; 143 144 Block* newBlock(size_t bytes); 145 }; 146 147 #endif 148