SkStream.cpp revision 3b429984664e88e0530eb6a1461a828898d8d96b
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.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.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
118d0b5770f8fcfdeb8ad9808e58c49116f14b6190reed@google.com#include "SkData.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFixed.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkString.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkOSFile.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1615e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.comSK_DEFINE_INST_COUNT(SkStream)
173b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkWStream)
183b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkFILEStream)
193b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkFDStream)
203b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkMemoryStream)
213b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkBufferStream)
223b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkFILEWStream)
233b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkMemoryWStream)
243b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkDynamicMemoryWStream)
253b429984664e88e0530eb6a1461a828898d8d96breed@google.comSK_DEFINE_INST_COUNT(SkDebugWStream)
2615e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com
273b429984664e88e0530eb6a1461a828898d8d96breed@google.com///////////////////////////////////////////////////////////////////////////////
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkStream::getFileName()
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // override in subclass if you represent a file
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst void* SkStream::getMemoryBase()
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // override in subclass if you represent a memory block
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkStream::skip(size_t size)
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /*  Check for size == 0, and just return 0. If we passed that
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        to read(), it would interpret it as a request for the entire
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size of the stream.
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return size ? this->read(NULL, size) : 0;
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint8_t SkStream::readS8() {
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int8_t value;
5204225dcdec5a01bc9889b7fb03e7aceb87fccc6ereed@android.com    SkDEBUGCODE(size_t len =) this->read(&value, 1);
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(1 == len);
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return value;
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint16_t SkStream::readS16() {
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int16_t value;
5904225dcdec5a01bc9889b7fb03e7aceb87fccc6ereed@android.com    SkDEBUGCODE(size_t len =) this->read(&value, 2);
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(2 == len);
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return value;
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint32_t SkStream::readS32() {
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int32_t value;
6604225dcdec5a01bc9889b7fb03e7aceb87fccc6ereed@android.com    SkDEBUGCODE(size_t len =) this->read(&value, 4);
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(4 == len);
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return value;
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkScalar SkStream::readScalar() {
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar value;
7304225dcdec5a01bc9889b7fb03e7aceb87fccc6ereed@android.com    SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(sizeof(SkScalar) == len);
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return value;
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7819f286b6f4ca4c124250caeea7f427c870c64370reed@google.com#define SK_MAX_BYTE_FOR_U8          0xFD
7919f286b6f4ca4c124250caeea7f427c870c64370reed@google.com#define SK_BYTE_SENTINEL_FOR_U16    0xFE
8019f286b6f4ca4c124250caeea7f427c870c64370reed@google.com#define SK_BYTE_SENTINEL_FOR_U32    0xFF
8119f286b6f4ca4c124250caeea7f427c870c64370reed@google.com
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkStream::readPackedUInt() {
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t byte;
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!this->read(&byte, 1)) {
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return 0;
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8719f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
8819f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        return this->readU16();
8919f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
9019f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        return this->readU32();
9119f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    } else {
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return byte;
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkWStream::~SkWStream()
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkWStream::newline()
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->write("\n", 1);
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkWStream::flush()
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::writeText(const char text[])
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(text);
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(text, strlen(text));
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::writeDecAsText(int32_t dec)
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkString    tmp;
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    tmp.appendS32(dec);
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(tmp.c_str(), tmp.size());
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
124d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.orgbool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
125d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org{
126d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org    SkString    tmp;
127d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org    tmp.appendS64(dec, minDigits);
128d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org    return this->write(tmp.c_str(), tmp.size());
129d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org}
130d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.org
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::writeHexAsText(uint32_t hex, int digits)
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkString    tmp;
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    tmp.appendHex(hex, digits);
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(tmp.c_str(), tmp.size());
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::writeScalarAsText(SkScalar value)
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkString    tmp;
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    tmp.appendScalar(value);
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(tmp.c_str(), tmp.size());
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::write8(U8CPU value) {
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t v = SkToU8(value);
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(&v, 1);
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::write16(U16CPU value) {
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint16_t v = SkToU16(value);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(&v, 2);
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::write32(uint32_t value) {
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(&value, 4);
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::writeScalar(SkScalar value) {
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->write(&value, sizeof(value));
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::writePackedUInt(size_t value) {
16419f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    uint8_t data[5];
16519f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    size_t len = 1;
16619f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    if (value <= SK_MAX_BYTE_FOR_U8) {
16719f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        data[0] = value;
16819f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        len = 1;
16919f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    } else if (value <= 0xFFFF) {
17019f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        uint16_t value16 = value;
17119f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        data[0] = SK_BYTE_SENTINEL_FOR_U16;
17219f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        memcpy(&data[1], &value16, 2);
17319f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        len = 3;
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } else {
17519f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        uint32_t value32 = value;
17619f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        data[0] = SK_BYTE_SENTINEL_FOR_U32;
17719f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        memcpy(&data[1], &value32, 4);
17819f286b6f4ca4c124250caeea7f427c870c64370reed@google.com        len = 5;
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
18019f286b6f4ca4c124250caeea7f427c870c64370reed@google.com    return this->write(data, len);
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkWStream::writeStream(SkStream* stream, size_t length) {
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char scratch[1024];
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const size_t MAX = sizeof(scratch);
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (length != 0) {
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size_t n = length;
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (n > MAX) {
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            n = MAX;
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        stream->read(scratch, n);
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (!this->write(scratch, n)) {
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return false;
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        length -= n;
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2018a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.combool SkWStream::writeData(const SkData* data) {
2028a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (data) {
2038a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        this->write(data->data(), data->size());
2048a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    }
2058a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    return true;
2068a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com}
2078a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
2088a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com///////////////////////////////////////////////////////////////////////////////
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFILEStream::SkFILEStream(const char file[]) : fName(file)
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFILEStream::~SkFILEStream()
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFILE)
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_fclose(fFILE);
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFILEStream::setPath(const char path[])
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fName.set(path);
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFILE)
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_fclose(fFILE);
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fFILE = NULL;
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (path)
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkFILEStream::getFileName()
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fName.c_str();
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkFILEStream::rewind()
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFILE)
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (sk_frewind(fFILE))
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // we hit an error
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_fclose(fFILE);
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fFILE = NULL;
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkFILEStream::read(void* buffer, size_t size)
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFILE)
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (buffer == NULL && size == 0)    // special signature, they want the total size
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return sk_fgetsize(fFILE);
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        else
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return sk_fread(buffer, size, fFILE);
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return 0;
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2638a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com///////////////////////////////////////////////////////////////////////////////
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
26567d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.comstatic SkData* newFromParams(const void* src, size_t size, bool copyData) {
26667d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com    if (copyData) {
26767d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com        return SkData::NewWithCopy(src, size);
26867d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com    } else {
26967d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com        return SkData::NewWithProc(src, size, NULL, NULL);
27067d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com    }
27167d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com}
27267d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com
2738a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comSkMemoryStream::SkMemoryStream() {
2748a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fData = SkData::NewEmpty();
2758a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fOffset = 0;
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkMemoryStream::SkMemoryStream(size_t size) {
2798a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fOffset = 0;
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2838a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comSkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
28467d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com    fData = newFromParams(src, size, copyData);
2858a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fOffset = 0;
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2888a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comSkMemoryStream::~SkMemoryStream() {
2898a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fData->unref();
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2928a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comvoid SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
2938a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fData->unref();
2948a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fData = SkData::NewFromMalloc(src, size);
29557f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com    fOffset = 0;
29657f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com}
29757f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com
2988a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comvoid SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
2998a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fData->unref();
30067d0cff9acb2f2a9fe19c5282ca06ac3332a043creed@google.com    fData = newFromParams(src, size, copyData);
3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fOffset = 0;
3028a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com}
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3048a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comSkData* SkMemoryStream::copyToData() const {
3058a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fData->ref();
3068a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    return fData;
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3098a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comSkData* SkMemoryStream::setData(SkData* data) {
3108a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    SkRefCnt_SafeAssign(fData, data);
3118a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    return data;
3128a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com}
3138a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
3148a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comvoid SkMemoryStream::skipToAlign4() {
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // cast to remove unary-minus warning
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fOffset += -(int)fOffset & 0x03;
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3198a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.combool SkMemoryStream::rewind() {
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fOffset = 0;
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3248a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comsize_t SkMemoryStream::read(void* buffer, size_t size) {
3258a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    size_t dataSize = fData->size();
3268a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (buffer == NULL && size == 0)    // special signature, they want the total size
3288a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        return dataSize;
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // if buffer is NULL, seek ahead by size
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3328a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (size == 0) {
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return 0;
3348a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    }
3358a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (size > dataSize - fOffset) {
3368a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        size = dataSize - fOffset;
3378a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    }
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (buffer) {
3398a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        memcpy(buffer, fData->bytes() + fOffset, size);
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fOffset += size;
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return size;
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3458a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comconst void* SkMemoryStream::getMemoryBase() {
3468a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    return fData->data();
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3498a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comconst void* SkMemoryStream::getAtPos() {
3508a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    return fData->bytes() + fOffset;
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3538a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comsize_t SkMemoryStream::seek(size_t offset) {
3548a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (offset > fData->size()) {
3558a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        offset = fData->size();
3568a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    }
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fOffset = offset;
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return offset;
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3618a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com///////////////////////////////////////////////////////////////////////////////
3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBufferStream::SkBufferStream(SkStream* proxy, size_t bufferSize)
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    : fProxy(proxy)
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(proxy != NULL);
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    proxy->ref();
3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->init(NULL, bufferSize);
3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBufferStream::SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize)
3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    : fProxy(proxy)
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(proxy != NULL);
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(buffer == NULL || bufferSize != 0);    // init(addr, 0) makes no sense, we must know how big their buffer is
3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    proxy->ref();
3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->init(buffer, bufferSize);
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkBufferStream::init(void* buffer, size_t bufferSize)
3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bufferSize == 0)
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferSize = kDefaultBufferSize;
3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fOrigBufferSize = bufferSize;
3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBufferSize = bufferSize;
3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBufferOffset = bufferSize; // to trigger a reload on the first read()
3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (buffer == NULL)
3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBuffer = (char*)sk_malloc_throw(fBufferSize);
3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fWeOwnTheBuffer = true;
3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    else
3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBuffer = (char*)buffer;
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fWeOwnTheBuffer = false;
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBufferStream::~SkBufferStream()
4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fProxy->unref();
4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fWeOwnTheBuffer)
4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_free(fBuffer);
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkBufferStream::rewind()
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBufferOffset = fBufferSize = fOrigBufferSize;
4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fProxy->rewind();
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char* SkBufferStream::getFileName()
4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fProxy->getFileName();
4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//  #define SK_TRACE_BUFFERSTREAM
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkBufferStream::read(void* buffer, size_t size) {
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_BUFFERSTREAM
4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("Request %d", size);
4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (buffer == NULL && size == 0) {
4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return fProxy->read(buffer, size);    // requesting total size
4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (0 == size) {
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return 0;
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // skip size bytes
4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (NULL == buffer) {
4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size_t remaining = fBufferSize - fBufferOffset;
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (remaining >= size) {
4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fBufferOffset += size;
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return size;
4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // if we get here, we are being asked to skip beyond our current buffer
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // so reset our offset to force a read next time, and skip the diff
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // in our proxy
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBufferOffset = fOrigBufferSize;
4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return remaining + fProxy->read(NULL, size - remaining);
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t s = size;
4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t actuallyRead = 0;
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // flush what we can from our fBuffer
4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fBufferOffset < fBufferSize)
4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (s > fBufferSize - fBufferOffset)
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            s = fBufferSize - fBufferOffset;
4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(buffer, fBuffer + fBufferOffset, s);
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_BUFFERSTREAM
4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf(" flush %d", s);
4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size -= s;
4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBufferOffset += s;
4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        buffer = (char*)buffer + s;
4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        actuallyRead = s;
4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // check if there is more to read
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (size)
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(fBufferOffset >= fBufferSize); // need to refill our fBuffer
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (size < fBufferSize) // lets try to read more than the request
4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        {
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            s = fProxy->read(fBuffer, fBufferSize);
4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_BUFFERSTREAM
4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkDebugf(" read %d into fBuffer", s);
4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (size > s)   // they asked for too much
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                size = s;
4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (size)
4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            {
4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                memcpy(buffer, fBuffer, size);
4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                actuallyRead += size;
4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_BUFFERSTREAM
4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkDebugf(" memcpy %d into dst", size);
4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fBufferOffset = size;
4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fBufferSize = s;        // record the (possibly smaller) size for the buffer
4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        else    // just do a direct read
4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        {
4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            actuallyRead += fProxy->read(buffer, size);
4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_BUFFERSTREAM
4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkDebugf(" direct read %d", size);
4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_BUFFERSTREAM
5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("\n");
5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return actuallyRead;
5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst void* SkBufferStream::getMemoryBase()
5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fProxy->getMemoryBase();
5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////////////////////////////////
5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////////////////////////////////
5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFILEWStream::SkFILEWStream(const char path[])
5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFILEWStream::~SkFILEWStream()
5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFILE)
5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_fclose(fFILE);
5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkFILEWStream::write(const void* buffer, size_t size)
5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFILE == NULL)
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return false;
5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (sk_fwrite(buffer, size, fFILE) != size)
5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_fclose(fFILE);
5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fFILE = NULL;
5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return false;
5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFILEWStream::flush()
5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fFILE)
5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_fflush(fFILE);
5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////
5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkMemoryWStream::write(const void* buffer, size_t size)
5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size = SkMin32(size, fMaxLength - fBytesWritten);
5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (size > 0)
5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(fBuffer + fBytesWritten, buffer, size);
5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBytesWritten += size;
5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////
5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkDynamicMemoryWStream_MinBlockSize   256
5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkDynamicMemoryWStream::Block {
5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Block*  fNext;
5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char*   fCurr;
5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char*   fStop;
5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const char* start() const { return (const char*)(this + 1); }
5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char*   start() { return (char*)(this + 1); }
5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t  avail() const { return fStop - fCurr; }
5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t  written() const { return fCurr - this->start(); }
5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void init(size_t size)
5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fNext = NULL;
5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fCurr = this->start();
5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fStop = this->start() + size;
5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const void* append(const void* data, size_t size)
5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT((size_t)(fStop - fCurr) >= size);
5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memcpy(fCurr, data, size);
5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fCurr += size;
5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return (const void*)((const char*)data + size);
5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5968a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comSkDynamicMemoryWStream::SkDynamicMemoryWStream()
5978a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDynamicMemoryWStream::~SkDynamicMemoryWStream()
6028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    reset();
6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDynamicMemoryWStream::reset()
6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
6088a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    this->invalidateCopy();
6098a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Block*  block = fHead;
6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (block != NULL) {
6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Block*  next = block->fNext;
6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        sk_free(block);
6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        block = next;
6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fHead = fTail = NULL;
6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBytesWritten = 0;
6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (count > 0) {
6248a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        this->invalidateCopy();
6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBytesWritten += count;
6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size_t  size;
6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fTail != NULL && fTail->avail() > 0) {
6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            size = SkMin32(fTail->avail(), count);
6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            buffer = fTail->append(buffer, size);
6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkASSERT(count >= size);
6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            count -= size;
6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count == 0)
6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size = SkMax32(count, SkDynamicMemoryWStream_MinBlockSize);
6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        block->init(size);
6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        block->append(buffer, count);
6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fTail != NULL)
6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fTail->fNext = block;
6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        else
6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fHead = fTail = block;
6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fTail = block;
6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
6558a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (offset + count > fBytesWritten) {
6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return false; // test does not partially modify
6578a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    }
6588a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
6598a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    this->invalidateCopy();
6608a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Block* block = fHead;
6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (block != NULL) {
6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size_t size = block->written();
6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (offset < size) {
6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            size_t part = offset + count > size ? size - offset : count;
6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            memcpy(block->start() + offset, buffer, part);
6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= part)
6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            count -= part;
6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            buffer = (const void*) ((char* ) buffer + part);
6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        offset = offset > size ? offset - size : 0;
6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        block = block->fNext;
6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (offset + count > fBytesWritten)
6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return false; // test does not partially modify
6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Block* block = fHead;
6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (block != NULL) {
6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        size_t size = block->written();
6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (offset < size) {
6868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            size_t part = offset + count > size ? size - offset : count;
6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            memcpy(buffer, block->start() + offset, part);
6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (count <= part)
6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            count -= part;
6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            buffer = (void*) ((char* ) buffer + part);
6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        offset = offset > size ? offset - size : 0;
6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        block = block->fNext;
6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return false;
6978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDynamicMemoryWStream::copyTo(void* dst) const
7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
7018a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (fCopy) {
7028a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        memcpy(dst, fCopy->data(), fBytesWritten);
7038a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    } else {
7048a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        Block* block = fHead;
7058a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
7068a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        while (block != NULL) {
7078a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com            size_t size = block->written();
7088a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com            memcpy(dst, block->start(), size);
7098a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com            dst = (void*)((char*)dst + size);
7108a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com            block = block->fNext;
7118a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        }
7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDynamicMemoryWStream::padToAlign4()
7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // cast to remove unary-minus warning
7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int padBytes = -(int)fBytesWritten & 0x03;
7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (padBytes == 0)
7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int zero = 0;
7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    write(&zero, padBytes);
7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7258a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comSkData* SkDynamicMemoryWStream::copyToData() const {
7268a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (NULL == fCopy) {
7278a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        void* buffer = sk_malloc_throw(fBytesWritten);
7288a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        this->copyTo(buffer);
7298a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
7308a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    }
7318a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    fCopy->ref();
7328a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    return fCopy;
73370442a6cf73c9a822df23961f5e16dc3abc18f26reed@google.com}
73470442a6cf73c9a822df23961f5e16dc3abc18f26reed@google.com
7358a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.comvoid SkDynamicMemoryWStream::invalidateCopy() {
7368a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    if (fCopy) {
7378a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        fCopy->unref();
7388a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        fCopy = NULL;
7398a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    }
74070442a6cf73c9a822df23961f5e16dc3abc18f26reed@google.com}
74170442a6cf73c9a822df23961f5e16dc3abc18f26reed@google.com
7428a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com///////////////////////////////////////////////////////////////////////////////
7438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDebugWStream::newline()
7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("\n");
7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDebugWStream::write(const void* buffer, size_t size)
7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* s = new char[size+1];
7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    memcpy(s, buffer, size);
7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    s[size] = 0;
7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("%s", s);
7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    delete[] s;
7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
762