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::peek(void* buffer, size_t size) const { 371 SkASSERT(buffer != NULL); 372 const size_t position = fOffset; 373 if (size > fData->size() - position) { 374 // The stream is not large enough to satisfy this request. 375 return false; 376 } 377 SkMemoryStream* nonConstThis = const_cast<SkMemoryStream*>(this); 378 SkDEBUGCODE(const size_t bytesRead =) nonConstThis->read(buffer, size); 379 SkASSERT(bytesRead == size); 380 nonConstThis->fOffset = position; 381 return true; 382 } 383 384 bool SkMemoryStream::isAtEnd() const { 385 return fOffset == fData->size(); 386 } 387 388 bool SkMemoryStream::rewind() { 389 fOffset = 0; 390 return true; 391 } 392 393 SkMemoryStream* SkMemoryStream::duplicate() const { 394 return SkNEW_ARGS(SkMemoryStream, (fData)); 395 } 396 397 size_t SkMemoryStream::getPosition() const { 398 return fOffset; 399 } 400 401 bool SkMemoryStream::seek(size_t position) { 402 fOffset = position > fData->size() 403 ? fData->size() 404 : position; 405 return true; 406 } 407 408 bool SkMemoryStream::move(long offset) { 409 return this->seek(fOffset + offset); 410 } 411 412 SkMemoryStream* SkMemoryStream::fork() const { 413 SkAutoTDelete<SkMemoryStream> that(this->duplicate()); 414 that->seek(fOffset); 415 return that.detach(); 416 } 417 418 size_t SkMemoryStream::getLength() const { 419 return fData->size(); 420 } 421 422 const void* SkMemoryStream::getMemoryBase() { 423 return fData->data(); 424 } 425 426 const void* SkMemoryStream::getAtPos() { 427 return fData->bytes() + fOffset; 428 } 429 430 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 431 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 432 433 SkFILEWStream::SkFILEWStream(const char path[]) 434 { 435 fFILE = sk_fopen(path, kWrite_SkFILE_Flag); 436 } 437 438 SkFILEWStream::~SkFILEWStream() 439 { 440 if (fFILE) { 441 sk_fclose(fFILE); 442 } 443 } 444 445 size_t SkFILEWStream::bytesWritten() const { 446 return sk_ftell(fFILE); 447 } 448 449 bool SkFILEWStream::write(const void* buffer, size_t size) 450 { 451 if (fFILE == NULL) { 452 return false; 453 } 454 455 if (sk_fwrite(buffer, size, fFILE) != size) 456 { 457 SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);) 458 sk_fclose(fFILE); 459 fFILE = NULL; 460 return false; 461 } 462 return true; 463 } 464 465 void SkFILEWStream::flush() 466 { 467 if (fFILE) { 468 sk_fflush(fFILE); 469 } 470 } 471 472 //////////////////////////////////////////////////////////////////////// 473 474 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size) 475 : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0) 476 { 477 } 478 479 bool SkMemoryWStream::write(const void* buffer, size_t size) { 480 size = SkTMin(size, fMaxLength - fBytesWritten); 481 if (size > 0) { 482 memcpy(fBuffer + fBytesWritten, buffer, size); 483 fBytesWritten += size; 484 return true; 485 } 486 return false; 487 } 488 489 //////////////////////////////////////////////////////////////////////// 490 491 #define SkDynamicMemoryWStream_MinBlockSize 256 492 493 struct SkDynamicMemoryWStream::Block { 494 Block* fNext; 495 char* fCurr; 496 char* fStop; 497 498 const char* start() const { return (const char*)(this + 1); } 499 char* start() { return (char*)(this + 1); } 500 size_t avail() const { return fStop - fCurr; } 501 size_t written() const { return fCurr - this->start(); } 502 503 void init(size_t size) 504 { 505 fNext = NULL; 506 fCurr = this->start(); 507 fStop = this->start() + size; 508 } 509 510 const void* append(const void* data, size_t size) 511 { 512 SkASSERT((size_t)(fStop - fCurr) >= size); 513 memcpy(fCurr, data, size); 514 fCurr += size; 515 return (const void*)((const char*)data + size); 516 } 517 }; 518 519 SkDynamicMemoryWStream::SkDynamicMemoryWStream() 520 : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL) 521 { 522 } 523 524 SkDynamicMemoryWStream::~SkDynamicMemoryWStream() 525 { 526 reset(); 527 } 528 529 void SkDynamicMemoryWStream::reset() 530 { 531 this->invalidateCopy(); 532 533 Block* block = fHead; 534 535 while (block != NULL) { 536 Block* next = block->fNext; 537 sk_free(block); 538 block = next; 539 } 540 fHead = fTail = NULL; 541 fBytesWritten = 0; 542 } 543 544 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count) 545 { 546 if (count > 0) { 547 this->invalidateCopy(); 548 549 fBytesWritten += count; 550 551 size_t size; 552 553 if (fTail != NULL && fTail->avail() > 0) { 554 size = SkTMin(fTail->avail(), count); 555 buffer = fTail->append(buffer, size); 556 SkASSERT(count >= size); 557 count -= size; 558 if (count == 0) 559 return true; 560 } 561 562 size = SkTMax<size_t>(count, SkDynamicMemoryWStream_MinBlockSize); 563 Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); 564 block->init(size); 565 block->append(buffer, count); 566 567 if (fTail != NULL) 568 fTail->fNext = block; 569 else 570 fHead = fTail = block; 571 fTail = block; 572 } 573 return true; 574 } 575 576 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count) 577 { 578 if (offset + count > fBytesWritten) { 579 return false; // test does not partially modify 580 } 581 582 this->invalidateCopy(); 583 584 Block* block = fHead; 585 while (block != NULL) { 586 size_t size = block->written(); 587 if (offset < size) { 588 size_t part = offset + count > size ? size - offset : count; 589 memcpy(block->start() + offset, buffer, part); 590 if (count <= part) 591 return true; 592 count -= part; 593 buffer = (const void*) ((char* ) buffer + part); 594 } 595 offset = offset > size ? offset - size : 0; 596 block = block->fNext; 597 } 598 return false; 599 } 600 601 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count) 602 { 603 if (offset + count > fBytesWritten) 604 return false; // test does not partially modify 605 Block* block = fHead; 606 while (block != NULL) { 607 size_t size = block->written(); 608 if (offset < size) { 609 size_t part = offset + count > size ? size - offset : count; 610 memcpy(buffer, block->start() + offset, part); 611 if (count <= part) 612 return true; 613 count -= part; 614 buffer = (void*) ((char* ) buffer + part); 615 } 616 offset = offset > size ? offset - size : 0; 617 block = block->fNext; 618 } 619 return false; 620 } 621 622 void SkDynamicMemoryWStream::copyTo(void* dst) const 623 { 624 if (fCopy) { 625 memcpy(dst, fCopy->data(), fBytesWritten); 626 } else { 627 Block* block = fHead; 628 629 while (block != NULL) { 630 size_t size = block->written(); 631 memcpy(dst, block->start(), size); 632 dst = (void*)((char*)dst + size); 633 block = block->fNext; 634 } 635 } 636 } 637 638 void SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const { 639 for (Block* block = fHead; block != NULL; block = block->fNext) { 640 dst->write(block->start(), block->written()); 641 } 642 } 643 644 void SkDynamicMemoryWStream::padToAlign4() 645 { 646 // cast to remove unary-minus warning 647 int padBytes = -(int)fBytesWritten & 0x03; 648 if (padBytes == 0) 649 return; 650 int zero = 0; 651 write(&zero, padBytes); 652 } 653 654 SkData* SkDynamicMemoryWStream::copyToData() const { 655 if (NULL == fCopy) { 656 SkData* data = SkData::NewUninitialized(fBytesWritten); 657 // be sure to call copyTo() before we assign to fCopy 658 this->copyTo(data->writable_data()); 659 fCopy = data; 660 } 661 return SkRef(fCopy); 662 } 663 664 void SkDynamicMemoryWStream::invalidateCopy() { 665 if (fCopy) { 666 fCopy->unref(); 667 fCopy = NULL; 668 } 669 } 670 671 class SkBlockMemoryRefCnt : public SkRefCnt { 672 public: 673 explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { } 674 675 virtual ~SkBlockMemoryRefCnt() { 676 SkDynamicMemoryWStream::Block* block = fHead; 677 while (block != NULL) { 678 SkDynamicMemoryWStream::Block* next = block->fNext; 679 sk_free(block); 680 block = next; 681 } 682 } 683 684 SkDynamicMemoryWStream::Block* const fHead; 685 }; 686 687 class SkBlockMemoryStream : public SkStreamAsset { 688 public: 689 SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size) 690 : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head) 691 , fSize(size) , fOffset(0), fCurrentOffset(0) { } 692 693 SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size) 694 : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead) 695 , fSize(size) , fOffset(0), fCurrentOffset(0) { } 696 697 size_t read(void* buffer, size_t rawCount) override { 698 size_t count = rawCount; 699 if (fOffset + count > fSize) { 700 count = fSize - fOffset; 701 } 702 size_t bytesLeftToRead = count; 703 while (fCurrent != NULL) { 704 size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset; 705 size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent); 706 if (buffer) { 707 memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent); 708 buffer = SkTAddOffset<void>(buffer, bytesFromCurrent); 709 } 710 if (bytesLeftToRead <= bytesFromCurrent) { 711 fCurrentOffset += bytesFromCurrent; 712 fOffset += count; 713 return count; 714 } 715 bytesLeftToRead -= bytesFromCurrent; 716 fCurrent = fCurrent->fNext; 717 fCurrentOffset = 0; 718 } 719 SkASSERT(false); 720 return 0; 721 } 722 723 bool isAtEnd() const override { 724 return fOffset == fSize; 725 } 726 727 bool rewind() override { 728 fCurrent = fBlockMemory->fHead; 729 fOffset = 0; 730 fCurrentOffset = 0; 731 return true; 732 } 733 734 SkBlockMemoryStream* duplicate() const override { 735 return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize)); 736 } 737 738 size_t getPosition() const override { 739 return fOffset; 740 } 741 742 bool seek(size_t position) override { 743 // If possible, skip forward. 744 if (position >= fOffset) { 745 size_t skipAmount = position - fOffset; 746 return this->skip(skipAmount) == skipAmount; 747 } 748 // If possible, move backward within the current block. 749 size_t moveBackAmount = fOffset - position; 750 if (moveBackAmount <= fCurrentOffset) { 751 fCurrentOffset -= moveBackAmount; 752 fOffset -= moveBackAmount; 753 return true; 754 } 755 // Otherwise rewind and move forward. 756 return this->rewind() && this->skip(position) == position; 757 } 758 759 bool move(long offset) override { 760 return seek(fOffset + offset); 761 } 762 763 SkBlockMemoryStream* fork() const override { 764 SkAutoTDelete<SkBlockMemoryStream> that(this->duplicate()); 765 that->fCurrent = this->fCurrent; 766 that->fOffset = this->fOffset; 767 that->fCurrentOffset = this->fCurrentOffset; 768 return that.detach(); 769 } 770 771 size_t getLength() const override { 772 return fSize; 773 } 774 775 const void* getMemoryBase() override { 776 if (NULL == fBlockMemory->fHead->fNext) { 777 return fBlockMemory->fHead->start(); 778 } 779 return NULL; 780 } 781 782 private: 783 SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory; 784 SkDynamicMemoryWStream::Block const * fCurrent; 785 size_t const fSize; 786 size_t fOffset; 787 size_t fCurrentOffset; 788 }; 789 790 SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() { 791 if (fCopy) { 792 SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy)); 793 this->reset(); 794 return stream; 795 } 796 SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten)); 797 fHead = 0; 798 this->reset(); 799 return stream; 800 } 801 802 /////////////////////////////////////////////////////////////////////////////// 803 804 void SkDebugWStream::newline() 805 { 806 #if defined(SK_DEBUG) || defined(SK_DEVELOPER) 807 SkDebugf("\n"); 808 fBytesWritten++; 809 #endif 810 } 811 812 bool SkDebugWStream::write(const void* buffer, size_t size) 813 { 814 #if defined(SK_DEBUG) || defined(SK_DEVELOPER) 815 char* s = new char[size+1]; 816 memcpy(s, buffer, size); 817 s[size] = 0; 818 SkDebugf("%s", s); 819 delete[] s; 820 fBytesWritten += size; 821 #endif 822 return true; 823 } 824 825 /////////////////////////////////////////////////////////////////////////////// 826 /////////////////////////////////////////////////////////////////////////////// 827 828 829 static SkData* mmap_filename(const char path[]) { 830 SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag); 831 if (NULL == file) { 832 return NULL; 833 } 834 835 SkData* data = SkData::NewFromFILE(file); 836 sk_fclose(file); 837 return data; 838 } 839 840 SkStreamAsset* SkStream::NewFromFile(const char path[]) { 841 SkAutoTUnref<SkData> data(mmap_filename(path)); 842 if (data.get()) { 843 return SkNEW_ARGS(SkMemoryStream, (data.get())); 844 } 845 846 // If we get here, then our attempt at using mmap failed, so try normal 847 // file access. 848 SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path)); 849 if (!stream->isValid()) { 850 SkDELETE(stream); 851 stream = NULL; 852 } 853 return stream; 854 } 855 856 // Declared in SkStreamPriv.h: 857 size_t SkCopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) { 858 SkASSERT(storage != NULL); 859 SkASSERT(stream != NULL); 860 861 if (stream->hasLength()) { 862 const size_t length = stream->getLength(); 863 void* dst = storage->reset(length); 864 if (stream->read(dst, length) != length) { 865 return 0; 866 } 867 return length; 868 } 869 870 SkDynamicMemoryWStream tempStream; 871 // Arbitrary buffer size. 872 const size_t bufferSize = 256 * 1024; // 256KB 873 char buffer[bufferSize]; 874 SkDEBUGCODE(size_t debugLength = 0;) 875 do { 876 size_t bytesRead = stream->read(buffer, bufferSize); 877 tempStream.write(buffer, bytesRead); 878 SkDEBUGCODE(debugLength += bytesRead); 879 SkASSERT(tempStream.bytesWritten() == debugLength); 880 } while (!stream->isAtEnd()); 881 const size_t length = tempStream.bytesWritten(); 882 void* dst = storage->reset(length); 883 tempStream.copyTo(dst); 884 return length; 885 } 886 887 // Declared in SkStreamPriv.h: 888 SkData* SkCopyStreamToData(SkStream* stream) { 889 SkASSERT(stream != NULL); 890 891 if (stream->hasLength()) { 892 return SkData::NewFromStream(stream, stream->getLength()); 893 } 894 895 SkDynamicMemoryWStream tempStream; 896 const size_t bufferSize = 4096; 897 char buffer[bufferSize]; 898 do { 899 size_t bytesRead = stream->read(buffer, bufferSize); 900 tempStream.write(buffer, bytesRead); 901 } while (!stream->isAtEnd()); 902 return tempStream.copyToData(); 903 } 904 905 SkStreamRewindable* SkStreamRewindableFromSkStream(SkStream* stream) { 906 if (!stream) { 907 return NULL; 908 } 909 SkAutoTDelete<SkStreamRewindable> dupStream(stream->duplicate()); 910 if (dupStream) { 911 return dupStream.detach(); 912 } 913 stream->rewind(); 914 if (stream->hasLength()) { 915 size_t length = stream->getLength(); 916 if (stream->hasPosition()) { // If stream has length, but can't rewind. 917 length -= stream->getPosition(); 918 } 919 SkAutoTUnref<SkData> data(SkData::NewFromStream(stream, length)); 920 return SkNEW_ARGS(SkMemoryStream, (data.get())); 921 } 922 SkDynamicMemoryWStream tempStream; 923 const size_t bufferSize = 4096; 924 char buffer[bufferSize]; 925 do { 926 size_t bytesRead = stream->read(buffer, bufferSize); 927 tempStream.write(buffer, bytesRead); 928 } while (!stream->isAtEnd()); 929 return tempStream.detachAsStream(); // returns a SkBlockMemoryStream, 930 // cheaper than copying to SkData 931 } 932