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 21int8_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 28int16_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 35int32_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 42SkScalar 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 53size_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 69SkWStream::~SkWStream() 70{ 71} 72 73void SkWStream::newline() 74{ 75 this->write("\n", 1); 76} 77 78void SkWStream::flush() 79{ 80} 81 82bool SkWStream::writeText(const char text[]) 83{ 84 SkASSERT(text); 85 return this->write(text, strlen(text)); 86} 87 88bool SkWStream::writeDecAsText(int32_t dec) 89{ 90 SkString tmp; 91 tmp.appendS32(dec); 92 return this->write(tmp.c_str(), tmp.size()); 93} 94 95bool 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 102bool 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 109bool SkWStream::writeScalarAsText(SkScalar value) 110{ 111 SkString tmp; 112 tmp.appendScalar(value); 113 return this->write(tmp.c_str(), tmp.size()); 114} 115 116bool SkWStream::write8(U8CPU value) { 117 uint8_t v = SkToU8(value); 118 return this->write(&v, 1); 119} 120 121bool SkWStream::write16(U16CPU value) { 122 uint16_t v = SkToU16(value); 123 return this->write(&v, 2); 124} 125 126bool SkWStream::write32(uint32_t value) { 127 return this->write(&value, 4); 128} 129 130bool SkWStream::writeScalar(SkScalar value) { 131 return this->write(&value, sizeof(value)); 132} 133 134int 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 143bool 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 163bool 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 183SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) { 184 fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL; 185} 186 187SkFILEStream::SkFILEStream(FILE* file, Ownership ownership) 188 : fFILE((SkFILE*)file) 189 , fOwnership(ownership) { 190} 191 192SkFILEStream::~SkFILEStream() { 193 if (fFILE && fOwnership != kCallerRetains_Ownership) { 194 sk_fclose(fFILE); 195 } 196} 197 198void 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 209size_t SkFILEStream::read(void* buffer, size_t size) { 210 if (fFILE) { 211 return sk_fread(buffer, size, fFILE); 212 } 213 return 0; 214} 215 216bool SkFILEStream::isAtEnd() const { 217 return sk_feof(fFILE); 218} 219 220bool 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 232SkStreamAsset* 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 255size_t SkFILEStream::getPosition() const { 256 return sk_ftell(fFILE); 257} 258 259bool SkFILEStream::seek(size_t position) { 260 return sk_fseek(fFILE, position); 261} 262 263bool SkFILEStream::move(long offset) { 264 return sk_fmove(fFILE, offset); 265} 266 267SkStreamAsset* SkFILEStream::fork() const { 268 SkAutoTUnref<SkStreamAsset> that(this->duplicate()); 269 that->seek(this->getPosition()); 270 return that.detach(); 271} 272 273size_t SkFILEStream::getLength() const { 274 return sk_fgetsize(fFILE); 275} 276 277const void* SkFILEStream::getMemoryBase() { 278 if (NULL == fData.get()) { 279 return NULL; 280 } 281 return fData->data(); 282} 283 284/////////////////////////////////////////////////////////////////////////////// 285 286static 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 294SkMemoryStream::SkMemoryStream() { 295 fData = SkData::NewEmpty(); 296 fOffset = 0; 297} 298 299SkMemoryStream::SkMemoryStream(size_t size) { 300 fData = SkData::NewUninitialized(size); 301 fOffset = 0; 302} 303 304SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) { 305 fData = newFromParams(src, size, copyData); 306 fOffset = 0; 307} 308 309SkMemoryStream::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 319SkMemoryStream::~SkMemoryStream() { 320 fData->unref(); 321} 322 323void SkMemoryStream::setMemoryOwned(const void* src, size_t size) { 324 fData->unref(); 325 fData = SkData::NewFromMalloc(src, size); 326 fOffset = 0; 327} 328 329void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) { 330 fData->unref(); 331 fData = newFromParams(src, size, copyData); 332 fOffset = 0; 333} 334 335SkData* SkMemoryStream::copyToData() const { 336 fData->ref(); 337 return fData; 338} 339 340SkData* 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 352void SkMemoryStream::skipToAlign4() { 353 // cast to remove unary-minus warning 354 fOffset += -(int)fOffset & 0x03; 355} 356 357size_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 370bool SkMemoryStream::isAtEnd() const { 371 return fOffset == fData->size(); 372} 373 374bool SkMemoryStream::rewind() { 375 fOffset = 0; 376 return true; 377} 378 379SkMemoryStream* SkMemoryStream::duplicate() const { 380 return SkNEW_ARGS(SkMemoryStream, (fData)); 381} 382 383size_t SkMemoryStream::getPosition() const { 384 return fOffset; 385} 386 387bool SkMemoryStream::seek(size_t position) { 388 fOffset = position > fData->size() 389 ? fData->size() 390 : position; 391 return true; 392} 393 394bool SkMemoryStream::move(long offset) { 395 return this->seek(fOffset + offset); 396} 397 398SkMemoryStream* SkMemoryStream::fork() const { 399 SkAutoTUnref<SkMemoryStream> that(this->duplicate()); 400 that->seek(fOffset); 401 return that.detach(); 402} 403 404size_t SkMemoryStream::getLength() const { 405 return fData->size(); 406} 407 408const void* SkMemoryStream::getMemoryBase() { 409 return fData->data(); 410} 411 412const void* SkMemoryStream::getAtPos() { 413 return fData->bytes() + fOffset; 414} 415 416///////////////////////////////////////////////////////////////////////////////////////////////////////// 417///////////////////////////////////////////////////////////////////////////////////////////////////////// 418 419SkFILEWStream::SkFILEWStream(const char path[]) 420{ 421 fFILE = sk_fopen(path, kWrite_SkFILE_Flag); 422} 423 424SkFILEWStream::~SkFILEWStream() 425{ 426 if (fFILE) { 427 sk_fclose(fFILE); 428 } 429} 430 431size_t SkFILEWStream::bytesWritten() const { 432 return sk_ftell(fFILE); 433} 434 435bool 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 451void SkFILEWStream::flush() 452{ 453 if (fFILE) { 454 sk_fflush(fFILE); 455 } 456} 457 458//////////////////////////////////////////////////////////////////////// 459 460SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size) 461 : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0) 462{ 463} 464 465bool 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 479struct 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 505SkDynamicMemoryWStream::SkDynamicMemoryWStream() 506 : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL) 507{ 508} 509 510SkDynamicMemoryWStream::~SkDynamicMemoryWStream() 511{ 512 reset(); 513} 514 515void 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 530bool 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 562bool 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 587bool 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 608void 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 624void 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 634SkData* 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 644void SkDynamicMemoryWStream::invalidateCopy() { 645 if (fCopy) { 646 fCopy->unref(); 647 fCopy = NULL; 648 } 649} 650 651class SkBlockMemoryRefCnt : public SkRefCnt { 652public: 653 explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { } 654 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 667class SkBlockMemoryStream : public SkStreamAsset { 668public: 669 SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size) 670 : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head) 671 , fSize(size) , fOffset(0), fCurrentOffset(0) { } 672 673 SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size) 674 : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead) 675 , fSize(size) , fOffset(0), fCurrentOffset(0) { } 676 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 703 virtual bool isAtEnd() const SK_OVERRIDE { 704 return fOffset == fSize; 705 } 706 707 virtual bool rewind() SK_OVERRIDE { 708 fCurrent = fBlockMemory->fHead; 709 fOffset = 0; 710 fCurrentOffset = 0; 711 return true; 712 } 713 714 virtual SkBlockMemoryStream* duplicate() const SK_OVERRIDE { 715 return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize)); 716 } 717 718 virtual size_t getPosition() const SK_OVERRIDE { 719 return fOffset; 720 } 721 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 739 virtual bool move(long offset) SK_OVERRIDE { 740 return seek(fOffset + offset); 741 } 742 743 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 751 virtual size_t getLength() const SK_OVERRIDE { 752 return fSize; 753 } 754 755 virtual const void* getMemoryBase() SK_OVERRIDE { 756 if (NULL == fBlockMemory->fHead->fNext) { 757 return fBlockMemory->fHead->start(); 758 } 759 return NULL; 760 } 761 762private: 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 770SkStreamAsset* 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 784void SkDebugWStream::newline() 785{ 786#if defined(SK_DEBUG) || defined(SK_DEVELOPER) 787 SkDebugf("\n"); 788 fBytesWritten++; 789#endif 790} 791 792bool 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 809static 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 820SkStreamAsset* 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: 837size_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: 868SkData* 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 885SkStreamRewindable* 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