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
13f3c15b7cfc4eed2528f7db87ea6c1444b55ee856bungeman#include "../private/SkTemplates.h"
14c30dcb9b128887c7e16afe32fdf35105cc42380bcommit-bot@chromium.org#include "SkData.h"
1519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkMatrix.h"
1694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com#include "SkPath.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPoint.h"
184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h"
1919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkRect.h"
202b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#include "SkRegion.h"
2119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkScalar.h"
2219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkStream.h"
2319382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org#include "SkTypes.h"
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
253f547cb6a7fcb86d01e063b99c2d8b79d356e87fbsalomonclass SK_API SkWriter32 : SkNoncopyable {
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
27e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com    /**
28e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     *  The caller can specify an initial block of storage, which the caller manages.
2919382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *
3019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *  SkWriter32 will try to back reserve and write calls with this external storage until the
3119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *  first time an allocation doesn't fit.  From then it will use dynamically allocated storage.
3219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org     *  This used to be optional behavior, but pipe now relies on it.
33e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com     */
34ca21a00c736d05686c84ab874ce6a49008da6a76commit-bot@chromium.org    SkWriter32(void* external = NULL, size_t externalBytes = 0) {
3519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        this->reset(external, externalBytes);
3619382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
381cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    // return the current offset (will always be a multiple of 4)
39046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    size_t bytesWritten() const { return fUsed; }
404469938e92d779dff05e745559e67907bbf21e78reed@google.com
414469938e92d779dff05e745559e67907bbf21e78reed@google.com    SK_ATTR_DEPRECATED("use bytesWritten")
42adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com    size_t size() const { return this->bytesWritten(); }
431cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
4419382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void reset(void* external = NULL, size_t externalBytes = 0) {
4519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        SkASSERT(SkIsAlign4((uintptr_t)external));
4619382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        SkASSERT(SkIsAlign4(externalBytes));
47046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org
48046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fData = (uint8_t*)external;
49046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fCapacity = externalBytes;
50046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fUsed = 0;
51046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fExternal = external;
52ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org    }
53ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org
54046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    // Returns the current buffer.
55046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    // The pointer may be invalidated by any future write calls.
5619382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    const uint32_t* contiguousArray() const {
57046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        return (uint32_t*)fData;
5819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
59b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com
605595af1b2ebe6590e98641464d43d22281a7f295reed@google.com    // size MUST be multiple of 4
615595af1b2ebe6590e98641464d43d22281a7f295reed@google.com    uint32_t* reserve(size_t size) {
625595af1b2ebe6590e98641464d43d22281a7f295reed@google.com        SkASSERT(SkAlign4(size) == size);
63046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        size_t offset = fUsed;
64046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        size_t totalRequired = fUsed + size;
65046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        if (totalRequired > fCapacity) {
66a87b21cd0041bac0d96b6836ac6e71a2dbcd4e10commit-bot@chromium.org            this->growToAtLeast(totalRequired);
6719382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        }
68046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fUsed = totalRequired;
69046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        return (uint32_t*)(fData + offset);
7019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
71b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com
72536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org    /**
73536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org     *  Read a T record at offset, which must be a multiple of 4. Only legal if the record
74c30dcb9b128887c7e16afe32fdf35105cc42380bcommit-bot@chromium.org     *  was written atomically using the write methods below.
75536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org     */
76536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org    template<typename T>
77536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org    const T& readTAt(size_t offset) const {
78046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(SkAlign4(offset) == offset);
79046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(offset < fUsed);
80536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org        return *(T*)(fData + offset);
81046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    }
82046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org
83536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org    /**
84536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org     *  Overwrite a T record at offset, which must be a multiple of 4. Only legal if the record
85c30dcb9b128887c7e16afe32fdf35105cc42380bcommit-bot@chromium.org     *  was written atomically using the write methods below.
86536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org     */
87536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org    template<typename T>
88536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org    void overwriteTAt(size_t offset, const T& value) {
89046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(SkAlign4(offset) == offset);
90046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(offset < fUsed);
91536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org        *(T*)(fData + offset) = value;
92046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    }
93a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool writeBool(bool value) {
9519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        this->write32(value);
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return value;
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
98fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeInt(int32_t value) {
10019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        this->write32(value);
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
102fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write8(int32_t value) {
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
106fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write16(int32_t value) {
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
110fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void write32(int32_t value) {
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(int32_t*)this->reserve(sizeof(value)) = value;
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
114fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
11519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void writePtr(void* value) {
11619382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        *(void**)this->reserve(sizeof(value)) = value;
11751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    }
11851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeScalar(SkScalar value) {
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkScalar*)this->reserve(sizeof(value)) = value;
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
122fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writePoint(const SkPoint& pt) {
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkPoint*)this->reserve(sizeof(pt)) = pt;
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
126fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeRect(const SkRect& rect) {
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *(SkRect*)this->reserve(sizeof(rect)) = rect;
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
130306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com
1315587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com    void writeIRect(const SkIRect& rect) {
1325587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com        *(SkIRect*)this->reserve(sizeof(rect)) = rect;
1335587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com    }
1345587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com
1354ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    void writeRRect(const SkRRect& rrect) {
1364ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com        rrect.writeToMemory(this->reserve(SkRRect::kSizeInMemory));
1374ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com    }
138306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com
13994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    void writePath(const SkPath& path) {
14094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = path.writeToMemory(NULL);
14194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        SkASSERT(SkAlign4(size) == size);
14294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        path.writeToMemory(this->reserve(size));
14394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    }
14494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com
1452b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    void writeMatrix(const SkMatrix& matrix) {
14694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = matrix.writeToMemory(NULL);
1472b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        SkASSERT(SkAlign4(size) == size);
14894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        matrix.writeToMemory(this->reserve(size));
1492b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    }
150fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1512b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    void writeRegion(const SkRegion& rgn) {
15294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        size_t size = rgn.writeToMemory(NULL);
1532b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com        SkASSERT(SkAlign4(size) == size);
15494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com        rgn.writeToMemory(this->reserve(size));
1552b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    }
1562b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // write count bytes (must be a multiple of 4)
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void writeMul4(const void* values, size_t size) {
1595b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com        this->write(values, size);
1605b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    }
1615b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com
1625b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    /**
1635b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     *  Write size bytes from values. size must be a multiple of 4, though
1645b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     *  values need not be 4-byte aligned.
1655b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com     */
1665b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com    void write(const void* values, size_t size) {
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(SkAlign4(size) == size);
168e0021c0b05e78e12cd58727e770f28a45a848bb4mtklein        sk_careful_memcpy(this->reserve(size), values, size);
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
170fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1715a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com    /**
1725a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be
1735a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  filled in with zeroes.
1745a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     */
17519382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    uint32_t* reservePad(size_t size) {
176536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org        size_t alignedSize = SkAlign4(size);
177536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org        uint32_t* p = this->reserve(alignedSize);
178536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org        if (alignedSize != size) {
179536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org            SkASSERT(alignedSize >= 4);
180536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org            p[alignedSize / 4 - 1] = 0;
18119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        }
18219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        return p;
18319382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
1845a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com
1855a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com    /**
1865a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     *  Write size bytes from src, and pad to 4 byte alignment with zeroes.
1875a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com     */
18819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void writePad(const void* src, size_t size) {
189cff15aa36d750bc84bd6a48a66c9969f57476decmtklein        sk_careful_memcpy(this->reservePad(size), src, size);
19019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
191dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
192dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    /**
193dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  Writes a string to the writer, which can be retrieved with
194dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  SkReader32::readString().
195dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  The length can be specified, or if -1 is passed, it will be computed by
1960038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com     *  calling strlen(). The length must be < max size_t.
1970038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com     *
1980038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com     *  If you write NULL, it will be read as "".
199dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     */
200dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    void writeString(const char* str, size_t len = (size_t)-1);
201dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
202dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    /**
203dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  Computes the size (aligned to multiple of 4) need to write the string
204dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  in a call to writeString(). If the length is not specified, it will be
205dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     *  computed by calling strlen().
206dde0956375e87027df2fdd80d430dd819c217aacreed@google.com     */
207dde0956375e87027df2fdd80d430dd819c217aacreed@google.com    static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
208dde0956375e87027df2fdd80d430dd819c217aacreed@google.com
2091cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com    /**
2101cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     *  Move the cursor back to offset bytes from the beginning.
211c6d3c444ca76feba5a8937dbc80626ade5347275commit-bot@chromium.org     *  offset must be a multiple of 4 no greater than size().
2121cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com     */
21319382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void rewindToOffset(size_t offset) {
21419382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        SkASSERT(SkAlign4(offset) == offset);
215046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        SkASSERT(offset <= bytesWritten());
216046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        fUsed = offset;
21719382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
2181cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // copy into a single buffer (allocated by caller). Must be at least size()
22019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    void flatten(void* dst) const {
221046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        memcpy(dst, fData, fUsed);
22219382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
22319382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org
22419382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    bool writeToStream(SkWStream* stream) const {
225046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org        return stream->write(fData, fUsed);
22619382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    }
227fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // read from the stream, and write up to length bytes. Return the actual
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // number of bytes written.
23019382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org    size_t readFromStream(SkStream* stream, size_t length) {
23119382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.org        return stream->read(this->reservePad(length), length);
2325595af1b2ebe6590e98641464d43d22281a7f295reed@google.com    }
233e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com
234c30dcb9b128887c7e16afe32fdf35105cc42380bcommit-bot@chromium.org    /**
235c30dcb9b128887c7e16afe32fdf35105cc42380bcommit-bot@chromium.org     *  Captures a snapshot of the data as it is right now, and return it.
236c30dcb9b128887c7e16afe32fdf35105cc42380bcommit-bot@chromium.org     */
237c30dcb9b128887c7e16afe32fdf35105cc42380bcommit-bot@chromium.org    SkData* snapshotAsData() const;
23819382421b916aab00be7265815ba4e2690adf2c9commit-bot@chromium.orgprivate:
239046f1f6ff4b2b3f4571a9562e74f41e82419a4a1commit-bot@chromium.org    void growToAtLeast(size_t size);
2401cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com
241ca21a00c736d05686c84ab874ce6a49008da6a76commit-bot@chromium.org    uint8_t* fData;                    // Points to either fInternal or fExternal.
242ca21a00c736d05686c84ab874ce6a49008da6a76commit-bot@chromium.org    size_t fCapacity;                  // Number of bytes we can write to fData.
243ca21a00c736d05686c84ab874ce6a49008da6a76commit-bot@chromium.org    size_t fUsed;                      // Number of bytes written.
244ca21a00c736d05686c84ab874ce6a49008da6a76commit-bot@chromium.org    void* fExternal;                   // Unmanaged memory block.
245ca21a00c736d05686c84ab874ce6a49008da6a76commit-bot@chromium.org    SkAutoTMalloc<uint8_t> fInternal;  // Managed memory block.
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com/**
24951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  Helper class to allocated SIZE bytes as part of the writer, and to provide
25051c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  that storage to the constructor as its initial storage buffer.
25151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *
25251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *  This wrapper ensures proper alignment rules are met for the storage.
25351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com */
25451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comtemplate <size_t SIZE> class SkSWriter32 : public SkWriter32 {
25551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.compublic:
256a87b21cd0041bac0d96b6836ac6e71a2dbcd4e10commit-bot@chromium.org    SkSWriter32() { this->reset(); }
257a87b21cd0041bac0d96b6836ac6e71a2dbcd4e10commit-bot@chromium.org
258a87b21cd0041bac0d96b6836ac6e71a2dbcd4e10commit-bot@chromium.org    void reset() {this->INHERITED::reset(fData.fStorage, SIZE); }
259fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
26051c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comprivate:
26151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    union {
26251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        void*   fPtrAlignment;
26351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        double  fDoubleAlignment;
26451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com        char    fStorage[SIZE];
26551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com    } fData;
266a87b21cd0041bac0d96b6836ac6e71a2dbcd4e10commit-bot@chromium.org
267a87b21cd0041bac0d96b6836ac6e71a2dbcd4e10commit-bot@chromium.org    typedef SkWriter32 INHERITED;
26851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com};
26951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
271