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
readS8()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
readS16()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
readS32()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
readScalar()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
readPackedUInt()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
~SkWStream()69 SkWStream::~SkWStream()
70 {
71 }
72
newline()73 void SkWStream::newline()
74 {
75 this->write("\n", 1);
76 }
77
flush()78 void SkWStream::flush()
79 {
80 }
81
writeText(const char text[])82 bool SkWStream::writeText(const char text[])
83 {
84 SkASSERT(text);
85 return this->write(text, strlen(text));
86 }
87
writeDecAsText(int32_t dec)88 bool SkWStream::writeDecAsText(int32_t dec)
89 {
90 SkString tmp;
91 tmp.appendS32(dec);
92 return this->write(tmp.c_str(), tmp.size());
93 }
94
writeBigDecAsText(int64_t dec,int minDigits)95 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
96 {
97 SkString tmp;
98 tmp.appendS64(dec, minDigits);
99 return this->write(tmp.c_str(), tmp.size());
100 }
101
writeHexAsText(uint32_t hex,int digits)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
writeScalarAsText(SkScalar value)109 bool SkWStream::writeScalarAsText(SkScalar value)
110 {
111 SkString tmp;
112 tmp.appendScalar(value);
113 return this->write(tmp.c_str(), tmp.size());
114 }
115
write8(U8CPU value)116 bool SkWStream::write8(U8CPU value) {
117 uint8_t v = SkToU8(value);
118 return this->write(&v, 1);
119 }
120
write16(U16CPU value)121 bool SkWStream::write16(U16CPU value) {
122 uint16_t v = SkToU16(value);
123 return this->write(&v, 2);
124 }
125
write32(uint32_t value)126 bool SkWStream::write32(uint32_t value) {
127 return this->write(&value, 4);
128 }
129
writeScalar(SkScalar value)130 bool SkWStream::writeScalar(SkScalar value) {
131 return this->write(&value, sizeof(value));
132 }
133
SizeOfPackedUInt(size_t value)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
writePackedUInt(size_t value)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
writeStream(SkStream * stream,size_t length)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
SkFILEStream(const char file[])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
SkFILEStream(FILE * file,Ownership ownership)187 SkFILEStream::SkFILEStream(FILE* file, Ownership ownership)
188 : fFILE((SkFILE*)file)
189 , fOwnership(ownership) {
190 }
191
~SkFILEStream()192 SkFILEStream::~SkFILEStream() {
193 if (fFILE && fOwnership != kCallerRetains_Ownership) {
194 sk_fclose(fFILE);
195 }
196 }
197
setPath(const char path[])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
read(void * buffer,size_t size)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
isAtEnd() const216 bool SkFILEStream::isAtEnd() const {
217 return sk_feof(fFILE);
218 }
219
rewind()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
duplicate() const232 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 SkAutoTUnref<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
getPosition() const255 size_t SkFILEStream::getPosition() const {
256 return sk_ftell(fFILE);
257 }
258
seek(size_t position)259 bool SkFILEStream::seek(size_t position) {
260 return sk_fseek(fFILE, position);
261 }
262
move(long offset)263 bool SkFILEStream::move(long offset) {
264 return sk_fmove(fFILE, offset);
265 }
266
fork() const267 SkStreamAsset* SkFILEStream::fork() const {
268 SkAutoTUnref<SkStreamAsset> that(this->duplicate());
269 that->seek(this->getPosition());
270 return that.detach();
271 }
272
getLength() const273 size_t SkFILEStream::getLength() const {
274 return sk_fgetsize(fFILE);
275 }
276
getMemoryBase()277 const void* SkFILEStream::getMemoryBase() {
278 if (NULL == fData.get()) {
279 return NULL;
280 }
281 return fData->data();
282 }
283
284 ///////////////////////////////////////////////////////////////////////////////
285
newFromParams(const void * src,size_t size,bool copyData)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
SkMemoryStream()294 SkMemoryStream::SkMemoryStream() {
295 fData = SkData::NewEmpty();
296 fOffset = 0;
297 }
298
SkMemoryStream(size_t size)299 SkMemoryStream::SkMemoryStream(size_t size) {
300 fData = SkData::NewUninitialized(size);
301 fOffset = 0;
302 }
303
SkMemoryStream(const void * src,size_t size,bool copyData)304 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
305 fData = newFromParams(src, size, copyData);
306 fOffset = 0;
307 }
308
SkMemoryStream(SkData * data)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
~SkMemoryStream()319 SkMemoryStream::~SkMemoryStream() {
320 fData->unref();
321 }
322
setMemoryOwned(const void * src,size_t size)323 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
324 fData->unref();
325 fData = SkData::NewFromMalloc(src, size);
326 fOffset = 0;
327 }
328
setMemory(const void * src,size_t size,bool copyData)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
copyToData() const335 SkData* SkMemoryStream::copyToData() const {
336 fData->ref();
337 return fData;
338 }
339
setData(SkData * data)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
skipToAlign4()352 void SkMemoryStream::skipToAlign4() {
353 // cast to remove unary-minus warning
354 fOffset += -(int)fOffset & 0x03;
355 }
356
read(void * buffer,size_t size)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
isAtEnd() const370 bool SkMemoryStream::isAtEnd() const {
371 return fOffset == fData->size();
372 }
373
rewind()374 bool SkMemoryStream::rewind() {
375 fOffset = 0;
376 return true;
377 }
378
duplicate() const379 SkMemoryStream* SkMemoryStream::duplicate() const {
380 return SkNEW_ARGS(SkMemoryStream, (fData));
381 }
382
getPosition() const383 size_t SkMemoryStream::getPosition() const {
384 return fOffset;
385 }
386
seek(size_t position)387 bool SkMemoryStream::seek(size_t position) {
388 fOffset = position > fData->size()
389 ? fData->size()
390 : position;
391 return true;
392 }
393
move(long offset)394 bool SkMemoryStream::move(long offset) {
395 return this->seek(fOffset + offset);
396 }
397
fork() const398 SkMemoryStream* SkMemoryStream::fork() const {
399 SkAutoTUnref<SkMemoryStream> that(this->duplicate());
400 that->seek(fOffset);
401 return that.detach();
402 }
403
getLength() const404 size_t SkMemoryStream::getLength() const {
405 return fData->size();
406 }
407
getMemoryBase()408 const void* SkMemoryStream::getMemoryBase() {
409 return fData->data();
410 }
411
getAtPos()412 const void* SkMemoryStream::getAtPos() {
413 return fData->bytes() + fOffset;
414 }
415
416 /////////////////////////////////////////////////////////////////////////////////////////////////////////
417 /////////////////////////////////////////////////////////////////////////////////////////////////////////
418
SkFILEWStream(const char path[])419 SkFILEWStream::SkFILEWStream(const char path[])
420 {
421 fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
422 }
423
~SkFILEWStream()424 SkFILEWStream::~SkFILEWStream()
425 {
426 if (fFILE) {
427 sk_fclose(fFILE);
428 }
429 }
430
bytesWritten() const431 size_t SkFILEWStream::bytesWritten() const {
432 return sk_ftell(fFILE);
433 }
434
write(const void * buffer,size_t size)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
flush()451 void SkFILEWStream::flush()
452 {
453 if (fFILE) {
454 sk_fflush(fFILE);
455 }
456 }
457
458 ////////////////////////////////////////////////////////////////////////
459
SkMemoryWStream(void * buffer,size_t size)460 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size)
461 : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0)
462 {
463 }
464
write(const void * buffer,size_t size)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
startSkDynamicMemoryWStream::Block484 const char* start() const { return (const char*)(this + 1); }
startSkDynamicMemoryWStream::Block485 char* start() { return (char*)(this + 1); }
availSkDynamicMemoryWStream::Block486 size_t avail() const { return fStop - fCurr; }
writtenSkDynamicMemoryWStream::Block487 size_t written() const { return fCurr - this->start(); }
488
initSkDynamicMemoryWStream::Block489 void init(size_t size)
490 {
491 fNext = NULL;
492 fCurr = this->start();
493 fStop = this->start() + size;
494 }
495
appendSkDynamicMemoryWStream::Block496 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
SkDynamicMemoryWStream()505 SkDynamicMemoryWStream::SkDynamicMemoryWStream()
506 : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL)
507 {
508 }
509
~SkDynamicMemoryWStream()510 SkDynamicMemoryWStream::~SkDynamicMemoryWStream()
511 {
512 reset();
513 }
514
reset()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
write(const void * buffer,size_t count)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
write(const void * buffer,size_t offset,size_t count)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
read(void * buffer,size_t offset,size_t count)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
copyTo(void * dst) const608 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
padToAlign4()624 void SkDynamicMemoryWStream::padToAlign4()
625 {
626 // cast to remove unary-minus warning
627 int padBytes = -(int)fBytesWritten & 0x03;
628 if (padBytes == 0)
629 return;
630 int zero = 0;
631 write(&zero, padBytes);
632 }
633
copyToData() const634 SkData* SkDynamicMemoryWStream::copyToData() const {
635 if (NULL == fCopy) {
636 SkData* data = SkData::NewUninitialized(fBytesWritten);
637 // be sure to call copyTo() before we assign to fCopy
638 this->copyTo(data->writable_data());
639 fCopy = data;
640 }
641 return SkRef(fCopy);
642 }
643
invalidateCopy()644 void SkDynamicMemoryWStream::invalidateCopy() {
645 if (fCopy) {
646 fCopy->unref();
647 fCopy = NULL;
648 }
649 }
650
651 class SkBlockMemoryRefCnt : public SkRefCnt {
652 public:
SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block * head)653 explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
654
~SkBlockMemoryRefCnt()655 virtual ~SkBlockMemoryRefCnt() {
656 SkDynamicMemoryWStream::Block* block = fHead;
657 while (block != NULL) {
658 SkDynamicMemoryWStream::Block* next = block->fNext;
659 sk_free(block);
660 block = next;
661 }
662 }
663
664 SkDynamicMemoryWStream::Block* const fHead;
665 };
666
667 class SkBlockMemoryStream : public SkStreamAsset {
668 public:
SkBlockMemoryStream(SkDynamicMemoryWStream::Block * head,size_t size)669 SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
670 : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head)
671 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
672
SkBlockMemoryStream(SkBlockMemoryRefCnt * headRef,size_t size)673 SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
674 : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead)
675 , fSize(size) , fOffset(0), fCurrentOffset(0) { }
676
read(void * buffer,size_t rawCount)677 virtual size_t read(void* buffer, size_t rawCount) SK_OVERRIDE {
678 size_t count = rawCount;
679 if (fOffset + count > fSize) {
680 count = fSize - fOffset;
681 }
682 size_t bytesLeftToRead = count;
683 while (fCurrent != NULL) {
684 size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
685 size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent);
686 if (buffer) {
687 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
688 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
689 }
690 if (bytesLeftToRead <= bytesFromCurrent) {
691 fCurrentOffset += bytesFromCurrent;
692 fOffset += count;
693 return count;
694 }
695 bytesLeftToRead -= bytesFromCurrent;
696 fCurrent = fCurrent->fNext;
697 fCurrentOffset = 0;
698 }
699 SkASSERT(false);
700 return 0;
701 }
702
isAtEnd() const703 virtual bool isAtEnd() const SK_OVERRIDE {
704 return fOffset == fSize;
705 }
706
rewind()707 virtual bool rewind() SK_OVERRIDE {
708 fCurrent = fBlockMemory->fHead;
709 fOffset = 0;
710 fCurrentOffset = 0;
711 return true;
712 }
713
duplicate() const714 virtual SkBlockMemoryStream* duplicate() const SK_OVERRIDE {
715 return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize));
716 }
717
getPosition() const718 virtual size_t getPosition() const SK_OVERRIDE {
719 return fOffset;
720 }
721
seek(size_t position)722 virtual bool seek(size_t position) SK_OVERRIDE {
723 // If possible, skip forward.
724 if (position >= fOffset) {
725 size_t skipAmount = position - fOffset;
726 return this->skip(skipAmount) == skipAmount;
727 }
728 // If possible, move backward within the current block.
729 size_t moveBackAmount = fOffset - position;
730 if (moveBackAmount <= fCurrentOffset) {
731 fCurrentOffset -= moveBackAmount;
732 fOffset -= moveBackAmount;
733 return true;
734 }
735 // Otherwise rewind and move forward.
736 return this->rewind() && this->skip(position) == position;
737 }
738
move(long offset)739 virtual bool move(long offset) SK_OVERRIDE {
740 return seek(fOffset + offset);
741 }
742
fork() const743 virtual SkBlockMemoryStream* fork() const SK_OVERRIDE {
744 SkAutoTUnref<SkBlockMemoryStream> that(this->duplicate());
745 that->fCurrent = this->fCurrent;
746 that->fOffset = this->fOffset;
747 that->fCurrentOffset = this->fCurrentOffset;
748 return that.detach();
749 }
750
getLength() const751 virtual size_t getLength() const SK_OVERRIDE {
752 return fSize;
753 }
754
getMemoryBase()755 virtual const void* getMemoryBase() SK_OVERRIDE {
756 if (NULL == fBlockMemory->fHead->fNext) {
757 return fBlockMemory->fHead->start();
758 }
759 return NULL;
760 }
761
762 private:
763 SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory;
764 SkDynamicMemoryWStream::Block const * fCurrent;
765 size_t const fSize;
766 size_t fOffset;
767 size_t fCurrentOffset;
768 };
769
detachAsStream()770 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() {
771 if (fCopy) {
772 SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy));
773 this->reset();
774 return stream;
775 }
776 SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten));
777 fHead = 0;
778 this->reset();
779 return stream;
780 }
781
782 ///////////////////////////////////////////////////////////////////////////////
783
newline()784 void SkDebugWStream::newline()
785 {
786 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
787 SkDebugf("\n");
788 fBytesWritten++;
789 #endif
790 }
791
write(const void * buffer,size_t size)792 bool SkDebugWStream::write(const void* buffer, size_t size)
793 {
794 #if defined(SK_DEBUG) || defined(SK_DEVELOPER)
795 char* s = new char[size+1];
796 memcpy(s, buffer, size);
797 s[size] = 0;
798 SkDebugf("%s", s);
799 delete[] s;
800 fBytesWritten += size;
801 #endif
802 return true;
803 }
804
805 ///////////////////////////////////////////////////////////////////////////////
806 ///////////////////////////////////////////////////////////////////////////////
807
808
mmap_filename(const char path[])809 static SkData* mmap_filename(const char path[]) {
810 SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag);
811 if (NULL == file) {
812 return NULL;
813 }
814
815 SkData* data = SkData::NewFromFILE(file);
816 sk_fclose(file);
817 return data;
818 }
819
NewFromFile(const char path[])820 SkStreamAsset* SkStream::NewFromFile(const char path[]) {
821 SkAutoTUnref<SkData> data(mmap_filename(path));
822 if (data.get()) {
823 return SkNEW_ARGS(SkMemoryStream, (data.get()));
824 }
825
826 // If we get here, then our attempt at using mmap failed, so try normal
827 // file access.
828 SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
829 if (!stream->isValid()) {
830 stream->unref();
831 stream = NULL;
832 }
833 return stream;
834 }
835
836 // Declared in SkStreamPriv.h:
SkCopyStreamToStorage(SkAutoMalloc * storage,SkStream * stream)837 size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
838 SkASSERT(storage != NULL);
839 SkASSERT(stream != NULL);
840
841 if (stream->hasLength()) {
842 const size_t length = stream->getLength();
843 void* dst = storage->reset(length);
844 if (stream->read(dst, length) != length) {
845 return 0;
846 }
847 return length;
848 }
849
850 SkDynamicMemoryWStream tempStream;
851 // Arbitrary buffer size.
852 const size_t bufferSize = 256 * 1024; // 256KB
853 char buffer[bufferSize];
854 SkDEBUGCODE(size_t debugLength = 0;)
855 do {
856 size_t bytesRead = stream->read(buffer, bufferSize);
857 tempStream.write(buffer, bytesRead);
858 SkDEBUGCODE(debugLength += bytesRead);
859 SkASSERT(tempStream.bytesWritten() == debugLength);
860 } while (!stream->isAtEnd());
861 const size_t length = tempStream.bytesWritten();
862 void* dst = storage->reset(length);
863 tempStream.copyTo(dst);
864 return length;
865 }
866
867 // Declared in SkStreamPriv.h:
SkCopyStreamToData(SkStream * stream)868 SkData* SkCopyStreamToData(SkStream* stream) {
869 SkASSERT(stream != NULL);
870
871 if (stream->hasLength()) {
872 return SkData::NewFromStream(stream, stream->getLength());
873 }
874
875 SkDynamicMemoryWStream tempStream;
876 const size_t bufferSize = 4096;
877 char buffer[bufferSize];
878 do {
879 size_t bytesRead = stream->read(buffer, bufferSize);
880 tempStream.write(buffer, bytesRead);
881 } while (!stream->isAtEnd());
882 return tempStream.copyToData();
883 }
884
SkStreamRewindableFromSkStream(SkStream * stream)885 SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) {
886 if (!stream) {
887 return NULL;
888 }
889 SkAutoTUnref<SkStreamRewindable> dupStream(stream->duplicate());
890 if (dupStream) {
891 return dupStream.detach();
892 }
893 stream->rewind();
894 if (stream->hasLength()) {
895 size_t length = stream->getLength();
896 if (stream->hasPosition()) { // If stream has length, but can't rewind.
897 length -= stream->getPosition();
898 }
899 SkAutoTUnref<SkData> data(SkData::NewFromStream(stream, length));
900 return SkNEW_ARGS(SkMemoryStream, (data.get()));
901 }
902 SkDynamicMemoryWStream tempStream;
903 const size_t bufferSize = 4096;
904 char buffer[bufferSize];
905 do {
906 size_t bytesRead = stream->read(buffer, bufferSize);
907 tempStream.write(buffer, bytesRead);
908 } while (!stream->isAtEnd());
909 return tempStream.detachAsStream(); // returns a SkBlockMemoryStream,
910 // cheaper than copying to SkData
911 }
912