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