Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkStream.h"
     11 #include "SkStreamPriv.h"
     12 #include "SkData.h"
     13 #include "SkFixed.h"
     14 #include "SkString.h"
     15 #include "SkOSFile.h"
     16 #include "SkTypes.h"
     17 
     18 ///////////////////////////////////////////////////////////////////////////////
     19 
     20 
     21 int8_t SkStream::readS8() {
     22     int8_t value;
     23     SkDEBUGCODE(size_t len =) this->read(&value, 1);
     24     SkASSERT(1 == len);
     25     return value;
     26 }
     27 
     28 int16_t SkStream::readS16() {
     29     int16_t value;
     30     SkDEBUGCODE(size_t len =) this->read(&value, 2);
     31     SkASSERT(2 == len);
     32     return value;
     33 }
     34 
     35 int32_t SkStream::readS32() {
     36     int32_t value;
     37     SkDEBUGCODE(size_t len =) this->read(&value, 4);
     38     SkASSERT(4 == len);
     39     return value;
     40 }
     41 
     42 SkScalar SkStream::readScalar() {
     43     SkScalar value;
     44     SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
     45     SkASSERT(sizeof(SkScalar) == len);
     46     return value;
     47 }
     48 
     49 #define SK_MAX_BYTE_FOR_U8          0xFD
     50 #define SK_BYTE_SENTINEL_FOR_U16    0xFE
     51 #define SK_BYTE_SENTINEL_FOR_U32    0xFF
     52 
     53 size_t SkStream::readPackedUInt() {
     54     uint8_t byte;
     55     if (!this->read(&byte, 1)) {
     56         return 0;
     57     }
     58     if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
     59         return this->readU16();
     60     } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
     61         return this->readU32();
     62     } else {
     63         return byte;
     64     }
     65 }
     66 
     67 //////////////////////////////////////////////////////////////////////////////////////
     68 
     69 SkWStream::~SkWStream()
     70 {
     71 }
     72 
     73 void SkWStream::newline()
     74 {
     75     this->write("\n", 1);
     76 }
     77 
     78 void SkWStream::flush()
     79 {
     80 }
     81 
     82 bool SkWStream::writeText(const char text[])
     83 {
     84     SkASSERT(text);
     85     return this->write(text, strlen(text));
     86 }
     87 
     88 bool SkWStream::writeDecAsText(int32_t dec)
     89 {
     90     char buffer[SkStrAppendS32_MaxSize];
     91     char* stop = SkStrAppendS32(buffer, dec);
     92     return this->write(buffer, stop - buffer);
     93 }
     94 
     95 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
     96 {
     97     char buffer[SkStrAppendU64_MaxSize];
     98     char* stop = SkStrAppendU64(buffer, dec, minDigits);
     99     return this->write(buffer, stop - buffer);
    100 }
    101 
    102 bool SkWStream::writeHexAsText(uint32_t hex, int digits)
    103 {
    104     SkString    tmp;
    105     tmp.appendHex(hex, digits);
    106     return this->write(tmp.c_str(), tmp.size());
    107 }
    108 
    109 bool SkWStream::writeScalarAsText(SkScalar value)
    110 {
    111     char buffer[SkStrAppendScalar_MaxSize];
    112     char* stop = SkStrAppendScalar(buffer, value);
    113     return this->write(buffer, stop - buffer);
    114 }
    115 
    116 bool SkWStream::write8(U8CPU value) {
    117     uint8_t v = SkToU8(value);
    118     return this->write(&v, 1);
    119 }
    120 
    121 bool SkWStream::write16(U16CPU value) {
    122     uint16_t v = SkToU16(value);
    123     return this->write(&v, 2);
    124 }
    125 
    126 bool SkWStream::write32(uint32_t value) {
    127     return this->write(&value, 4);
    128 }
    129 
    130 bool SkWStream::writeScalar(SkScalar value) {
    131     return this->write(&value, sizeof(value));
    132 }
    133 
    134 int SkWStream::SizeOfPackedUInt(size_t value) {
    135     if (value <= SK_MAX_BYTE_FOR_U8) {
    136         return 1;
    137     } else if (value <= 0xFFFF) {
    138         return 3;
    139     }
    140     return 5;
    141 }
    142 
    143 bool SkWStream::writePackedUInt(size_t value) {
    144     uint8_t data[5];
    145     size_t len = 1;
    146     if (value <= SK_MAX_BYTE_FOR_U8) {
    147         data[0] = value;
    148         len = 1;
    149     } else if (value <= 0xFFFF) {
    150         uint16_t value16 = value;
    151         data[0] = SK_BYTE_SENTINEL_FOR_U16;
    152         memcpy(&data[1], &value16, 2);
    153         len = 3;
    154     } else {
    155         uint32_t value32 = SkToU32(value);
    156         data[0] = SK_BYTE_SENTINEL_FOR_U32;
    157         memcpy(&data[1], &value32, 4);
    158         len = 5;
    159     }
    160     return this->write(data, len);
    161 }
    162 
    163 bool SkWStream::writeStream(SkStream* stream, size_t length) {
    164     char scratch[1024];
    165     const size_t MAX = sizeof(scratch);
    166 
    167     while (length != 0) {
    168         size_t n = length;
    169         if (n > MAX) {
    170             n = MAX;
    171         }
    172         stream->read(scratch, n);
    173         if (!this->write(scratch, n)) {
    174             return false;
    175         }
    176         length -= n;
    177     }
    178     return true;
    179 }
    180 
    181 ///////////////////////////////////////////////////////////////////////////////
    182 
    183 SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) {
    184     fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
    185 }
    186 
    187 SkFILEStream::SkFILEStream(FILE* file, Ownership ownership)
    188     : fFILE((SkFILE*)file)
    189     , fOwnership(ownership) {
    190 }
    191 
    192 SkFILEStream::~SkFILEStream() {
    193     if (fFILE && fOwnership != kCallerRetains_Ownership) {
    194         sk_fclose(fFILE);
    195     }
    196 }
    197 
    198 void SkFILEStream::setPath(const char path[]) {
    199     fName.set(path);
    200     if (fFILE) {
    201         sk_fclose(fFILE);
    202         fFILE = NULL;
    203     }
    204     if (path) {
    205         fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
    206     }
    207 }
    208 
    209 size_t SkFILEStream::read(void* buffer, size_t size) {
    210     if (fFILE) {
    211         return sk_fread(buffer, size, fFILE);
    212     }
    213     return 0;
    214 }
    215 
    216 bool SkFILEStream::isAtEnd() const {
    217     return sk_feof(fFILE);
    218 }
    219 
    220 bool SkFILEStream::rewind() {
    221     if (fFILE) {
    222         if (sk_frewind(fFILE)) {
    223             return true;
    224         }
    225         // we hit an error
    226         sk_fclose(fFILE);
    227         fFILE = NULL;
    228     }
    229     return false;
    230 }
    231 
    232 SkStreamAsset* SkFILEStream::duplicate() const {
    233     if (NULL == fFILE) {
    234         return new SkMemoryStream();
    235     }
    236 
    237     if (fData.get()) {
    238         return new SkMemoryStream(fData);
    239     }
    240 
    241     if (!fName.isEmpty()) {
    242         SkAutoTDelete<SkFILEStream> that(new SkFILEStream(fName.c_str()));
    243         if (sk_fidentical(that->fFILE, this->fFILE)) {
    244             return that.detach();
    245         }
    246     }
    247 
    248     fData.reset(SkData::NewFromFILE(fFILE));
    249     if (NULL == fData.get()) {
    250         return NULL;
    251     }
    252     return new SkMemoryStream(fData);
    253 }
    254 
    255 size_t SkFILEStream::getPosition() const {
    256     return sk_ftell(fFILE);
    257 }
    258 
    259 bool SkFILEStream::seek(size_t position) {
    260     return sk_fseek(fFILE, position);
    261 }
    262 
    263 bool SkFILEStream::move(long offset) {
    264     return sk_fmove(fFILE, offset);
    265 }
    266 
    267 SkStreamAsset* SkFILEStream::fork() const {
    268     SkAutoTDelete<SkStreamAsset> that(this->duplicate());
    269     that->seek(this->getPosition());
    270     return that.detach();
    271 }
    272 
    273 size_t SkFILEStream::getLength() const {
    274     return sk_fgetsize(fFILE);
    275 }
    276 
    277 const void* SkFILEStream::getMemoryBase() {
    278     if (NULL == fData.get()) {
    279         return NULL;
    280     }
    281     return fData->data();
    282 }
    283 
    284 ///////////////////////////////////////////////////////////////////////////////
    285 
    286 static SkData* newFromParams(const void* src, size_t size, bool copyData) {
    287     if (copyData) {
    288         return SkData::NewWithCopy(src, size);
    289     } else {
    290         return SkData::NewWithoutCopy(src, size);
    291     }
    292 }
    293 
    294 SkMemoryStream::SkMemoryStream() {
    295     fData = SkData::NewEmpty();
    296     fOffset = 0;
    297 }
    298 
    299 SkMemoryStream::SkMemoryStream(size_t size) {
    300     fData = SkData::NewUninitialized(size);
    301     fOffset = 0;
    302 }
    303 
    304 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
    305     fData = newFromParams(src, size, copyData);
    306     fOffset = 0;
    307 }
    308 
    309 SkMemoryStream::SkMemoryStream(SkData* data) {
    310     if (NULL == data) {
    311         fData = SkData::NewEmpty();
    312     } else {
    313         fData = data;
    314         fData->ref();
    315     }
    316     fOffset = 0;
    317 }
    318 
    319 SkMemoryStream::~SkMemoryStream() {
    320     fData->unref();
    321 }
    322 
    323 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
    324     fData->unref();
    325     fData = SkData::NewFromMalloc(src, size);
    326     fOffset = 0;
    327 }
    328 
    329 void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
    330     fData->unref();
    331     fData = newFromParams(src, size, copyData);
    332     fOffset = 0;
    333 }
    334 
    335 SkData* SkMemoryStream::copyToData() const {
    336     fData->ref();
    337     return fData;
    338 }
    339 
    340 SkData* SkMemoryStream::setData(SkData* data) {
    341     fData->unref();
    342     if (NULL == data) {
    343         fData = SkData::NewEmpty();
    344     } else {
    345         fData = data;
    346         fData->ref();
    347     }
    348     fOffset = 0;
    349     return data;
    350 }
    351 
    352 void SkMemoryStream::skipToAlign4() {
    353     // cast to remove unary-minus warning
    354     fOffset += -(int)fOffset & 0x03;
    355 }
    356 
    357 size_t SkMemoryStream::read(void* buffer, size_t size) {
    358     size_t dataSize = fData->size();
    359 
    360     if (size > dataSize - fOffset) {
    361         size = dataSize - fOffset;
    362     }
    363     if (buffer) {
    364         memcpy(buffer, fData->bytes() + fOffset, size);
    365     }
    366     fOffset += size;
    367     return size;
    368 }
    369 
    370 bool SkMemoryStream::peek(void* buffer, size_t size) const {
    371     SkASSERT(buffer != NULL);
    372     const size_t position = fOffset;
    373     if (size > fData->size() - position) {
    374         // The stream is not large enough to satisfy this request.
    375         return false;
    376     }
    377     SkMemoryStream* nonConstThis = const_cast<SkMemoryStream*>(this);
    378     SkDEBUGCODE(const size_t bytesRead =) nonConstThis->read(buffer, size);
    379     SkASSERT(bytesRead == size);
    380     nonConstThis->fOffset = position;
    381     return true;
    382 }
    383 
    384 bool SkMemoryStream::isAtEnd() const {
    385     return fOffset == fData->size();
    386 }
    387 
    388 bool SkMemoryStream::rewind() {
    389     fOffset = 0;
    390     return true;
    391 }
    392 
    393 SkMemoryStream* SkMemoryStream::duplicate() const {
    394     return SkNEW_ARGS(SkMemoryStream, (fData));
    395 }
    396 
    397 size_t SkMemoryStream::getPosition() const {
    398     return fOffset;
    399 }
    400 
    401 bool SkMemoryStream::seek(size_t position) {
    402     fOffset = position > fData->size()
    403             ? fData->size()
    404             : position;
    405     return true;
    406 }
    407 
    408 bool SkMemoryStream::move(long offset) {
    409     return this->seek(fOffset + offset);
    410 }
    411 
    412 SkMemoryStream* SkMemoryStream::fork() const {
    413     SkAutoTDelete<SkMemoryStream> that(this->duplicate());
    414     that->seek(fOffset);
    415     return that.detach();
    416 }
    417 
    418 size_t SkMemoryStream::getLength() const {
    419     return fData->size();
    420 }
    421 
    422 const void* SkMemoryStream::getMemoryBase() {
    423     return fData->data();
    424 }
    425 
    426 const void* SkMemoryStream::getAtPos() {
    427     return fData->bytes() + fOffset;
    428 }
    429 
    430 /////////////////////////////////////////////////////////////////////////////////////////////////////////
    431 /////////////////////////////////////////////////////////////////////////////////////////////////////////
    432 
    433 SkFILEWStream::SkFILEWStream(const char path[])
    434 {
    435     fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
    436 }
    437 
    438 SkFILEWStream::~SkFILEWStream()
    439 {
    440     if (fFILE) {
    441         sk_fclose(fFILE);
    442     }
    443 }
    444 
    445 size_t SkFILEWStream::bytesWritten() const {
    446     return sk_ftell(fFILE);
    447 }
    448 
    449 bool SkFILEWStream::write(const void* buffer, size_t size)
    450 {
    451     if (fFILE == NULL) {
    452         return false;
    453     }
    454 
    455     if (sk_fwrite(buffer, size, fFILE) != size)
    456     {
    457         SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
    458         sk_fclose(fFILE);
    459         fFILE = NULL;
    460         return false;
    461     }
    462     return true;
    463 }
    464 
    465 void SkFILEWStream::flush()
    466 {
    467     if (fFILE) {
    468         sk_fflush(fFILE);
    469     }
    470 }
    471 
    472 ////////////////////////////////////////////////////////////////////////
    473 
    474 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
    475     : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
    476 {
    477 }
    478 
    479 bool SkMemoryWStream::write(const void* buffer, size_t size) {
    480     size = SkTMin(size, fMaxLength - fBytesWritten);
    481     if (size > 0) {
    482         memcpy(fBuffer + fBytesWritten, buffer, size);
    483         fBytesWritten += size;
    484         return true;
    485     }
    486     return false;
    487 }
    488 
    489 ////////////////////////////////////////////////////////////////////////
    490 
    491 #define SkDynamicMemoryWStream_MinBlockSize   256
    492 
    493 struct SkDynamicMemoryWStream::Block {
    494     Block*  fNext;
    495     char*   fCurr;
    496     char*   fStop;
    497 
    498     const char* start() const { return (const char*)(this + 1); }
    499     char*   start() { return (char*)(this + 1); }
    500     size_t  avail() const { return fStop - fCurr; }
    501     size_t  written() const { return fCurr - this->start(); }
    502 
    503     void init(size_t size)
    504     {
    505         fNext = NULL;
    506         fCurr = this->start();
    507         fStop = this->start() + size;
    508     }
    509 
    510     const void* append(const void* data, size_t size)
    511     {
    512         SkASSERT((size_t)(fStop - fCurr) >= size);
    513         memcpy(fCurr, data, size);
    514         fCurr += size;
    515         return (const void*)((const char*)data + size);
    516     }
    517 };
    518 
    519 SkDynamicMemoryWStream::SkDynamicMemoryWStream()
    520     : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
    521 {
    522 }
    523 
    524 SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
    525 {
    526     reset();
    527 }
    528 
    529 void SkDynamicMemoryWStream::reset()
    530 {
    531     this->invalidateCopy();
    532 
    533     Block*  block = fHead;
    534 
    535     while (block != NULL) {
    536         Block*  next = block->fNext;
    537         sk_free(block);
    538         block = next;
    539     }
    540     fHead = fTail = NULL;
    541     fBytesWritten = 0;
    542 }
    543 
    544 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
    545 {
    546     if (count > 0) {
    547         this->invalidateCopy();
    548 
    549         fBytesWritten += count;
    550 
    551         size_t  size;
    552 
    553         if (fTail != NULL && fTail->avail() > 0) {
    554             size = SkTMin(fTail->avail(), count);
    555             buffer = fTail->append(buffer, size);
    556             SkASSERT(count >= size);
    557             count -= size;
    558             if (count == 0)
    559                 return true;
    560         }
    561 
    562         size = SkTMax<size_t>(count, SkDynamicMemoryWStream_MinBlockSize);
    563         Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
    564         block->init(size);
    565         block->append(buffer, count);
    566 
    567         if (fTail != NULL)
    568             fTail->fNext = block;
    569         else
    570             fHead = fTail = block;
    571         fTail = block;
    572     }
    573     return true;
    574 }
    575 
    576 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
    577 {
    578     if (offset + count > fBytesWritten) {
    579         return false; // test does not partially modify
    580     }
    581 
    582     this->invalidateCopy();
    583 
    584     Block* block = fHead;
    585     while (block != NULL) {
    586         size_t size = block->written();
    587         if (offset < size) {
    588             size_t part = offset + count > size ? size - offset : count;
    589             memcpy(block->start() + offset, buffer, part);
    590             if (count <= part)
    591                 return true;
    592             count -= part;
    593             buffer = (const void*) ((char* ) buffer + part);
    594         }
    595         offset = offset > size ? offset - size : 0;
    596         block = block->fNext;
    597     }
    598     return false;
    599 }
    600 
    601 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
    602 {
    603     if (offset + count > fBytesWritten)
    604         return false; // test does not partially modify
    605     Block* block = fHead;
    606     while (block != NULL) {
    607         size_t size = block->written();
    608         if (offset < size) {
    609             size_t part = offset + count > size ? size - offset : count;
    610             memcpy(buffer, block->start() + offset, part);
    611             if (count <= part)
    612                 return true;
    613             count -= part;
    614             buffer = (void*) ((char* ) buffer + part);
    615         }
    616         offset = offset > size ? offset - size : 0;
    617         block = block->fNext;
    618     }
    619     return false;
    620 }
    621 
    622 void SkDynamicMemoryWStream::copyTo(void* dst) const
    623 {
    624     if (fCopy) {
    625         memcpy(dst, fCopy->data(), fBytesWritten);
    626     } else {
    627         Block* block = fHead;
    628 
    629         while (block != NULL) {
    630             size_t size = block->written();
    631             memcpy(dst, block->start(), size);
    632             dst = (void*)((char*)dst + size);
    633             block = block->fNext;
    634         }
    635     }
    636 }
    637 
    638 void SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const {
    639     for (Block* block = fHead; block != NULL; block = block->fNext) {
    640         dst->write(block->start(), block->written());
    641     }
    642 }
    643 
    644 void SkDynamicMemoryWStream::padToAlign4()
    645 {
    646     // cast to remove unary-minus warning
    647     int padBytes = -(int)fBytesWritten & 0x03;
    648     if (padBytes == 0)
    649         return;
    650     int zero = 0;
    651     write(&zero, padBytes);
    652 }
    653 
    654 SkData* SkDynamicMemoryWStream::copyToData() const {
    655     if (NULL == fCopy) {
    656         SkData* data = SkData::NewUninitialized(fBytesWritten);
    657         // be sure to call copyTo() before we assign to fCopy
    658         this->copyTo(data->writable_data());
    659         fCopy = data;
    660     }
    661     return SkRef(fCopy);
    662 }
    663 
    664 void SkDynamicMemoryWStream::invalidateCopy() {
    665     if (fCopy) {
    666         fCopy->unref();
    667         fCopy = NULL;
    668     }
    669 }
    670 
    671 class SkBlockMemoryRefCnt : public SkRefCnt {
    672 public:
    673     explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
    674 
    675     virtual ~SkBlockMemoryRefCnt() {
    676         SkDynamicMemoryWStream::Block* block = fHead;
    677         while (block != NULL) {
    678             SkDynamicMemoryWStream::Block* next = block->fNext;
    679             sk_free(block);
    680             block = next;
    681         }
    682     }
    683 
    684     SkDynamicMemoryWStream::Block* const fHead;
    685 };
    686 
    687 class SkBlockMemoryStream : public SkStreamAsset {
    688 public:
    689     SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
    690         : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head)
    691         , fSize(size) , fOffset(0), fCurrentOffset(0) { }
    692 
    693     SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
    694         : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead)
    695         , fSize(size) , fOffset(0), fCurrentOffset(0) { }
    696 
    697     size_t read(void* buffer, size_t rawCount) override {
    698         size_t count = rawCount;
    699         if (fOffset + count > fSize) {
    700             count = fSize - fOffset;
    701         }
    702         size_t bytesLeftToRead = count;
    703         while (fCurrent != NULL) {
    704             size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
    705             size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
    706             if (buffer) {
    707                 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
    708                 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
    709             }
    710             if (bytesLeftToRead <= bytesFromCurrent) {
    711                 fCurrentOffset += bytesFromCurrent;
    712                 fOffset += count;
    713                 return count;
    714             }
    715             bytesLeftToRead -= bytesFromCurrent;
    716             fCurrent = fCurrent->fNext;
    717             fCurrentOffset = 0;
    718         }
    719         SkASSERT(false);
    720         return 0;
    721     }
    722 
    723     bool isAtEnd() const override {
    724         return fOffset == fSize;
    725     }
    726 
    727     bool rewind() override {
    728         fCurrent = fBlockMemory->fHead;
    729         fOffset = 0;
    730         fCurrentOffset = 0;
    731         return true;
    732     }
    733 
    734     SkBlockMemoryStream* duplicate() const override {
    735         return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize));
    736     }
    737 
    738     size_t getPosition() const override {
    739         return fOffset;
    740     }
    741 
    742     bool seek(size_t position) override {
    743         // If possible, skip forward.
    744         if (position >= fOffset) {
    745             size_t skipAmount = position - fOffset;
    746             return this->skip(skipAmount) == skipAmount;
    747         }
    748         // If possible, move backward within the current block.
    749         size_t moveBackAmount = fOffset - position;
    750         if (moveBackAmount <= fCurrentOffset) {
    751             fCurrentOffset -= moveBackAmount;
    752             fOffset -= moveBackAmount;
    753             return true;
    754         }
    755         // Otherwise rewind and move forward.
    756         return this->rewind() && this->skip(position) == position;
    757     }
    758 
    759     bool move(long offset) override {
    760         return seek(fOffset + offset);
    761     }
    762 
    763     SkBlockMemoryStream* fork() const override {
    764         SkAutoTDelete<SkBlockMemoryStream> that(this->duplicate());
    765         that->fCurrent = this->fCurrent;
    766         that->fOffset = this->fOffset;
    767         that->fCurrentOffset = this->fCurrentOffset;
    768         return that.detach();
    769     }
    770 
    771     size_t getLength() const override {
    772         return fSize;
    773     }
    774 
    775     const void* getMemoryBase() override {
    776         if (NULL == fBlockMemory->fHead->fNext) {
    777             return fBlockMemory->fHead->start();
    778         }
    779         return NULL;
    780     }
    781 
    782 private:
    783     SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory;
    784     SkDynamicMemoryWStream::Block const * fCurrent;
    785     size_t const fSize;
    786     size_t fOffset;
    787     size_t fCurrentOffset;
    788 };
    789 
    790 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() {
    791     if (fCopy) {
    792         SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy));
    793         this->reset();
    794         return stream;
    795     }
    796     SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten));
    797     fHead = 0;
    798     this->reset();
    799     return stream;
    800 }
    801 
    802 ///////////////////////////////////////////////////////////////////////////////
    803 
    804 void SkDebugWStream::newline()
    805 {
    806 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
    807     SkDebugf("\n");
    808     fBytesWritten++;
    809 #endif
    810 }
    811 
    812 bool SkDebugWStream::write(const void* buffer, size_t size)
    813 {
    814 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
    815     char* s = new char[size+1];
    816     memcpy(s, buffer, size);
    817     s[size] = 0;
    818     SkDebugf("%s", s);
    819     delete[] s;
    820     fBytesWritten += size;
    821 #endif
    822     return true;
    823 }
    824 
    825 ///////////////////////////////////////////////////////////////////////////////
    826 ///////////////////////////////////////////////////////////////////////////////
    827 
    828 
    829 static SkData* mmap_filename(const char path[]) {
    830     SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
    831     if (NULL == file) {
    832         return NULL;
    833     }
    834 
    835     SkData* data = SkData::NewFromFILE(file);
    836     sk_fclose(file);
    837     return data;
    838 }
    839 
    840 SkStreamAsset* SkStream::NewFromFile(const char path[]) {
    841     SkAutoTUnref<SkData> data(mmap_filename(path));
    842     if (data.get()) {
    843         return SkNEW_ARGS(SkMemoryStream, (data.get()));
    844     }
    845 
    846     // If we get here, then our attempt at using mmap failed, so try normal
    847     // file access.
    848     SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
    849     if (!stream->isValid()) {
    850         SkDELETE(stream);
    851         stream = NULL;
    852     }
    853     return stream;
    854 }
    855 
    856 // Declared in SkStreamPriv.h:
    857 size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
    858     SkASSERT(storage != NULL);
    859     SkASSERT(stream != NULL);
    860 
    861     if (stream->hasLength()) {
    862         const size_t length = stream->getLength();
    863         void* dst = storage->reset(length);
    864         if (stream->read(dst, length) != length) {
    865             return 0;
    866         }
    867         return length;
    868     }
    869 
    870     SkDynamicMemoryWStream tempStream;
    871     // Arbitrary buffer size.
    872     const size_t bufferSize = 256 * 1024; // 256KB
    873     char buffer[bufferSize];
    874     SkDEBUGCODE(size_t debugLength = 0;)
    875     do {
    876         size_t bytesRead = stream->read(buffer, bufferSize);
    877         tempStream.write(buffer, bytesRead);
    878         SkDEBUGCODE(debugLength += bytesRead);
    879         SkASSERT(tempStream.bytesWritten() == debugLength);
    880     } while (!stream->isAtEnd());
    881     const size_t length = tempStream.bytesWritten();
    882     void* dst = storage->reset(length);
    883     tempStream.copyTo(dst);
    884     return length;
    885 }
    886 
    887 // Declared in SkStreamPriv.h:
    888 SkData* SkCopyStreamToData(SkStream* stream) {
    889     SkASSERT(stream != NULL);
    890 
    891     if (stream->hasLength()) {
    892         return SkData::NewFromStream(stream, stream->getLength());
    893     }
    894 
    895     SkDynamicMemoryWStream tempStream;
    896     const size_t bufferSize = 4096;
    897     char buffer[bufferSize];
    898     do {
    899         size_t bytesRead = stream->read(buffer, bufferSize);
    900         tempStream.write(buffer, bytesRead);
    901     } while (!stream->isAtEnd());
    902     return tempStream.copyToData();
    903 }
    904 
    905 SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) {
    906     if (!stream) {
    907         return NULL;
    908     }
    909     SkAutoTDelete<SkStreamRewindable> dupStream(stream->duplicate());
    910     if (dupStream) {
    911         return dupStream.detach();
    912     }
    913     stream->rewind();
    914     if (stream->hasLength()) {
    915         size_t length = stream->getLength();
    916         if (stream->hasPosition()) {  // If stream has length, but can't rewind.
    917             length -= stream->getPosition();
    918         }
    919         SkAutoTUnref<SkData> data(SkData::NewFromStream(stream, length));
    920         return SkNEW_ARGS(SkMemoryStream, (data.get()));
    921     }
    922     SkDynamicMemoryWStream tempStream;
    923     const size_t bufferSize = 4096;
    924     char buffer[bufferSize];
    925     do {
    926         size_t bytesRead = stream->read(buffer, bufferSize);
    927         tempStream.write(buffer, bytesRead);
    928     } while (!stream->isAtEnd());
    929     return tempStream.detachAsStream();  // returns a SkBlockMemoryStream,
    930                                          // cheaper than copying to SkData
    931 }
    932