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 "SkData.h" 12 #include "SkFixed.h" 13 #include "SkString.h" 14 #include "SkOSFile.h" 15 16 SK_DEFINE_INST_COUNT(SkStream) 17 SK_DEFINE_INST_COUNT(SkWStream) 18 SK_DEFINE_INST_COUNT(SkFILEStream) 19 SK_DEFINE_INST_COUNT(SkFDStream) 20 SK_DEFINE_INST_COUNT(SkMemoryStream) 21 SK_DEFINE_INST_COUNT(SkBufferStream) 22 SK_DEFINE_INST_COUNT(SkFILEWStream) 23 SK_DEFINE_INST_COUNT(SkMemoryWStream) 24 SK_DEFINE_INST_COUNT(SkDynamicMemoryWStream) 25 SK_DEFINE_INST_COUNT(SkDebugWStream) 26 27 /////////////////////////////////////////////////////////////////////////////// 28 29 const char* SkStream::getFileName() 30 { 31 // override in subclass if you represent a file 32 return NULL; 33 } 34 35 const void* SkStream::getMemoryBase() 36 { 37 // override in subclass if you represent a memory block 38 return NULL; 39 } 40 41 size_t SkStream::skip(size_t size) 42 { 43 /* Check for size == 0, and just return 0. If we passed that 44 to read(), it would interpret it as a request for the entire 45 size of the stream. 46 */ 47 return size ? this->read(NULL, size) : 0; 48 } 49 50 int8_t SkStream::readS8() { 51 int8_t value; 52 SkDEBUGCODE(size_t len =) this->read(&value, 1); 53 SkASSERT(1 == len); 54 return value; 55 } 56 57 int16_t SkStream::readS16() { 58 int16_t value; 59 SkDEBUGCODE(size_t len =) this->read(&value, 2); 60 SkASSERT(2 == len); 61 return value; 62 } 63 64 int32_t SkStream::readS32() { 65 int32_t value; 66 SkDEBUGCODE(size_t len =) this->read(&value, 4); 67 SkASSERT(4 == len); 68 return value; 69 } 70 71 SkScalar SkStream::readScalar() { 72 SkScalar value; 73 SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar)); 74 SkASSERT(sizeof(SkScalar) == len); 75 return value; 76 } 77 78 #define SK_MAX_BYTE_FOR_U8 0xFD 79 #define SK_BYTE_SENTINEL_FOR_U16 0xFE 80 #define SK_BYTE_SENTINEL_FOR_U32 0xFF 81 82 size_t SkStream::readPackedUInt() { 83 uint8_t byte; 84 if (!this->read(&byte, 1)) { 85 return 0; 86 } 87 if (SK_BYTE_SENTINEL_FOR_U16 == byte) { 88 return this->readU16(); 89 } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) { 90 return this->readU32(); 91 } else { 92 return byte; 93 } 94 } 95 96 SkData* SkStream::readData() { 97 size_t size = this->readU32(); 98 if (0 == size) { 99 return SkData::NewEmpty(); 100 } else { 101 void* buffer = sk_malloc_throw(size); 102 this->read(buffer, size); 103 return SkData::NewFromMalloc(buffer, size); 104 } 105 } 106 107 ////////////////////////////////////////////////////////////////////////////////////// 108 109 SkWStream::~SkWStream() 110 { 111 } 112 113 void SkWStream::newline() 114 { 115 this->write("\n", 1); 116 } 117 118 void SkWStream::flush() 119 { 120 } 121 122 bool SkWStream::writeText(const char text[]) 123 { 124 SkASSERT(text); 125 return this->write(text, strlen(text)); 126 } 127 128 bool SkWStream::writeDecAsText(int32_t dec) 129 { 130 SkString tmp; 131 tmp.appendS32(dec); 132 return this->write(tmp.c_str(), tmp.size()); 133 } 134 135 bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits) 136 { 137 SkString tmp; 138 tmp.appendS64(dec, minDigits); 139 return this->write(tmp.c_str(), tmp.size()); 140 } 141 142 bool SkWStream::writeHexAsText(uint32_t hex, int digits) 143 { 144 SkString tmp; 145 tmp.appendHex(hex, digits); 146 return this->write(tmp.c_str(), tmp.size()); 147 } 148 149 bool SkWStream::writeScalarAsText(SkScalar value) 150 { 151 SkString tmp; 152 tmp.appendScalar(value); 153 return this->write(tmp.c_str(), tmp.size()); 154 } 155 156 bool SkWStream::write8(U8CPU value) { 157 uint8_t v = SkToU8(value); 158 return this->write(&v, 1); 159 } 160 161 bool SkWStream::write16(U16CPU value) { 162 uint16_t v = SkToU16(value); 163 return this->write(&v, 2); 164 } 165 166 bool SkWStream::write32(uint32_t value) { 167 return this->write(&value, 4); 168 } 169 170 bool SkWStream::writeScalar(SkScalar value) { 171 return this->write(&value, sizeof(value)); 172 } 173 174 bool SkWStream::writePackedUInt(size_t value) { 175 uint8_t data[5]; 176 size_t len = 1; 177 if (value <= SK_MAX_BYTE_FOR_U8) { 178 data[0] = value; 179 len = 1; 180 } else if (value <= 0xFFFF) { 181 uint16_t value16 = value; 182 data[0] = SK_BYTE_SENTINEL_FOR_U16; 183 memcpy(&data[1], &value16, 2); 184 len = 3; 185 } else { 186 uint32_t value32 = value; 187 data[0] = SK_BYTE_SENTINEL_FOR_U32; 188 memcpy(&data[1], &value32, 4); 189 len = 5; 190 } 191 return this->write(data, len); 192 } 193 194 bool SkWStream::writeStream(SkStream* stream, size_t length) { 195 char scratch[1024]; 196 const size_t MAX = sizeof(scratch); 197 198 while (length != 0) { 199 size_t n = length; 200 if (n > MAX) { 201 n = MAX; 202 } 203 stream->read(scratch, n); 204 if (!this->write(scratch, n)) { 205 return false; 206 } 207 length -= n; 208 } 209 return true; 210 } 211 212 bool SkWStream::writeData(const SkData* data) { 213 if (data) { 214 this->write32(data->size()); 215 this->write(data->data(), data->size()); 216 } else { 217 this->write32(0); 218 } 219 return true; 220 } 221 222 /////////////////////////////////////////////////////////////////////////////// 223 224 SkFILEStream::SkFILEStream(const char file[]) : fName(file) 225 { 226 fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL; 227 } 228 229 SkFILEStream::~SkFILEStream() 230 { 231 if (fFILE) 232 sk_fclose(fFILE); 233 } 234 235 void SkFILEStream::setPath(const char path[]) 236 { 237 fName.set(path); 238 if (fFILE) 239 { 240 sk_fclose(fFILE); 241 fFILE = NULL; 242 } 243 if (path) 244 fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag); 245 } 246 247 const char* SkFILEStream::getFileName() 248 { 249 return fName.c_str(); 250 } 251 252 bool SkFILEStream::rewind() 253 { 254 if (fFILE) 255 { 256 if (sk_frewind(fFILE)) 257 return true; 258 // we hit an error 259 sk_fclose(fFILE); 260 fFILE = NULL; 261 } 262 return false; 263 } 264 265 size_t SkFILEStream::read(void* buffer, size_t size) 266 { 267 if (fFILE) 268 { 269 if (buffer == NULL && size == 0) // special signature, they want the total size 270 return sk_fgetsize(fFILE); 271 else 272 return sk_fread(buffer, size, fFILE); 273 } 274 return 0; 275 } 276 277 /////////////////////////////////////////////////////////////////////////////// 278 279 static SkData* newFromParams(const void* src, size_t size, bool copyData) { 280 if (copyData) { 281 return SkData::NewWithCopy(src, size); 282 } else { 283 return SkData::NewWithProc(src, size, NULL, NULL); 284 } 285 } 286 287 SkMemoryStream::SkMemoryStream() { 288 fData = SkData::NewEmpty(); 289 fOffset = 0; 290 } 291 292 SkMemoryStream::SkMemoryStream(size_t size) { 293 fData = SkData::NewFromMalloc(sk_malloc_throw(size), size); 294 fOffset = 0; 295 } 296 297 SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) { 298 fData = newFromParams(src, size, copyData); 299 fOffset = 0; 300 } 301 302 SkMemoryStream::SkMemoryStream(SkData* data) { 303 if (NULL == data) { 304 fData = SkData::NewEmpty(); 305 } else { 306 fData = data; 307 fData->ref(); 308 } 309 fOffset = 0; 310 } 311 312 SkMemoryStream::~SkMemoryStream() { 313 fData->unref(); 314 } 315 316 void SkMemoryStream::setMemoryOwned(const void* src, size_t size) { 317 fData->unref(); 318 fData = SkData::NewFromMalloc(src, size); 319 fOffset = 0; 320 } 321 322 void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) { 323 fData->unref(); 324 fData = newFromParams(src, size, copyData); 325 fOffset = 0; 326 } 327 328 SkData* SkMemoryStream::copyToData() const { 329 fData->ref(); 330 return fData; 331 } 332 333 SkData* SkMemoryStream::setData(SkData* data) { 334 fData->unref(); 335 if (NULL == data) { 336 fData = SkData::NewEmpty(); 337 } else { 338 fData = data; 339 fData->ref(); 340 } 341 return data; 342 } 343 344 void SkMemoryStream::skipToAlign4() { 345 // cast to remove unary-minus warning 346 fOffset += -(int)fOffset & 0x03; 347 } 348 349 bool SkMemoryStream::rewind() { 350 fOffset = 0; 351 return true; 352 } 353 354 size_t SkMemoryStream::read(void* buffer, size_t size) { 355 size_t dataSize = fData->size(); 356 357 if (buffer == NULL && size == 0) // special signature, they want the total size 358 return dataSize; 359 360 // if buffer is NULL, seek ahead by size 361 362 if (size == 0) { 363 return 0; 364 } 365 if (size > dataSize - fOffset) { 366 size = dataSize - fOffset; 367 } 368 if (buffer) { 369 memcpy(buffer, fData->bytes() + fOffset, size); 370 } 371 fOffset += size; 372 return size; 373 } 374 375 const void* SkMemoryStream::getMemoryBase() { 376 return fData->data(); 377 } 378 379 const void* SkMemoryStream::getAtPos() { 380 return fData->bytes() + fOffset; 381 } 382 383 size_t SkMemoryStream::seek(size_t offset) { 384 if (offset > fData->size()) { 385 offset = fData->size(); 386 } 387 fOffset = offset; 388 return offset; 389 } 390 391 /////////////////////////////////////////////////////////////////////////////// 392 393 SkBufferStream::SkBufferStream(SkStream* proxy, size_t bufferSize) 394 : fProxy(proxy) 395 { 396 SkASSERT(proxy != NULL); 397 proxy->ref(); 398 this->init(NULL, bufferSize); 399 } 400 401 SkBufferStream::SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize) 402 : fProxy(proxy) 403 { 404 SkASSERT(proxy != NULL); 405 SkASSERT(buffer == NULL || bufferSize != 0); // init(addr, 0) makes no sense, we must know how big their buffer is 406 proxy->ref(); 407 this->init(buffer, bufferSize); 408 } 409 410 void SkBufferStream::init(void* buffer, size_t bufferSize) 411 { 412 if (bufferSize == 0) 413 bufferSize = kDefaultBufferSize; 414 415 fOrigBufferSize = bufferSize; 416 fBufferSize = bufferSize; 417 fBufferOffset = bufferSize; // to trigger a reload on the first read() 418 419 if (buffer == NULL) 420 { 421 fBuffer = (char*)sk_malloc_throw(fBufferSize); 422 fWeOwnTheBuffer = true; 423 } 424 else 425 { 426 fBuffer = (char*)buffer; 427 fWeOwnTheBuffer = false; 428 } 429 } 430 431 SkBufferStream::~SkBufferStream() 432 { 433 fProxy->unref(); 434 if (fWeOwnTheBuffer) 435 sk_free(fBuffer); 436 } 437 438 bool SkBufferStream::rewind() 439 { 440 fBufferOffset = fBufferSize = fOrigBufferSize; 441 return fProxy->rewind(); 442 } 443 444 const char* SkBufferStream::getFileName() 445 { 446 return fProxy->getFileName(); 447 } 448 449 #ifdef SK_DEBUG 450 // #define SK_TRACE_BUFFERSTREAM 451 #endif 452 453 size_t SkBufferStream::read(void* buffer, size_t size) { 454 #ifdef SK_TRACE_BUFFERSTREAM 455 SkDebugf("Request %d", size); 456 #endif 457 458 if (buffer == NULL && size == 0) { 459 return fProxy->read(buffer, size); // requesting total size 460 } 461 462 if (0 == size) { 463 return 0; 464 } 465 466 // skip size bytes 467 if (NULL == buffer) { 468 size_t remaining = fBufferSize - fBufferOffset; 469 if (remaining >= size) { 470 fBufferOffset += size; 471 return size; 472 } 473 // if we get here, we are being asked to skip beyond our current buffer 474 // so reset our offset to force a read next time, and skip the diff 475 // in our proxy 476 fBufferOffset = fOrigBufferSize; 477 return remaining + fProxy->read(NULL, size - remaining); 478 } 479 480 size_t s = size; 481 size_t actuallyRead = 0; 482 483 // flush what we can from our fBuffer 484 if (fBufferOffset < fBufferSize) 485 { 486 if (s > fBufferSize - fBufferOffset) 487 s = fBufferSize - fBufferOffset; 488 memcpy(buffer, fBuffer + fBufferOffset, s); 489 #ifdef SK_TRACE_BUFFERSTREAM 490 SkDebugf(" flush %d", s); 491 #endif 492 size -= s; 493 fBufferOffset += s; 494 buffer = (char*)buffer + s; 495 actuallyRead = s; 496 } 497 498 // check if there is more to read 499 if (size) 500 { 501 SkASSERT(fBufferOffset >= fBufferSize); // need to refill our fBuffer 502 503 if (size < fBufferSize) // lets try to read more than the request 504 { 505 s = fProxy->read(fBuffer, fBufferSize); 506 #ifdef SK_TRACE_BUFFERSTREAM 507 SkDebugf(" read %d into fBuffer", s); 508 #endif 509 if (size > s) // they asked for too much 510 size = s; 511 if (size) 512 { 513 memcpy(buffer, fBuffer, size); 514 actuallyRead += size; 515 #ifdef SK_TRACE_BUFFERSTREAM 516 SkDebugf(" memcpy %d into dst", size); 517 #endif 518 } 519 520 fBufferOffset = size; 521 fBufferSize = s; // record the (possibly smaller) size for the buffer 522 } 523 else // just do a direct read 524 { 525 actuallyRead += fProxy->read(buffer, size); 526 #ifdef SK_TRACE_BUFFERSTREAM 527 SkDebugf(" direct read %d", size); 528 #endif 529 } 530 } 531 #ifdef SK_TRACE_BUFFERSTREAM 532 SkDebugf("\n"); 533 #endif 534 return actuallyRead; 535 } 536 537 const void* SkBufferStream::getMemoryBase() 538 { 539 return fProxy->getMemoryBase(); 540 } 541 542 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 543 ///////////////////////////////////////////////////////////////////////////////////////////////////////// 544 545 SkFILEWStream::SkFILEWStream(const char path[]) 546 { 547 fFILE = sk_fopen(path, kWrite_SkFILE_Flag); 548 } 549 550 SkFILEWStream::~SkFILEWStream() 551 { 552 if (fFILE) 553 sk_fclose(fFILE); 554 } 555 556 bool SkFILEWStream::write(const void* buffer, size_t size) 557 { 558 if (fFILE == NULL) 559 return false; 560 561 if (sk_fwrite(buffer, size, fFILE) != size) 562 { 563 SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);) 564 sk_fclose(fFILE); 565 fFILE = NULL; 566 return false; 567 } 568 return true; 569 } 570 571 void SkFILEWStream::flush() 572 { 573 if (fFILE) 574 sk_fflush(fFILE); 575 } 576 577 //////////////////////////////////////////////////////////////////////// 578 579 SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size) 580 : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0) 581 { 582 } 583 584 bool SkMemoryWStream::write(const void* buffer, size_t size) 585 { 586 size = SkMin32(size, fMaxLength - fBytesWritten); 587 if (size > 0) 588 { 589 memcpy(fBuffer + fBytesWritten, buffer, size); 590 fBytesWritten += size; 591 return true; 592 } 593 return false; 594 } 595 596 //////////////////////////////////////////////////////////////////////// 597 598 #define SkDynamicMemoryWStream_MinBlockSize 256 599 600 struct SkDynamicMemoryWStream::Block { 601 Block* fNext; 602 char* fCurr; 603 char* fStop; 604 605 const char* start() const { return (const char*)(this + 1); } 606 char* start() { return (char*)(this + 1); } 607 size_t avail() const { return fStop - fCurr; } 608 size_t written() const { return fCurr - this->start(); } 609 610 void init(size_t size) 611 { 612 fNext = NULL; 613 fCurr = this->start(); 614 fStop = this->start() + size; 615 } 616 617 const void* append(const void* data, size_t size) 618 { 619 SkASSERT((size_t)(fStop - fCurr) >= size); 620 memcpy(fCurr, data, size); 621 fCurr += size; 622 return (const void*)((const char*)data + size); 623 } 624 }; 625 626 SkDynamicMemoryWStream::SkDynamicMemoryWStream() 627 : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL) 628 { 629 } 630 631 SkDynamicMemoryWStream::~SkDynamicMemoryWStream() 632 { 633 reset(); 634 } 635 636 void SkDynamicMemoryWStream::reset() 637 { 638 this->invalidateCopy(); 639 640 Block* block = fHead; 641 642 while (block != NULL) { 643 Block* next = block->fNext; 644 sk_free(block); 645 block = next; 646 } 647 fHead = fTail = NULL; 648 fBytesWritten = 0; 649 } 650 651 bool SkDynamicMemoryWStream::write(const void* buffer, size_t count) 652 { 653 if (count > 0) { 654 this->invalidateCopy(); 655 656 fBytesWritten += count; 657 658 size_t size; 659 660 if (fTail != NULL && fTail->avail() > 0) { 661 size = SkMin32(fTail->avail(), count); 662 buffer = fTail->append(buffer, size); 663 SkASSERT(count >= size); 664 count -= size; 665 if (count == 0) 666 return true; 667 } 668 669 size = SkMax32(count, SkDynamicMemoryWStream_MinBlockSize); 670 Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); 671 block->init(size); 672 block->append(buffer, count); 673 674 if (fTail != NULL) 675 fTail->fNext = block; 676 else 677 fHead = fTail = block; 678 fTail = block; 679 } 680 return true; 681 } 682 683 bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count) 684 { 685 if (offset + count > fBytesWritten) { 686 return false; // test does not partially modify 687 } 688 689 this->invalidateCopy(); 690 691 Block* block = fHead; 692 while (block != NULL) { 693 size_t size = block->written(); 694 if (offset < size) { 695 size_t part = offset + count > size ? size - offset : count; 696 memcpy(block->start() + offset, buffer, part); 697 if (count <= part) 698 return true; 699 count -= part; 700 buffer = (const void*) ((char* ) buffer + part); 701 } 702 offset = offset > size ? offset - size : 0; 703 block = block->fNext; 704 } 705 return false; 706 } 707 708 bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count) 709 { 710 if (offset + count > fBytesWritten) 711 return false; // test does not partially modify 712 Block* block = fHead; 713 while (block != NULL) { 714 size_t size = block->written(); 715 if (offset < size) { 716 size_t part = offset + count > size ? size - offset : count; 717 memcpy(buffer, block->start() + offset, part); 718 if (count <= part) 719 return true; 720 count -= part; 721 buffer = (void*) ((char* ) buffer + part); 722 } 723 offset = offset > size ? offset - size : 0; 724 block = block->fNext; 725 } 726 return false; 727 } 728 729 void SkDynamicMemoryWStream::copyTo(void* dst) const 730 { 731 if (fCopy) { 732 memcpy(dst, fCopy->data(), fBytesWritten); 733 } else { 734 Block* block = fHead; 735 736 while (block != NULL) { 737 size_t size = block->written(); 738 memcpy(dst, block->start(), size); 739 dst = (void*)((char*)dst + size); 740 block = block->fNext; 741 } 742 } 743 } 744 745 void SkDynamicMemoryWStream::padToAlign4() 746 { 747 // cast to remove unary-minus warning 748 int padBytes = -(int)fBytesWritten & 0x03; 749 if (padBytes == 0) 750 return; 751 int zero = 0; 752 write(&zero, padBytes); 753 } 754 755 SkData* SkDynamicMemoryWStream::copyToData() const { 756 if (NULL == fCopy) { 757 void* buffer = sk_malloc_throw(fBytesWritten); 758 this->copyTo(buffer); 759 fCopy = SkData::NewFromMalloc(buffer, fBytesWritten); 760 } 761 fCopy->ref(); 762 return fCopy; 763 } 764 765 void SkDynamicMemoryWStream::invalidateCopy() { 766 if (fCopy) { 767 fCopy->unref(); 768 fCopy = NULL; 769 } 770 } 771 772 /////////////////////////////////////////////////////////////////////////////// 773 774 void SkDebugWStream::newline() 775 { 776 #if defined(SK_DEBUG) || defined(SK_DEVELOPER) 777 SkDebugf("\n"); 778 #endif 779 } 780 781 bool SkDebugWStream::write(const void* buffer, size_t size) 782 { 783 #if defined(SK_DEBUG) || defined(SK_DEVELOPER) 784 char* s = new char[size+1]; 785 memcpy(s, buffer, size); 786 s[size] = 0; 787 SkDebugf("%s", s); 788 delete[] s; 789 #endif 790 return true; 791 } 792