Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / include / core / SkWriter32.h
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 "SkData.h"
14 #include "SkMatrix.h"
15 #include "SkPath.h"
16 #include "SkPoint.h"
17 #include "SkRRect.h"
18 #include "SkRect.h"
19 #include "SkRegion.h"
20 #include "SkScalar.h"
21 #include "SkStream.h"
22 #include "SkTemplates.h"
23 #include "SkTypes.h"
24
25 class SK_API SkWriter32 : SkNoncopyable {
26 public:
27     /**
28      *  The caller can specify an initial block of storage, which the caller manages.
29      *
30      *  SkWriter32 will try to back reserve and write calls with this external storage until the
31      *  first time an allocation doesn't fit.  From then it will use dynamically allocated storage.
32      *  This used to be optional behavior, but pipe now relies on it.
33      */
34     SkWriter32(void* external = NULL, size_t externalBytes = 0) {
35         this->reset(external, externalBytes);
36     }
37
38     // return the current offset (will always be a multiple of 4)
39     size_t bytesWritten() const { return fUsed; }
40
41     SK_ATTR_DEPRECATED("use bytesWritten")
42     size_t size() const { return this->bytesWritten(); }
43
44     void reset(void* external = NULL, size_t externalBytes = 0) {
45         SkASSERT(SkIsAlign4((uintptr_t)external));
46         SkASSERT(SkIsAlign4(externalBytes));
47
48         fSnapshot.reset(NULL);
49         fData = (uint8_t*)external;
50         fCapacity = externalBytes;
51         fUsed = 0;
52         fExternal = external;
53     }
54
55     // Returns the current buffer.
56     // The pointer may be invalidated by any future write calls.
57     const uint32_t* contiguousArray() const {
58         return (uint32_t*)fData;
59     }
60
61     // size MUST be multiple of 4
62     uint32_t* reserve(size_t size) {
63         SkASSERT(SkAlign4(size) == size);
64         size_t offset = fUsed;
65         size_t totalRequired = fUsed + size;
66         if (totalRequired > fCapacity) {
67             this->growToAtLeast(totalRequired);
68         }
69         fUsed = totalRequired;
70         return (uint32_t*)(fData + offset);
71     }
72
73     /**
74      *  Read a T record at offset, which must be a multiple of 4. Only legal if the record
75      *  was written atomically using the write methods below.
76      */
77     template<typename T>
78     const T& readTAt(size_t offset) const {
79         SkASSERT(SkAlign4(offset) == offset);
80         SkASSERT(offset < fUsed);
81         return *(T*)(fData + offset);
82     }
83
84     /**
85      *  Overwrite a T record at offset, which must be a multiple of 4. Only legal if the record
86      *  was written atomically using the write methods below.
87      */
88     template<typename T>
89     void overwriteTAt(size_t offset, const T& value) {
90         SkASSERT(SkAlign4(offset) == offset);
91         SkASSERT(offset < fUsed);
92         SkASSERT(fSnapshot.get() == NULL);
93         *(T*)(fData + offset) = value;
94     }
95
96     bool writeBool(bool value) {
97         this->write32(value);
98         return value;
99     }
100
101     void writeInt(int32_t value) {
102         this->write32(value);
103     }
104
105     void write8(int32_t value) {
106         *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
107     }
108
109     void write16(int32_t value) {
110         *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
111     }
112
113     void write32(int32_t value) {
114         *(int32_t*)this->reserve(sizeof(value)) = value;
115     }
116
117     void writePtr(void* value) {
118         *(void**)this->reserve(sizeof(value)) = value;
119     }
120
121     void writeScalar(SkScalar value) {
122         *(SkScalar*)this->reserve(sizeof(value)) = value;
123     }
124
125     void writePoint(const SkPoint& pt) {
126         *(SkPoint*)this->reserve(sizeof(pt)) = pt;
127     }
128
129     void writeRect(const SkRect& rect) {
130         *(SkRect*)this->reserve(sizeof(rect)) = rect;
131     }
132
133     void writeIRect(const SkIRect& rect) {
134         *(SkIRect*)this->reserve(sizeof(rect)) = rect;
135     }
136
137     void writeRRect(const SkRRect& rrect) {
138         rrect.writeToMemory(this->reserve(SkRRect::kSizeInMemory));
139     }
140
141     void writePath(const SkPath& path) {
142         size_t size = path.writeToMemory(NULL);
143         SkASSERT(SkAlign4(size) == size);
144         path.writeToMemory(this->reserve(size));
145     }
146
147     void writeMatrix(const SkMatrix& matrix) {
148         size_t size = matrix.writeToMemory(NULL);
149         SkASSERT(SkAlign4(size) == size);
150         matrix.writeToMemory(this->reserve(size));
151     }
152
153     void writeRegion(const SkRegion& rgn) {
154         size_t size = rgn.writeToMemory(NULL);
155         SkASSERT(SkAlign4(size) == size);
156         rgn.writeToMemory(this->reserve(size));
157     }
158
159     // write count bytes (must be a multiple of 4)
160     void writeMul4(const void* values, size_t size) {
161         this->write(values, size);
162     }
163
164     /**
165      *  Write size bytes from values. size must be a multiple of 4, though
166      *  values need not be 4-byte aligned.
167      */
168     void write(const void* values, size_t size) {
169         SkASSERT(SkAlign4(size) == size);
170         memcpy(this->reserve(size), values, size);
171     }
172
173     /**
174      *  Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be
175      *  filled in with zeroes.
176      */
177     uint32_t* reservePad(size_t size) {
178         size_t alignedSize = SkAlign4(size);
179         uint32_t* p = this->reserve(alignedSize);
180         if (alignedSize != size) {
181             SkASSERT(alignedSize >= 4);
182             p[alignedSize / 4 - 1] = 0;
183         }
184         return p;
185     }
186
187     /**
188      *  Write size bytes from src, and pad to 4 byte alignment with zeroes.
189      */
190     void writePad(const void* src, size_t size) {
191         memcpy(this->reservePad(size), src, size);
192     }
193
194     /**
195      *  Writes a string to the writer, which can be retrieved with
196      *  SkReader32::readString().
197      *  The length can be specified, or if -1 is passed, it will be computed by
198      *  calling strlen(). The length must be < max size_t.
199      *
200      *  If you write NULL, it will be read as "".
201      */
202     void writeString(const char* str, size_t len = (size_t)-1);
203
204     /**
205      *  Computes the size (aligned to multiple of 4) need to write the string
206      *  in a call to writeString(). If the length is not specified, it will be
207      *  computed by calling strlen().
208      */
209     static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
210
211     /**
212      *  Move the cursor back to offset bytes from the beginning.
213      *  offset must be a multiple of 4 no greater than size().
214      */
215     void rewindToOffset(size_t offset) {
216         SkASSERT(SkAlign4(offset) == offset);
217         SkASSERT(offset <= bytesWritten());
218         fUsed = offset;
219     }
220
221     // copy into a single buffer (allocated by caller). Must be at least size()
222     void flatten(void* dst) const {
223         memcpy(dst, fData, fUsed);
224     }
225
226     bool writeToStream(SkWStream* stream) const {
227         return stream->write(fData, fUsed);
228     }
229
230     // read from the stream, and write up to length bytes. Return the actual
231     // number of bytes written.
232     size_t readFromStream(SkStream* stream, size_t length) {
233         return stream->read(this->reservePad(length), length);
234     }
235
236     /**
237      *  Captures a snapshot of the data as it is right now, and return it.
238      *  Multiple calls without intervening writes may return the same SkData,
239      *  but this is not guaranteed.
240      *  Future appends will not affect the returned buffer.
241      *  It is illegal to call overwriteTAt after this without an intervening
242      *  append. It may cause the snapshot buffer to be corrupted.
243      *  Callers must unref the returned SkData.
244      *  This is not thread safe, it should only be called on the writing thread,
245      *  the result however can be shared across threads.
246      */
247     SkData* snapshotAsData() const;
248 private:
249     void growToAtLeast(size_t size);
250
251     uint8_t* fData;                    // Points to either fInternal or fExternal.
252     size_t fCapacity;                  // Number of bytes we can write to fData.
253     size_t fUsed;                      // Number of bytes written.
254     void* fExternal;                   // Unmanaged memory block.
255     SkAutoTMalloc<uint8_t> fInternal;  // Managed memory block.
256     SkAutoTUnref<SkData> fSnapshot;    // Holds the result of last asData.
257 };
258
259 /**
260  *  Helper class to allocated SIZE bytes as part of the writer, and to provide
261  *  that storage to the constructor as its initial storage buffer.
262  *
263  *  This wrapper ensures proper alignment rules are met for the storage.
264  */
265 template <size_t SIZE> class SkSWriter32 : public SkWriter32 {
266 public:
267     SkSWriter32() { this->reset(); }
268
269     void reset() {this->INHERITED::reset(fData.fStorage, SIZE); }
270
271 private:
272     union {
273         void*   fPtrAlignment;
274         double  fDoubleAlignment;
275         char    fStorage[SIZE];
276     } fData;
277
278     typedef SkWriter32 INHERITED;
279 };
280
281 #endif