65e1bee1a08f1f97dfccabcc1e8b0ce129b2b01c
[platform/upstream/libSkiaSharp.git] / src / core / SkStream.cpp
1
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9
10 #include "SkStream.h"
11 #include "SkStreamPriv.h"
12 #include "SkData.h"
13 #include "SkFixed.h"
14 #include "SkString.h"
15 #include "SkOSFile.h"
16 #include "SkTypes.h"
17
18 ///////////////////////////////////////////////////////////////////////////////
19
20
21 int8_t SkStream::readS8() {
22     int8_t value;
23     SkDEBUGCODE(size_t len =) this->read(&value, 1);
24     SkASSERT(1 == len);
25     return value;
26 }
27
28 int16_t SkStream::readS16() {
29     int16_t value;
30     SkDEBUGCODE(size_t len =) this->read(&value, 2);
31     SkASSERT(2 == len);
32     return value;
33 }
34
35 int32_t SkStream::readS32() {
36     int32_t value;
37     SkDEBUGCODE(size_t len =) this->read(&value, 4);
38     SkASSERT(4 == len);
39     return value;
40 }
41
42 SkScalar SkStream::readScalar() {
43     SkScalar value;
44     SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar));
45     SkASSERT(sizeof(SkScalar) == len);
46     return value;
47 }
48
49 #define SK_MAX_BYTE_FOR_U8          0xFD
50 #define SK_BYTE_SENTINEL_FOR_U16    0xFE
51 #define SK_BYTE_SENTINEL_FOR_U32    0xFF
52
53 size_t SkStream::readPackedUInt() {
54     uint8_t byte;
55     if (!this->read(&byte, 1)) {
56         return 0;
57     }
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();
62     } else {
63         return byte;
64     }
65 }
66
67 //////////////////////////////////////////////////////////////////////////////////////
68
69 SkWStream::~SkWStream()
70 {
71 }
72
73 void SkWStream::newline()
74 {
75     this->write("\n", 1);
76 }
77
78 void SkWStream::flush()
79 {
80 }
81
82 bool SkWStream::writeText(const char text[])
83 {
84     SkASSERT(text);
85     return this->write(text, strlen(text));
86 }
87
88 bool SkWStream::writeDecAsText(int32_t dec)
89 {
90     char buffer[SkStrAppendS32_MaxSize];
91     char* stop = SkStrAppendS32(buffer, dec);
92     return this->write(buffer, stop - buffer);
93 }
94
95 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
96 {
97     char buffer[SkStrAppendU64_MaxSize];
98     char* stop = SkStrAppendU64(buffer, dec, minDigits);
99     return this->write(buffer, stop - buffer);
100 }
101
102 bool SkWStream::writeHexAsText(uint32_t hex, int digits)
103 {
104     SkString    tmp;
105     tmp.appendHex(hex, digits);
106     return this->write(tmp.c_str(), tmp.size());
107 }
108
109 bool SkWStream::writeScalarAsText(SkScalar value)
110 {
111     char buffer[SkStrAppendScalar_MaxSize];
112     char* stop = SkStrAppendScalar(buffer, value);
113     return this->write(buffer, stop - buffer);
114 }
115
116 bool SkWStream::write8(U8CPU value) {
117     uint8_t v = SkToU8(value);
118     return this->write(&v, 1);
119 }
120
121 bool SkWStream::write16(U16CPU value) {
122     uint16_t v = SkToU16(value);
123     return this->write(&v, 2);
124 }
125
126 bool SkWStream::write32(uint32_t value) {
127     return this->write(&value, 4);
128 }
129
130 bool SkWStream::writeScalar(SkScalar value) {
131     return this->write(&value, sizeof(value));
132 }
133
134 int SkWStream::SizeOfPackedUInt(size_t value) {
135     if (value <= SK_MAX_BYTE_FOR_U8) {
136         return 1;
137     } else if (value <= 0xFFFF) {
138         return 3;
139     }
140     return 5;
141 }
142
143 bool SkWStream::writePackedUInt(size_t value) {
144     uint8_t data[5];
145     size_t len = 1;
146     if (value <= SK_MAX_BYTE_FOR_U8) {
147         data[0] = value;
148         len = 1;
149     } else if (value <= 0xFFFF) {
150         uint16_t value16 = value;
151         data[0] = SK_BYTE_SENTINEL_FOR_U16;
152         memcpy(&data[1], &value16, 2);
153         len = 3;
154     } else {
155         uint32_t value32 = SkToU32(value);
156         data[0] = SK_BYTE_SENTINEL_FOR_U32;
157         memcpy(&data[1], &value32, 4);
158         len = 5;
159     }
160     return this->write(data, len);
161 }
162
163 bool SkWStream::writeStream(SkStream* stream, size_t length) {
164     char scratch[1024];
165     const size_t MAX = sizeof(scratch);
166
167     while (length != 0) {
168         size_t n = length;
169         if (n > MAX) {
170             n = MAX;
171         }
172         stream->read(scratch, n);
173         if (!this->write(scratch, n)) {
174             return false;
175         }
176         length -= n;
177     }
178     return true;
179 }
180
181 ///////////////////////////////////////////////////////////////////////////////
182
183 SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) {
184     fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL;
185 }
186
187 SkFILEStream::SkFILEStream(FILE* file, Ownership ownership)
188     : fFILE((SkFILE*)file)
189     , fOwnership(ownership) {
190 }
191
192 SkFILEStream::~SkFILEStream() {
193     if (fFILE && fOwnership != kCallerRetains_Ownership) {
194         sk_fclose(fFILE);
195     }
196 }
197
198 void SkFILEStream::setPath(const char path[]) {
199     fName.set(path);
200     if (fFILE) {
201         sk_fclose(fFILE);
202         fFILE = NULL;
203     }
204     if (path) {
205         fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag);
206     }
207 }
208
209 size_t SkFILEStream::read(void* buffer, size_t size) {
210     if (fFILE) {
211         return sk_fread(buffer, size, fFILE);
212     }
213     return 0;
214 }
215
216 bool SkFILEStream::isAtEnd() const {
217     return sk_feof(fFILE);
218 }
219
220 bool SkFILEStream::rewind() {
221     if (fFILE) {
222         if (sk_frewind(fFILE)) {
223             return true;
224         }
225         // we hit an error
226         sk_fclose(fFILE);
227         fFILE = NULL;
228     }
229     return false;
230 }
231
232 SkStreamAsset* SkFILEStream::duplicate() const {
233     if (NULL == fFILE) {
234         return new SkMemoryStream();
235     }
236
237     if (fData.get()) {
238         return new SkMemoryStream(fData);
239     }
240
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();
245         }
246     }
247
248     fData.reset(SkData::NewFromFILE(fFILE));
249     if (NULL == fData.get()) {
250         return NULL;
251     }
252     return new SkMemoryStream(fData);
253 }
254
255 size_t SkFILEStream::getPosition() const {
256     return sk_ftell(fFILE);
257 }
258
259 bool SkFILEStream::seek(size_t position) {
260     return sk_fseek(fFILE, position);
261 }
262
263 bool SkFILEStream::move(long offset) {
264     return sk_fmove(fFILE, offset);
265 }
266
267 SkStreamAsset* SkFILEStream::fork() const {
268     SkAutoTDelete<SkStreamAsset> that(this->duplicate());
269     that->seek(this->getPosition());
270     return that.detach();
271 }
272
273 size_t SkFILEStream::getLength() const {
274     return sk_fgetsize(fFILE);
275 }
276
277 const void* SkFILEStream::getMemoryBase() {
278     if (NULL == fData.get()) {
279         return NULL;
280     }
281     return fData->data();
282 }
283
284 ///////////////////////////////////////////////////////////////////////////////
285
286 static SkData* newFromParams(const void* src, size_t size, bool copyData) {
287     if (copyData) {
288         return SkData::NewWithCopy(src, size);
289     } else {
290         return SkData::NewWithoutCopy(src, size);
291     }
292 }
293
294 SkMemoryStream::SkMemoryStream() {
295     fData = SkData::NewEmpty();
296     fOffset = 0;
297 }
298
299 SkMemoryStream::SkMemoryStream(size_t size) {
300     fData = SkData::NewUninitialized(size);
301     fOffset = 0;
302 }
303
304 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
305     fData = newFromParams(src, size, copyData);
306     fOffset = 0;
307 }
308
309 SkMemoryStream::SkMemoryStream(SkData* data) {
310     if (NULL == data) {
311         fData = SkData::NewEmpty();
312     } else {
313         fData = data;
314         fData->ref();
315     }
316     fOffset = 0;
317 }
318
319 SkMemoryStream::~SkMemoryStream() {
320     fData->unref();
321 }
322
323 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
324     fData->unref();
325     fData = SkData::NewFromMalloc(src, size);
326     fOffset = 0;
327 }
328
329 void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
330     fData->unref();
331     fData = newFromParams(src, size, copyData);
332     fOffset = 0;
333 }
334
335 SkData* SkMemoryStream::copyToData() const {
336     fData->ref();
337     return fData;
338 }
339
340 SkData* SkMemoryStream::setData(SkData* data) {
341     fData->unref();
342     if (NULL == data) {
343         fData = SkData::NewEmpty();
344     } else {
345         fData = data;
346         fData->ref();
347     }
348     fOffset = 0;
349     return data;
350 }
351
352 void SkMemoryStream::skipToAlign4() {
353     // cast to remove unary-minus warning
354     fOffset += -(int)fOffset & 0x03;
355 }
356
357 size_t SkMemoryStream::read(void* buffer, size_t size) {
358     size_t dataSize = fData->size();
359
360     if (size > dataSize - fOffset) {
361         size = dataSize - fOffset;
362     }
363     if (buffer) {
364         memcpy(buffer, fData->bytes() + fOffset, size);
365     }
366     fOffset += size;
367     return size;
368 }
369
370 bool SkMemoryStream::isAtEnd() const {
371     return fOffset == fData->size();
372 }
373
374 bool SkMemoryStream::rewind() {
375     fOffset = 0;
376     return true;
377 }
378
379 SkMemoryStream* SkMemoryStream::duplicate() const {
380     return SkNEW_ARGS(SkMemoryStream, (fData));
381 }
382
383 size_t SkMemoryStream::getPosition() const {
384     return fOffset;
385 }
386
387 bool SkMemoryStream::seek(size_t position) {
388     fOffset = position > fData->size()
389             ? fData->size()
390             : position;
391     return true;
392 }
393
394 bool SkMemoryStream::move(long offset) {
395     return this->seek(fOffset + offset);
396 }
397
398 SkMemoryStream* SkMemoryStream::fork() const {
399     SkAutoTDelete<SkMemoryStream> that(this->duplicate());
400     that->seek(fOffset);
401     return that.detach();
402 }
403
404 size_t SkMemoryStream::getLength() const {
405     return fData->size();
406 }
407
408 const void* SkMemoryStream::getMemoryBase() {
409     return fData->data();
410 }
411
412 const void* SkMemoryStream::getAtPos() {
413     return fData->bytes() + fOffset;
414 }
415
416 /////////////////////////////////////////////////////////////////////////////////////////////////////////
417 /////////////////////////////////////////////////////////////////////////////////////////////////////////
418
419 SkFILEWStream::SkFILEWStream(const char path[])
420 {
421     fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
422 }
423
424 SkFILEWStream::~SkFILEWStream()
425 {
426     if (fFILE) {
427         sk_fclose(fFILE);
428     }
429 }
430
431 size_t SkFILEWStream::bytesWritten() const {
432     return sk_ftell(fFILE);
433 }
434
435 bool SkFILEWStream::write(const void* buffer, size_t size)
436 {
437     if (fFILE == NULL) {
438         return false;
439     }
440
441     if (sk_fwrite(buffer, size, fFILE) != size)
442     {
443         SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
444         sk_fclose(fFILE);
445         fFILE = NULL;
446         return false;
447     }
448     return true;
449 }
450
451 void SkFILEWStream::flush()
452 {
453     if (fFILE) {
454         sk_fflush(fFILE);
455     }
456 }
457
458 ////////////////////////////////////////////////////////////////////////
459
460 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
461     : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
462 {
463 }
464
465 bool SkMemoryWStream::write(const void* buffer, size_t size) {
466     size = SkTMin(size, fMaxLength - fBytesWritten);
467     if (size > 0) {
468         memcpy(fBuffer + fBytesWritten, buffer, size);
469         fBytesWritten += size;
470         return true;
471     }
472     return false;
473 }
474
475 ////////////////////////////////////////////////////////////////////////
476
477 #define SkDynamicMemoryWStream_MinBlockSize   256
478
479 struct SkDynamicMemoryWStream::Block {
480     Block*  fNext;
481     char*   fCurr;
482     char*   fStop;
483
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(); }
488
489     void init(size_t size)
490     {
491         fNext = NULL;
492         fCurr = this->start();
493         fStop = this->start() + size;
494     }
495
496     const void* append(const void* data, size_t size)
497     {
498         SkASSERT((size_t)(fStop - fCurr) >= size);
499         memcpy(fCurr, data, size);
500         fCurr += size;
501         return (const void*)((const char*)data + size);
502     }
503 };
504
505 SkDynamicMemoryWStream::SkDynamicMemoryWStream()
506     : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
507 {
508 }
509
510 SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
511 {
512     reset();
513 }
514
515 void SkDynamicMemoryWStream::reset()
516 {
517     this->invalidateCopy();
518
519     Block*  block = fHead;
520
521     while (block != NULL) {
522         Block*  next = block->fNext;
523         sk_free(block);
524         block = next;
525     }
526     fHead = fTail = NULL;
527     fBytesWritten = 0;
528 }
529
530 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count)
531 {
532     if (count > 0) {
533         this->invalidateCopy();
534
535         fBytesWritten += count;
536
537         size_t  size;
538
539         if (fTail != NULL && fTail->avail() > 0) {
540             size = SkTMin(fTail->avail(), count);
541             buffer = fTail->append(buffer, size);
542             SkASSERT(count >= size);
543             count -= size;
544             if (count == 0)
545                 return true;
546         }
547
548         size = SkTMax<size_t>(count, SkDynamicMemoryWStream_MinBlockSize);
549         Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
550         block->init(size);
551         block->append(buffer, count);
552
553         if (fTail != NULL)
554             fTail->fNext = block;
555         else
556             fHead = fTail = block;
557         fTail = block;
558     }
559     return true;
560 }
561
562 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count)
563 {
564     if (offset + count > fBytesWritten) {
565         return false; // test does not partially modify
566     }
567
568     this->invalidateCopy();
569
570     Block* block = fHead;
571     while (block != NULL) {
572         size_t size = block->written();
573         if (offset < size) {
574             size_t part = offset + count > size ? size - offset : count;
575             memcpy(block->start() + offset, buffer, part);
576             if (count <= part)
577                 return true;
578             count -= part;
579             buffer = (const void*) ((char* ) buffer + part);
580         }
581         offset = offset > size ? offset - size : 0;
582         block = block->fNext;
583     }
584     return false;
585 }
586
587 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count)
588 {
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();
594         if (offset < size) {
595             size_t part = offset + count > size ? size - offset : count;
596             memcpy(buffer, block->start() + offset, part);
597             if (count <= part)
598                 return true;
599             count -= part;
600             buffer = (void*) ((char* ) buffer + part);
601         }
602         offset = offset > size ? offset - size : 0;
603         block = block->fNext;
604     }
605     return false;
606 }
607
608 void SkDynamicMemoryWStream::copyTo(void* dst) const
609 {
610     if (fCopy) {
611         memcpy(dst, fCopy->data(), fBytesWritten);
612     } else {
613         Block* block = fHead;
614
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;
620         }
621     }
622 }
623
624 void SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const {
625     for (Block* block = fHead; block != NULL; block = block->fNext) {
626         dst->write(block->start(), block->written());
627     }
628 }
629
630 void SkDynamicMemoryWStream::padToAlign4()
631 {
632     // cast to remove unary-minus warning
633     int padBytes = -(int)fBytesWritten & 0x03;
634     if (padBytes == 0)
635         return;
636     int zero = 0;
637     write(&zero, padBytes);
638 }
639
640 SkData* SkDynamicMemoryWStream::copyToData() const {
641     if (NULL == fCopy) {
642         SkData* data = SkData::NewUninitialized(fBytesWritten);
643         // be sure to call copyTo() before we assign to fCopy
644         this->copyTo(data->writable_data());
645         fCopy = data;
646     }
647     return SkRef(fCopy);
648 }
649
650 void SkDynamicMemoryWStream::invalidateCopy() {
651     if (fCopy) {
652         fCopy->unref();
653         fCopy = NULL;
654     }
655 }
656
657 class SkBlockMemoryRefCnt : public SkRefCnt {
658 public:
659     explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
660
661     virtual ~SkBlockMemoryRefCnt() {
662         SkDynamicMemoryWStream::Block* block = fHead;
663         while (block != NULL) {
664             SkDynamicMemoryWStream::Block* next = block->fNext;
665             sk_free(block);
666             block = next;
667         }
668     }
669
670     SkDynamicMemoryWStream::Block* const fHead;
671 };
672
673 class SkBlockMemoryStream : public SkStreamAsset {
674 public:
675     SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
676         : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head)
677         , fSize(size) , fOffset(0), fCurrentOffset(0) { }
678
679     SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
680         : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead)
681         , fSize(size) , fOffset(0), fCurrentOffset(0) { }
682
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;
687         }
688         size_t bytesLeftToRead = count;
689         while (fCurrent != NULL) {
690             size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
691             size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
692             if (buffer) {
693                 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
694                 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
695             }
696             if (bytesLeftToRead <= bytesFromCurrent) {
697                 fCurrentOffset += bytesFromCurrent;
698                 fOffset += count;
699                 return count;
700             }
701             bytesLeftToRead -= bytesFromCurrent;
702             fCurrent = fCurrent->fNext;
703             fCurrentOffset = 0;
704         }
705         SkASSERT(false);
706         return 0;
707     }
708
709     bool isAtEnd() const SK_OVERRIDE {
710         return fOffset == fSize;
711     }
712
713     bool rewind() SK_OVERRIDE {
714         fCurrent = fBlockMemory->fHead;
715         fOffset = 0;
716         fCurrentOffset = 0;
717         return true;
718     }
719
720     SkBlockMemoryStream* duplicate() const SK_OVERRIDE {
721         return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize));
722     }
723
724     size_t getPosition() const SK_OVERRIDE {
725         return fOffset;
726     }
727
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;
733         }
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;
739             return true;
740         }
741         // Otherwise rewind and move forward.
742         return this->rewind() && this->skip(position) == position;
743     }
744
745     bool move(long offset) SK_OVERRIDE {
746         return seek(fOffset + offset);
747     }
748
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();
755     }
756
757     size_t getLength() const SK_OVERRIDE {
758         return fSize;
759     }
760
761     const void* getMemoryBase() SK_OVERRIDE {
762         if (NULL == fBlockMemory->fHead->fNext) {
763             return fBlockMemory->fHead->start();
764         }
765         return NULL;
766     }
767
768 private:
769     SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory;
770     SkDynamicMemoryWStream::Block const * fCurrent;
771     size_t const fSize;
772     size_t fOffset;
773     size_t fCurrentOffset;
774 };
775
776 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() {
777     if (fCopy) {
778         SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy));
779         this->reset();
780         return stream;
781     }
782     SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten));
783     fHead = 0;
784     this->reset();
785     return stream;
786 }
787
788 ///////////////////////////////////////////////////////////////////////////////
789
790 void SkDebugWStream::newline()
791 {
792 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
793     SkDebugf("\n");
794     fBytesWritten++;
795 #endif
796 }
797
798 bool SkDebugWStream::write(const void* buffer, size_t size)
799 {
800 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
801     char* s = new char[size+1];
802     memcpy(s, buffer, size);
803     s[size] = 0;
804     SkDebugf("%s", s);
805     delete[] s;
806     fBytesWritten += size;
807 #endif
808     return true;
809 }
810
811 ///////////////////////////////////////////////////////////////////////////////
812 ///////////////////////////////////////////////////////////////////////////////
813
814
815 static SkData* mmap_filename(const char path[]) {
816     SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
817     if (NULL == file) {
818         return NULL;
819     }
820
821     SkData* data = SkData::NewFromFILE(file);
822     sk_fclose(file);
823     return data;
824 }
825
826 SkStreamAsset* SkStream::NewFromFile(const char path[]) {
827     SkAutoTUnref<SkData> data(mmap_filename(path));
828     if (data.get()) {
829         return SkNEW_ARGS(SkMemoryStream, (data.get()));
830     }
831
832     // If we get here, then our attempt at using mmap failed, so try normal
833     // file access.
834     SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
835     if (!stream->isValid()) {
836         SkDELETE(stream);
837         stream = NULL;
838     }
839     return stream;
840 }
841
842 // Declared in SkStreamPriv.h:
843 size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
844     SkASSERT(storage != NULL);
845     SkASSERT(stream != NULL);
846
847     if (stream->hasLength()) {
848         const size_t length = stream->getLength();
849         void* dst = storage->reset(length);
850         if (stream->read(dst, length) != length) {
851             return 0;
852         }
853         return length;
854     }
855
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;)
861     do {
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);
870     return length;
871 }
872
873 // Declared in SkStreamPriv.h:
874 SkData* SkCopyStreamToData(SkStream* stream) {
875     SkASSERT(stream != NULL);
876
877     if (stream->hasLength()) {
878         return SkData::NewFromStream(stream, stream->getLength());
879     }
880
881     SkDynamicMemoryWStream tempStream;
882     const size_t bufferSize = 4096;
883     char buffer[bufferSize];
884     do {
885         size_t bytesRead = stream->read(buffer, bufferSize);
886         tempStream.write(buffer, bytesRead);
887     } while (!stream->isAtEnd());
888     return tempStream.copyToData();
889 }
890
891 SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) {
892     if (!stream) {
893         return NULL;
894     }
895     SkAutoTDelete<SkStreamRewindable> dupStream(stream->duplicate());
896     if (dupStream) {
897         return dupStream.detach();
898     }
899     stream->rewind();
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();
904         }
905         SkAutoTUnref<SkData> data(SkData::NewFromStream(stream, length));
906         return SkNEW_ARGS(SkMemoryStream, (data.get()));
907     }
908     SkDynamicMemoryWStream tempStream;
909     const size_t bufferSize = 4096;
910     char buffer[bufferSize];
911     do {
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
917 }