3 * Copyright 2006 The Android Open Source Project
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
11 #include "SkStreamPriv.h"
18 ///////////////////////////////////////////////////////////////////////////////
21 int8_t SkStream::readS8() {
23 SkDEBUGCODE(size_t len =) this->read(&value, 1);
28 int16_t SkStream::readS16() {
30 SkDEBUGCODE(size_t len =) this->read(&value, 2);
35 int32_t SkStream::readS32() {
37 SkDEBUGCODE(size_t len =) this->read(&value, 4);
42 SkScalar SkStream::readScalar() {
44 SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
45 SkASSERT(sizeof(SkScalar) == len);
49 #define SK_MAX_BYTE_FOR_U8 0xFD
50 #define SK_BYTE_SENTINEL_FOR_U16 0xFE
51 #define SK_BYTE_SENTINEL_FOR_U32 0xFF
53 size_t SkStream::readPackedUInt() {
55 if (!this->read(&byte, 1)) {
58 if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
59 return this->readU16();
60 } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
61 return this->readU32();
67 SkData* SkStream::readData() {
68 size_t size = this->readU32();
70 return SkData::NewEmpty();
72 void* buffer = sk_malloc_throw(size);
73 this->read(buffer, size);
74 return SkData::NewFromMalloc(buffer, size);
78 //////////////////////////////////////////////////////////////////////////////////////
80 SkWStream::~SkWStream()
84 void SkWStream::newline()
89 void SkWStream::flush()
93 bool SkWStream::writeText(const char text[])
96 return this->write(text, strlen(text));
99 bool SkWStream::writeDecAsText(int32_t dec)
103 return this->write(tmp.c_str(), tmp.size());
106 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
109 tmp.appendS64(dec, minDigits);
110 return this->write(tmp.c_str(), tmp.size());
113 bool SkWStream::writeHexAsText(uint32_t hex, int digits)
116 tmp.appendHex(hex, digits);
117 return this->write(tmp.c_str(), tmp.size());
120 bool SkWStream::writeScalarAsText(SkScalar value)
123 tmp.appendScalar(value);
124 return this->write(tmp.c_str(), tmp.size());
127 bool SkWStream::write8(U8CPU value) {
128 uint8_t v = SkToU8(value);
129 return this->write(&v, 1);
132 bool SkWStream::write16(U16CPU value) {
133 uint16_t v = SkToU16(value);
134 return this->write(&v, 2);
137 bool SkWStream::write32(uint32_t value) {
138 return this->write(&value, 4);
141 bool SkWStream::writeScalar(SkScalar value) {
142 return this->write(&value, sizeof(value));
145 int SkWStream::SizeOfPackedUInt(size_t value) {
146 if (value <= SK_MAX_BYTE_FOR_U8) {
148 } else if (value <= 0xFFFF) {
154 bool SkWStream::writePackedUInt(size_t value) {
157 if (value <= SK_MAX_BYTE_FOR_U8) {
160 } else if (value <= 0xFFFF) {
161 uint16_t value16 = value;
162 data[0] = SK_BYTE_SENTINEL_FOR_U16;
163 memcpy(&data[1], &value16, 2);
166 uint32_t value32 = SkToU32(value);
167 data[0] = SK_BYTE_SENTINEL_FOR_U32;
168 memcpy(&data[1], &value32, 4);
171 return this->write(data, len);
174 bool SkWStream::writeStream(SkStream* stream, size_t length) {
176 const size_t MAX = sizeof(scratch);
178 while (length != 0) {
183 stream->read(scratch, n);
184 if (!this->write(scratch, n)) {
192 bool SkWStream::writeData(const SkData* data) {
194 this->write32(SkToU32(data->size()));
195 this->write(data->data(), data->size());
202 ///////////////////////////////////////////////////////////////////////////////
204 SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) {
205 fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
208 SkFILEStream::SkFILEStream(FILE* file, Ownership ownership)
209 : fFILE((SkFILE*)file)
210 , fOwnership(ownership) {
213 SkFILEStream::~SkFILEStream() {
214 if (fFILE && fOwnership != kCallerRetains_Ownership) {
219 void SkFILEStream::setPath(const char path[]) {
226 fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
230 size_t SkFILEStream::read(void* buffer, size_t size) {
232 return sk_fread(buffer, size, fFILE);
237 bool SkFILEStream::isAtEnd() const {
238 return sk_feof(fFILE);
241 bool SkFILEStream::rewind() {
243 if (sk_frewind(fFILE)) {
253 SkStreamAsset* SkFILEStream::duplicate() const {
255 return new SkMemoryStream();
258 if (NULL != fData.get()) {
259 return new SkMemoryStream(fData);
262 if (!fName.isEmpty()) {
263 SkAutoTUnref<SkFILEStream> that(new SkFILEStream(fName.c_str()));
264 if (sk_fidentical(that->fFILE, this->fFILE)) {
265 return that.detach();
269 fData.reset(SkData::NewFromFILE(fFILE));
270 if (NULL == fData.get()) {
273 return new SkMemoryStream(fData);
276 size_t SkFILEStream::getPosition() const {
277 return sk_ftell(fFILE);
280 bool SkFILEStream::seek(size_t position) {
281 return sk_fseek(fFILE, position);
284 bool SkFILEStream::move(long offset) {
285 return sk_fmove(fFILE, offset);
288 SkStreamAsset* SkFILEStream::fork() const {
289 SkAutoTUnref<SkStreamAsset> that(this->duplicate());
290 that->seek(this->getPosition());
291 return that.detach();
294 size_t SkFILEStream::getLength() const {
295 return sk_fgetsize(fFILE);
298 const void* SkFILEStream::getMemoryBase() {
299 if (NULL == fData.get()) {
302 return fData->data();
305 ///////////////////////////////////////////////////////////////////////////////
307 static SkData* newFromParams(const void* src, size_t size, bool copyData) {
309 return SkData::NewWithCopy(src, size);
311 return SkData::NewWithProc(src, size, NULL, NULL);
315 SkMemoryStream::SkMemoryStream() {
316 fData = SkData::NewEmpty();
320 SkMemoryStream::SkMemoryStream(size_t size) {
321 fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
325 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
326 fData = newFromParams(src, size, copyData);
330 SkMemoryStream::SkMemoryStream(SkData* data) {
332 fData = SkData::NewEmpty();
340 SkMemoryStream::~SkMemoryStream() {
344 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
346 fData = SkData::NewFromMalloc(src, size);
350 void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
352 fData = newFromParams(src, size, copyData);
356 SkData* SkMemoryStream::copyToData() const {
361 SkData* SkMemoryStream::setData(SkData* data) {
364 fData = SkData::NewEmpty();
373 void SkMemoryStream::skipToAlign4() {
374 // cast to remove unary-minus warning
375 fOffset += -(int)fOffset & 0x03;
378 size_t SkMemoryStream::read(void* buffer, size_t size) {
379 size_t dataSize = fData->size();
381 if (size > dataSize - fOffset) {
382 size = dataSize - fOffset;
385 memcpy(buffer, fData->bytes() + fOffset, size);
391 bool SkMemoryStream::isAtEnd() const {
392 return fOffset == fData->size();
395 bool SkMemoryStream::rewind() {
400 SkMemoryStream* SkMemoryStream::duplicate() const {
401 return SkNEW_ARGS(SkMemoryStream, (fData));
404 size_t SkMemoryStream::getPosition() const {
408 bool SkMemoryStream::seek(size_t position) {
409 fOffset = position > fData->size()
415 bool SkMemoryStream::move(long offset) {
416 return this->seek(fOffset + offset);
419 SkMemoryStream* SkMemoryStream::fork() const {
420 SkAutoTUnref<SkMemoryStream> that(this->duplicate());
422 return that.detach();
425 size_t SkMemoryStream::getLength() const {
426 return fData->size();
429 const void* SkMemoryStream::getMemoryBase() {
430 return fData->data();
433 const void* SkMemoryStream::getAtPos() {
434 return fData->bytes() + fOffset;
437 /////////////////////////////////////////////////////////////////////////////////////////////////////////
438 /////////////////////////////////////////////////////////////////////////////////////////////////////////
440 SkFILEWStream::SkFILEWStream(const char path[])
442 fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
445 SkFILEWStream::~SkFILEWStream()
452 size_t SkFILEWStream::bytesWritten() const {
453 return sk_ftell(fFILE);
456 bool SkFILEWStream::write(const void* buffer, size_t size)
462 if (sk_fwrite(buffer, size, fFILE) != size)
464 SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
472 void SkFILEWStream::flush()
479 ////////////////////////////////////////////////////////////////////////
481 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
482 : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
486 bool SkMemoryWStream::write(const void* buffer, size_t size) {
487 size = SkTMin(size, fMaxLength - fBytesWritten);
489 memcpy(fBuffer + fBytesWritten, buffer, size);
490 fBytesWritten += size;
496 ////////////////////////////////////////////////////////////////////////
498 #define SkDynamicMemoryWStream_MinBlockSize 256
500 struct SkDynamicMemoryWStream::Block {
505 const char* start() const { return (const char*)(this + 1); }
506 char* start() { return (char*)(this + 1); }
507 size_t avail() const { return fStop - fCurr; }
508 size_t written() const { return fCurr - this->start(); }
510 void init(size_t size)
513 fCurr = this->start();
514 fStop = this->start() + size;
517 const void* append(const void* data, size_t size)
519 SkASSERT((size_t)(fStop - fCurr) >= size);
520 memcpy(fCurr, data, size);
522 return (const void*)((const char*)data + size);
526 SkDynamicMemoryWStream::SkDynamicMemoryWStream()
527 : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
531 SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
536 void SkDynamicMemoryWStream::reset()
538 this->invalidateCopy();
540 Block* block = fHead;
542 while (block != NULL) {
543 Block* next = block->fNext;
547 fHead = fTail = NULL;
551 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
554 this->invalidateCopy();
556 fBytesWritten += count;
560 if (fTail != NULL && fTail->avail() > 0) {
561 size = SkTMin(fTail->avail(), count);
562 buffer = fTail->append(buffer, size);
563 SkASSERT(count >= size);
569 size = SkTMax<size_t>(count, SkDynamicMemoryWStream_MinBlockSize);
570 Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
572 block->append(buffer, count);
575 fTail->fNext = block;
577 fHead = fTail = block;
583 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
585 if (offset + count > fBytesWritten) {
586 return false; // test does not partially modify
589 this->invalidateCopy();
591 Block* block = fHead;
592 while (block != NULL) {
593 size_t size = block->written();
595 size_t part = offset + count > size ? size - offset : count;
596 memcpy(block->start() + offset, buffer, part);
600 buffer = (const void*) ((char* ) buffer + part);
602 offset = offset > size ? offset - size : 0;
603 block = block->fNext;
608 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
610 if (offset + count > fBytesWritten)
611 return false; // test does not partially modify
612 Block* block = fHead;
613 while (block != NULL) {
614 size_t size = block->written();
616 size_t part = offset + count > size ? size - offset : count;
617 memcpy(buffer, block->start() + offset, part);
621 buffer = (void*) ((char* ) buffer + part);
623 offset = offset > size ? offset - size : 0;
624 block = block->fNext;
629 void SkDynamicMemoryWStream::copyTo(void* dst) const
632 memcpy(dst, fCopy->data(), fBytesWritten);
634 Block* block = fHead;
636 while (block != NULL) {
637 size_t size = block->written();
638 memcpy(dst, block->start(), size);
639 dst = (void*)((char*)dst + size);
640 block = block->fNext;
645 void SkDynamicMemoryWStream::padToAlign4()
647 // cast to remove unary-minus warning
648 int padBytes = -(int)fBytesWritten & 0x03;
652 write(&zero, padBytes);
655 SkData* SkDynamicMemoryWStream::copyToData() const {
657 void* buffer = sk_malloc_throw(fBytesWritten);
658 this->copyTo(buffer);
659 fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
665 void SkDynamicMemoryWStream::invalidateCopy() {
672 class SkBlockMemoryRefCnt : public SkRefCnt {
674 explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
676 virtual ~SkBlockMemoryRefCnt() {
677 SkDynamicMemoryWStream::Block* block = fHead;
678 while (block != NULL) {
679 SkDynamicMemoryWStream::Block* next = block->fNext;
685 SkDynamicMemoryWStream::Block* const fHead;
688 class SkBlockMemoryStream : public SkStreamAsset {
690 SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
691 : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head)
692 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
694 SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
695 : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead)
696 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
698 virtual size_t read(void* buffer, size_t rawCount) SK_OVERRIDE {
699 size_t count = rawCount;
700 if (fOffset + count > fSize) {
701 count = fSize - fOffset;
703 size_t bytesLeftToRead = count;
704 while (fCurrent != NULL) {
705 size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
706 size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
708 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
709 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
711 if (bytesLeftToRead <= bytesFromCurrent) {
712 fCurrentOffset += bytesFromCurrent;
716 bytesLeftToRead -= bytesFromCurrent;
717 fCurrent = fCurrent->fNext;
724 virtual bool isAtEnd() const SK_OVERRIDE {
725 return fOffset == fSize;
728 virtual bool rewind() SK_OVERRIDE {
729 fCurrent = fBlockMemory->fHead;
735 virtual SkBlockMemoryStream* duplicate() const SK_OVERRIDE {
736 return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize));
739 virtual size_t getPosition() const SK_OVERRIDE {
743 virtual bool seek(size_t position) SK_OVERRIDE {
744 // If possible, skip forward.
745 if (position >= fOffset) {
746 size_t skipAmount = position - fOffset;
747 return this->skip(skipAmount) == skipAmount;
749 // If possible, move backward within the current block.
750 size_t moveBackAmount = fOffset - position;
751 if (moveBackAmount <= fCurrentOffset) {
752 fCurrentOffset -= moveBackAmount;
753 fOffset -= moveBackAmount;
756 // Otherwise rewind and move forward.
757 return this->rewind() && this->skip(position) == position;
760 virtual bool move(long offset) SK_OVERRIDE {
761 return seek(fOffset + offset);
764 virtual SkBlockMemoryStream* fork() const SK_OVERRIDE {
765 SkAutoTUnref<SkBlockMemoryStream> that(this->duplicate());
766 that->fCurrent = this->fCurrent;
767 that->fOffset = this->fOffset;
768 that->fCurrentOffset = this->fCurrentOffset;
769 return that.detach();
772 virtual size_t getLength() const SK_OVERRIDE {
776 virtual const void* getMemoryBase() SK_OVERRIDE {
777 if (NULL == fBlockMemory->fHead->fNext) {
778 return fBlockMemory->fHead->start();
784 SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory;
785 SkDynamicMemoryWStream::Block const * fCurrent;
788 size_t fCurrentOffset;
791 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() {
793 SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy));
797 SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten));
803 ///////////////////////////////////////////////////////////////////////////////
805 void SkDebugWStream::newline()
807 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
813 bool SkDebugWStream::write(const void* buffer, size_t size)
815 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
816 char* s = new char[size+1];
817 memcpy(s, buffer, size);
821 fBytesWritten += size;
826 ///////////////////////////////////////////////////////////////////////////////
827 ///////////////////////////////////////////////////////////////////////////////
830 static SkData* mmap_filename(const char path[]) {
831 SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
836 SkData* data = SkData::NewFromFILE(file);
841 SkStreamAsset* SkStream::NewFromFile(const char path[]) {
842 SkAutoTUnref<SkData> data(mmap_filename(path));
844 return SkNEW_ARGS(SkMemoryStream, (data.get()));
847 // If we get here, then our attempt at using mmap failed, so try normal
849 SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
850 if (!stream->isValid()) {
857 // Declared in SkStreamPriv.h:
858 size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
859 SkASSERT(storage != NULL);
860 SkASSERT(stream != NULL);
862 if (stream->hasLength()) {
863 const size_t length = stream->getLength();
864 void* dst = storage->reset(length);
865 if (stream->read(dst, length) != length) {
871 SkDynamicMemoryWStream tempStream;
872 // Arbitrary buffer size.
873 const size_t bufferSize = 256 * 1024; // 256KB
874 char buffer[bufferSize];
875 SkDEBUGCODE(size_t debugLength = 0;)
877 size_t bytesRead = stream->read(buffer, bufferSize);
878 tempStream.write(buffer, bytesRead);
879 SkDEBUGCODE(debugLength += bytesRead);
880 SkASSERT(tempStream.bytesWritten() == debugLength);
881 } while (!stream->isAtEnd());
882 const size_t length = tempStream.bytesWritten();
883 void* dst = storage->reset(length);
884 tempStream.copyTo(dst);
888 // Declared in SkStreamPriv.h:
889 SkData* SkCopyStreamToData(SkStream* stream) {
890 SkASSERT(stream != NULL);
892 if (stream->hasLength()) {
893 const size_t length = stream->getLength();
894 SkAutoMalloc dst(length);
895 if (stream->read(dst.get(), length) != length) {
898 return SkData::NewFromMalloc(dst.detach(), length);
901 SkDynamicMemoryWStream tempStream;
902 const size_t bufferSize = 4096;
903 char buffer[bufferSize];
905 size_t bytesRead = stream->read(buffer, bufferSize);
906 tempStream.write(buffer, bytesRead);
907 } while (!stream->isAtEnd());
908 return tempStream.copyToData();
911 SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) {
915 SkAutoTUnref<SkStreamRewindable> dupStream(stream->duplicate());
917 return dupStream.detach();
920 if (stream->hasLength()) {
921 size_t length = stream->getLength();
922 if (stream->hasPosition()) { // If stream has length, but can't rewind.
923 length -= stream->getPosition();
925 SkAutoMalloc allocMemory(length);
926 SkDEBUGCODE(size_t read =) stream->read(allocMemory.get(), length);
927 SkASSERT(length == read);
928 SkAutoTUnref<SkData> data(
929 SkData::NewFromMalloc(allocMemory.detach(), length));
930 return SkNEW_ARGS(SkMemoryStream, (data.get()));
932 SkDynamicMemoryWStream tempStream;
933 const size_t bufferSize = 4096;
934 char buffer[bufferSize];
936 size_t bytesRead = stream->read(buffer, bufferSize);
937 tempStream.write(buffer, bytesRead);
938 } while (!stream->isAtEnd());
939 return tempStream.detachAsStream(); // returns a SkBlockMemoryStream,
940 // cheaper than copying to SkData