SkWriter32.h revision 5a7c6be72b940dde8ff6ad2485a09aecd56a2660
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkWriter32_DEFINED
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkWriter32_DEFINED
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypes.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalar.h"
1694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com#include "SkPath.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPoint.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRect.h"
192b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#include "SkMatrix.h"
202b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#include "SkRegion.h"
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkStream;
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkWStream;
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkWriter32 : SkNoncopyable {
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
27e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com    /**
28e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     *  The caller can specify an initial block of storage, which the caller manages.
29e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     *  SkWriter32 will not attempt to free this in its destructor. It is up to the
30e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     *  implementation to decide if, and how much, of the storage to utilize, and it
31e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     *  is possible that it may be ignored entirely.
32e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     */
33e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com    SkWriter32(size_t minSize, void* initialStorage, size_t storageSize);
34e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com
35e1bc274295ec57cb3d3f01aaa8abff3b49c76c73vandebo@chromium.org    SkWriter32(size_t minSize)
36e1bc274295ec57cb3d3f01aaa8abff3b49c76c73vandebo@chromium.org        : fMinSize(minSize),
37e1bc274295ec57cb3d3f01aaa8abff3b49c76c73vandebo@chromium.org          fSize(0),
38e1bc274295ec57cb3d3f01aaa8abff3b49c76c73vandebo@chromium.org          fSingleBlock(NULL),
39e1bc274295ec57cb3d3f01aaa8abff3b49c76c73vandebo@chromium.org          fSingleBlockSize(0),
40e1bc274295ec57cb3d3f01aaa8abff3b49c76c73vandebo@chromium.org          fHead(NULL),
41e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com          fTail(NULL),
42e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com          fHeadIsExternalStorage(false) {}
43e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ~SkWriter32();
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
46acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    /**
47acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com     *  Returns the single block backing the writer, or NULL if the memory is
48acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com     *  to be dynamically allocated.
49acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com     */
50acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    void* getSingleBlock() const { return fSingleBlock; }
51acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
521cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    // return the current offset (will always be a multiple of 4)
531cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    uint32_t bytesWritten() const { return fSize; }
541cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    // DEPRECATED: use byetsWritten instead
551cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    uint32_t  size() const { return this->bytesWritten(); }
561cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
571cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    void      reset();
581cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    uint32_t* reserve(size_t size); // size MUST be multiple of 4
59a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com
60acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    /**
61acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com     *  Specify the single block to back the writer, rathern than dynamically
62acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com     *  allocating the memory. If block == NULL, then the writer reverts to
63acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com     *  dynamic allocation (and resets).
64acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com     */
65acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    void reset(void* block, size_t size);
66e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool writeBool(bool value) {
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->writeInt(value);
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return value;
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
71fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeInt(int32_t value) {
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value;
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
75fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write8(int32_t value) {
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write16(int32_t value) {
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
83fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write32(int32_t value) {
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value;
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
87fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
8851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    void writePtr(void* ptr) {
8951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        // Since we "know" that we're always 4-byte aligned, we can tell the
9051c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        // compiler that here, by assigning to an int32 ptr.
9151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        int32_t* addr = (int32_t*)this->reserve(sizeof(void*));
9251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        if (4 == sizeof(void*)) {
9351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com            *(void**)addr = ptr;
9451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        } else {
9551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com            memcpy(addr, &ptr, sizeof(void*));
9651c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        }
9751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    }
9851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeScalar(SkScalar value) {
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkScalar*)this->reserve(sizeof(value)) = value;
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
102fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writePoint(const SkPoint& pt) {
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkPoint*)this->reserve(sizeof(pt)) = pt;
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
106fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeRect(const SkRect& rect) {
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkRect*)this->reserve(sizeof(rect)) = rect;
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1102b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com
11194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    void writePath(const SkPath& path) {
11294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = path.writeToMemory(NULL);
11394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        SkASSERT(SkAlign4(size) == size);
11494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        path.writeToMemory(this->reserve(size));
11594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    }
11694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
1172b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    void writeMatrix(const SkMatrix& matrix) {
11894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = matrix.writeToMemory(NULL);
1192b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        SkASSERT(SkAlign4(size) == size);
12094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        matrix.writeToMemory(this->reserve(size));
1212b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    }
122fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1232b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    void writeRegion(const SkRegion& rgn) {
12494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = rgn.writeToMemory(NULL);
1252b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        SkASSERT(SkAlign4(size) == size);
12694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        rgn.writeToMemory(this->reserve(size));
1272b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    }
1282b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // write count bytes (must be a multiple of 4)
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeMul4(const void* values, size_t size) {
1315b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com        this->write(values, size);
1325b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    }
1335b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com
1345b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    /**
1355b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     *  Write size bytes from values. size must be a multiple of 4, though
1365b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     *  values need not be 4-byte aligned.
1375b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     */
1385b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    void write(const void* values, size_t size) {
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkAlign4(size) == size);
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // if we could query how much is avail in the current block, we might
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // copy that much, and then alloc the rest. That would reduce the waste
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // in the current block
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(this->reserve(size), values, size);
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
145fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1465a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com    /**
1475a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be
1485a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  filled in with zeroes.
1495a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     */
1505a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com    uint32_t* reservePad(size_t size);
1515a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com
1525a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com    /**
1535a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  Write size bytes from src, and pad to 4 byte alignment with zeroes.
1545a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     */
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writePad(const void* src, size_t size);
156dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
157dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    /**
158dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  Writes a string to the writer, which can be retrieved with
159dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  SkReader32::readString().
160dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  The length can be specified, or if -1 is passed, it will be computed by
161dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  calling strlen(). The length must be < 0xFFFF
162dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     */
163dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    void writeString(const char* str, size_t len = (size_t)-1);
164dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
165dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    /**
166dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  Computes the size (aligned to multiple of 4) need to write the string
167dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  in a call to writeString(). If the length is not specified, it will be
168dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  computed by calling strlen().
169dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     */
170dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
171dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // return the address of the 4byte int at the specified offset (which must
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // be a multiple of 4. This does not allocate any new space, so the returned
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // address is only valid for 1 int.
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t* peek32(size_t offset);
176fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1771cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    /**
1781cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     *  Move the cursor back to offset bytes from the beginning.
1791cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     *  This has the same restrictions as peek32: offset must be <= size() and
1801cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     *  offset must be a multiple of 4.
1811cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     */
1821cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    void rewindToOffset(size_t offset);
1831cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // copy into a single buffer (allocated by caller). Must be at least size()
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void flatten(void* dst) const;
186fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // read from the stream, and write up to length bytes. Return the actual
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // number of bytes written.
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t readFromStream(SkStream*, size_t length);
190fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool writeToStream(SkWStream*);
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t      fMinSize;
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint32_t    fSize;
196acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
197acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    char*       fSingleBlock;
198acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com    uint32_t    fSingleBlockSize;
199e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    struct Block;
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Block*  fHead;
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Block*  fTail;
203acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com
204e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com    bool fHeadIsExternalStorage;
205e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Block* newBlock(size_t bytes);
2071cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
2081cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    SkDEBUGCODE(void validate() const;)
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
21151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com/**
21251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  Helper class to allocated SIZE bytes as part of the writer, and to provide
21351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  that storage to the constructor as its initial storage buffer.
21451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *
21551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  This wrapper ensures proper alignment rules are met for the storage.
21651c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com */
21751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comtemplate <size_t SIZE> class SkSWriter32 : public SkWriter32 {
21851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.compublic:
21951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    SkSWriter32(size_t minSize) : SkWriter32(minSize, fData.fStorage, SIZE) {}
220fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
22151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comprivate:
22251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    union {
22351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        void*   fPtrAlignment;
22451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        double  fDoubleAlignment;
22551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        char    fStorage[SIZE];
22651c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    } fData;
22751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com};
22851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
230