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.
16 ///////////////////////////////////////////////////////////////////////////////
19 int8_t SkStream::readS8() {
21 SkDEBUGCODE(size_t len =) this->read(&value, 1);
26 int16_t SkStream::readS16() {
28 SkDEBUGCODE(size_t len =) this->read(&value, 2);
33 int32_t SkStream::readS32() {
35 SkDEBUGCODE(size_t len =) this->read(&value, 4);
40 SkScalar SkStream::readScalar() {
42 SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
43 SkASSERT(sizeof(SkScalar) == len);
47 #define SK_MAX_BYTE_FOR_U8 0xFD
48 #define SK_BYTE_SENTINEL_FOR_U16 0xFE
49 #define SK_BYTE_SENTINEL_FOR_U32 0xFF
51 size_t SkStream::readPackedUInt() {
53 if (!this->read(&byte, 1)) {
56 if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
57 return this->readU16();
58 } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
59 return this->readU32();
65 SkData* SkStream::readData() {
66 size_t size = this->readU32();
68 return SkData::NewEmpty();
70 void* buffer = sk_malloc_throw(size);
71 this->read(buffer, size);
72 return SkData::NewFromMalloc(buffer, size);
76 //////////////////////////////////////////////////////////////////////////////////////
78 SkWStream::~SkWStream()
82 void SkWStream::newline()
87 void SkWStream::flush()
91 bool SkWStream::writeText(const char text[])
94 return this->write(text, strlen(text));
97 bool SkWStream::writeDecAsText(int32_t dec)
101 return this->write(tmp.c_str(), tmp.size());
104 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
107 tmp.appendS64(dec, minDigits);
108 return this->write(tmp.c_str(), tmp.size());
111 bool SkWStream::writeHexAsText(uint32_t hex, int digits)
114 tmp.appendHex(hex, digits);
115 return this->write(tmp.c_str(), tmp.size());
118 bool SkWStream::writeScalarAsText(SkScalar value)
121 tmp.appendScalar(value);
122 return this->write(tmp.c_str(), tmp.size());
125 bool SkWStream::write8(U8CPU value) {
126 uint8_t v = SkToU8(value);
127 return this->write(&v, 1);
130 bool SkWStream::write16(U16CPU value) {
131 uint16_t v = SkToU16(value);
132 return this->write(&v, 2);
135 bool SkWStream::write32(uint32_t value) {
136 return this->write(&value, 4);
139 bool SkWStream::writeScalar(SkScalar value) {
140 return this->write(&value, sizeof(value));
143 int SkWStream::SizeOfPackedUInt(size_t value) {
144 if (value <= SK_MAX_BYTE_FOR_U8) {
146 } else if (value <= 0xFFFF) {
152 bool SkWStream::writePackedUInt(size_t value) {
155 if (value <= SK_MAX_BYTE_FOR_U8) {
158 } else if (value <= 0xFFFF) {
159 uint16_t value16 = value;
160 data[0] = SK_BYTE_SENTINEL_FOR_U16;
161 memcpy(&data[1], &value16, 2);
164 uint32_t value32 = SkToU32(value);
165 data[0] = SK_BYTE_SENTINEL_FOR_U32;
166 memcpy(&data[1], &value32, 4);
169 return this->write(data, len);
172 bool SkWStream::writeStream(SkStream* stream, size_t length) {
174 const size_t MAX = sizeof(scratch);
176 while (length != 0) {
181 stream->read(scratch, n);
182 if (!this->write(scratch, n)) {
190 bool SkWStream::writeData(const SkData* data) {
192 this->write32(SkToU32(data->size()));
193 this->write(data->data(), data->size());
200 ///////////////////////////////////////////////////////////////////////////////
202 SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) {
203 fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
206 SkFILEStream::SkFILEStream(FILE* file, Ownership ownership)
207 : fFILE((SkFILE*)file)
208 , fOwnership(ownership) {
211 SkFILEStream::~SkFILEStream() {
212 if (fFILE && fOwnership != kCallerRetains_Ownership) {
217 void SkFILEStream::setPath(const char path[]) {
224 fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
228 size_t SkFILEStream::read(void* buffer, size_t size) {
230 return sk_fread(buffer, size, fFILE);
235 bool SkFILEStream::isAtEnd() const {
236 return sk_feof(fFILE);
239 bool SkFILEStream::rewind() {
241 if (sk_frewind(fFILE)) {
251 SkStreamAsset* SkFILEStream::duplicate() const {
253 return new SkMemoryStream();
256 if (NULL != fData.get()) {
257 return new SkMemoryStream(fData);
260 if (!fName.isEmpty()) {
261 SkAutoTUnref<SkFILEStream> that(new SkFILEStream(fName.c_str()));
262 if (sk_fidentical(that->fFILE, this->fFILE)) {
263 return that.detach();
267 fData.reset(SkData::NewFromFILE(fFILE));
268 if (NULL == fData.get()) {
271 return new SkMemoryStream(fData);
274 size_t SkFILEStream::getPosition() const {
275 return sk_ftell(fFILE);
278 bool SkFILEStream::seek(size_t position) {
279 return sk_fseek(fFILE, position);
282 bool SkFILEStream::move(long offset) {
283 return sk_fmove(fFILE, offset);
286 SkStreamAsset* SkFILEStream::fork() const {
287 SkAutoTUnref<SkStreamAsset> that(this->duplicate());
288 that->seek(this->getPosition());
289 return that.detach();
292 size_t SkFILEStream::getLength() const {
293 return sk_fgetsize(fFILE);
296 const void* SkFILEStream::getMemoryBase() {
297 if (NULL == fData.get()) {
300 return fData->data();
303 ///////////////////////////////////////////////////////////////////////////////
305 static SkData* newFromParams(const void* src, size_t size, bool copyData) {
307 return SkData::NewWithCopy(src, size);
309 return SkData::NewWithProc(src, size, NULL, NULL);
313 SkMemoryStream::SkMemoryStream() {
314 fData = SkData::NewEmpty();
318 SkMemoryStream::SkMemoryStream(size_t size) {
319 fData = SkData::NewFromMalloc(sk_malloc_throw(size), size);
323 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
324 fData = newFromParams(src, size, copyData);
328 SkMemoryStream::SkMemoryStream(SkData* data) {
330 fData = SkData::NewEmpty();
338 SkMemoryStream::~SkMemoryStream() {
342 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
344 fData = SkData::NewFromMalloc(src, size);
348 void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
350 fData = newFromParams(src, size, copyData);
354 SkData* SkMemoryStream::copyToData() const {
359 SkData* SkMemoryStream::setData(SkData* data) {
362 fData = SkData::NewEmpty();
371 void SkMemoryStream::skipToAlign4() {
372 // cast to remove unary-minus warning
373 fOffset += -(int)fOffset & 0x03;
376 size_t SkMemoryStream::read(void* buffer, size_t size) {
377 size_t dataSize = fData->size();
379 if (size > dataSize - fOffset) {
380 size = dataSize - fOffset;
383 memcpy(buffer, fData->bytes() + fOffset, size);
389 bool SkMemoryStream::isAtEnd() const {
390 return fOffset == fData->size();
393 bool SkMemoryStream::rewind() {
398 SkMemoryStream* SkMemoryStream::duplicate() const {
399 return SkNEW_ARGS(SkMemoryStream, (fData));
402 size_t SkMemoryStream::getPosition() const {
406 bool SkMemoryStream::seek(size_t position) {
407 fOffset = position > fData->size()
413 bool SkMemoryStream::move(long offset) {
414 return this->seek(fOffset + offset);
417 SkMemoryStream* SkMemoryStream::fork() const {
418 SkAutoTUnref<SkMemoryStream> that(this->duplicate());
420 return that.detach();
423 size_t SkMemoryStream::getLength() const {
424 return fData->size();
427 const void* SkMemoryStream::getMemoryBase() {
428 return fData->data();
431 const void* SkMemoryStream::getAtPos() {
432 return fData->bytes() + fOffset;
435 /////////////////////////////////////////////////////////////////////////////////////////////////////////
436 /////////////////////////////////////////////////////////////////////////////////////////////////////////
438 SkFILEWStream::SkFILEWStream(const char path[])
440 fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
443 SkFILEWStream::~SkFILEWStream()
450 size_t SkFILEWStream::bytesWritten() const {
451 return sk_ftell(fFILE);
454 bool SkFILEWStream::write(const void* buffer, size_t size)
460 if (sk_fwrite(buffer, size, fFILE) != size)
462 SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
470 void SkFILEWStream::flush()
477 ////////////////////////////////////////////////////////////////////////
479 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
480 : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
484 bool SkMemoryWStream::write(const void* buffer, size_t size) {
485 size = SkTMin(size, fMaxLength - fBytesWritten);
487 memcpy(fBuffer + fBytesWritten, buffer, size);
488 fBytesWritten += size;
494 ////////////////////////////////////////////////////////////////////////
496 #define SkDynamicMemoryWStream_MinBlockSize 256
498 struct SkDynamicMemoryWStream::Block {
503 const char* start() const { return (const char*)(this + 1); }
504 char* start() { return (char*)(this + 1); }
505 size_t avail() const { return fStop - fCurr; }
506 size_t written() const { return fCurr - this->start(); }
508 void init(size_t size)
511 fCurr = this->start();
512 fStop = this->start() + size;
515 const void* append(const void* data, size_t size)
517 SkASSERT((size_t)(fStop - fCurr) >= size);
518 memcpy(fCurr, data, size);
520 return (const void*)((const char*)data + size);
524 SkDynamicMemoryWStream::SkDynamicMemoryWStream()
525 : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
529 SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
534 void SkDynamicMemoryWStream::reset()
536 this->invalidateCopy();
538 Block* block = fHead;
540 while (block != NULL) {
541 Block* next = block->fNext;
545 fHead = fTail = NULL;
549 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
552 this->invalidateCopy();
554 fBytesWritten += count;
558 if (fTail != NULL && fTail->avail() > 0) {
559 size = SkTMin(fTail->avail(), count);
560 buffer = fTail->append(buffer, size);
561 SkASSERT(count >= size);
567 size = SkTMax<size_t>(count, SkDynamicMemoryWStream_MinBlockSize);
568 Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
570 block->append(buffer, count);
573 fTail->fNext = block;
575 fHead = fTail = block;
581 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
583 if (offset + count > fBytesWritten) {
584 return false; // test does not partially modify
587 this->invalidateCopy();
589 Block* block = fHead;
590 while (block != NULL) {
591 size_t size = block->written();
593 size_t part = offset + count > size ? size - offset : count;
594 memcpy(block->start() + offset, buffer, part);
598 buffer = (const void*) ((char* ) buffer + part);
600 offset = offset > size ? offset - size : 0;
601 block = block->fNext;
606 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
608 if (offset + count > fBytesWritten)
609 return false; // test does not partially modify
610 Block* block = fHead;
611 while (block != NULL) {
612 size_t size = block->written();
614 size_t part = offset + count > size ? size - offset : count;
615 memcpy(buffer, block->start() + offset, part);
619 buffer = (void*) ((char* ) buffer + part);
621 offset = offset > size ? offset - size : 0;
622 block = block->fNext;
627 void SkDynamicMemoryWStream::copyTo(void* dst) const
630 memcpy(dst, fCopy->data(), fBytesWritten);
632 Block* block = fHead;
634 while (block != NULL) {
635 size_t size = block->written();
636 memcpy(dst, block->start(), size);
637 dst = (void*)((char*)dst + size);
638 block = block->fNext;
643 void SkDynamicMemoryWStream::padToAlign4()
645 // cast to remove unary-minus warning
646 int padBytes = -(int)fBytesWritten & 0x03;
650 write(&zero, padBytes);
653 SkData* SkDynamicMemoryWStream::copyToData() const {
655 void* buffer = sk_malloc_throw(fBytesWritten);
656 this->copyTo(buffer);
657 fCopy = SkData::NewFromMalloc(buffer, fBytesWritten);
663 void SkDynamicMemoryWStream::invalidateCopy() {
670 class SkBlockMemoryRefCnt : public SkRefCnt {
672 explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
674 virtual ~SkBlockMemoryRefCnt() {
675 SkDynamicMemoryWStream::Block* block = fHead;
676 while (block != NULL) {
677 SkDynamicMemoryWStream::Block* next = block->fNext;
683 SkDynamicMemoryWStream::Block* const fHead;
686 class SkBlockMemoryStream : public SkStreamAsset {
688 SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
689 : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head)
690 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
692 SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
693 : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead)
694 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
696 virtual size_t read(void* buffer, size_t rawCount) SK_OVERRIDE {
697 size_t count = rawCount;
698 if (fOffset + count > fSize) {
699 count = fSize - fOffset;
701 size_t bytesLeftToRead = count;
702 while (fCurrent != NULL) {
703 size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
704 size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
706 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
707 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
709 if (bytesLeftToRead <= bytesFromCurrent) {
710 fCurrentOffset += bytesFromCurrent;
714 bytesLeftToRead -= bytesFromCurrent;
715 fCurrent = fCurrent->fNext;
722 virtual bool isAtEnd() const SK_OVERRIDE {
723 return fOffset == fSize;
726 virtual bool rewind() SK_OVERRIDE {
727 fCurrent = fBlockMemory->fHead;
733 virtual SkBlockMemoryStream* duplicate() const SK_OVERRIDE {
734 return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize));
737 virtual size_t getPosition() const SK_OVERRIDE {
741 virtual bool seek(size_t position) SK_OVERRIDE {
742 // If possible, skip forward.
743 if (position >= fOffset) {
744 size_t skipAmount = position - fOffset;
745 return this->skip(skipAmount) == skipAmount;
747 // If possible, move backward within the current block.
748 size_t moveBackAmount = fOffset - position;
749 if (moveBackAmount <= fCurrentOffset) {
750 fCurrentOffset -= moveBackAmount;
751 fOffset -= moveBackAmount;
754 // Otherwise rewind and move forward.
755 return this->rewind() && this->skip(position) == position;
758 virtual bool move(long offset) SK_OVERRIDE {
759 return seek(fOffset + offset);
762 virtual SkBlockMemoryStream* fork() const SK_OVERRIDE {
763 SkAutoTUnref<SkBlockMemoryStream> that(this->duplicate());
764 that->fCurrent = this->fCurrent;
765 that->fOffset = this->fOffset;
766 that->fCurrentOffset = this->fCurrentOffset;
767 return that.detach();
770 virtual size_t getLength() const SK_OVERRIDE {
774 virtual const void* getMemoryBase() SK_OVERRIDE {
775 if (NULL == fBlockMemory->fHead->fNext) {
776 return fBlockMemory->fHead->start();
782 SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory;
783 SkDynamicMemoryWStream::Block const * fCurrent;
786 size_t fCurrentOffset;
789 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() {
791 SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy));
795 SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten));
801 ///////////////////////////////////////////////////////////////////////////////
803 void SkDebugWStream::newline()
805 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
811 bool SkDebugWStream::write(const void* buffer, size_t size)
813 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
814 char* s = new char[size+1];
815 memcpy(s, buffer, size);
819 fBytesWritten += size;
824 ///////////////////////////////////////////////////////////////////////////////
825 ///////////////////////////////////////////////////////////////////////////////
828 static SkData* mmap_filename(const char path[]) {
829 SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
834 SkData* data = SkData::NewFromFILE(file);
839 SkStreamAsset* SkStream::NewFromFile(const char path[]) {
840 SkAutoTUnref<SkData> data(mmap_filename(path));
842 return SkNEW_ARGS(SkMemoryStream, (data.get()));
845 // If we get here, then our attempt at using mmap failed, so try normal
847 SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
848 if (!stream->isValid()) {