Skia
2D Graphics Library
SkStream.h
Go to the documentation of this file.
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 "include/core/SkData.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/core/SkScalar.h"
14 #include "include/core/SkTypes.h"
15 #include "include/private/base/SkCPUTypes.h"
16 #include "include/private/base/SkTo.h"
17 
18 #include <cstdint>
19 #include <cstdio>
20 #include <cstring>
21 #include <memory>
22 #include <utility>
23 class SkStreamAsset;
24 
29 class SK_API SkStream {
30 public:
31  virtual ~SkStream() {}
32  SkStream() {}
33 
37  static std::unique_ptr<SkStreamAsset> MakeFromFile(const char path[]);
38 
46  virtual size_t read(void* buffer, size_t size) = 0;
47 
51  size_t skip(size_t size) {
52  return this->read(nullptr, size);
53  }
54 
68  virtual size_t peek(void* /*buffer*/, size_t /*size*/) const { return 0; }
69 
77  virtual bool isAtEnd() const = 0;
78 
79  [[nodiscard]] bool readS8(int8_t*);
80  [[nodiscard]] bool readS16(int16_t*);
81  [[nodiscard]] bool readS32(int32_t*);
82 
83  [[nodiscard]] bool readU8(uint8_t* i) { return this->readS8((int8_t*)i); }
84  [[nodiscard]] bool readU16(uint16_t* i) { return this->readS16((int16_t*)i); }
85  [[nodiscard]] bool readU32(uint32_t* i) { return this->readS32((int32_t*)i); }
86 
87  [[nodiscard]] bool readBool(bool* b) {
88  uint8_t i;
89  if (!this->readU8(&i)) { return false; }
90  *b = (i != 0);
91  return true;
92  }
93  [[nodiscard]] bool readScalar(SkScalar*);
94  [[nodiscard]] bool readPackedUInt(size_t*);
95 
96 //SkStreamRewindable
100  virtual bool rewind() { return false; }
101 
105  std::unique_ptr<SkStream> duplicate() const {
106  return std::unique_ptr<SkStream>(this->onDuplicate());
107  }
111  std::unique_ptr<SkStream> fork() const {
112  return std::unique_ptr<SkStream>(this->onFork());
113  }
114 
115 //SkStreamSeekable
117  virtual bool hasPosition() const { return false; }
119  virtual size_t getPosition() const { return 0; }
120 
125  virtual bool seek(size_t /*position*/) { return false; }
126 
131  virtual bool move(long /*offset*/) { return false; }
132 
133 //SkStreamAsset
135  virtual bool hasLength() const { return false; }
137  virtual size_t getLength() const { return 0; }
138 
139 //SkStreamMemory
141  //TODO: replace with virtual const SkData* getData()
142  virtual const void* getMemoryBase() { return nullptr; }
143 
144 private:
145  virtual SkStream* onDuplicate() const { return nullptr; }
146  virtual SkStream* onFork() const { return nullptr; }
147 
148  SkStream(SkStream&&) = delete;
149  SkStream(const SkStream&) = delete;
150  SkStream& operator=(SkStream&&) = delete;
151  SkStream& operator=(const SkStream&) = delete;
152 };
153 
155 class SK_API SkStreamRewindable : public SkStream {
156 public:
157  bool rewind() override = 0;
158  std::unique_ptr<SkStreamRewindable> duplicate() const {
159  return std::unique_ptr<SkStreamRewindable>(this->onDuplicate());
160  }
161 private:
162  SkStreamRewindable* onDuplicate() const override = 0;
163 };
164 
166 class SK_API SkStreamSeekable : public SkStreamRewindable {
167 public:
168  std::unique_ptr<SkStreamSeekable> duplicate() const {
169  return std::unique_ptr<SkStreamSeekable>(this->onDuplicate());
170  }
171 
172  bool hasPosition() const override { return true; }
173  size_t getPosition() const override = 0;
174  bool seek(size_t position) override = 0;
175  bool move(long offset) override = 0;
176 
177  std::unique_ptr<SkStreamSeekable> fork() const {
178  return std::unique_ptr<SkStreamSeekable>(this->onFork());
179  }
180 private:
181  SkStreamSeekable* onDuplicate() const override = 0;
182  SkStreamSeekable* onFork() const override = 0;
183 };
184 
186 class SK_API SkStreamAsset : public SkStreamSeekable {
187 public:
188  bool hasLength() const override { return true; }
189  size_t getLength() const override = 0;
190 
191  std::unique_ptr<SkStreamAsset> duplicate() const {
192  return std::unique_ptr<SkStreamAsset>(this->onDuplicate());
193  }
194  std::unique_ptr<SkStreamAsset> fork() const {
195  return std::unique_ptr<SkStreamAsset>(this->onFork());
196  }
197 private:
198  SkStreamAsset* onDuplicate() const override = 0;
199  SkStreamAsset* onFork() const override = 0;
200 };
201 
203 class SK_API SkStreamMemory : public SkStreamAsset {
204 public:
205  const void* getMemoryBase() override = 0;
206 
207  std::unique_ptr<SkStreamMemory> duplicate() const {
208  return std::unique_ptr<SkStreamMemory>(this->onDuplicate());
209  }
210  std::unique_ptr<SkStreamMemory> fork() const {
211  return std::unique_ptr<SkStreamMemory>(this->onFork());
212  }
213 private:
214  SkStreamMemory* onDuplicate() const override = 0;
215  SkStreamMemory* onFork() const override = 0;
216 };
217 
218 class SK_API SkWStream {
219 public:
220  virtual ~SkWStream();
222 
228  virtual bool write(const void* buffer, size_t size) = 0;
229  virtual void flush();
230 
231  virtual size_t bytesWritten() const = 0;
232 
233  // helpers
234 
235  bool write8(U8CPU value) {
236  uint8_t v = SkToU8(value);
237  return this->write(&v, 1);
238  }
239  bool write16(U16CPU value) {
240  uint16_t v = SkToU16(value);
241  return this->write(&v, 2);
242  }
243  bool write32(uint32_t v) {
244  return this->write(&v, 4);
245  }
246 
247  bool writeText(const char text[]) {
248  SkASSERT(text);
249  return this->write(text, std::strlen(text));
250  }
251 
252  bool newline() { return this->write("\n", std::strlen("\n")); }
253 
254  bool writeDecAsText(int32_t);
255  bool writeBigDecAsText(int64_t, int minDigits = 0);
256  bool writeHexAsText(uint32_t, int minDigits = 0);
258 
259  bool writeBool(bool v) { return this->write8(v); }
261  bool writePackedUInt(size_t);
262 
263  bool writeStream(SkStream* input, size_t length);
264 
269  static int SizeOfPackedUInt(size_t value);
270 
271 private:
272  SkWStream(const SkWStream&) = delete;
273  SkWStream& operator=(const SkWStream&) = delete;
274 };
275 
276 class SK_API SkNullWStream : public SkWStream {
277 public:
278  SkNullWStream() : fBytesWritten(0) {}
279 
280  bool write(const void* , size_t n) override { fBytesWritten += n; return true; }
281  void flush() override {}
282  size_t bytesWritten() const override { return fBytesWritten; }
283 
284 private:
285  size_t fBytesWritten;
286 };
287 
289 
291 class SK_API SkFILEStream : public SkStreamAsset {
292 public:
296  explicit SkFILEStream(const char path[] = nullptr);
297 
303  explicit SkFILEStream(FILE* file);
304 
310  explicit SkFILEStream(FILE* file, size_t size);
311 
312  ~SkFILEStream() override;
313 
314  static std::unique_ptr<SkFILEStream> Make(const char path[]) {
315  std::unique_ptr<SkFILEStream> stream(new SkFILEStream(path));
316  return stream->isValid() ? std::move(stream) : nullptr;
317  }
318 
320  bool isValid() const { return fFILE != nullptr; }
321 
323  void close();
324 
325  size_t read(void* buffer, size_t size) override;
326  bool isAtEnd() const override;
327 
328  bool rewind() override;
329  std::unique_ptr<SkStreamAsset> duplicate() const {
330  return std::unique_ptr<SkStreamAsset>(this->onDuplicate());
331  }
332 
333  size_t getPosition() const override;
334  bool seek(size_t position) override;
335  bool move(long offset) override;
336 
337  std::unique_ptr<SkStreamAsset> fork() const {
338  return std::unique_ptr<SkStreamAsset>(this->onFork());
339  }
340 
341  size_t getLength() const override;
342 
343 private:
344  explicit SkFILEStream(FILE*, size_t size, size_t start);
345  explicit SkFILEStream(std::shared_ptr<FILE>, size_t end, size_t start);
346  explicit SkFILEStream(std::shared_ptr<FILE>, size_t end, size_t start, size_t current);
347 
348  SkStreamAsset* onDuplicate() const override;
349  SkStreamAsset* onFork() const override;
350 
351  std::shared_ptr<FILE> fFILE;
352  // My own council will I keep on sizes and offsets.
353  // These are seek positions in the underling FILE, not offsets into the stream.
354  size_t fEnd;
355  size_t fStart;
356  size_t fCurrent;
357 
358  using INHERITED = SkStreamAsset;
359 };
360 
361 class SK_API SkMemoryStream : public SkStreamMemory {
362 public:
364 
366  SkMemoryStream(size_t length);
367 
369  SkMemoryStream(const void* data, size_t length, bool copyData = false);
370 
373 
375  static std::unique_ptr<SkMemoryStream> MakeCopy(const void* data, size_t length);
376 
378  static std::unique_ptr<SkMemoryStream> MakeDirect(const void* data, size_t length);
379 
381  static std::unique_ptr<SkMemoryStream> Make(sk_sp<SkData> data);
382 
387  virtual void setMemory(const void* data, size_t length,
388  bool copyData = false);
393  void setMemoryOwned(const void* data, size_t length);
394 
395  sk_sp<SkData> asData() const { return fData; }
396  void setData(sk_sp<SkData> data);
397 
398  void skipToAlign4();
399  const void* getAtPos();
400 
401  size_t read(void* buffer, size_t size) override;
402  bool isAtEnd() const override;
403 
404  size_t peek(void* buffer, size_t size) const override;
405 
406  bool rewind() override;
407 
408  std::unique_ptr<SkMemoryStream> duplicate() const {
409  return std::unique_ptr<SkMemoryStream>(this->onDuplicate());
410  }
411 
412  size_t getPosition() const override;
413  bool seek(size_t position) override;
414  bool move(long offset) override;
415 
416  std::unique_ptr<SkMemoryStream> fork() const {
417  return std::unique_ptr<SkMemoryStream>(this->onFork());
418  }
419 
420  size_t getLength() const override;
421 
422  const void* getMemoryBase() override;
423 
424 private:
425  SkMemoryStream* onDuplicate() const override;
426  SkMemoryStream* onFork() const override;
427 
428  sk_sp<SkData> fData;
429  size_t fOffset;
430 
431  using INHERITED = SkStreamMemory;
432 };
433 
435 
436 class SK_API SkFILEWStream : public SkWStream {
437 public:
438  SkFILEWStream(const char path[]);
439  ~SkFILEWStream() override;
440 
443  bool isValid() const { return fFILE != nullptr; }
444 
445  bool write(const void* buffer, size_t size) override;
446  void flush() override;
447  void fsync();
448  size_t bytesWritten() const override;
449 
450 private:
451  FILE* fFILE;
452 
453  using INHERITED = SkWStream;
454 };
455 
456 class SK_API SkDynamicMemoryWStream : public SkWStream {
457 public:
462 
463  bool write(const void* buffer, size_t size) override;
464  size_t bytesWritten() const override;
465 
466  bool read(void* buffer, size_t offset, size_t size);
467 
469  void copyTo(void* dst) const;
470  bool writeToStream(SkWStream* dst) const;
471 
473  void copyToAndReset(void* dst);
474 
477 
481 
484 
487 
489  std::unique_ptr<SkStreamAsset> detachAsStream();
490 
492  void reset();
493  void padToAlign4();
494 private:
495  struct Block;
496  Block* fHead = nullptr;
497  Block* fTail = nullptr;
498  size_t fBytesWrittenBeforeTail = 0;
499 
500 #ifdef SK_DEBUG
501  void validate() const;
502 #else
503  void validate() const {}
504 #endif
505 
506  // For access to the Block type.
507  friend class SkBlockMemoryStream;
508  friend class SkBlockMemoryRefCnt;
509 
510  using INHERITED = SkWStream;
511 };
512 
513 #endif
float SkScalar
Definition: SkScalar.h:14
Definition: SkStream.h:456
void reset()
Reset the stream to its original, empty, state.
size_t bytesWritten() const override
SkDynamicMemoryWStream(SkDynamicMemoryWStream &&)
SkDynamicMemoryWStream & operator=(SkDynamicMemoryWStream &&)
sk_sp< SkData > detachAsData()
Return the contents as SkData, and then reset the stream.
~SkDynamicMemoryWStream() override
bool writeToStream(SkWStream *dst) const
std::unique_ptr< SkStreamAsset > detachAsStream()
Reset, returning a reader stream with the current content.
bool writeToAndReset(SkWStream *dst)
Equivalent to writeToStream() followed by reset(), but may save memory use.
void copyToAndReset(void *dst)
Equivalent to copyTo() followed by reset(), but may save memory use.
void copyTo(void *dst) const
More efficient version of read(dst, 0, bytesWritten()).
SkDynamicMemoryWStream()=default
bool writeToAndReset(SkDynamicMemoryWStream *dst)
Equivalent to writeToStream() followed by reset(), but may save memory use.
bool write(const void *buffer, size_t size) override
Called to write bytes to a SkWStream.
bool read(void *buffer, size_t offset, size_t size)
void prependToAndReset(SkDynamicMemoryWStream *dst)
Prepend this stream to dst, resetting this.
A stream that wraps a C FILE* file stream.
Definition: SkStream.h:291
static std::unique_ptr< SkFILEStream > Make(const char path[])
Definition: SkStream.h:314
bool move(long offset) override
Seeks to an relative offset in the stream.
bool seek(size_t position) override
Seeks to an absolute position in the stream.
size_t read(void *buffer, size_t size) override
Reads or skips size number of bytes.
std::unique_ptr< SkStreamAsset > fork() const
Definition: SkStream.h:337
bool isAtEnd() const override
Returns true when all the bytes in the stream have been read.
bool isValid() const
Returns true if the current path could be opened.
Definition: SkStream.h:320
size_t getLength() const override
Returns the total length of the stream.
bool rewind() override
Rewinds to the beginning of the stream.
SkFILEStream(FILE *file)
Initialize the stream with an existing C FILE stream.
void close()
Close this SkFILEStream.
size_t getPosition() const override
Returns the current position in the stream.
~SkFILEStream() override
SkFILEStream(FILE *file, size_t size)
Initialize the stream with an existing C FILE stream.
SkFILEStream(const char path[]=nullptr)
Initialize the stream by calling sk_fopen on the specified path.
std::unique_ptr< SkStreamAsset > duplicate() const
Definition: SkStream.h:329
Definition: SkStream.h:436
size_t bytesWritten() const override
bool write(const void *buffer, size_t size) override
Called to write bytes to a SkWStream.
void flush() override
~SkFILEWStream() override
SkFILEWStream(const char path[])
bool isValid() const
Returns true if the current path could be opened.
Definition: SkStream.h:443
Definition: SkStream.h:361
const void * getAtPos()
bool isAtEnd() const override
Returns true when all the bytes in the stream have been read.
bool move(long offset) override
Seeks to an relative offset in the stream.
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Returns a stream with a shared reference to the input data.
bool seek(size_t position) override
Seeks to an absolute position in the stream.
static std::unique_ptr< SkMemoryStream > MakeCopy(const void *data, size_t length)
Returns a stream with a copy of the input data.
size_t read(void *buffer, size_t size) override
Reads or skips size number of bytes.
void setMemoryOwned(const void *data, size_t length)
Replace any memory buffer with the specified buffer.
std::unique_ptr< SkMemoryStream > duplicate() const
Definition: SkStream.h:408
sk_sp< SkData > asData() const
Definition: SkStream.h:395
SkMemoryStream(sk_sp< SkData > data)
Creates the stream to read from the specified data.
size_t getLength() const override
Returns the total length of the stream.
virtual void setMemory(const void *data, size_t length, bool copyData=false)
Resets the stream to the specified data and length, just like the constructor.
size_t peek(void *buffer, size_t size) const override
Attempt to peek at size bytes.
bool rewind() override
Rewinds to the beginning of the stream.
std::unique_ptr< SkMemoryStream > fork() const
Definition: SkStream.h:416
SkMemoryStream(const void *data, size_t length, bool copyData=false)
If copyData is true, the stream makes a private copy of the data.
void setData(sk_sp< SkData > data)
const void * getMemoryBase() override
Returns the starting address for the data.
void skipToAlign4()
SkMemoryStream(size_t length)
We allocate (and free) the memory.
size_t getPosition() const override
Returns the current position in the stream.
static std::unique_ptr< SkMemoryStream > MakeDirect(const void *data, size_t length)
Returns a stream with a bare pointer reference to the input data.
Definition: SkStream.h:276
size_t bytesWritten() const override
Definition: SkStream.h:282
SkNullWStream()
Definition: SkStream.h:278
void flush() override
Definition: SkStream.h:281
bool write(const void *, size_t n) override
Called to write bytes to a SkWStream.
Definition: SkStream.h:280
SkStreamAsset is a SkStreamSeekable for which getLength is required.
Definition: SkStream.h:186
bool hasLength() const override
Returns true if this stream can report its total length.
Definition: SkStream.h:188
size_t getLength() const override=0
Returns the total length of the stream.
std::unique_ptr< SkStreamAsset > duplicate() const
Definition: SkStream.h:191
std::unique_ptr< SkStreamAsset > fork() const
Definition: SkStream.h:194
SkStreamMemory is a SkStreamAsset for which getMemoryBase is required.
Definition: SkStream.h:203
const void * getMemoryBase() override=0
Returns the starting address for the data.
std::unique_ptr< SkStreamMemory > duplicate() const
Definition: SkStream.h:207
std::unique_ptr< SkStreamMemory > fork() const
Definition: SkStream.h:210
SkStreamRewindable is a SkStream for which rewind and duplicate are required.
Definition: SkStream.h:155
bool rewind() override=0
Rewinds to the beginning of the stream.
std::unique_ptr< SkStreamRewindable > duplicate() const
Definition: SkStream.h:158
SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required.
Definition: SkStream.h:166
size_t getPosition() const override=0
Returns the current position in the stream.
std::unique_ptr< SkStreamSeekable > fork() const
Definition: SkStream.h:177
std::unique_ptr< SkStreamSeekable > duplicate() const
Definition: SkStream.h:168
bool move(long offset) override=0
Seeks to an relative offset in the stream.
bool hasPosition() const override
Returns true if this stream can report its current position.
Definition: SkStream.h:172
bool seek(size_t position) override=0
Seeks to an absolute position in the stream.
SkStream – abstraction for a source of bytes.
Definition: SkStream.h:29
bool readU8(uint8_t *i)
Definition: SkStream.h:83
bool readS16(int16_t *)
virtual bool move(long)
Seeks to an relative offset in the stream.
Definition: SkStream.h:131
bool readScalar(SkScalar *)
SkStream()
Definition: SkStream.h:32
virtual bool rewind()
Rewinds to the beginning of the stream.
Definition: SkStream.h:100
bool readS32(int32_t *)
virtual const void * getMemoryBase()
Returns the starting address for the data.
Definition: SkStream.h:142
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
Attempts to open the specified file as a stream, returns nullptr on failure.
bool readBool(bool *b)
Definition: SkStream.h:87
bool readS8(int8_t *)
virtual size_t peek(void *, size_t) const
Attempt to peek at size bytes.
Definition: SkStream.h:68
bool readPackedUInt(size_t *)
virtual bool hasPosition() const
Returns true if this stream can report its current position.
Definition: SkStream.h:117
virtual size_t getPosition() const
Returns the current position in the stream.
Definition: SkStream.h:119
virtual ~SkStream()
Definition: SkStream.h:31
bool readU16(uint16_t *i)
Definition: SkStream.h:84
std::unique_ptr< SkStream > duplicate() const
Duplicates this stream.
Definition: SkStream.h:105
size_t skip(size_t size)
Skip size number of bytes.
Definition: SkStream.h:51
bool readU32(uint32_t *i)
Definition: SkStream.h:85
virtual bool isAtEnd() const =0
Returns true when all the bytes in the stream have been read.
virtual bool seek(size_t)
Seeks to an absolute position in the stream.
Definition: SkStream.h:125
std::unique_ptr< SkStream > fork() const
Duplicates this stream.
Definition: SkStream.h:111
virtual size_t getLength() const
Returns the total length of the stream.
Definition: SkStream.h:137
virtual bool hasLength() const
Returns true if this stream can report its total length.
Definition: SkStream.h:135
virtual size_t read(void *buffer, size_t size)=0
Reads or skips size number of bytes.
Definition: SkStream.h:218
bool writePackedUInt(size_t)
virtual bool write(const void *buffer, size_t size)=0
Called to write bytes to a SkWStream.
bool writeScalarAsText(SkScalar)
bool write32(uint32_t v)
Definition: SkStream.h:243
bool write8(U8CPU value)
Definition: SkStream.h:235
bool write16(U16CPU value)
Definition: SkStream.h:239
bool writeHexAsText(uint32_t, int minDigits=0)
SkWStream()
Definition: SkStream.h:221
virtual ~SkWStream()
static int SizeOfPackedUInt(size_t value)
This returns the number of bytes in the stream required to store 'value'.
bool writeStream(SkStream *input, size_t length)
bool writeDecAsText(int32_t)
bool writeBigDecAsText(int64_t, int minDigits=0)
virtual size_t bytesWritten() const =0
bool writeBool(bool v)
Definition: SkStream.h:259
bool writeScalar(SkScalar)
bool writeText(const char text[])
Definition: SkStream.h:247
virtual void flush()
bool newline()
Definition: SkStream.h:252