SkStream.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  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. #include "include/core/SkStream.h"
  8. #include "include/core/SkData.h"
  9. #include "include/core/SkString.h"
  10. #include "include/core/SkTypes.h"
  11. #include "include/private/SkFixed.h"
  12. #include "include/private/SkTFitsIn.h"
  13. #include "include/private/SkTo.h"
  14. #include "src/core/SkMakeUnique.h"
  15. #include "src/core/SkOSFile.h"
  16. #include "src/core/SkSafeMath.h"
  17. #include "src/core/SkStreamPriv.h"
  18. #include <limits>
  19. ///////////////////////////////////////////////////////////////////////////////
  20. bool SkStream::readS8(int8_t* i) {
  21. return this->read(i, sizeof(*i)) == sizeof(*i);
  22. }
  23. bool SkStream::readS16(int16_t* i) {
  24. return this->read(i, sizeof(*i)) == sizeof(*i);
  25. }
  26. bool SkStream::readS32(int32_t* i) {
  27. return this->read(i, sizeof(*i)) == sizeof(*i);
  28. }
  29. bool SkStream::readScalar(SkScalar* i) {
  30. return this->read(i, sizeof(*i)) == sizeof(*i);
  31. }
  32. #define SK_MAX_BYTE_FOR_U8 0xFD
  33. #define SK_BYTE_SENTINEL_FOR_U16 0xFE
  34. #define SK_BYTE_SENTINEL_FOR_U32 0xFF
  35. bool SkStream::readPackedUInt(size_t* i) {
  36. uint8_t byte;
  37. if (!this->read(&byte, 1)) {
  38. return false;
  39. }
  40. if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
  41. uint16_t i16;
  42. if (!this->readU16(&i16)) { return false; }
  43. *i = i16;
  44. } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
  45. uint32_t i32;
  46. if (!this->readU32(&i32)) { return false; }
  47. *i = i32;
  48. } else {
  49. *i = byte;
  50. }
  51. return true;
  52. }
  53. //////////////////////////////////////////////////////////////////////////////////////
  54. SkWStream::~SkWStream()
  55. {
  56. }
  57. void SkWStream::flush()
  58. {
  59. }
  60. bool SkWStream::writeDecAsText(int32_t dec)
  61. {
  62. char buffer[SkStrAppendS32_MaxSize];
  63. char* stop = SkStrAppendS32(buffer, dec);
  64. return this->write(buffer, stop - buffer);
  65. }
  66. bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
  67. {
  68. char buffer[SkStrAppendU64_MaxSize];
  69. char* stop = SkStrAppendU64(buffer, dec, minDigits);
  70. return this->write(buffer, stop - buffer);
  71. }
  72. bool SkWStream::writeHexAsText(uint32_t hex, int digits)
  73. {
  74. SkString tmp;
  75. tmp.appendHex(hex, digits);
  76. return this->write(tmp.c_str(), tmp.size());
  77. }
  78. bool SkWStream::writeScalarAsText(SkScalar value)
  79. {
  80. char buffer[SkStrAppendScalar_MaxSize];
  81. char* stop = SkStrAppendScalar(buffer, value);
  82. return this->write(buffer, stop - buffer);
  83. }
  84. bool SkWStream::writeScalar(SkScalar value) {
  85. return this->write(&value, sizeof(value));
  86. }
  87. int SkWStream::SizeOfPackedUInt(size_t value) {
  88. if (value <= SK_MAX_BYTE_FOR_U8) {
  89. return 1;
  90. } else if (value <= 0xFFFF) {
  91. return 3;
  92. }
  93. return 5;
  94. }
  95. bool SkWStream::writePackedUInt(size_t value) {
  96. uint8_t data[5];
  97. size_t len = 1;
  98. if (value <= SK_MAX_BYTE_FOR_U8) {
  99. data[0] = value;
  100. len = 1;
  101. } else if (value <= 0xFFFF) {
  102. uint16_t value16 = value;
  103. data[0] = SK_BYTE_SENTINEL_FOR_U16;
  104. memcpy(&data[1], &value16, 2);
  105. len = 3;
  106. } else {
  107. uint32_t value32 = SkToU32(value);
  108. data[0] = SK_BYTE_SENTINEL_FOR_U32;
  109. memcpy(&data[1], &value32, 4);
  110. len = 5;
  111. }
  112. return this->write(data, len);
  113. }
  114. bool SkWStream::writeStream(SkStream* stream, size_t length) {
  115. char scratch[1024];
  116. const size_t MAX = sizeof(scratch);
  117. while (length != 0) {
  118. size_t n = length;
  119. if (n > MAX) {
  120. n = MAX;
  121. }
  122. stream->read(scratch, n);
  123. if (!this->write(scratch, n)) {
  124. return false;
  125. }
  126. length -= n;
  127. }
  128. return true;
  129. }
  130. ///////////////////////////////////////////////////////////////////////////////
  131. SkFILEStream::SkFILEStream(std::shared_ptr<FILE> file, size_t size,
  132. size_t offset, size_t originalOffset)
  133. : fFILE(std::move(file))
  134. , fSize(size)
  135. , fOffset(SkTMin(offset, fSize))
  136. , fOriginalOffset(SkTMin(originalOffset, fSize))
  137. { }
  138. SkFILEStream::SkFILEStream(std::shared_ptr<FILE> file, size_t size, size_t offset)
  139. : SkFILEStream(std::move(file), size, offset, offset)
  140. { }
  141. SkFILEStream::SkFILEStream(FILE* file)
  142. : SkFILEStream(std::shared_ptr<FILE>(file, sk_fclose),
  143. file ? sk_fgetsize(file) : 0,
  144. file ? sk_ftell(file) : 0)
  145. { }
  146. SkFILEStream::SkFILEStream(const char path[])
  147. : SkFILEStream(path ? sk_fopen(path, kRead_SkFILE_Flag) : nullptr)
  148. { }
  149. SkFILEStream::~SkFILEStream() {
  150. this->close();
  151. }
  152. void SkFILEStream::close() {
  153. fFILE.reset();
  154. fSize = 0;
  155. fOffset = 0;
  156. }
  157. size_t SkFILEStream::read(void* buffer, size_t size) {
  158. if (size > fSize - fOffset) {
  159. size = fSize - fOffset;
  160. }
  161. size_t bytesRead = size;
  162. if (buffer) {
  163. bytesRead = sk_qread(fFILE.get(), buffer, size, fOffset);
  164. }
  165. if (bytesRead == SIZE_MAX) {
  166. return 0;
  167. }
  168. fOffset += bytesRead;
  169. return bytesRead;
  170. }
  171. bool SkFILEStream::isAtEnd() const {
  172. if (fOffset == fSize) {
  173. return true;
  174. }
  175. return fOffset >= sk_fgetsize(fFILE.get());
  176. }
  177. bool SkFILEStream::rewind() {
  178. fOffset = fOriginalOffset;
  179. return true;
  180. }
  181. SkStreamAsset* SkFILEStream::onDuplicate() const {
  182. return new SkFILEStream(fFILE, fSize, fOriginalOffset, fOriginalOffset);
  183. }
  184. size_t SkFILEStream::getPosition() const {
  185. SkASSERT(fOffset >= fOriginalOffset);
  186. return fOffset - fOriginalOffset;
  187. }
  188. bool SkFILEStream::seek(size_t position) {
  189. fOffset = SkTMin(SkSafeMath::Add(position, fOriginalOffset), fSize);
  190. return true;
  191. }
  192. bool SkFILEStream::move(long offset) {
  193. if (offset < 0) {
  194. if (offset == std::numeric_limits<long>::min()
  195. || !SkTFitsIn<size_t>(-offset)
  196. || (size_t) (-offset) >= this->getPosition()) {
  197. fOffset = fOriginalOffset;
  198. } else {
  199. fOffset += offset;
  200. }
  201. } else if (!SkTFitsIn<size_t>(offset)) {
  202. fOffset = fSize;
  203. } else {
  204. fOffset = SkTMin(SkSafeMath::Add(fOffset, (size_t) offset), fSize);
  205. }
  206. SkASSERT(fOffset >= fOriginalOffset && fOffset <= fSize);
  207. return true;
  208. }
  209. SkStreamAsset* SkFILEStream::onFork() const {
  210. return new SkFILEStream(fFILE, fSize, fOffset, fOriginalOffset);
  211. }
  212. size_t SkFILEStream::getLength() const {
  213. return fSize - fOriginalOffset;
  214. }
  215. ///////////////////////////////////////////////////////////////////////////////
  216. static sk_sp<SkData> newFromParams(const void* src, size_t size, bool copyData) {
  217. if (copyData) {
  218. return SkData::MakeWithCopy(src, size);
  219. } else {
  220. return SkData::MakeWithoutCopy(src, size);
  221. }
  222. }
  223. SkMemoryStream::SkMemoryStream() {
  224. fData = SkData::MakeEmpty();
  225. fOffset = 0;
  226. }
  227. SkMemoryStream::SkMemoryStream(size_t size) {
  228. fData = SkData::MakeUninitialized(size);
  229. fOffset = 0;
  230. }
  231. SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
  232. fData = newFromParams(src, size, copyData);
  233. fOffset = 0;
  234. }
  235. SkMemoryStream::SkMemoryStream(sk_sp<SkData> data) : fData(std::move(data)) {
  236. if (nullptr == fData) {
  237. fData = SkData::MakeEmpty();
  238. }
  239. fOffset = 0;
  240. }
  241. std::unique_ptr<SkMemoryStream> SkMemoryStream::MakeCopy(const void* data, size_t length) {
  242. return skstd::make_unique<SkMemoryStream>(data, length, true);
  243. }
  244. std::unique_ptr<SkMemoryStream> SkMemoryStream::MakeDirect(const void* data, size_t length) {
  245. return skstd::make_unique<SkMemoryStream>(data, length, false);
  246. }
  247. std::unique_ptr<SkMemoryStream> SkMemoryStream::Make(sk_sp<SkData> data) {
  248. return skstd::make_unique<SkMemoryStream>(std::move(data));
  249. }
  250. void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
  251. fData = SkData::MakeFromMalloc(src, size);
  252. fOffset = 0;
  253. }
  254. void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
  255. fData = newFromParams(src, size, copyData);
  256. fOffset = 0;
  257. }
  258. void SkMemoryStream::setData(sk_sp<SkData> data) {
  259. if (nullptr == data) {
  260. fData = SkData::MakeEmpty();
  261. } else {
  262. fData = data;
  263. }
  264. fOffset = 0;
  265. }
  266. void SkMemoryStream::skipToAlign4() {
  267. // cast to remove unary-minus warning
  268. fOffset += -(int)fOffset & 0x03;
  269. }
  270. size_t SkMemoryStream::read(void* buffer, size_t size) {
  271. size_t dataSize = fData->size();
  272. if (size > dataSize - fOffset) {
  273. size = dataSize - fOffset;
  274. }
  275. if (buffer) {
  276. memcpy(buffer, fData->bytes() + fOffset, size);
  277. }
  278. fOffset += size;
  279. return size;
  280. }
  281. size_t SkMemoryStream::peek(void* buffer, size_t size) const {
  282. SkASSERT(buffer != nullptr);
  283. const size_t currentOffset = fOffset;
  284. SkMemoryStream* nonConstThis = const_cast<SkMemoryStream*>(this);
  285. const size_t bytesRead = nonConstThis->read(buffer, size);
  286. nonConstThis->fOffset = currentOffset;
  287. return bytesRead;
  288. }
  289. bool SkMemoryStream::isAtEnd() const {
  290. return fOffset == fData->size();
  291. }
  292. bool SkMemoryStream::rewind() {
  293. fOffset = 0;
  294. return true;
  295. }
  296. SkMemoryStream* SkMemoryStream::onDuplicate() const {
  297. return new SkMemoryStream(fData);
  298. }
  299. size_t SkMemoryStream::getPosition() const {
  300. return fOffset;
  301. }
  302. bool SkMemoryStream::seek(size_t position) {
  303. fOffset = position > fData->size()
  304. ? fData->size()
  305. : position;
  306. return true;
  307. }
  308. bool SkMemoryStream::move(long offset) {
  309. return this->seek(fOffset + offset);
  310. }
  311. SkMemoryStream* SkMemoryStream::onFork() const {
  312. std::unique_ptr<SkMemoryStream> that(this->duplicate());
  313. that->seek(fOffset);
  314. return that.release();
  315. }
  316. size_t SkMemoryStream::getLength() const {
  317. return fData->size();
  318. }
  319. const void* SkMemoryStream::getMemoryBase() {
  320. return fData->data();
  321. }
  322. const void* SkMemoryStream::getAtPos() {
  323. return fData->bytes() + fOffset;
  324. }
  325. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  326. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  327. SkFILEWStream::SkFILEWStream(const char path[])
  328. {
  329. fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
  330. }
  331. SkFILEWStream::~SkFILEWStream()
  332. {
  333. if (fFILE) {
  334. sk_fclose(fFILE);
  335. }
  336. }
  337. size_t SkFILEWStream::bytesWritten() const {
  338. return sk_ftell(fFILE);
  339. }
  340. bool SkFILEWStream::write(const void* buffer, size_t size)
  341. {
  342. if (fFILE == nullptr) {
  343. return false;
  344. }
  345. if (sk_fwrite(buffer, size, fFILE) != size)
  346. {
  347. SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
  348. sk_fclose(fFILE);
  349. fFILE = nullptr;
  350. return false;
  351. }
  352. return true;
  353. }
  354. void SkFILEWStream::flush()
  355. {
  356. if (fFILE) {
  357. sk_fflush(fFILE);
  358. }
  359. }
  360. void SkFILEWStream::fsync()
  361. {
  362. flush();
  363. if (fFILE) {
  364. sk_fsync(fFILE);
  365. }
  366. }
  367. ////////////////////////////////////////////////////////////////////////
  368. static inline void sk_memcpy_4bytes(void* dst, const void* src, size_t size) {
  369. if (size == 4) {
  370. memcpy(dst, src, 4);
  371. } else {
  372. memcpy(dst, src, size);
  373. }
  374. }
  375. #define SkDynamicMemoryWStream_MinBlockSize 4096
  376. struct SkDynamicMemoryWStream::Block {
  377. Block* fNext;
  378. char* fCurr;
  379. char* fStop;
  380. const char* start() const { return (const char*)(this + 1); }
  381. char* start() { return (char*)(this + 1); }
  382. size_t avail() const { return fStop - fCurr; }
  383. size_t written() const { return fCurr - this->start(); }
  384. void init(size_t size) {
  385. fNext = nullptr;
  386. fCurr = this->start();
  387. fStop = this->start() + size;
  388. }
  389. const void* append(const void* data, size_t size) {
  390. SkASSERT((size_t)(fStop - fCurr) >= size);
  391. sk_memcpy_4bytes(fCurr, data, size);
  392. fCurr += size;
  393. return (const void*)((const char*)data + size);
  394. }
  395. };
  396. SkDynamicMemoryWStream::SkDynamicMemoryWStream(SkDynamicMemoryWStream&& other)
  397. : fHead(other.fHead)
  398. , fTail(other.fTail)
  399. , fBytesWrittenBeforeTail(other.fBytesWrittenBeforeTail)
  400. {
  401. other.fHead = nullptr;
  402. other.fTail = nullptr;
  403. other.fBytesWrittenBeforeTail = 0;
  404. }
  405. SkDynamicMemoryWStream& SkDynamicMemoryWStream::operator=(SkDynamicMemoryWStream&& other) {
  406. if (this != &other) {
  407. this->~SkDynamicMemoryWStream();
  408. new (this) SkDynamicMemoryWStream(std::move(other));
  409. }
  410. return *this;
  411. }
  412. SkDynamicMemoryWStream::~SkDynamicMemoryWStream() {
  413. this->reset();
  414. }
  415. void SkDynamicMemoryWStream::reset() {
  416. Block* block = fHead;
  417. while (block != nullptr) {
  418. Block* next = block->fNext;
  419. sk_free(block);
  420. block = next;
  421. }
  422. fHead = fTail = nullptr;
  423. fBytesWrittenBeforeTail = 0;
  424. }
  425. size_t SkDynamicMemoryWStream::bytesWritten() const {
  426. this->validate();
  427. if (fTail) {
  428. return fBytesWrittenBeforeTail + fTail->written();
  429. }
  430. return 0;
  431. }
  432. bool SkDynamicMemoryWStream::write(const void* buffer, size_t count) {
  433. if (count > 0) {
  434. SkASSERT(buffer);
  435. size_t size;
  436. if (fTail) {
  437. if (fTail->avail() > 0) {
  438. size = SkTMin(fTail->avail(), count);
  439. buffer = fTail->append(buffer, size);
  440. SkASSERT(count >= size);
  441. count -= size;
  442. if (count == 0) {
  443. return true;
  444. }
  445. }
  446. // If we get here, we've just exhausted fTail, so update our tracker
  447. fBytesWrittenBeforeTail += fTail->written();
  448. }
  449. size = SkTMax<size_t>(count, SkDynamicMemoryWStream_MinBlockSize - sizeof(Block));
  450. size = SkAlign4(size); // ensure we're always a multiple of 4 (see padToAlign4())
  451. Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
  452. block->init(size);
  453. block->append(buffer, count);
  454. if (fTail != nullptr) {
  455. fTail->fNext = block;
  456. } else {
  457. fHead = fTail = block;
  458. }
  459. fTail = block;
  460. this->validate();
  461. }
  462. return true;
  463. }
  464. bool SkDynamicMemoryWStream::writeToAndReset(SkDynamicMemoryWStream* dst) {
  465. SkASSERT(dst);
  466. SkASSERT(dst != this);
  467. if (0 == this->bytesWritten()) {
  468. return true;
  469. }
  470. if (0 == dst->bytesWritten()) {
  471. *dst = std::move(*this);
  472. return true;
  473. }
  474. dst->fTail->fNext = fHead;
  475. dst->fBytesWrittenBeforeTail += fBytesWrittenBeforeTail + dst->fTail->written();
  476. dst->fTail = fTail;
  477. fHead = fTail = nullptr;
  478. fBytesWrittenBeforeTail = 0;
  479. return true;
  480. }
  481. void SkDynamicMemoryWStream::prependToAndReset(SkDynamicMemoryWStream* dst) {
  482. SkASSERT(dst);
  483. SkASSERT(dst != this);
  484. if (0 == this->bytesWritten()) {
  485. return;
  486. }
  487. if (0 == dst->bytesWritten()) {
  488. *dst = std::move(*this);
  489. return;
  490. }
  491. fTail->fNext = dst->fHead;
  492. dst->fHead = fHead;
  493. dst->fBytesWrittenBeforeTail += fBytesWrittenBeforeTail + fTail->written();
  494. fHead = fTail = nullptr;
  495. fBytesWrittenBeforeTail = 0;
  496. return;
  497. }
  498. bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count) {
  499. if (offset + count > this->bytesWritten()) {
  500. return false; // test does not partially modify
  501. }
  502. Block* block = fHead;
  503. while (block != nullptr) {
  504. size_t size = block->written();
  505. if (offset < size) {
  506. size_t part = offset + count > size ? size - offset : count;
  507. memcpy(buffer, block->start() + offset, part);
  508. if (count <= part) {
  509. return true;
  510. }
  511. count -= part;
  512. buffer = (void*) ((char* ) buffer + part);
  513. }
  514. offset = offset > size ? offset - size : 0;
  515. block = block->fNext;
  516. }
  517. return false;
  518. }
  519. void SkDynamicMemoryWStream::copyTo(void* dst) const {
  520. SkASSERT(dst);
  521. Block* block = fHead;
  522. while (block != nullptr) {
  523. size_t size = block->written();
  524. memcpy(dst, block->start(), size);
  525. dst = (void*)((char*)dst + size);
  526. block = block->fNext;
  527. }
  528. }
  529. bool SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const {
  530. SkASSERT(dst);
  531. for (Block* block = fHead; block != nullptr; block = block->fNext) {
  532. if (!dst->write(block->start(), block->written())) {
  533. return false;
  534. }
  535. }
  536. return true;
  537. }
  538. void SkDynamicMemoryWStream::padToAlign4() {
  539. // The contract is to write zeros until the entire stream has written a multiple of 4 bytes.
  540. // Our Blocks are guaranteed always be (a) full (except the tail) and (b) a multiple of 4
  541. // so it is sufficient to just examine the tail (if present).
  542. if (fTail) {
  543. // cast to remove unary-minus warning
  544. int padBytes = -(int)fTail->written() & 0x03;
  545. if (padBytes) {
  546. int zero = 0;
  547. fTail->append(&zero, padBytes);
  548. }
  549. }
  550. }
  551. void SkDynamicMemoryWStream::copyToAndReset(void* ptr) {
  552. if (!ptr) {
  553. this->reset();
  554. return;
  555. }
  556. // By looping through the source and freeing as we copy, we
  557. // can reduce real memory use with large streams.
  558. char* dst = reinterpret_cast<char*>(ptr);
  559. Block* block = fHead;
  560. while (block != nullptr) {
  561. size_t len = block->written();
  562. memcpy(dst, block->start(), len);
  563. dst += len;
  564. Block* next = block->fNext;
  565. sk_free(block);
  566. block = next;
  567. }
  568. fHead = fTail = nullptr;
  569. fBytesWrittenBeforeTail = 0;
  570. }
  571. bool SkDynamicMemoryWStream::writeToAndReset(SkWStream* dst) {
  572. SkASSERT(dst);
  573. // By looping through the source and freeing as we copy, we
  574. // can reduce real memory use with large streams.
  575. bool dstStreamGood = true;
  576. for (Block* block = fHead; block != nullptr; ) {
  577. if (dstStreamGood && !dst->write(block->start(), block->written())) {
  578. dstStreamGood = false;
  579. }
  580. Block* next = block->fNext;
  581. sk_free(block);
  582. block = next;
  583. }
  584. fHead = fTail = nullptr;
  585. fBytesWrittenBeforeTail = 0;
  586. return dstStreamGood;
  587. }
  588. sk_sp<SkData> SkDynamicMemoryWStream::detachAsData() {
  589. const size_t size = this->bytesWritten();
  590. if (0 == size) {
  591. return SkData::MakeEmpty();
  592. }
  593. sk_sp<SkData> data = SkData::MakeUninitialized(size);
  594. this->copyToAndReset(data->writable_data());
  595. return data;
  596. }
  597. #ifdef SK_DEBUG
  598. void SkDynamicMemoryWStream::validate() const {
  599. if (!fHead) {
  600. SkASSERT(!fTail);
  601. SkASSERT(fBytesWrittenBeforeTail == 0);
  602. return;
  603. }
  604. SkASSERT(fTail);
  605. size_t bytes = 0;
  606. const Block* block = fHead;
  607. while (block) {
  608. if (block->fNext) {
  609. bytes += block->written();
  610. }
  611. block = block->fNext;
  612. }
  613. SkASSERT(bytes == fBytesWrittenBeforeTail);
  614. }
  615. #endif
  616. ////////////////////////////////////////////////////////////////////////////////////////////////
  617. class SkBlockMemoryRefCnt : public SkRefCnt {
  618. public:
  619. explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
  620. virtual ~SkBlockMemoryRefCnt() {
  621. SkDynamicMemoryWStream::Block* block = fHead;
  622. while (block != nullptr) {
  623. SkDynamicMemoryWStream::Block* next = block->fNext;
  624. sk_free(block);
  625. block = next;
  626. }
  627. }
  628. SkDynamicMemoryWStream::Block* const fHead;
  629. };
  630. class SkBlockMemoryStream : public SkStreamAsset {
  631. public:
  632. SkBlockMemoryStream(sk_sp<SkBlockMemoryRefCnt> headRef, size_t size)
  633. : fBlockMemory(std::move(headRef)), fCurrent(fBlockMemory->fHead)
  634. , fSize(size) , fOffset(0), fCurrentOffset(0) { }
  635. size_t read(void* buffer, size_t rawCount) override {
  636. size_t count = rawCount;
  637. if (fOffset + count > fSize) {
  638. count = fSize - fOffset;
  639. }
  640. size_t bytesLeftToRead = count;
  641. while (fCurrent != nullptr) {
  642. size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
  643. size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
  644. if (buffer) {
  645. memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
  646. buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
  647. }
  648. if (bytesLeftToRead <= bytesFromCurrent) {
  649. fCurrentOffset += bytesFromCurrent;
  650. fOffset += count;
  651. return count;
  652. }
  653. bytesLeftToRead -= bytesFromCurrent;
  654. fCurrent = fCurrent->fNext;
  655. fCurrentOffset = 0;
  656. }
  657. SkASSERT(false);
  658. return 0;
  659. }
  660. bool isAtEnd() const override {
  661. return fOffset == fSize;
  662. }
  663. size_t peek(void* buff, size_t bytesToPeek) const override {
  664. SkASSERT(buff != nullptr);
  665. bytesToPeek = SkTMin(bytesToPeek, fSize - fOffset);
  666. size_t bytesLeftToPeek = bytesToPeek;
  667. char* buffer = static_cast<char*>(buff);
  668. const SkDynamicMemoryWStream::Block* current = fCurrent;
  669. size_t currentOffset = fCurrentOffset;
  670. while (bytesLeftToPeek) {
  671. SkASSERT(current);
  672. size_t bytesFromCurrent = SkTMin(current->written() - currentOffset, bytesLeftToPeek);
  673. memcpy(buffer, current->start() + currentOffset, bytesFromCurrent);
  674. bytesLeftToPeek -= bytesFromCurrent;
  675. buffer += bytesFromCurrent;
  676. current = current->fNext;
  677. currentOffset = 0;
  678. }
  679. return bytesToPeek;
  680. }
  681. bool rewind() override {
  682. fCurrent = fBlockMemory->fHead;
  683. fOffset = 0;
  684. fCurrentOffset = 0;
  685. return true;
  686. }
  687. SkBlockMemoryStream* onDuplicate() const override {
  688. return new SkBlockMemoryStream(fBlockMemory, fSize);
  689. }
  690. size_t getPosition() const override {
  691. return fOffset;
  692. }
  693. bool seek(size_t position) override {
  694. // If possible, skip forward.
  695. if (position >= fOffset) {
  696. size_t skipAmount = position - fOffset;
  697. return this->skip(skipAmount) == skipAmount;
  698. }
  699. // If possible, move backward within the current block.
  700. size_t moveBackAmount = fOffset - position;
  701. if (moveBackAmount <= fCurrentOffset) {
  702. fCurrentOffset -= moveBackAmount;
  703. fOffset -= moveBackAmount;
  704. return true;
  705. }
  706. // Otherwise rewind and move forward.
  707. return this->rewind() && this->skip(position) == position;
  708. }
  709. bool move(long offset) override {
  710. return seek(fOffset + offset);
  711. }
  712. SkBlockMemoryStream* onFork() const override {
  713. SkBlockMemoryStream* that = this->onDuplicate();
  714. that->fCurrent = this->fCurrent;
  715. that->fOffset = this->fOffset;
  716. that->fCurrentOffset = this->fCurrentOffset;
  717. return that;
  718. }
  719. size_t getLength() const override {
  720. return fSize;
  721. }
  722. const void* getMemoryBase() override {
  723. if (fBlockMemory->fHead && !fBlockMemory->fHead->fNext) {
  724. return fBlockMemory->fHead->start();
  725. }
  726. return nullptr;
  727. }
  728. private:
  729. sk_sp<SkBlockMemoryRefCnt> const fBlockMemory;
  730. SkDynamicMemoryWStream::Block const * fCurrent;
  731. size_t const fSize;
  732. size_t fOffset;
  733. size_t fCurrentOffset;
  734. };
  735. std::unique_ptr<SkStreamAsset> SkDynamicMemoryWStream::detachAsStream() {
  736. if (nullptr == fHead) {
  737. // no need to reset.
  738. return SkMemoryStream::Make(nullptr);
  739. }
  740. if (fHead == fTail) { // one block, may be worth shrinking.
  741. ptrdiff_t used = fTail->fCurr - (char*)fTail;
  742. fHead = fTail = (SkDynamicMemoryWStream::Block*)sk_realloc_throw(fTail, SkToSizeT(used));
  743. fTail->fStop = fTail->fCurr = (char*)fTail + used; // Update pointers.
  744. SkASSERT(nullptr == fTail->fNext);
  745. SkASSERT(0 == fBytesWrittenBeforeTail);
  746. }
  747. std::unique_ptr<SkStreamAsset> stream
  748. = skstd::make_unique<SkBlockMemoryStream>(sk_make_sp<SkBlockMemoryRefCnt>(fHead),
  749. this->bytesWritten());
  750. fHead = nullptr; // signal reset() to not free anything
  751. this->reset();
  752. return stream;
  753. }
  754. ///////////////////////////////////////////////////////////////////////////////
  755. ///////////////////////////////////////////////////////////////////////////////
  756. static sk_sp<SkData> mmap_filename(const char path[]) {
  757. FILE* file = sk_fopen(path, kRead_SkFILE_Flag);
  758. if (nullptr == file) {
  759. return nullptr;
  760. }
  761. auto data = SkData::MakeFromFILE(file);
  762. sk_fclose(file);
  763. return data;
  764. }
  765. std::unique_ptr<SkStreamAsset> SkStream::MakeFromFile(const char path[]) {
  766. auto data(mmap_filename(path));
  767. if (data) {
  768. return skstd::make_unique<SkMemoryStream>(std::move(data));
  769. }
  770. // If we get here, then our attempt at using mmap failed, so try normal file access.
  771. auto stream = skstd::make_unique<SkFILEStream>(path);
  772. if (!stream->isValid()) {
  773. return nullptr;
  774. }
  775. return std::move(stream);
  776. }
  777. // Declared in SkStreamPriv.h:
  778. sk_sp<SkData> SkCopyStreamToData(SkStream* stream) {
  779. SkASSERT(stream != nullptr);
  780. if (stream->hasLength()) {
  781. return SkData::MakeFromStream(stream, stream->getLength());
  782. }
  783. SkDynamicMemoryWStream tempStream;
  784. const size_t bufferSize = 4096;
  785. char buffer[bufferSize];
  786. do {
  787. size_t bytesRead = stream->read(buffer, bufferSize);
  788. tempStream.write(buffer, bytesRead);
  789. } while (!stream->isAtEnd());
  790. return tempStream.detachAsData();
  791. }
  792. bool SkStreamCopy(SkWStream* out, SkStream* input) {
  793. const char* base = static_cast<const char*>(input->getMemoryBase());
  794. if (base && input->hasPosition() && input->hasLength()) {
  795. // Shortcut that avoids the while loop.
  796. size_t position = input->getPosition();
  797. size_t length = input->getLength();
  798. SkASSERT(length >= position);
  799. return out->write(&base[position], length - position);
  800. }
  801. char scratch[4096];
  802. size_t count;
  803. while (true) {
  804. count = input->read(scratch, sizeof(scratch));
  805. if (0 == count) {
  806. return true;
  807. }
  808. if (!out->write(scratch, count)) {
  809. return false;
  810. }
  811. }
  812. }