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 19class SkStream; 20class SkWStream; 21 22class SkWriter32 : SkNoncopyable { 23public: 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 */ 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 47 bool writeBool(bool value) { 48 this->writeInt(value); 49 return value; 50 } 51 52 void writeInt(int32_t value) { 53 *(int32_t*)this->reserve(sizeof(value)) = value; 54 } 55 56 void write8(int32_t value) { 57 *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF; 58 } 59 60 void write16(int32_t value) { 61 *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF; 62 } 63 64 void write32(int32_t value) { 65 *(int32_t*)this->reserve(sizeof(value)) = value; 66 } 67 68 void writeScalar(SkScalar value) { 69 *(SkScalar*)this->reserve(sizeof(value)) = value; 70 } 71 72 void writePoint(const SkPoint& pt) { 73 *(SkPoint*)this->reserve(sizeof(pt)) = pt; 74 } 75 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) 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 */ 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) 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 133private: 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