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