LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkStream.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 412 0 0.0 %
Date: 2012-06-02 Functions: 84 0 0.0 %

       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 "SkData.h"
      12                 : #include "SkFixed.h"
      13                 : #include "SkString.h"
      14                 : #include "SkOSFile.h"
      15                 : 
      16               0 : SkStream::~SkStream() {}
      17                 : 
      18               0 : const char* SkStream::getFileName()
      19                 : {
      20                 :     // override in subclass if you represent a file
      21               0 :     return NULL;
      22                 : }
      23                 : 
      24               0 : const void* SkStream::getMemoryBase()
      25                 : {
      26                 :     // override in subclass if you represent a memory block
      27               0 :     return NULL;
      28                 : }
      29                 : 
      30               0 : size_t SkStream::skip(size_t size)
      31                 : {
      32                 :     /*  Check for size == 0, and just return 0. If we passed that
      33                 :         to read(), it would interpret it as a request for the entire
      34                 :         size of the stream.
      35                 :     */
      36               0 :     return size ? this->read(NULL, size) : 0;
      37                 : }
      38                 : 
      39               0 : int8_t SkStream::readS8() {
      40                 :     int8_t value;
      41               0 :     SkDEBUGCODE(size_t len =) this->read(&value, 1);
      42               0 :     SkASSERT(1 == len);
      43               0 :     return value;
      44                 : }
      45                 : 
      46               0 : int16_t SkStream::readS16() {
      47                 :     int16_t value;
      48               0 :     SkDEBUGCODE(size_t len =) this->read(&value, 2);
      49               0 :     SkASSERT(2 == len);
      50               0 :     return value;
      51                 : }
      52                 : 
      53               0 : int32_t SkStream::readS32() {
      54                 :     int32_t value;
      55               0 :     SkDEBUGCODE(size_t len =) this->read(&value, 4);
      56               0 :     SkASSERT(4 == len);
      57               0 :     return value;
      58                 : }
      59                 : 
      60               0 : SkScalar SkStream::readScalar() {
      61                 :     SkScalar value;
      62               0 :     SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
      63               0 :     SkASSERT(sizeof(SkScalar) == len);
      64               0 :     return value;
      65                 : }
      66                 : 
      67                 : #define SK_MAX_BYTE_FOR_U8          0xFD
      68                 : #define SK_BYTE_SENTINEL_FOR_U16    0xFE
      69                 : #define SK_BYTE_SENTINEL_FOR_U32    0xFF
      70                 : 
      71               0 : size_t SkStream::readPackedUInt() {
      72                 :     uint8_t byte;    
      73               0 :     if (!this->read(&byte, 1)) {
      74               0 :         return 0;
      75                 :     }
      76               0 :     if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
      77               0 :         return this->readU16();
      78               0 :     } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
      79               0 :         return this->readU32();
      80                 :     } else {
      81               0 :         return byte;
      82                 :     }
      83                 : }
      84                 : 
      85                 : //////////////////////////////////////////////////////////////////////////////////////
      86                 : 
      87               0 : SkWStream::~SkWStream()
      88                 : {
      89               0 : }
      90                 : 
      91               0 : void SkWStream::newline()
      92                 : {
      93               0 :     this->write("\n", 1);
      94               0 : }
      95                 : 
      96               0 : void SkWStream::flush()
      97                 : {
      98               0 : }
      99                 : 
     100               0 : bool SkWStream::writeText(const char text[])
     101                 : {
     102               0 :     SkASSERT(text);
     103               0 :     return this->write(text, strlen(text));
     104                 : }
     105                 : 
     106               0 : bool SkWStream::writeDecAsText(int32_t dec)
     107                 : {
     108               0 :     SkString    tmp;
     109               0 :     tmp.appendS32(dec);
     110               0 :     return this->write(tmp.c_str(), tmp.size());
     111                 : }
     112                 : 
     113               0 : bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
     114                 : {
     115               0 :     SkString    tmp;
     116               0 :     tmp.appendS64(dec, minDigits);
     117               0 :     return this->write(tmp.c_str(), tmp.size());
     118                 : }
     119                 : 
     120               0 : bool SkWStream::writeHexAsText(uint32_t hex, int digits)
     121                 : {
     122               0 :     SkString    tmp;
     123               0 :     tmp.appendHex(hex, digits);
     124               0 :     return this->write(tmp.c_str(), tmp.size());
     125                 : }
     126                 : 
     127               0 : bool SkWStream::writeScalarAsText(SkScalar value)
     128                 : {
     129               0 :     SkString    tmp;
     130               0 :     tmp.appendScalar(value);
     131               0 :     return this->write(tmp.c_str(), tmp.size());
     132                 : }
     133                 : 
     134               0 : bool SkWStream::write8(U8CPU value) {
     135               0 :     uint8_t v = SkToU8(value);
     136               0 :     return this->write(&v, 1);
     137                 : }
     138                 : 
     139               0 : bool SkWStream::write16(U16CPU value) {
     140               0 :     uint16_t v = SkToU16(value);
     141               0 :     return this->write(&v, 2);
     142                 : }
     143                 : 
     144               0 : bool SkWStream::write32(uint32_t value) {
     145               0 :     return this->write(&value, 4);
     146                 : }
     147                 : 
     148               0 : bool SkWStream::writeScalar(SkScalar value) {
     149               0 :     return this->write(&value, sizeof(value));
     150                 : }
     151                 : 
     152               0 : bool SkWStream::writePackedUInt(size_t value) {
     153                 :     uint8_t data[5];
     154               0 :     size_t len = 1;
     155               0 :     if (value <= SK_MAX_BYTE_FOR_U8) {
     156               0 :         data[0] = value;
     157               0 :         len = 1;
     158               0 :     } else if (value <= 0xFFFF) {
     159               0 :         uint16_t value16 = value;
     160               0 :         data[0] = SK_BYTE_SENTINEL_FOR_U16;
     161               0 :         memcpy(&data[1], &value16, 2);
     162               0 :         len = 3;
     163                 :     } else {
     164               0 :         uint32_t value32 = value;
     165               0 :         data[0] = SK_BYTE_SENTINEL_FOR_U32;
     166               0 :         memcpy(&data[1], &value32, 4);
     167               0 :         len = 5;
     168                 :     }
     169               0 :     return this->write(data, len);
     170                 : }
     171                 : 
     172               0 : bool SkWStream::writeStream(SkStream* stream, size_t length) {
     173                 :     char scratch[1024];
     174               0 :     const size_t MAX = sizeof(scratch);
     175                 :     
     176               0 :     while (length != 0) {
     177               0 :         size_t n = length;
     178               0 :         if (n > MAX) {
     179               0 :             n = MAX;
     180                 :         }
     181               0 :         stream->read(scratch, n);
     182               0 :         if (!this->write(scratch, n)) {
     183               0 :             return false;
     184                 :         }
     185               0 :         length -= n;
     186                 :     }
     187               0 :     return true;
     188                 : }
     189                 : 
     190               0 : bool SkWStream::writeData(const SkData* data) {
     191               0 :     if (data) {
     192               0 :         this->write(data->data(), data->size());
     193                 :     }
     194               0 :     return true;
     195                 : }
     196                 : 
     197                 : ///////////////////////////////////////////////////////////////////////////////
     198                 : 
     199               0 : SkFILEStream::SkFILEStream(const char file[]) : fName(file)
     200                 : {
     201               0 :     fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
     202               0 : }
     203                 : 
     204               0 : SkFILEStream::~SkFILEStream()
     205                 : {
     206               0 :     if (fFILE)
     207               0 :         sk_fclose(fFILE);
     208               0 : }
     209                 : 
     210               0 : void SkFILEStream::setPath(const char path[])
     211                 : {
     212               0 :     fName.set(path);
     213               0 :     if (fFILE)
     214                 :     {
     215               0 :         sk_fclose(fFILE);
     216               0 :         fFILE = NULL;
     217                 :     }
     218               0 :     if (path)
     219               0 :         fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
     220               0 : }
     221                 : 
     222               0 : const char* SkFILEStream::getFileName()
     223                 : {
     224               0 :     return fName.c_str();
     225                 : }
     226                 : 
     227               0 : bool SkFILEStream::rewind()
     228                 : {
     229               0 :     if (fFILE)
     230                 :     {
     231               0 :         if (sk_frewind(fFILE))
     232               0 :             return true;
     233                 :         // we hit an error
     234               0 :         sk_fclose(fFILE);
     235               0 :         fFILE = NULL;
     236                 :     }
     237               0 :     return false;
     238                 : }
     239                 : 
     240               0 : size_t SkFILEStream::read(void* buffer, size_t size)
     241                 : {
     242               0 :     if (fFILE)
     243                 :     {
     244               0 :         if (buffer == NULL && size == 0)    // special signature, they want the total size
     245               0 :             return sk_fgetsize(fFILE);
     246                 :         else
     247               0 :             return sk_fread(buffer, size, fFILE);
     248                 :     }
     249               0 :     return 0;
     250                 : }
     251                 : 
     252                 : ///////////////////////////////////////////////////////////////////////////////
     253                 : 
     254               0 : static SkData* newFromParams(const void* src, size_t size, bool copyData) {
     255               0 :     if (copyData) {
     256               0 :         return SkData::NewWithCopy(src, size);
     257                 :     } else {
     258               0 :         return SkData::NewWithProc(src, size, NULL, NULL);
     259                 :     }
     260                 : }
     261                 : 
     262               0 : SkMemoryStream::SkMemoryStream() {
     263               0 :     fData = SkData::NewEmpty();
     264               0 :     fOffset = 0;
     265               0 : }
     266                 : 
     267               0 : SkMemoryStream::SkMemoryStream(size_t size) {
     268               0 :     fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
     269               0 :     fOffset = 0;
     270               0 : }
     271                 : 
     272               0 : SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
     273               0 :     fData = newFromParams(src, size, copyData);
     274               0 :     fOffset = 0;
     275               0 : }
     276                 : 
     277               0 : SkMemoryStream::~SkMemoryStream() {
     278               0 :     fData->unref();
     279               0 : }
     280                 : 
     281               0 : void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
     282               0 :     fData->unref();
     283               0 :     fData = SkData::NewFromMalloc(src, size);
     284               0 :     fOffset = 0;
     285               0 : }
     286                 : 
     287               0 : void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
     288               0 :     fData->unref();
     289               0 :     fData = newFromParams(src, size, copyData);
     290               0 :     fOffset = 0;
     291               0 : }
     292                 : 
     293               0 : SkData* SkMemoryStream::copyToData() const {
     294               0 :     fData->ref();
     295               0 :     return fData;
     296                 : }
     297                 : 
     298               0 : SkData* SkMemoryStream::setData(SkData* data) {
     299               0 :     SkRefCnt_SafeAssign(fData, data);
     300               0 :     return data;
     301                 : }
     302                 : 
     303               0 : void SkMemoryStream::skipToAlign4() {
     304                 :     // cast to remove unary-minus warning
     305               0 :     fOffset += -(int)fOffset & 0x03;
     306               0 : }
     307                 : 
     308               0 : bool SkMemoryStream::rewind() {
     309               0 :     fOffset = 0;
     310               0 :     return true;
     311                 : }
     312                 : 
     313               0 : size_t SkMemoryStream::read(void* buffer, size_t size) {
     314               0 :     size_t dataSize = fData->size();
     315                 : 
     316               0 :     if (buffer == NULL && size == 0)    // special signature, they want the total size
     317               0 :         return dataSize;
     318                 : 
     319                 :     // if buffer is NULL, seek ahead by size
     320                 : 
     321               0 :     if (size == 0) {
     322               0 :         return 0;
     323                 :     }
     324               0 :     if (size > dataSize - fOffset) {
     325               0 :         size = dataSize - fOffset;
     326                 :     }
     327               0 :     if (buffer) {
     328               0 :         memcpy(buffer, fData->bytes() + fOffset, size);
     329                 :     }
     330               0 :     fOffset += size;
     331               0 :     return size;
     332                 : }
     333                 : 
     334               0 : const void* SkMemoryStream::getMemoryBase() {
     335               0 :     return fData->data();
     336                 : }
     337                 : 
     338               0 : const void* SkMemoryStream::getAtPos() {
     339               0 :     return fData->bytes() + fOffset;
     340                 : }
     341                 : 
     342               0 : size_t SkMemoryStream::seek(size_t offset) {
     343               0 :     if (offset > fData->size()) {
     344               0 :         offset = fData->size();
     345                 :     }
     346               0 :     fOffset = offset;
     347               0 :     return offset;
     348                 : }
     349                 : 
     350                 : ///////////////////////////////////////////////////////////////////////////////
     351                 : 
     352               0 : SkBufferStream::SkBufferStream(SkStream* proxy, size_t bufferSize)
     353               0 :     : fProxy(proxy)
     354                 : {
     355               0 :     SkASSERT(proxy != NULL);
     356               0 :     proxy->ref();
     357               0 :     this->init(NULL, bufferSize);
     358               0 : }
     359                 : 
     360               0 : SkBufferStream::SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize)
     361               0 :     : fProxy(proxy)
     362                 : {
     363               0 :     SkASSERT(proxy != NULL);
     364               0 :     SkASSERT(buffer == NULL || bufferSize != 0);    // init(addr, 0) makes no sense, we must know how big their buffer is
     365               0 :     proxy->ref();
     366               0 :     this->init(buffer, bufferSize);
     367               0 : }
     368                 : 
     369               0 : void SkBufferStream::init(void* buffer, size_t bufferSize)
     370                 : {
     371               0 :     if (bufferSize == 0)
     372               0 :         bufferSize = kDefaultBufferSize;
     373                 : 
     374               0 :     fOrigBufferSize = bufferSize;
     375               0 :     fBufferSize = bufferSize;
     376               0 :     fBufferOffset = bufferSize; // to trigger a reload on the first read()
     377                 : 
     378               0 :     if (buffer == NULL)
     379                 :     {
     380               0 :         fBuffer = (char*)sk_malloc_throw(fBufferSize);
     381               0 :         fWeOwnTheBuffer = true;
     382                 :     }
     383                 :     else
     384                 :     {
     385               0 :         fBuffer = (char*)buffer;
     386               0 :         fWeOwnTheBuffer = false;
     387                 :     }
     388               0 : }
     389                 : 
     390               0 : SkBufferStream::~SkBufferStream()
     391                 : {
     392               0 :     fProxy->unref();
     393               0 :     if (fWeOwnTheBuffer)
     394               0 :         sk_free(fBuffer);
     395               0 : }
     396                 : 
     397               0 : bool SkBufferStream::rewind()
     398                 : {
     399               0 :     fBufferOffset = fBufferSize = fOrigBufferSize;
     400               0 :     return fProxy->rewind();
     401                 : }
     402                 : 
     403               0 : const char* SkBufferStream::getFileName()
     404                 : {
     405               0 :     return fProxy->getFileName();
     406                 : }
     407                 : 
     408                 : #ifdef SK_DEBUG
     409                 : //  #define SK_TRACE_BUFFERSTREAM
     410                 : #endif
     411                 : 
     412               0 : size_t SkBufferStream::read(void* buffer, size_t size) {
     413                 : #ifdef SK_TRACE_BUFFERSTREAM
     414                 :     SkDebugf("Request %d", size);
     415                 : #endif
     416                 : 
     417               0 :     if (buffer == NULL && size == 0) {
     418               0 :         return fProxy->read(buffer, size);    // requesting total size
     419                 :     }
     420                 : 
     421               0 :     if (0 == size) {
     422               0 :         return 0;
     423                 :     }
     424                 : 
     425                 :     // skip size bytes
     426               0 :     if (NULL == buffer) {
     427               0 :         size_t remaining = fBufferSize - fBufferOffset;
     428               0 :         if (remaining >= size) {
     429               0 :             fBufferOffset += size;
     430               0 :             return size;
     431                 :         }
     432                 :         // if we get here, we are being asked to skip beyond our current buffer
     433                 :         // so reset our offset to force a read next time, and skip the diff
     434                 :         // in our proxy
     435               0 :         fBufferOffset = fOrigBufferSize;
     436               0 :         return remaining + fProxy->read(NULL, size - remaining);
     437                 :     }
     438                 : 
     439               0 :     size_t s = size;
     440               0 :     size_t actuallyRead = 0;
     441                 : 
     442                 :     // flush what we can from our fBuffer
     443               0 :     if (fBufferOffset < fBufferSize)
     444                 :     {
     445               0 :         if (s > fBufferSize - fBufferOffset)
     446               0 :             s = fBufferSize - fBufferOffset;
     447               0 :         memcpy(buffer, fBuffer + fBufferOffset, s);
     448                 : #ifdef SK_TRACE_BUFFERSTREAM
     449                 :         SkDebugf(" flush %d", s);
     450                 : #endif
     451               0 :         size -= s;
     452               0 :         fBufferOffset += s;
     453               0 :         buffer = (char*)buffer + s;
     454               0 :         actuallyRead = s;
     455                 :     }
     456                 : 
     457                 :     // check if there is more to read
     458               0 :     if (size)
     459                 :     {
     460               0 :         SkASSERT(fBufferOffset >= fBufferSize); // need to refill our fBuffer
     461                 : 
     462               0 :         if (size < fBufferSize) // lets try to read more than the request
     463                 :         {
     464               0 :             s = fProxy->read(fBuffer, fBufferSize);
     465                 : #ifdef SK_TRACE_BUFFERSTREAM
     466                 :             SkDebugf(" read %d into fBuffer", s);
     467                 : #endif
     468               0 :             if (size > s)   // they asked for too much
     469               0 :                 size = s;
     470               0 :             if (size)
     471                 :             {
     472               0 :                 memcpy(buffer, fBuffer, size);
     473               0 :                 actuallyRead += size;
     474                 : #ifdef SK_TRACE_BUFFERSTREAM
     475                 :                 SkDebugf(" memcpy %d into dst", size);
     476                 : #endif
     477                 :             }
     478                 : 
     479               0 :             fBufferOffset = size;
     480               0 :             fBufferSize = s;        // record the (possibly smaller) size for the buffer
     481                 :         }
     482                 :         else    // just do a direct read
     483                 :         {
     484               0 :             actuallyRead += fProxy->read(buffer, size);
     485                 : #ifdef SK_TRACE_BUFFERSTREAM
     486                 :             SkDebugf(" direct read %d", size);
     487                 : #endif
     488                 :         }
     489                 :     }
     490                 : #ifdef SK_TRACE_BUFFERSTREAM
     491                 :     SkDebugf("\n");
     492                 : #endif
     493               0 :     return actuallyRead;
     494                 : }
     495                 : 
     496               0 : const void* SkBufferStream::getMemoryBase()
     497                 : {
     498               0 :     return fProxy->getMemoryBase();
     499                 : }
     500                 : 
     501                 : /////////////////////////////////////////////////////////////////////////////////////////////////////////
     502                 : /////////////////////////////////////////////////////////////////////////////////////////////////////////
     503                 : 
     504               0 : SkFILEWStream::SkFILEWStream(const char path[])
     505                 : {
     506               0 :     fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
     507               0 : }
     508                 : 
     509               0 : SkFILEWStream::~SkFILEWStream()
     510                 : {
     511               0 :     if (fFILE)
     512               0 :         sk_fclose(fFILE);
     513               0 : }
     514                 : 
     515               0 : bool SkFILEWStream::write(const void* buffer, size_t size)
     516                 : {
     517               0 :     if (fFILE == NULL)
     518               0 :         return false;
     519                 : 
     520               0 :     if (sk_fwrite(buffer, size, fFILE) != size)
     521                 :     {
     522               0 :         SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
     523               0 :         sk_fclose(fFILE);
     524               0 :         fFILE = NULL;
     525               0 :         return false;
     526                 :     }
     527               0 :     return true;
     528                 : }
     529                 : 
     530               0 : void SkFILEWStream::flush()
     531                 : {
     532               0 :     if (fFILE)
     533               0 :         sk_fflush(fFILE);
     534               0 : }
     535                 : 
     536                 : ////////////////////////////////////////////////////////////////////////
     537                 : 
     538               0 : SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
     539               0 :     : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
     540                 : {
     541               0 : }
     542                 : 
     543               0 : bool SkMemoryWStream::write(const void* buffer, size_t size)
     544                 : {
     545               0 :     size = SkMin32(size, fMaxLength - fBytesWritten);
     546               0 :     if (size > 0)
     547                 :     {
     548               0 :         memcpy(fBuffer + fBytesWritten, buffer, size);
     549               0 :         fBytesWritten += size;
     550               0 :         return true;
     551                 :     }
     552               0 :     return false;
     553                 : }
     554                 : 
     555                 : ////////////////////////////////////////////////////////////////////////
     556                 : 
     557                 : #define SkDynamicMemoryWStream_MinBlockSize   256
     558                 : 
     559                 : struct SkDynamicMemoryWStream::Block {
     560                 :     Block*  fNext;
     561                 :     char*   fCurr;
     562                 :     char*   fStop;
     563                 : 
     564               0 :     const char* start() const { return (const char*)(this + 1); }
     565               0 :     char*   start() { return (char*)(this + 1); }
     566               0 :     size_t  avail() const { return fStop - fCurr; }
     567               0 :     size_t  written() const { return fCurr - this->start(); }
     568                 :     
     569               0 :     void init(size_t size)
     570                 :     {
     571               0 :         fNext = NULL;
     572               0 :         fCurr = this->start();
     573               0 :         fStop = this->start() + size;
     574               0 :     }
     575                 :     
     576               0 :     const void* append(const void* data, size_t size)
     577                 :     {
     578               0 :         SkASSERT((size_t)(fStop - fCurr) >= size);
     579               0 :         memcpy(fCurr, data, size);
     580               0 :         fCurr += size;
     581               0 :         return (const void*)((const char*)data + size);
     582                 :     }
     583                 : };
     584                 : 
     585               0 : SkDynamicMemoryWStream::SkDynamicMemoryWStream()
     586               0 :     : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
     587                 : {
     588               0 : }
     589                 : 
     590               0 : SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
     591                 : {
     592               0 :     reset();
     593               0 : }
     594                 : 
     595               0 : void SkDynamicMemoryWStream::reset()
     596                 : {
     597               0 :     this->invalidateCopy();
     598                 :     
     599               0 :     Block*  block = fHead;
     600                 :     
     601               0 :     while (block != NULL) {
     602               0 :         Block*  next = block->fNext;
     603               0 :         sk_free(block);
     604               0 :         block = next;
     605                 :     }
     606               0 :     fHead = fTail = NULL;
     607               0 :     fBytesWritten = 0;
     608               0 : }
     609                 : 
     610               0 : bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
     611                 : {
     612               0 :     if (count > 0) {
     613               0 :         this->invalidateCopy();
     614                 : 
     615               0 :         fBytesWritten += count;
     616                 :         
     617                 :         size_t  size;
     618                 :         
     619               0 :         if (fTail != NULL && fTail->avail() > 0) {
     620               0 :             size = SkMin32(fTail->avail(), count);
     621               0 :             buffer = fTail->append(buffer, size);
     622               0 :             SkASSERT(count >= size);
     623               0 :             count -= size;        
     624               0 :             if (count == 0)
     625               0 :                 return true;
     626                 :         }
     627                 :             
     628               0 :         size = SkMax32(count, SkDynamicMemoryWStream_MinBlockSize);
     629               0 :         Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
     630               0 :         block->init(size);
     631               0 :         block->append(buffer, count);
     632                 :         
     633               0 :         if (fTail != NULL)
     634               0 :             fTail->fNext = block;
     635                 :         else
     636               0 :             fHead = fTail = block;
     637               0 :         fTail = block;
     638                 :     }
     639               0 :     return true;
     640                 : }
     641                 : 
     642               0 : bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
     643                 : {
     644               0 :     if (offset + count > fBytesWritten) {
     645               0 :         return false; // test does not partially modify
     646                 :     }
     647                 : 
     648               0 :     this->invalidateCopy();
     649                 :     
     650               0 :     Block* block = fHead;
     651               0 :     while (block != NULL) {
     652               0 :         size_t size = block->written();
     653               0 :         if (offset < size) {
     654               0 :             size_t part = offset + count > size ? size - offset : count;
     655               0 :             memcpy(block->start() + offset, buffer, part);
     656               0 :             if (count <= part)
     657               0 :                 return true;
     658               0 :             count -= part;
     659               0 :             buffer = (const void*) ((char* ) buffer + part);
     660                 :         }
     661               0 :         offset = offset > size ? offset - size : 0;
     662               0 :         block = block->fNext;
     663                 :     }
     664               0 :     return false;
     665                 : }
     666                 : 
     667               0 : bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
     668                 : {
     669               0 :     if (offset + count > fBytesWritten)
     670               0 :         return false; // test does not partially modify
     671               0 :     Block* block = fHead;
     672               0 :     while (block != NULL) {
     673               0 :         size_t size = block->written();
     674               0 :         if (offset < size) {
     675               0 :             size_t part = offset + count > size ? size - offset : count;
     676               0 :             memcpy(buffer, block->start() + offset, part);
     677               0 :             if (count <= part)
     678               0 :                 return true;
     679               0 :             count -= part;
     680               0 :             buffer = (void*) ((char* ) buffer + part);
     681                 :         }
     682               0 :         offset = offset > size ? offset - size : 0;
     683               0 :         block = block->fNext;
     684                 :     }
     685               0 :     return false;
     686                 : }
     687                 : 
     688               0 : void SkDynamicMemoryWStream::copyTo(void* dst) const
     689                 : {
     690               0 :     if (fCopy) {
     691               0 :         memcpy(dst, fCopy->data(), fBytesWritten);
     692                 :     } else {
     693               0 :         Block* block = fHead;
     694                 :         
     695               0 :         while (block != NULL) {
     696               0 :             size_t size = block->written();
     697               0 :             memcpy(dst, block->start(), size);
     698               0 :             dst = (void*)((char*)dst + size);
     699               0 :             block = block->fNext;
     700                 :         }
     701                 :     }
     702               0 : }
     703                 : 
     704               0 : void SkDynamicMemoryWStream::padToAlign4()
     705                 : {
     706                 :     // cast to remove unary-minus warning
     707               0 :     int padBytes = -(int)fBytesWritten & 0x03;
     708               0 :     if (padBytes == 0)
     709               0 :         return;
     710               0 :     int zero = 0;
     711               0 :     write(&zero, padBytes);
     712                 : }
     713                 : 
     714               0 : SkData* SkDynamicMemoryWStream::copyToData() const {
     715               0 :     if (NULL == fCopy) {
     716               0 :         void* buffer = sk_malloc_throw(fBytesWritten);
     717               0 :         this->copyTo(buffer);
     718               0 :         fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
     719                 :     }
     720               0 :     fCopy->ref();
     721               0 :     return fCopy;
     722                 : }
     723                 : 
     724               0 : void SkDynamicMemoryWStream::invalidateCopy() {
     725               0 :     if (fCopy) {
     726               0 :         fCopy->unref();
     727               0 :         fCopy = NULL;
     728                 :     }
     729               0 : }
     730                 : 
     731                 : ///////////////////////////////////////////////////////////////////////////////
     732                 : 
     733               0 : void SkDebugWStream::newline()
     734                 : {
     735                 : #ifdef SK_DEBUG
     736               0 :     SkDebugf("\n");
     737                 : #endif
     738               0 : }
     739                 : 
     740               0 : bool SkDebugWStream::write(const void* buffer, size_t size)
     741                 : {
     742                 : #ifdef SK_DEBUG
     743               0 :     char* s = new char[size+1];
     744               0 :     memcpy(s, buffer, size);
     745               0 :     s[size] = 0;
     746               0 :     SkDebugf("%s", s);
     747               0 :     delete[] s;
     748                 : #endif
     749               0 :     return true;
     750                 : }

Generated by: LCOV version 1.7