SkWriter32.h revision 046f1f6ff4b2b3f4571a9562e74f41e82419a4a1
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
1319382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkMatrix.h"
1494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com#include "SkPath.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPoint.h"
164ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h"
1719382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkRect.h"
182b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#include "SkRegion.h"
1919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkScalar.h"
2019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkStream.h"
2119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkTDArray.h"
2219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkTypes.h"
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkWriter32 : SkNoncopyable {
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
26e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com    /**
27e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     *  The caller can specify an initial block of storage, which the caller manages.
2819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *
2919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *  SkWriter32 will try to back reserve and write calls with this external storage until the
3019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *  first time an allocation doesn't fit.  From then it will use dynamically allocated storage.
3119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *  This used to be optional behavior, but pipe now relies on it.
32e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     */
33046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    SkWriter32(void* external = NULL, size_t externalBytes = 0)
34046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        : fData(0)
35046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        , fCapacity(0)
36046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        , fUsed(0)
37046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        , fExternal(0)
38046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    {
3919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        this->reset(external, externalBytes);
4019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
421cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    // return the current offset (will always be a multiple of 4)
43046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    size_t bytesWritten() const { return fUsed; }
444469938e92d779dff05e745559e67907bbf21e78reed@google.com
454469938e92d779dff05e745559e67907bbf21e78reed@google.com    SK_ATTR_DEPRECATED("use bytesWritten")
46adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com    size_t size() const { return this->bytesWritten(); }
471cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
4819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void reset(void* external = NULL, size_t externalBytes = 0) {
4919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        SkASSERT(SkIsAlign4((uintptr_t)external));
5019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        SkASSERT(SkIsAlign4(externalBytes));
51046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org
52046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fData = (uint8_t*)external;
53046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fCapacity = externalBytes;
54046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fUsed = 0;
55046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fExternal = external;
56ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org    }
57ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org
58046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    // Returns the current buffer.
59046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    // The pointer may be invalidated by any future write calls.
6019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    const uint32_t* contiguousArray() const {
61046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        return (uint32_t*)fData;
6219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
63b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com
645595af1b2ebe6590e98641464d43d22281a7f295reed@google.com    // size MUST be multiple of 4
655595af1b2ebe6590e98641464d43d22281a7f295reed@google.com    uint32_t* reserve(size_t size) {
665595af1b2ebe6590e98641464d43d22281a7f295reed@google.com        SkASSERT(SkAlign4(size) == size);
67046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        size_t offset = fUsed;
68046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        size_t totalRequired = fUsed + size;
69046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        if (totalRequired > fCapacity) {
70046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org            growToAtLeast(totalRequired);
7119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        }
72046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fUsed = totalRequired;
73046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        return (uint32_t*)(fData + offset);
7419382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
75b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com
76c6d3c444ca76feba5a8937dbc80626ade5347275commit-bot@chromium.org    // Read or write 4 bytes at offset, which must be a multiple of 4 <= size().
77046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    uint32_t read32At(size_t offset) {
78046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(SkAlign4(offset) == offset);
79046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(offset < fUsed);
80046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        return *(uint32_t*)(fData + offset);
81046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    }
82046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org
83046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    void write32At(size_t offset, uint32_t val) {
84046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(SkAlign4(offset) == offset);
85046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(offset < fUsed);
86046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        *(uint32_t*)(fData + offset) = val;
87046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    }
88a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool writeBool(bool value) {
9019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        this->write32(value);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return value;
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
93fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeInt(int32_t value) {
9519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        this->write32(value);
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
97fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write8(int32_t value) {
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
101fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write16(int32_t value) {
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
105fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write32(int32_t value) {
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value;
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
109fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
11019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void writePtr(void* value) {
11119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        *(void**)this->reserve(sizeof(value)) = value;
11251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    }
11351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeScalar(SkScalar value) {
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkScalar*)this->reserve(sizeof(value)) = value;
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
117fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writePoint(const SkPoint& pt) {
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkPoint*)this->reserve(sizeof(pt)) = pt;
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
121fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeRect(const SkRect& rect) {
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkRect*)this->reserve(sizeof(rect)) = rect;
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
125306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com
1265587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com    void writeIRect(const SkIRect& rect) {
1275587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com        *(SkIRect*)this->reserve(sizeof(rect)) = rect;
1285587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com    }
1295587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com
1304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    void writeRRect(const SkRRect& rrect) {
1314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        rrect.writeToMemory(this->reserve(SkRRect::kSizeInMemory));
1324ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    }
133306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com
13494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    void writePath(const SkPath& path) {
13594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = path.writeToMemory(NULL);
13694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        SkASSERT(SkAlign4(size) == size);
13794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        path.writeToMemory(this->reserve(size));
13894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    }
13994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
1402b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    void writeMatrix(const SkMatrix& matrix) {
14194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = matrix.writeToMemory(NULL);
1422b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        SkASSERT(SkAlign4(size) == size);
14394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        matrix.writeToMemory(this->reserve(size));
1442b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    }
145fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1462b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    void writeRegion(const SkRegion& rgn) {
14794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = rgn.writeToMemory(NULL);
1482b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        SkASSERT(SkAlign4(size) == size);
14994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        rgn.writeToMemory(this->reserve(size));
1502b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    }
1512b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // write count bytes (must be a multiple of 4)
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeMul4(const void* values, size_t size) {
1545b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com        this->write(values, size);
1555b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    }
1565b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com
1575b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    /**
1585b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     *  Write size bytes from values. size must be a multiple of 4, though
1595b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     *  values need not be 4-byte aligned.
1605b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     */
1615b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    void write(const void* values, size_t size) {
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkAlign4(size) == size);
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(this->reserve(size), values, size);
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
165fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1665a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com    /**
1675a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be
1685a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  filled in with zeroes.
1695a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     */
17019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    uint32_t* reservePad(size_t size) {
17119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        uint32_t* p = this->reserve(SkAlign4(size));
17219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        uint8_t* tail = (uint8_t*)p + size;
17319382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        switch (SkAlign4(size) - size) {
17419382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org            default: SkDEBUGFAIL("SkAlign4(x) - x should always be 0, 1, 2, or 3.");
17519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org            case 3: *tail++ = 0x00;  // fallthrough is intentional
17619382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org            case 2: *tail++ = 0x00;  // fallthrough is intentional
17719382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org            case 1: *tail++ = 0x00;
17819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org            case 0: ;/*nothing to do*/
17919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        }
18019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        return p;
18119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
1825a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com
1835a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com    /**
1845a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  Write size bytes from src, and pad to 4 byte alignment with zeroes.
1855a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     */
18619382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void writePad(const void* src, size_t size) {
18719382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        memcpy(this->reservePad(size), src, size);
18819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
189dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
190dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    /**
191dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  Writes a string to the writer, which can be retrieved with
192dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  SkReader32::readString().
193dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  The length can be specified, or if -1 is passed, it will be computed by
1940038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com     *  calling strlen(). The length must be < max size_t.
1950038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com     *
1960038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com     *  If you write NULL, it will be read as "".
197dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     */
198dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    void writeString(const char* str, size_t len = (size_t)-1);
199dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
200dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    /**
201dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  Computes the size (aligned to multiple of 4) need to write the string
202dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  in a call to writeString(). If the length is not specified, it will be
203dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  computed by calling strlen().
204dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     */
205dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
206dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
2071cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    /**
2081cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     *  Move the cursor back to offset bytes from the beginning.
209c6d3c444ca76feba5a8937dbc80626ade5347275commit-bot@chromium.org     *  offset must be a multiple of 4 no greater than size().
2101cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     */
21119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void rewindToOffset(size_t offset) {
21219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        SkASSERT(SkAlign4(offset) == offset);
213046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(offset <= bytesWritten());
214046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fUsed = offset;
21519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
2161cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // copy into a single buffer (allocated by caller). Must be at least size()
21819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void flatten(void* dst) const {
219046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        memcpy(dst, fData, fUsed);
22019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
22119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org
22219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    bool writeToStream(SkWStream* stream) const {
223046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        return stream->write(fData, fUsed);
22419382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
225fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // read from the stream, and write up to length bytes. Return the actual
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // number of bytes written.
22819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    size_t readFromStream(SkStream* stream, size_t length) {
22919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        return stream->read(this->reservePad(length), length);
2305595af1b2ebe6590e98641464d43d22281a7f295reed@google.com    }
231e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com
23219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.orgprivate:
233046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    void growToAtLeast(size_t size);
2341cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
235046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    uint8_t* fData;                // Points to either fInternal or fExternal.
236046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    size_t fCapacity;              // Number of bytes we can write to fData.
237046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    size_t fUsed;                  // Number of bytes written.
238046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    void* fExternal;               // Unmanaged memory block.
239046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    SkTDArray<uint8_t> fInternal;  // Managed memory block.
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com/**
24351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  Helper class to allocated SIZE bytes as part of the writer, and to provide
24451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  that storage to the constructor as its initial storage buffer.
24551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *
24651c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  This wrapper ensures proper alignment rules are met for the storage.
24751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com */
24851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comtemplate <size_t SIZE> class SkSWriter32 : public SkWriter32 {
24951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.compublic:
25019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    SkSWriter32() : SkWriter32(fData.fStorage, SIZE) {}
251fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
25251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comprivate:
25351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    union {
25451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        void*   fPtrAlignment;
25551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        double  fDoubleAlignment;
25651c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        char    fStorage[SIZE];
25751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    } fData;
25851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com};
25951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
261