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 //////////////////////////////////////////////////////////////////////////////////////
69 SkWStream::~SkWStream()
73 void SkWStream::newline()
78 void SkWStream::flush()
82 bool SkWStream::writeText(const char text[])
85 return this->write(text, strlen(text));
88 bool SkWStream::writeDecAsText(int32_t dec)
90 char buffer[SkStrAppendS32_MaxSize];
91 char* stop = SkStrAppendS32(buffer, dec);
92 return this->write(buffer, stop - buffer);
95 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
97 char buffer[SkStrAppendU64_MaxSize];
98 char* stop = SkStrAppendU64(buffer, dec, minDigits);
99 return this->write(buffer, stop - buffer);
102 bool SkWStream::writeHexAsText(uint32_t hex, int digits)
105 tmp.appendHex(hex, digits);
106 return this->write(tmp.c_str(), tmp.size());
109 bool SkWStream::writeScalarAsText(SkScalar value)
111 char buffer[SkStrAppendScalar_MaxSize];
112 char* stop = SkStrAppendScalar(buffer, value);
113 return this->write(buffer, stop - buffer);
116 bool SkWStream::write8(U8CPU value) {
117 uint8_t v = SkToU8(value);
118 return this->write(&v, 1);
121 bool SkWStream::write16(U16CPU value) {
122 uint16_t v = SkToU16(value);
123 return this->write(&v, 2);
126 bool SkWStream::write32(uint32_t value) {
127 return this->write(&value, 4);
130 bool SkWStream::writeScalar(SkScalar value) {
131 return this->write(&value, sizeof(value));
134 int SkWStream::SizeOfPackedUInt(size_t value) {
135 if (value <= SK_MAX_BYTE_FOR_U8) {
137 } else if (value <= 0xFFFF) {
143 bool SkWStream::writePackedUInt(size_t value) {
146 if (value <= SK_MAX_BYTE_FOR_U8) {
149 } else if (value <= 0xFFFF) {
150 uint16_t value16 = value;
151 data[0] = SK_BYTE_SENTINEL_FOR_U16;
152 memcpy(&data[1], &value16, 2);
155 uint32_t value32 = SkToU32(value);
156 data[0] = SK_BYTE_SENTINEL_FOR_U32;
157 memcpy(&data[1], &value32, 4);
160 return this->write(data, len);
163 bool SkWStream::writeStream(SkStream* stream, size_t length) {
165 const size_t MAX = sizeof(scratch);
167 while (length != 0) {
172 stream->read(scratch, n);
173 if (!this->write(scratch, n)) {
181 ///////////////////////////////////////////////////////////////////////////////
183 SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) {
184 fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
187 SkFILEStream::SkFILEStream(FILE* file, Ownership ownership)
188 : fFILE((SkFILE*)file)
189 , fOwnership(ownership) {
192 SkFILEStream::~SkFILEStream() {
193 if (fFILE && fOwnership != kCallerRetains_Ownership) {
198 void SkFILEStream::setPath(const char path[]) {
205 fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
209 size_t SkFILEStream::read(void* buffer, size_t size) {
211 return sk_fread(buffer, size, fFILE);
216 bool SkFILEStream::isAtEnd() const {
217 return sk_feof(fFILE);
220 bool SkFILEStream::rewind() {
222 if (sk_frewind(fFILE)) {
232 SkStreamAsset* SkFILEStream::duplicate() const {
234 return new SkMemoryStream();
238 return new SkMemoryStream(fData);
241 if (!fName.isEmpty()) {
242 SkAutoTDelete<SkFILEStream> that(new SkFILEStream(fName.c_str()));
243 if (sk_fidentical(that->fFILE, this->fFILE)) {
244 return that.detach();
248 fData.reset(SkData::NewFromFILE(fFILE));
249 if (NULL == fData.get()) {
252 return new SkMemoryStream(fData);
255 size_t SkFILEStream::getPosition() const {
256 return sk_ftell(fFILE);
259 bool SkFILEStream::seek(size_t position) {
260 return sk_fseek(fFILE, position);
263 bool SkFILEStream::move(long offset) {
264 return sk_fmove(fFILE, offset);
267 SkStreamAsset* SkFILEStream::fork() const {
268 SkAutoTDelete<SkStreamAsset> that(this->duplicate());
269 that->seek(this->getPosition());
270 return that.detach();
273 size_t SkFILEStream::getLength() const {
274 return sk_fgetsize(fFILE);
277 const void* SkFILEStream::getMemoryBase() {
278 if (NULL == fData.get()) {
281 return fData->data();
284 ///////////////////////////////////////////////////////////////////////////////
286 static SkData* newFromParams(const void* src, size_t size, bool copyData) {
288 return SkData::NewWithCopy(src, size);
290 return SkData::NewWithoutCopy(src, size);
294 SkMemoryStream::SkMemoryStream() {
295 fData = SkData::NewEmpty();
299 SkMemoryStream::SkMemoryStream(size_t size) {
300 fData = SkData::NewUninitialized(size);
304 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
305 fData = newFromParams(src, size, copyData);
309 SkMemoryStream::SkMemoryStream(SkData* data) {
311 fData = SkData::NewEmpty();
319 SkMemoryStream::~SkMemoryStream() {
323 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
325 fData = SkData::NewFromMalloc(src, size);
329 void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
331 fData = newFromParams(src, size, copyData);
335 SkData* SkMemoryStream::copyToData() const {
340 SkData* SkMemoryStream::setData(SkData* data) {
343 fData = SkData::NewEmpty();
352 void SkMemoryStream::skipToAlign4() {
353 // cast to remove unary-minus warning
354 fOffset += -(int)fOffset & 0x03;
357 size_t SkMemoryStream::read(void* buffer, size_t size) {
358 size_t dataSize = fData->size();
360 if (size > dataSize - fOffset) {
361 size = dataSize - fOffset;
364 memcpy(buffer, fData->bytes() + fOffset, size);
370 bool SkMemoryStream::isAtEnd() const {
371 return fOffset == fData->size();
374 bool SkMemoryStream::rewind() {
379 SkMemoryStream* SkMemoryStream::duplicate() const {
380 return SkNEW_ARGS(SkMemoryStream, (fData));
383 size_t SkMemoryStream::getPosition() const {
387 bool SkMemoryStream::seek(size_t position) {
388 fOffset = position > fData->size()
394 bool SkMemoryStream::move(long offset) {
395 return this->seek(fOffset + offset);
398 SkMemoryStream* SkMemoryStream::fork() const {
399 SkAutoTDelete<SkMemoryStream> that(this->duplicate());
401 return that.detach();
404 size_t SkMemoryStream::getLength() const {
405 return fData->size();
408 const void* SkMemoryStream::getMemoryBase() {
409 return fData->data();
412 const void* SkMemoryStream::getAtPos() {
413 return fData->bytes() + fOffset;
416 /////////////////////////////////////////////////////////////////////////////////////////////////////////
417 /////////////////////////////////////////////////////////////////////////////////////////////////////////
419 SkFILEWStream::SkFILEWStream(const char path[])
421 fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
424 SkFILEWStream::~SkFILEWStream()
431 size_t SkFILEWStream::bytesWritten() const {
432 return sk_ftell(fFILE);
435 bool SkFILEWStream::write(const void* buffer, size_t size)
441 if (sk_fwrite(buffer, size, fFILE) != size)
443 SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
451 void SkFILEWStream::flush()
458 ////////////////////////////////////////////////////////////////////////
460 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
461 : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
465 bool SkMemoryWStream::write(const void* buffer, size_t size) {
466 size = SkTMin(size, fMaxLength - fBytesWritten);
468 memcpy(fBuffer + fBytesWritten, buffer, size);
469 fBytesWritten += size;
475 ////////////////////////////////////////////////////////////////////////
477 #define SkDynamicMemoryWStream_MinBlockSize 256
479 struct SkDynamicMemoryWStream::Block {
484 const char* start() const { return (const char*)(this + 1); }
485 char* start() { return (char*)(this + 1); }
486 size_t avail() const { return fStop - fCurr; }
487 size_t written() const { return fCurr - this->start(); }
489 void init(size_t size)
492 fCurr = this->start();
493 fStop = this->start() + size;
496 const void* append(const void* data, size_t size)
498 SkASSERT((size_t)(fStop - fCurr) >= size);
499 memcpy(fCurr, data, size);
501 return (const void*)((const char*)data + size);
505 SkDynamicMemoryWStream::SkDynamicMemoryWStream()
506 : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
510 SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
515 void SkDynamicMemoryWStream::reset()
517 this->invalidateCopy();
519 Block* block = fHead;
521 while (block != NULL) {
522 Block* next = block->fNext;
526 fHead = fTail = NULL;
530 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
533 this->invalidateCopy();
535 fBytesWritten += count;
539 if (fTail != NULL && fTail->avail() > 0) {
540 size = SkTMin(fTail->avail(), count);
541 buffer = fTail->append(buffer, size);
542 SkASSERT(count >= size);
548 size = SkTMax<size_t>(count, SkDynamicMemoryWStream_MinBlockSize);
549 Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
551 block->append(buffer, count);
554 fTail->fNext = block;
556 fHead = fTail = block;
562 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
564 if (offset + count > fBytesWritten) {
565 return false; // test does not partially modify
568 this->invalidateCopy();
570 Block* block = fHead;
571 while (block != NULL) {
572 size_t size = block->written();
574 size_t part = offset + count > size ? size - offset : count;
575 memcpy(block->start() + offset, buffer, part);
579 buffer = (const void*) ((char* ) buffer + part);
581 offset = offset > size ? offset - size : 0;
582 block = block->fNext;
587 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
589 if (offset + count > fBytesWritten)
590 return false; // test does not partially modify
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(buffer, block->start() + offset, part);
600 buffer = (void*) ((char* ) buffer + part);
602 offset = offset > size ? offset - size : 0;
603 block = block->fNext;
608 void SkDynamicMemoryWStream::copyTo(void* dst) const
611 memcpy(dst, fCopy->data(), fBytesWritten);
613 Block* block = fHead;
615 while (block != NULL) {
616 size_t size = block->written();
617 memcpy(dst, block->start(), size);
618 dst = (void*)((char*)dst + size);
619 block = block->fNext;
624 void SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const {
625 for (Block* block = fHead; block != NULL; block = block->fNext) {
626 dst->write(block->start(), block->written());
630 void SkDynamicMemoryWStream::padToAlign4()
632 // cast to remove unary-minus warning
633 int padBytes = -(int)fBytesWritten & 0x03;
637 write(&zero, padBytes);
640 SkData* SkDynamicMemoryWStream::copyToData() const {
642 SkData* data = SkData::NewUninitialized(fBytesWritten);
643 // be sure to call copyTo() before we assign to fCopy
644 this->copyTo(data->writable_data());
650 void SkDynamicMemoryWStream::invalidateCopy() {
657 class SkBlockMemoryRefCnt : public SkRefCnt {
659 explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
661 virtual ~SkBlockMemoryRefCnt() {
662 SkDynamicMemoryWStream::Block* block = fHead;
663 while (block != NULL) {
664 SkDynamicMemoryWStream::Block* next = block->fNext;
670 SkDynamicMemoryWStream::Block* const fHead;
673 class SkBlockMemoryStream : public SkStreamAsset {
675 SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
676 : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head)
677 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
679 SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
680 : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead)
681 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
683 size_t read(void* buffer, size_t rawCount) SK_OVERRIDE {
684 size_t count = rawCount;
685 if (fOffset + count > fSize) {
686 count = fSize - fOffset;
688 size_t bytesLeftToRead = count;
689 while (fCurrent != NULL) {
690 size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
691 size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
693 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
694 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
696 if (bytesLeftToRead <= bytesFromCurrent) {
697 fCurrentOffset += bytesFromCurrent;
701 bytesLeftToRead -= bytesFromCurrent;
702 fCurrent = fCurrent->fNext;
709 bool isAtEnd() const SK_OVERRIDE {
710 return fOffset == fSize;
713 bool rewind() SK_OVERRIDE {
714 fCurrent = fBlockMemory->fHead;
720 SkBlockMemoryStream* duplicate() const SK_OVERRIDE {
721 return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize));
724 size_t getPosition() const SK_OVERRIDE {
728 bool seek(size_t position) SK_OVERRIDE {
729 // If possible, skip forward.
730 if (position >= fOffset) {
731 size_t skipAmount = position - fOffset;
732 return this->skip(skipAmount) == skipAmount;
734 // If possible, move backward within the current block.
735 size_t moveBackAmount = fOffset - position;
736 if (moveBackAmount <= fCurrentOffset) {
737 fCurrentOffset -= moveBackAmount;
738 fOffset -= moveBackAmount;
741 // Otherwise rewind and move forward.
742 return this->rewind() && this->skip(position) == position;
745 bool move(long offset) SK_OVERRIDE {
746 return seek(fOffset + offset);
749 SkBlockMemoryStream* fork() const SK_OVERRIDE {
750 SkAutoTDelete<SkBlockMemoryStream> that(this->duplicate());
751 that->fCurrent = this->fCurrent;
752 that->fOffset = this->fOffset;
753 that->fCurrentOffset = this->fCurrentOffset;
754 return that.detach();
757 size_t getLength() const SK_OVERRIDE {
761 const void* getMemoryBase() SK_OVERRIDE {
762 if (NULL == fBlockMemory->fHead->fNext) {
763 return fBlockMemory->fHead->start();
769 SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory;
770 SkDynamicMemoryWStream::Block const * fCurrent;
773 size_t fCurrentOffset;
776 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() {
778 SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy));
782 SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten));
788 ///////////////////////////////////////////////////////////////////////////////
790 void SkDebugWStream::newline()
792 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
798 bool SkDebugWStream::write(const void* buffer, size_t size)
800 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
801 char* s = new char[size+1];
802 memcpy(s, buffer, size);
806 fBytesWritten += size;
811 ///////////////////////////////////////////////////////////////////////////////
812 ///////////////////////////////////////////////////////////////////////////////
815 static SkData* mmap_filename(const char path[]) {
816 SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
821 SkData* data = SkData::NewFromFILE(file);
826 SkStreamAsset* SkStream::NewFromFile(const char path[]) {
827 SkAutoTUnref<SkData> data(mmap_filename(path));
829 return SkNEW_ARGS(SkMemoryStream, (data.get()));
832 // If we get here, then our attempt at using mmap failed, so try normal
834 SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
835 if (!stream->isValid()) {
842 // Declared in SkStreamPriv.h:
843 size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
844 SkASSERT(storage != NULL);
845 SkASSERT(stream != NULL);
847 if (stream->hasLength()) {
848 const size_t length = stream->getLength();
849 void* dst = storage->reset(length);
850 if (stream->read(dst, length) != length) {
856 SkDynamicMemoryWStream tempStream;
857 // Arbitrary buffer size.
858 const size_t bufferSize = 256 * 1024; // 256KB
859 char buffer[bufferSize];
860 SkDEBUGCODE(size_t debugLength = 0;)
862 size_t bytesRead = stream->read(buffer, bufferSize);
863 tempStream.write(buffer, bytesRead);
864 SkDEBUGCODE(debugLength += bytesRead);
865 SkASSERT(tempStream.bytesWritten() == debugLength);
866 } while (!stream->isAtEnd());
867 const size_t length = tempStream.bytesWritten();
868 void* dst = storage->reset(length);
869 tempStream.copyTo(dst);
873 // Declared in SkStreamPriv.h:
874 SkData* SkCopyStreamToData(SkStream* stream) {
875 SkASSERT(stream != NULL);
877 if (stream->hasLength()) {
878 return SkData::NewFromStream(stream, stream->getLength());
881 SkDynamicMemoryWStream tempStream;
882 const size_t bufferSize = 4096;
883 char buffer[bufferSize];
885 size_t bytesRead = stream->read(buffer, bufferSize);
886 tempStream.write(buffer, bytesRead);
887 } while (!stream->isAtEnd());
888 return tempStream.copyToData();
891 SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) {
895 SkAutoTDelete<SkStreamRewindable> dupStream(stream->duplicate());
897 return dupStream.detach();
900 if (stream->hasLength()) {
901 size_t length = stream->getLength();
902 if (stream->hasPosition()) { // If stream has length, but can't rewind.
903 length -= stream->getPosition();
905 SkAutoTUnref<SkData> data(SkData::NewFromStream(stream, length));
906 return SkNEW_ARGS(SkMemoryStream, (data.get()));
908 SkDynamicMemoryWStream tempStream;
909 const size_t bufferSize = 4096;
910 char buffer[bufferSize];
912 size_t bytesRead = stream->read(buffer, bufferSize);
913 tempStream.write(buffer, bytesRead);
914 } while (!stream->isAtEnd());
915 return tempStream.detachAsStream(); // returns a SkBlockMemoryStream,
916 // cheaper than copying to SkData