SkStream.h 17 KB

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