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 SkString tmp; 91 tmp.appendS32(dec); 92 return this->write(tmp.c_str(), tmp.size()); 93 } 94 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 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 SkString tmp; 112 tmp.appendScalar(value); 113 return this->write(tmp.c_str(), tmp.size()); 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 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 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 SkAutoTUnref<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 SkAutoTUnref<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::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 634 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 644 void SkDynamicMemoryWStream::invalidateCopy() { 645 if (fCopy) { 646 fCopy->unref(); 647 fCopy = NULL; 648 } 649 } 650 651 class SkBlockMemoryRefCnt : public SkRefCnt { 652 public: 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 667 class SkBlockMemoryStream : public SkStreamAsset { 668 public: 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 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 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 784 void SkDebugWStream::newline() 785 { 786 #if defined(SK_DEBUG) || defined(SK_DEVELOPER) 787 SkDebugf("\n"); 788 fBytesWritten++; 789 #endif 790 } 791 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 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 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: 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: 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 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