• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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