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