LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkWriter32.h (source / functions) Hit Total Coverage
Test: output.info Lines: 12 98 12.2 %
Date: 2017-07-14 16:53:18 Functions: 3 26 11.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright 2008 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             : #ifndef SkWriter32_DEFINED
      11             : #define SkWriter32_DEFINED
      12             : 
      13             : #include "../private/SkTemplates.h"
      14             : #include "SkData.h"
      15             : #include "SkMatrix.h"
      16             : #include "SkPath.h"
      17             : #include "SkPoint.h"
      18             : #include "SkRRect.h"
      19             : #include "SkRect.h"
      20             : #include "SkRegion.h"
      21             : #include "SkScalar.h"
      22             : #include "SkStream.h"
      23             : #include "SkTypes.h"
      24             : 
      25          63 : class SK_API SkWriter32 : SkNoncopyable {
      26             : public:
      27             :     /**
      28             :      *  The caller can specify an initial block of storage, which the caller manages.
      29             :      *
      30             :      *  SkWriter32 will try to back reserve and write calls with this external storage until the
      31             :      *  first time an allocation doesn't fit.  From then it will use dynamically allocated storage.
      32             :      *  This used to be optional behavior, but pipe now relies on it.
      33             :      */
      34          63 :     SkWriter32(void* external = NULL, size_t externalBytes = 0) {
      35          63 :         this->reset(external, externalBytes);
      36          63 :     }
      37             : 
      38             :     // return the current offset (will always be a multiple of 4)
      39           0 :     size_t bytesWritten() const { return fUsed; }
      40             : 
      41             :     SK_ATTR_DEPRECATED("use bytesWritten")
      42             :     size_t size() const { return this->bytesWritten(); }
      43             : 
      44          63 :     void reset(void* external = NULL, size_t externalBytes = 0) {
      45          63 :         SkASSERT(SkIsAlign4((uintptr_t)external));
      46          63 :         SkASSERT(SkIsAlign4(externalBytes));
      47             : 
      48          63 :         fData = (uint8_t*)external;
      49          63 :         fCapacity = externalBytes;
      50          63 :         fUsed = 0;
      51          63 :         fExternal = external;
      52          63 :     }
      53             : 
      54             :     // size MUST be multiple of 4
      55           0 :     uint32_t* reserve(size_t size) {
      56           0 :         SkASSERT(SkAlign4(size) == size);
      57           0 :         size_t offset = fUsed;
      58           0 :         size_t totalRequired = fUsed + size;
      59           0 :         if (totalRequired > fCapacity) {
      60           0 :             this->growToAtLeast(totalRequired);
      61             :         }
      62           0 :         fUsed = totalRequired;
      63           0 :         return (uint32_t*)(fData + offset);
      64             :     }
      65             : 
      66             :     /**
      67             :      *  Read a T record at offset, which must be a multiple of 4. Only legal if the record
      68             :      *  was written atomically using the write methods below.
      69             :      */
      70             :     template<typename T>
      71           0 :     const T& readTAt(size_t offset) const {
      72           0 :         SkASSERT(SkAlign4(offset) == offset);
      73           0 :         SkASSERT(offset < fUsed);
      74           0 :         return *(T*)(fData + offset);
      75             :     }
      76             : 
      77             :     /**
      78             :      *  Overwrite a T record at offset, which must be a multiple of 4. Only legal if the record
      79             :      *  was written atomically using the write methods below.
      80             :      */
      81             :     template<typename T>
      82           0 :     void overwriteTAt(size_t offset, const T& value) {
      83           0 :         SkASSERT(SkAlign4(offset) == offset);
      84           0 :         SkASSERT(offset < fUsed);
      85           0 :         *(T*)(fData + offset) = value;
      86           0 :     }
      87             : 
      88           0 :     bool writeBool(bool value) {
      89           0 :         this->write32(value);
      90           0 :         return value;
      91             :     }
      92             : 
      93           0 :     void writeInt(int32_t value) {
      94           0 :         this->write32(value);
      95           0 :     }
      96             : 
      97             :     void write8(int32_t value) {
      98             :         *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
      99             :     }
     100             : 
     101             :     void write16(int32_t value) {
     102             :         *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
     103             :     }
     104             : 
     105           0 :     void write32(int32_t value) {
     106           0 :         *(int32_t*)this->reserve(sizeof(value)) = value;
     107           0 :     }
     108             : 
     109             :     void writePtr(void* value) {
     110             :         *(void**)this->reserve(sizeof(value)) = value;
     111             :     }
     112             : 
     113           0 :     void writeScalar(SkScalar value) {
     114           0 :         *(SkScalar*)this->reserve(sizeof(value)) = value;
     115           0 :     }
     116             : 
     117           0 :     void writePoint(const SkPoint& pt) {
     118           0 :         *(SkPoint*)this->reserve(sizeof(pt)) = pt;
     119           0 :     }
     120             : 
     121           0 :     void writeRect(const SkRect& rect) {
     122           0 :         *(SkRect*)this->reserve(sizeof(rect)) = rect;
     123           0 :     }
     124             : 
     125             :     void writeIRect(const SkIRect& rect) {
     126             :         *(SkIRect*)this->reserve(sizeof(rect)) = rect;
     127             :     }
     128             : 
     129           0 :     void writeRRect(const SkRRect& rrect) {
     130           0 :         rrect.writeToMemory(this->reserve(SkRRect::kSizeInMemory));
     131           0 :     }
     132             : 
     133           0 :     void writePath(const SkPath& path) {
     134           0 :         size_t size = path.writeToMemory(NULL);
     135           0 :         SkASSERT(SkAlign4(size) == size);
     136           0 :         path.writeToMemory(this->reserve(size));
     137           0 :     }
     138             : 
     139           0 :     void writeMatrix(const SkMatrix& matrix) {
     140           0 :         size_t size = matrix.writeToMemory(NULL);
     141           0 :         SkASSERT(SkAlign4(size) == size);
     142           0 :         matrix.writeToMemory(this->reserve(size));
     143           0 :     }
     144             : 
     145           0 :     void writeRegion(const SkRegion& rgn) {
     146           0 :         size_t size = rgn.writeToMemory(NULL);
     147           0 :         SkASSERT(SkAlign4(size) == size);
     148           0 :         rgn.writeToMemory(this->reserve(size));
     149           0 :     }
     150             : 
     151             :     // write count bytes (must be a multiple of 4)
     152           0 :     void writeMul4(const void* values, size_t size) {
     153           0 :         this->write(values, size);
     154           0 :     }
     155             : 
     156             :     /**
     157             :      *  Write size bytes from values. size must be a multiple of 4, though
     158             :      *  values need not be 4-byte aligned.
     159             :      */
     160           0 :     void write(const void* values, size_t size) {
     161           0 :         SkASSERT(SkAlign4(size) == size);
     162           0 :         sk_careful_memcpy(this->reserve(size), values, size);
     163           0 :     }
     164             : 
     165             :     /**
     166             :      *  Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be
     167             :      *  filled in with zeroes.
     168             :      */
     169           0 :     uint32_t* reservePad(size_t size) {
     170           0 :         size_t alignedSize = SkAlign4(size);
     171           0 :         uint32_t* p = this->reserve(alignedSize);
     172           0 :         if (alignedSize != size) {
     173           0 :             SkASSERT(alignedSize >= 4);
     174           0 :             p[alignedSize / 4 - 1] = 0;
     175             :         }
     176           0 :         return p;
     177             :     }
     178             : 
     179             :     /**
     180             :      *  Write size bytes from src, and pad to 4 byte alignment with zeroes.
     181             :      */
     182           0 :     void writePad(const void* src, size_t size) {
     183           0 :         sk_careful_memcpy(this->reservePad(size), src, size);
     184           0 :     }
     185             : 
     186             :     /**
     187             :      *  Writes a string to the writer, which can be retrieved with
     188             :      *  SkReader32::readString().
     189             :      *  The length can be specified, or if -1 is passed, it will be computed by
     190             :      *  calling strlen(). The length must be < max size_t.
     191             :      *
     192             :      *  If you write NULL, it will be read as "".
     193             :      */
     194             :     void writeString(const char* str, size_t len = (size_t)-1);
     195             : 
     196             :     /**
     197             :      *  Computes the size (aligned to multiple of 4) need to write the string
     198             :      *  in a call to writeString(). If the length is not specified, it will be
     199             :      *  computed by calling strlen().
     200             :      */
     201             :     static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
     202             : 
     203           0 :     void writeData(const SkData* data) {
     204           0 :         uint32_t len = data ? SkToU32(data->size()) : 0;
     205           0 :         this->write32(len);
     206           0 :         if (data) {
     207           0 :             this->writePad(data->data(), len);
     208             :         }
     209           0 :     }
     210             : 
     211           0 :     static size_t WriteDataSize(const SkData* data) {
     212           0 :         return 4 + SkAlign4(data ? data->size() : 0);
     213             :     }
     214             : 
     215             :     /**
     216             :      *  Move the cursor back to offset bytes from the beginning.
     217             :      *  offset must be a multiple of 4 no greater than size().
     218             :      */
     219             :     void rewindToOffset(size_t offset) {
     220             :         SkASSERT(SkAlign4(offset) == offset);
     221             :         SkASSERT(offset <= bytesWritten());
     222             :         fUsed = offset;
     223             :     }
     224             : 
     225             :     // copy into a single buffer (allocated by caller). Must be at least size()
     226           0 :     void flatten(void* dst) const {
     227           0 :         memcpy(dst, fData, fUsed);
     228           0 :     }
     229             : 
     230           0 :     bool writeToStream(SkWStream* stream) const {
     231           0 :         return stream->write(fData, fUsed);
     232             :     }
     233             : 
     234             :     // read from the stream, and write up to length bytes. Return the actual
     235             :     // number of bytes written.
     236           0 :     size_t readFromStream(SkStream* stream, size_t length) {
     237           0 :         return stream->read(this->reservePad(length), length);
     238             :     }
     239             : 
     240             :     /**
     241             :      *  Captures a snapshot of the data as it is right now, and return it.
     242             :      */
     243             :     sk_sp<SkData> snapshotAsData() const;
     244             : private:
     245             :     void growToAtLeast(size_t size);
     246             : 
     247             :     uint8_t* fData;                    // Points to either fInternal or fExternal.
     248             :     size_t fCapacity;                  // Number of bytes we can write to fData.
     249             :     size_t fUsed;                      // Number of bytes written.
     250             :     void* fExternal;                   // Unmanaged memory block.
     251             :     SkAutoTMalloc<uint8_t> fInternal;  // Managed memory block.
     252             : };
     253             : 
     254             : /**
     255             :  *  Helper class to allocated SIZE bytes as part of the writer, and to provide
     256             :  *  that storage to the constructor as its initial storage buffer.
     257             :  *
     258             :  *  This wrapper ensures proper alignment rules are met for the storage.
     259             :  */
     260             : template <size_t SIZE> class SkSWriter32 : public SkWriter32 {
     261             : public:
     262             :     SkSWriter32() { this->reset(); }
     263             : 
     264             :     void reset() {this->INHERITED::reset(fData.fStorage, SIZE); }
     265             : 
     266             : private:
     267             :     union {
     268             :         void*   fPtrAlignment;
     269             :         double  fDoubleAlignment;
     270             :         char    fStorage[SIZE];
     271             :     } fData;
     272             : 
     273             :     typedef SkWriter32 INHERITED;
     274             : };
     275             : 
     276             : #endif

Generated by: LCOV version 1.13