gfx/skia/trunk/src/core/SkStream.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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  */
    10 #include "SkStream.h"
    11 #include "SkData.h"
    12 #include "SkFixed.h"
    13 #include "SkString.h"
    14 #include "SkOSFile.h"
    16 ///////////////////////////////////////////////////////////////////////////////
    19 int8_t SkStream::readS8() {
    20     int8_t value;
    21     SkDEBUGCODE(size_t len =) this->read(&value, 1);
    22     SkASSERT(1 == len);
    23     return value;
    24 }
    26 int16_t SkStream::readS16() {
    27     int16_t value;
    28     SkDEBUGCODE(size_t len =) this->read(&value, 2);
    29     SkASSERT(2 == len);
    30     return value;
    31 }
    33 int32_t SkStream::readS32() {
    34     int32_t value;
    35     SkDEBUGCODE(size_t len =) this->read(&value, 4);
    36     SkASSERT(4 == len);
    37     return value;
    38 }
    40 SkScalar SkStream::readScalar() {
    41     SkScalar value;
    42     SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
    43     SkASSERT(sizeof(SkScalar) == len);
    44     return value;
    45 }
    47 #define SK_MAX_BYTE_FOR_U8          0xFD
    48 #define SK_BYTE_SENTINEL_FOR_U16    0xFE
    49 #define SK_BYTE_SENTINEL_FOR_U32    0xFF
    51 size_t SkStream::readPackedUInt() {
    52     uint8_t byte;
    53     if (!this->read(&byte, 1)) {
    54         return 0;
    55     }
    56     if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
    57         return this->readU16();
    58     } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
    59         return this->readU32();
    60     } else {
    61         return byte;
    62     }
    63 }
    65 SkData* SkStream::readData() {
    66     size_t size = this->readU32();
    67     if (0 == size) {
    68         return SkData::NewEmpty();
    69     } else {
    70         void* buffer = sk_malloc_throw(size);
    71         this->read(buffer, size);
    72         return SkData::NewFromMalloc(buffer, size);
    73     }
    74 }
    76 //////////////////////////////////////////////////////////////////////////////////////
    78 SkWStream::~SkWStream()
    79 {
    80 }
    82 void SkWStream::newline()
    83 {
    84     this->write("\n", 1);
    85 }
    87 void SkWStream::flush()
    88 {
    89 }
    91 bool SkWStream::writeText(const char text[])
    92 {
    93     SkASSERT(text);
    94     return this->write(text, strlen(text));
    95 }
    97 bool SkWStream::writeDecAsText(int32_t dec)
    98 {
    99     SkString    tmp;
   100     tmp.appendS32(dec);
   101     return this->write(tmp.c_str(), tmp.size());
   102 }
   104 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
   105 {
   106     SkString    tmp;
   107     tmp.appendS64(dec, minDigits);
   108     return this->write(tmp.c_str(), tmp.size());
   109 }
   111 bool SkWStream::writeHexAsText(uint32_t hex, int digits)
   112 {
   113     SkString    tmp;
   114     tmp.appendHex(hex, digits);
   115     return this->write(tmp.c_str(), tmp.size());
   116 }
   118 bool SkWStream::writeScalarAsText(SkScalar value)
   119 {
   120     SkString    tmp;
   121     tmp.appendScalar(value);
   122     return this->write(tmp.c_str(), tmp.size());
   123 }
   125 bool SkWStream::write8(U8CPU value) {
   126     uint8_t v = SkToU8(value);
   127     return this->write(&v, 1);
   128 }
   130 bool SkWStream::write16(U16CPU value) {
   131     uint16_t v = SkToU16(value);
   132     return this->write(&v, 2);
   133 }
   135 bool SkWStream::write32(uint32_t value) {
   136     return this->write(&value, 4);
   137 }
   139 bool SkWStream::writeScalar(SkScalar value) {
   140     return this->write(&value, sizeof(value));
   141 }
   143 int SkWStream::SizeOfPackedUInt(size_t value) {
   144     if (value <= SK_MAX_BYTE_FOR_U8) {
   145         return 1;
   146     } else if (value <= 0xFFFF) {
   147         return 3;
   148     }
   149     return 5;
   150 }
   152 bool SkWStream::writePackedUInt(size_t value) {
   153     uint8_t data[5];
   154     size_t len = 1;
   155     if (value <= SK_MAX_BYTE_FOR_U8) {
   156         data[0] = value;
   157         len = 1;
   158     } else if (value <= 0xFFFF) {
   159         uint16_t value16 = value;
   160         data[0] = SK_BYTE_SENTINEL_FOR_U16;
   161         memcpy(&data[1], &value16, 2);
   162         len = 3;
   163     } else {
   164         uint32_t value32 = value;
   165         data[0] = SK_BYTE_SENTINEL_FOR_U32;
   166         memcpy(&data[1], &value32, 4);
   167         len = 5;
   168     }
   169     return this->write(data, len);
   170 }
   172 bool SkWStream::writeStream(SkStream* stream, size_t length) {
   173     char scratch[1024];
   174     const size_t MAX = sizeof(scratch);
   176     while (length != 0) {
   177         size_t n = length;
   178         if (n > MAX) {
   179             n = MAX;
   180         }
   181         stream->read(scratch, n);
   182         if (!this->write(scratch, n)) {
   183             return false;
   184         }
   185         length -= n;
   186     }
   187     return true;
   188 }
   190 bool SkWStream::writeData(const SkData* data) {
   191     if (data) {
   192         this->write32(data->size());
   193         this->write(data->data(), data->size());
   194     } else {
   195         this->write32(0);
   196     }
   197     return true;
   198 }
   200 ///////////////////////////////////////////////////////////////////////////////
   202 SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) {
   203     fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
   204 }
   206 SkFILEStream::SkFILEStream(FILE* file, Ownership ownership)
   207     : fFILE((SkFILE*)file)
   208     , fOwnership(ownership) {
   209 }
   211 SkFILEStream::~SkFILEStream() {
   212     if (fFILE && fOwnership != kCallerRetains_Ownership) {
   213         sk_fclose(fFILE);
   214     }
   215 }
   217 void SkFILEStream::setPath(const char path[]) {
   218     fName.set(path);
   219     if (fFILE) {
   220         sk_fclose(fFILE);
   221         fFILE = NULL;
   222     }
   223     if (path) {
   224         fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
   225     }
   226 }
   228 size_t SkFILEStream::read(void* buffer, size_t size) {
   229     if (fFILE) {
   230         return sk_fread(buffer, size, fFILE);
   231     }
   232     return 0;
   233 }
   235 bool SkFILEStream::isAtEnd() const {
   236     return sk_feof(fFILE);
   237 }
   239 bool SkFILEStream::rewind() {
   240     if (fFILE) {
   241         if (sk_frewind(fFILE)) {
   242             return true;
   243         }
   244         // we hit an error
   245         sk_fclose(fFILE);
   246         fFILE = NULL;
   247     }
   248     return false;
   249 }
   251 SkStreamAsset* SkFILEStream::duplicate() const {
   252     if (NULL == fFILE) {
   253         return new SkMemoryStream();
   254     }
   256     if (NULL != fData.get()) {
   257         return new SkMemoryStream(fData);
   258     }
   260     if (!fName.isEmpty()) {
   261         SkAutoTUnref<SkFILEStream> that(new SkFILEStream(fName.c_str()));
   262         if (sk_fidentical(that->fFILE, this->fFILE)) {
   263             return that.detach();
   264         }
   265     }
   267     fData.reset(SkData::NewFromFILE(fFILE));
   268     if (NULL == fData.get()) {
   269         return NULL;
   270     }
   271     return new SkMemoryStream(fData);
   272 }
   274 size_t SkFILEStream::getPosition() const {
   275     return sk_ftell(fFILE);
   276 }
   278 bool SkFILEStream::seek(size_t position) {
   279     return sk_fseek(fFILE, position);
   280 }
   282 bool SkFILEStream::move(long offset) {
   283     return sk_fmove(fFILE, offset);
   284 }
   286 SkStreamAsset* SkFILEStream::fork() const {
   287     SkAutoTUnref<SkStreamAsset> that(this->duplicate());
   288     that->seek(this->getPosition());
   289     return that.detach();
   290 }
   292 size_t SkFILEStream::getLength() const {
   293     return sk_fgetsize(fFILE);
   294 }
   296 const void* SkFILEStream::getMemoryBase() {
   297     if (NULL == fData.get()) {
   298         return NULL;
   299     }
   300     return fData->data();
   301 }
   303 ///////////////////////////////////////////////////////////////////////////////
   305 static SkData* newFromParams(const void* src, size_t size, bool copyData) {
   306     if (copyData) {
   307         return SkData::NewWithCopy(src, size);
   308     } else {
   309         return SkData::NewWithProc(src, size, NULL, NULL);
   310     }
   311 }
   313 SkMemoryStream::SkMemoryStream() {
   314     fData = SkData::NewEmpty();
   315     fOffset = 0;
   316 }
   318 SkMemoryStream::SkMemoryStream(size_t size) {
   319     fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
   320     fOffset = 0;
   321 }
   323 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
   324     fData = newFromParams(src, size, copyData);
   325     fOffset = 0;
   326 }
   328 SkMemoryStream::SkMemoryStream(SkData* data) {
   329     if (NULL == data) {
   330         fData = SkData::NewEmpty();
   331     } else {
   332         fData = data;
   333         fData->ref();
   334     }
   335     fOffset = 0;
   336 }
   338 SkMemoryStream::~SkMemoryStream() {
   339     fData->unref();
   340 }
   342 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
   343     fData->unref();
   344     fData = SkData::NewFromMalloc(src, size);
   345     fOffset = 0;
   346 }
   348 void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
   349     fData->unref();
   350     fData = newFromParams(src, size, copyData);
   351     fOffset = 0;
   352 }
   354 SkData* SkMemoryStream::copyToData() const {
   355     fData->ref();
   356     return fData;
   357 }
   359 SkData* SkMemoryStream::setData(SkData* data) {
   360     fData->unref();
   361     if (NULL == data) {
   362         fData = SkData::NewEmpty();
   363     } else {
   364         fData = data;
   365         fData->ref();
   366     }
   367     fOffset = 0;
   368     return data;
   369 }
   371 void SkMemoryStream::skipToAlign4() {
   372     // cast to remove unary-minus warning
   373     fOffset += -(int)fOffset & 0x03;
   374 }
   376 size_t SkMemoryStream::read(void* buffer, size_t size) {
   377     size_t dataSize = fData->size();
   379     if (size > dataSize - fOffset) {
   380         size = dataSize - fOffset;
   381     }
   382     if (buffer) {
   383         memcpy(buffer, fData->bytes() + fOffset, size);
   384     }
   385     fOffset += size;
   386     return size;
   387 }
   389 bool SkMemoryStream::isAtEnd() const {
   390     return fOffset == fData->size();
   391 }
   393 bool SkMemoryStream::rewind() {
   394     fOffset = 0;
   395     return true;
   396 }
   398 SkMemoryStream* SkMemoryStream::duplicate() const {
   399     return SkNEW_ARGS(SkMemoryStream, (fData));
   400 }
   402 size_t SkMemoryStream::getPosition() const {
   403     return fOffset;
   404 }
   406 bool SkMemoryStream::seek(size_t position) {
   407     fOffset = position > fData->size()
   408             ? fData->size()
   409             : position;
   410     return true;
   411 }
   413 bool SkMemoryStream::move(long offset) {
   414     return this->seek(fOffset + offset);
   415 }
   417 SkMemoryStream* SkMemoryStream::fork() const {
   418     SkAutoTUnref<SkMemoryStream> that(this->duplicate());
   419     that->seek(fOffset);
   420     return that.detach();
   421 }
   423 size_t SkMemoryStream::getLength() const {
   424     return fData->size();
   425 }
   427 const void* SkMemoryStream::getMemoryBase() {
   428     return fData->data();
   429 }
   431 const void* SkMemoryStream::getAtPos() {
   432     return fData->bytes() + fOffset;
   433 }
   435 /////////////////////////////////////////////////////////////////////////////////////////////////////////
   436 /////////////////////////////////////////////////////////////////////////////////////////////////////////
   438 SkFILEWStream::SkFILEWStream(const char path[])
   439 {
   440     fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
   441 }
   443 SkFILEWStream::~SkFILEWStream()
   444 {
   445     if (fFILE) {
   446         sk_fclose(fFILE);
   447     }
   448 }
   450 size_t SkFILEWStream::bytesWritten() const {
   451     return sk_ftell(fFILE);
   452 }
   454 bool SkFILEWStream::write(const void* buffer, size_t size)
   455 {
   456     if (fFILE == NULL) {
   457         return false;
   458     }
   460     if (sk_fwrite(buffer, size, fFILE) != size)
   461     {
   462         SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
   463         sk_fclose(fFILE);
   464         fFILE = NULL;
   465         return false;
   466     }
   467     return true;
   468 }
   470 void SkFILEWStream::flush()
   471 {
   472     if (fFILE) {
   473         sk_fflush(fFILE);
   474     }
   475 }
   477 ////////////////////////////////////////////////////////////////////////
   479 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
   480     : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
   481 {
   482 }
   484 bool SkMemoryWStream::write(const void* buffer, size_t size)
   485 {
   486     size = SkMin32(size, fMaxLength - fBytesWritten);
   487     if (size > 0)
   488     {
   489         memcpy(fBuffer + fBytesWritten, buffer, size);
   490         fBytesWritten += size;
   491         return true;
   492     }
   493     return false;
   494 }
   496 ////////////////////////////////////////////////////////////////////////
   498 #define SkDynamicMemoryWStream_MinBlockSize   256
   500 struct SkDynamicMemoryWStream::Block {
   501     Block*  fNext;
   502     char*   fCurr;
   503     char*   fStop;
   505     const char* start() const { return (const char*)(this + 1); }
   506     char*   start() { return (char*)(this + 1); }
   507     size_t  avail() const { return fStop - fCurr; }
   508     size_t  written() const { return fCurr - this->start(); }
   510     void init(size_t size)
   511     {
   512         fNext = NULL;
   513         fCurr = this->start();
   514         fStop = this->start() + size;
   515     }
   517     const void* append(const void* data, size_t size)
   518     {
   519         SkASSERT((size_t)(fStop - fCurr) >= size);
   520         memcpy(fCurr, data, size);
   521         fCurr += size;
   522         return (const void*)((const char*)data + size);
   523     }
   524 };
   526 SkDynamicMemoryWStream::SkDynamicMemoryWStream()
   527     : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
   528 {
   529 }
   531 SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
   532 {
   533     reset();
   534 }
   536 void SkDynamicMemoryWStream::reset()
   537 {
   538     this->invalidateCopy();
   540     Block*  block = fHead;
   542     while (block != NULL) {
   543         Block*  next = block->fNext;
   544         sk_free(block);
   545         block = next;
   546     }
   547     fHead = fTail = NULL;
   548     fBytesWritten = 0;
   549 }
   551 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
   552 {
   553     if (count > 0) {
   554         this->invalidateCopy();
   556         fBytesWritten += count;
   558         size_t  size;
   560         if (fTail != NULL && fTail->avail() > 0) {
   561             size = SkMin32(fTail->avail(), count);
   562             buffer = fTail->append(buffer, size);
   563             SkASSERT(count >= size);
   564             count -= size;
   565             if (count == 0)
   566                 return true;
   567         }
   569         size = SkMax32(count, SkDynamicMemoryWStream_MinBlockSize);
   570         Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
   571         block->init(size);
   572         block->append(buffer, count);
   574         if (fTail != NULL)
   575             fTail->fNext = block;
   576         else
   577             fHead = fTail = block;
   578         fTail = block;
   579     }
   580     return true;
   581 }
   583 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
   584 {
   585     if (offset + count > fBytesWritten) {
   586         return false; // test does not partially modify
   587     }
   589     this->invalidateCopy();
   591     Block* block = fHead;
   592     while (block != NULL) {
   593         size_t size = block->written();
   594         if (offset < size) {
   595             size_t part = offset + count > size ? size - offset : count;
   596             memcpy(block->start() + offset, buffer, part);
   597             if (count <= part)
   598                 return true;
   599             count -= part;
   600             buffer = (const void*) ((char* ) buffer + part);
   601         }
   602         offset = offset > size ? offset - size : 0;
   603         block = block->fNext;
   604     }
   605     return false;
   606 }
   608 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
   609 {
   610     if (offset + count > fBytesWritten)
   611         return false; // test does not partially modify
   612     Block* block = fHead;
   613     while (block != NULL) {
   614         size_t size = block->written();
   615         if (offset < size) {
   616             size_t part = offset + count > size ? size - offset : count;
   617             memcpy(buffer, block->start() + offset, part);
   618             if (count <= part)
   619                 return true;
   620             count -= part;
   621             buffer = (void*) ((char* ) buffer + part);
   622         }
   623         offset = offset > size ? offset - size : 0;
   624         block = block->fNext;
   625     }
   626     return false;
   627 }
   629 void SkDynamicMemoryWStream::copyTo(void* dst) const
   630 {
   631     if (fCopy) {
   632         memcpy(dst, fCopy->data(), fBytesWritten);
   633     } else {
   634         Block* block = fHead;
   636         while (block != NULL) {
   637             size_t size = block->written();
   638             memcpy(dst, block->start(), size);
   639             dst = (void*)((char*)dst + size);
   640             block = block->fNext;
   641         }
   642     }
   643 }
   645 void SkDynamicMemoryWStream::padToAlign4()
   646 {
   647     // cast to remove unary-minus warning
   648     int padBytes = -(int)fBytesWritten & 0x03;
   649     if (padBytes == 0)
   650         return;
   651     int zero = 0;
   652     write(&zero, padBytes);
   653 }
   655 SkData* SkDynamicMemoryWStream::copyToData() const {
   656     if (NULL == fCopy) {
   657         void* buffer = sk_malloc_throw(fBytesWritten);
   658         this->copyTo(buffer);
   659         fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
   660     }
   661     fCopy->ref();
   662     return fCopy;
   663 }
   665 void SkDynamicMemoryWStream::invalidateCopy() {
   666     if (fCopy) {
   667         fCopy->unref();
   668         fCopy = NULL;
   669     }
   670 }
   672 class SkBlockMemoryRefCnt : public SkRefCnt {
   673 public:
   674     explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
   676     virtual ~SkBlockMemoryRefCnt() {
   677         SkDynamicMemoryWStream::Block* block = fHead;
   678         while (block != NULL) {
   679             SkDynamicMemoryWStream::Block* next = block->fNext;
   680             sk_free(block);
   681             block = next;
   682         }
   683     }
   685     SkDynamicMemoryWStream::Block* const fHead;
   686 };
   688 class SkBlockMemoryStream : public SkStreamAsset {
   689 public:
   690     SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
   691         : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head)
   692         , fSize(size) , fOffset(0), fCurrentOffset(0) { }
   694     SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
   695         : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead)
   696         , fSize(size) , fOffset(0), fCurrentOffset(0) { }
   698     virtual size_t read(void* buffer, size_t rawCount) SK_OVERRIDE {
   699         size_t count = rawCount;
   700         if (fOffset + count > fSize) {
   701             count = fSize - fOffset;
   702         }
   703         size_t bytesLeftToRead = count;
   704         while (fCurrent != NULL) {
   705             size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
   706             size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
   707             if (buffer) {
   708                 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
   709                 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
   710             }
   711             if (bytesLeftToRead <= bytesFromCurrent) {
   712                 fCurrentOffset += bytesFromCurrent;
   713                 fOffset += count;
   714                 return count;
   715             }
   716             bytesLeftToRead -= bytesFromCurrent;
   717             fCurrent = fCurrent->fNext;
   718             fCurrentOffset = 0;
   719         }
   720         SkASSERT(false);
   721         return 0;
   722     }
   724     virtual bool isAtEnd() const SK_OVERRIDE {
   725         return fOffset == fSize;
   726     }
   728     virtual bool rewind() SK_OVERRIDE {
   729         fCurrent = fBlockMemory->fHead;
   730         fOffset = 0;
   731         fCurrentOffset = 0;
   732         return true;
   733     }
   735     virtual SkBlockMemoryStream* duplicate() const SK_OVERRIDE {
   736         return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize));
   737     }
   739     virtual size_t getPosition() const SK_OVERRIDE {
   740         return fOffset;
   741     }
   743     virtual bool seek(size_t position) SK_OVERRIDE {
   744         // If possible, skip forward.
   745         if (position >= fOffset) {
   746             size_t skipAmount = position - fOffset;
   747             return this->skip(skipAmount) == skipAmount;
   748         }
   749         // If possible, move backward within the current block.
   750         size_t moveBackAmount = fOffset - position;
   751         if (moveBackAmount <= fCurrentOffset) {
   752             fCurrentOffset -= moveBackAmount;
   753             fOffset -= moveBackAmount;
   754             return true;
   755         }
   756         // Otherwise rewind and move forward.
   757         return this->rewind() && this->skip(position) == position;
   758     }
   760     virtual bool move(long offset) SK_OVERRIDE {
   761         return seek(fOffset + offset);
   762     }
   764     virtual SkBlockMemoryStream* fork() const SK_OVERRIDE {
   765         SkAutoTUnref<SkBlockMemoryStream> that(this->duplicate());
   766         that->fCurrent = this->fCurrent;
   767         that->fOffset = this->fOffset;
   768         that->fCurrentOffset = this->fCurrentOffset;
   769         return that.detach();
   770     }
   772     virtual size_t getLength() const SK_OVERRIDE {
   773         return fSize;
   774     }
   776     virtual const void* getMemoryBase() SK_OVERRIDE {
   777         if (NULL == fBlockMemory->fHead->fNext) {
   778             return fBlockMemory->fHead->start();
   779         }
   780         return NULL;
   781     }
   783 private:
   784     SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory;
   785     SkDynamicMemoryWStream::Block const * fCurrent;
   786     size_t const fSize;
   787     size_t fOffset;
   788     size_t fCurrentOffset;
   789 };
   791 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() {
   792     if (fCopy) {
   793         SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy));
   794         this->reset();
   795         return stream;
   796     }
   797     SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten));
   798     fHead = 0;
   799     this->reset();
   800     return stream;
   801 }
   803 ///////////////////////////////////////////////////////////////////////////////
   805 void SkDebugWStream::newline()
   806 {
   807 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
   808     SkDebugf("\n");
   809     fBytesWritten++;
   810 #endif
   811 }
   813 bool SkDebugWStream::write(const void* buffer, size_t size)
   814 {
   815 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
   816     char* s = new char[size+1];
   817     memcpy(s, buffer, size);
   818     s[size] = 0;
   819     SkDebugf("%s", s);
   820     delete[] s;
   821     fBytesWritten += size;
   822 #endif
   823     return true;
   824 }
   826 ///////////////////////////////////////////////////////////////////////////////
   827 ///////////////////////////////////////////////////////////////////////////////
   830 static SkData* mmap_filename(const char path[]) {
   831     SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
   832     if (NULL == file) {
   833         return NULL;
   834     }
   836     SkData* data = SkData::NewFromFILE(file);
   837     sk_fclose(file);
   838     return data;
   839 }
   841 SkStreamAsset* SkStream::NewFromFile(const char path[]) {
   842     SkAutoTUnref<SkData> data(mmap_filename(path));
   843     if (data.get()) {
   844         return SkNEW_ARGS(SkMemoryStream, (data.get()));
   845     }
   847     // If we get here, then our attempt at using mmap failed, so try normal
   848     // file access.
   849     SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
   850     if (!stream->isValid()) {
   851         stream->unref();
   852         stream = NULL;
   853     }
   854     return stream;
   855 }

mercurial