LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkStream.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 41 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 43 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2006 The Android Open Source Project
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #ifndef SkStream_DEFINED
       9             : #define SkStream_DEFINED
      10             : 
      11             : #include "SkData.h"
      12             : #include "SkRefCnt.h"
      13             : #include "SkScalar.h"
      14             : 
      15             : #include <memory.h>
      16             : 
      17             : class SkStream;
      18             : class SkStreamRewindable;
      19             : class SkStreamSeekable;
      20             : class SkStreamAsset;
      21             : class SkStreamMemory;
      22             : 
      23             : /**
      24             :  *  SkStream -- abstraction for a source of bytes. Subclasses can be backed by
      25             :  *  memory, or a file, or something else.
      26             :  *
      27             :  *  NOTE:
      28             :  *
      29             :  *  Classic "streams" APIs are sort of async, in that on a request for N
      30             :  *  bytes, they may return fewer than N bytes on a given call, in which case
      31             :  *  the caller can "try again" to get more bytes, eventually (modulo an error)
      32             :  *  receiving their total N bytes.
      33             :  *
      34             :  *  Skia streams behave differently. They are effectively synchronous, and will
      35             :  *  always return all N bytes of the request if possible. If they return fewer
      36             :  *  (the read() call returns the number of bytes read) then that means there is
      37             :  *  no more data (at EOF or hit an error). The caller should *not* call again
      38             :  *  in hopes of fulfilling more of the request.
      39             :  */
      40           0 : class SK_API SkStream : public SkNoncopyable {
      41             : public:
      42           0 :     virtual ~SkStream() {}
      43             : 
      44             :     /**
      45             :      *  Attempts to open the specified file as a stream, returns nullptr on failure.
      46             :      */
      47             :     static std::unique_ptr<SkStreamAsset> MakeFromFile(const char path[]);
      48             : 
      49             :     /** Reads or skips size number of bytes.
      50             :      *  If buffer == NULL, skip size bytes, return how many were skipped.
      51             :      *  If buffer != NULL, copy size bytes into buffer, return how many were copied.
      52             :      *  @param buffer when NULL skip size bytes, otherwise copy size bytes into buffer
      53             :      *  @param size the number of bytes to skip or copy
      54             :      *  @return the number of bytes actually read.
      55             :      */
      56             :     virtual size_t read(void* buffer, size_t size) = 0;
      57             : 
      58             :     /** Skip size number of bytes.
      59             :      *  @return the actual number bytes that could be skipped.
      60             :      */
      61           0 :     size_t skip(size_t size) {
      62           0 :         return this->read(NULL, size);
      63             :     }
      64             : 
      65             :     /**
      66             :      *  Attempt to peek at size bytes.
      67             :      *  If this stream supports peeking, copy min(size, peekable bytes) into
      68             :      *  buffer, and return the number of bytes copied.
      69             :      *  If the stream does not support peeking, or cannot peek any bytes,
      70             :      *  return 0 and leave buffer unchanged.
      71             :      *  The stream is guaranteed to be in the same visible state after this
      72             :      *  call, regardless of success or failure.
      73             :      *  @param buffer Must not be NULL, and must be at least size bytes. Destination
      74             :      *      to copy bytes.
      75             :      *  @param size Number of bytes to copy.
      76             :      *  @return The number of bytes peeked/copied.
      77             :      */
      78           0 :     virtual size_t peek(void* /*buffer*/, size_t /*size*/) const { return 0; }
      79             : 
      80             :     /** Returns true when all the bytes in the stream have been read.
      81             :      *  This may return true early (when there are no more bytes to be read)
      82             :      *  or late (after the first unsuccessful read).
      83             :      */
      84             :     virtual bool isAtEnd() const = 0;
      85             : 
      86             :     int8_t   readS8();
      87             :     int16_t  readS16();
      88             :     int32_t  readS32();
      89             : 
      90           0 :     uint8_t  readU8() { return (uint8_t)this->readS8(); }
      91           0 :     uint16_t readU16() { return (uint16_t)this->readS16(); }
      92           0 :     uint32_t readU32() { return (uint32_t)this->readS32(); }
      93             : 
      94           0 :     bool     readBool() { return this->readU8() != 0; }
      95             :     SkScalar readScalar();
      96             :     size_t   readPackedUInt();
      97             : 
      98             : //SkStreamRewindable
      99             :     /** Rewinds to the beginning of the stream. Returns true if the stream is known
     100             :      *  to be at the beginning after this call returns.
     101             :      */
     102           0 :     virtual bool rewind() { return false; }
     103             : 
     104             :     /** Duplicates this stream. If this cannot be done, returns NULL.
     105             :      *  The returned stream will be positioned at the beginning of its data.
     106             :      */
     107           0 :     virtual SkStreamRewindable* duplicate() const { return NULL; }
     108             : 
     109             : //SkStreamSeekable
     110             :     /** Returns true if this stream can report it's current position. */
     111           0 :     virtual bool hasPosition() const { return false; }
     112             :     /** Returns the current position in the stream. If this cannot be done, returns 0. */
     113           0 :     virtual size_t getPosition() const { return 0; }
     114             : 
     115             :     /** Seeks to an absolute position in the stream. If this cannot be done, returns false.
     116             :      *  If an attempt is made to seek past the end of the stream, the position will be set
     117             :      *  to the end of the stream.
     118             :      */
     119           0 :     virtual bool seek(size_t /*position*/) { return false; }
     120             : 
     121             :     /** Seeks to an relative offset in the stream. If this cannot be done, returns false.
     122             :      *  If an attempt is made to move to a position outside the stream, the position will be set
     123             :      *  to the closest point within the stream (beginning or end).
     124             :      */
     125           0 :     virtual bool move(long /*offset*/) { return false; }
     126             : 
     127             :     /** Duplicates this stream. If this cannot be done, returns NULL.
     128             :      *  The returned stream will be positioned the same as this stream.
     129             :      */
     130           0 :     virtual SkStreamSeekable* fork() const { return NULL; }
     131             : 
     132             : //SkStreamAsset
     133             :     /** Returns true if this stream can report it's total length. */
     134           0 :     virtual bool hasLength() const { return false; }
     135             :     /** Returns the total length of the stream. If this cannot be done, returns 0. */
     136           0 :     virtual size_t getLength() const { return 0; }
     137             : 
     138             : //SkStreamMemory
     139             :     /** Returns the starting address for the data. If this cannot be done, returns NULL. */
     140             :     //TODO: replace with virtual const SkData* getData()
     141           0 :     virtual const void* getMemoryBase() { return NULL; }
     142             : };
     143             : 
     144             : /** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */
     145           0 : class SK_API SkStreamRewindable : public SkStream {
     146             : public:
     147             :     bool rewind() override = 0;
     148             :     SkStreamRewindable* duplicate() const override = 0;
     149             : };
     150             : 
     151             : /** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */
     152           0 : class SK_API SkStreamSeekable : public SkStreamRewindable {
     153             : public:
     154             :     SkStreamSeekable* duplicate() const override = 0;
     155             : 
     156           0 :     bool hasPosition() const override { return true; }
     157             :     size_t getPosition() const override = 0;
     158             :     bool seek(size_t position) override = 0;
     159             :     bool move(long offset) override = 0;
     160             :     SkStreamSeekable* fork() const override = 0;
     161             : };
     162             : 
     163             : /** SkStreamAsset is a SkStreamSeekable for which getLength is required. */
     164           0 : class SK_API SkStreamAsset : public SkStreamSeekable {
     165             : public:
     166             :     SkStreamAsset* duplicate() const override = 0;
     167             :     SkStreamAsset* fork() const override = 0;
     168             : 
     169           0 :     bool hasLength() const override { return true; }
     170             :     size_t getLength() const override = 0;
     171             : };
     172             : 
     173             : /** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */
     174           0 : class SK_API SkStreamMemory : public SkStreamAsset {
     175             : public:
     176             :     SkStreamMemory* duplicate() const override = 0;
     177             :     SkStreamMemory* fork() const override = 0;
     178             : 
     179             :     const void* getMemoryBase() override = 0;
     180             : };
     181             : 
     182           0 : class SK_API SkWStream : SkNoncopyable {
     183             : public:
     184             :     virtual ~SkWStream();
     185             : 
     186             :     /** Called to write bytes to a SkWStream. Returns true on success
     187             :         @param buffer the address of at least size bytes to be written to the stream
     188             :         @param size The number of bytes in buffer to write to the stream
     189             :         @return true on success
     190             :     */
     191             :     virtual bool write(const void* buffer, size_t size) = 0;
     192             :     virtual void flush();
     193             : 
     194             :     virtual size_t bytesWritten() const = 0;
     195             : 
     196             :     // helpers
     197             : 
     198           0 :     bool write8(U8CPU value)   {
     199           0 :         uint8_t v = SkToU8(value);
     200           0 :         return this->write(&v, 1);
     201             :     }
     202           0 :     bool write16(U16CPU value) {
     203           0 :         uint16_t v = SkToU16(value);
     204           0 :         return this->write(&v, 2);
     205             :     }
     206           0 :     bool write32(uint32_t v) {
     207           0 :         return this->write(&v, 4);
     208             :     }
     209             : 
     210           0 :     bool writeText(const char text[]) {
     211           0 :         SkASSERT(text);
     212           0 :         return this->write(text, strlen(text));
     213             :     }
     214             : 
     215             :     bool newline() { return this->write("\n", strlen("\n")); }
     216             : 
     217             :     bool    writeDecAsText(int32_t);
     218             :     bool    writeBigDecAsText(int64_t, int minDigits = 0);
     219             :     bool    writeHexAsText(uint32_t, int minDigits = 0);
     220             :     bool    writeScalarAsText(SkScalar);
     221             : 
     222           0 :     bool    writeBool(bool v) { return this->write8(v); }
     223             :     bool    writeScalar(SkScalar);
     224             :     bool    writePackedUInt(size_t);
     225             : 
     226             :     bool    writeStream(SkStream* input, size_t length);
     227             : 
     228             :     /**
     229             :      * This returns the number of bytes in the stream required to store
     230             :      * 'value'.
     231             :      */
     232             :     static int SizeOfPackedUInt(size_t value);
     233             : };
     234             : 
     235             : class SK_API SkNullWStream : public SkWStream {
     236             : public:
     237             :     SkNullWStream() : fBytesWritten(0) {}
     238             : 
     239             :     bool write(const void*, size_t n) override { fBytesWritten += n; return true; }
     240             :     void flush() override {}
     241             :     size_t bytesWritten() const override { return fBytesWritten; }
     242             : 
     243             : private:
     244             :     size_t fBytesWritten;
     245             : };
     246             : 
     247             : ////////////////////////////////////////////////////////////////////////////////////////
     248             : 
     249             : #include <stdio.h>
     250             : 
     251             : /** A stream that wraps a C FILE* file stream. */
     252             : class SK_API SkFILEStream : public SkStreamAsset {
     253             : public:
     254             :     /** Initialize the stream by calling sk_fopen on the specified path.
     255             :      *  This internal stream will be closed in the destructor.
     256             :      */
     257             :     explicit SkFILEStream(const char path[] = nullptr);
     258             : 
     259             :     /** Initialize the stream with an existing C file stream.
     260             :      *  The C file stream will be closed in the destructor.
     261             :      */
     262             :     explicit SkFILEStream(FILE* file);
     263             : 
     264             :     ~SkFILEStream() override;
     265             : 
     266             :     /** Returns true if the current path could be opened. */
     267           0 :     bool isValid() const { return fFILE != nullptr; }
     268             : 
     269             :     /** Close this SkFILEStream. */
     270             :     void close();
     271             : 
     272             :     size_t read(void* buffer, size_t size) override;
     273             :     bool isAtEnd() const override;
     274             : 
     275             :     bool rewind() override;
     276             :     SkStreamAsset* duplicate() const override;
     277             : 
     278             :     size_t getPosition() const override;
     279             :     bool seek(size_t position) override;
     280             :     bool move(long offset) override;
     281             :     SkStreamAsset* fork() const override;
     282             : 
     283             :     size_t getLength() const override;
     284             : 
     285             :     const void* getMemoryBase() override;
     286             : 
     287             : private:
     288             :     explicit SkFILEStream(std::shared_ptr<FILE>, size_t size, size_t offset);
     289             :     explicit SkFILEStream(std::shared_ptr<FILE>, size_t size, size_t offset, size_t originalOffset);
     290             : 
     291             :     std::shared_ptr<FILE> fFILE;
     292             :     // My own council will I keep on sizes and offsets.
     293             :     size_t fSize;
     294             :     size_t fOffset;
     295             :     size_t fOriginalOffset;
     296             : 
     297             :     typedef SkStreamAsset INHERITED;
     298             : };
     299             : 
     300           0 : class SK_API SkMemoryStream : public SkStreamMemory {
     301             : public:
     302             :     SkMemoryStream();
     303             : 
     304             :     /** We allocate (and free) the memory. Write to it via getMemoryBase() */
     305             :     SkMemoryStream(size_t length);
     306             : 
     307             :     /** If copyData is true, the stream makes a private copy of the data. */
     308             :     SkMemoryStream(const void* data, size_t length, bool copyData = false);
     309             : 
     310             :     /** Creates the stream to read from the specified data */
     311             :     SkMemoryStream(sk_sp<SkData>);
     312             : 
     313             :     /** Resets the stream to the specified data and length,
     314             :         just like the constructor.
     315             :         if copyData is true, the stream makes a private copy of the data
     316             :     */
     317             :     virtual void setMemory(const void* data, size_t length,
     318             :                            bool copyData = false);
     319             :     /** Replace any memory buffer with the specified buffer. The caller
     320             :         must have allocated data with sk_malloc or sk_realloc, since it
     321             :         will be freed with sk_free.
     322             :     */
     323             :     void setMemoryOwned(const void* data, size_t length);
     324             : 
     325             :     sk_sp<SkData> asData() const { return fData; }
     326             :     void setData(sk_sp<SkData>);
     327             : 
     328             :     void skipToAlign4();
     329             :     const void* getAtPos();
     330             : 
     331             :     size_t read(void* buffer, size_t size) override;
     332             :     bool isAtEnd() const override;
     333             : 
     334             :     size_t peek(void* buffer, size_t size) const override;
     335             : 
     336             :     bool rewind() override;
     337             :     SkMemoryStream* duplicate() const override;
     338             : 
     339             :     size_t getPosition() const override;
     340             :     bool seek(size_t position) override;
     341             :     bool move(long offset) override;
     342             :     SkMemoryStream* fork() const override;
     343             : 
     344             :     size_t getLength() const override;
     345             : 
     346             :     const void* getMemoryBase() override;
     347             : 
     348             : private:
     349             :     sk_sp<SkData>   fData;
     350             :     size_t          fOffset;
     351             : 
     352             :     typedef SkStreamMemory INHERITED;
     353             : };
     354             : 
     355             : /////////////////////////////////////////////////////////////////////////////////////////////
     356             : 
     357             : class SK_API SkFILEWStream : public SkWStream {
     358             : public:
     359             :     SkFILEWStream(const char path[]);
     360             :     ~SkFILEWStream() override;
     361             : 
     362             :     /** Returns true if the current path could be opened.
     363             :     */
     364           0 :     bool isValid() const { return fFILE != NULL; }
     365             : 
     366             :     bool write(const void* buffer, size_t size) override;
     367             :     void flush() override;
     368             :     void fsync();
     369             :     size_t bytesWritten() const override;
     370             : 
     371             : private:
     372             :     FILE* fFILE;
     373             : 
     374             :     typedef SkWStream INHERITED;
     375             : };
     376             : 
     377             : class SK_API SkDynamicMemoryWStream : public SkWStream {
     378             : public:
     379             :     SkDynamicMemoryWStream();
     380             :     ~SkDynamicMemoryWStream() override;
     381             : 
     382             :     bool write(const void* buffer, size_t size) override;
     383             :     size_t bytesWritten() const override;
     384             : 
     385             :     bool read(void* buffer, size_t offset, size_t size);
     386             : 
     387             :     /** More efficient version of read(dst, 0, bytesWritten()). */
     388             :     void copyTo(void* dst) const;
     389             :     void writeToStream(SkWStream* dst) const;
     390             : 
     391             :     /** Equivalent to copyTo() followed by reset(), but may save memory use. */
     392             :     void copyToAndReset(void* dst);
     393             : 
     394             :     /** Return the contents as SkData, and then reset the stream. */
     395             :     sk_sp<SkData> detachAsData();
     396             : 
     397             :     /** Reset, returning a reader stream with the current content. */
     398             :     std::unique_ptr<SkStreamAsset> detachAsStream();
     399             : 
     400             :     /** Reset the stream to its original, empty, state. */
     401             :     void reset();
     402             :     void padToAlign4();
     403             : private:
     404             :     struct Block;
     405             :     Block*  fHead;
     406             :     Block*  fTail;
     407             :     size_t  fBytesWrittenBeforeTail;
     408             : 
     409             : #ifdef SK_DEBUG
     410             :     void validate() const;
     411             : #else
     412             :     void validate() const {}
     413             : #endif
     414             : 
     415             :     // For access to the Block type.
     416             :     friend class SkBlockMemoryStream;
     417             :     friend class SkBlockMemoryRefCnt;
     418             : 
     419             :     typedef SkWStream INHERITED;
     420             : };
     421             : 
     422             : #endif

Generated by: LCOV version 1.13