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