1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkStream.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,855 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkStream.h" 1.14 +#include "SkData.h" 1.15 +#include "SkFixed.h" 1.16 +#include "SkString.h" 1.17 +#include "SkOSFile.h" 1.18 + 1.19 +/////////////////////////////////////////////////////////////////////////////// 1.20 + 1.21 + 1.22 +int8_t SkStream::readS8() { 1.23 + int8_t value; 1.24 + SkDEBUGCODE(size_t len =) this->read(&value, 1); 1.25 + SkASSERT(1 == len); 1.26 + return value; 1.27 +} 1.28 + 1.29 +int16_t SkStream::readS16() { 1.30 + int16_t value; 1.31 + SkDEBUGCODE(size_t len =) this->read(&value, 2); 1.32 + SkASSERT(2 == len); 1.33 + return value; 1.34 +} 1.35 + 1.36 +int32_t SkStream::readS32() { 1.37 + int32_t value; 1.38 + SkDEBUGCODE(size_t len =) this->read(&value, 4); 1.39 + SkASSERT(4 == len); 1.40 + return value; 1.41 +} 1.42 + 1.43 +SkScalar SkStream::readScalar() { 1.44 + SkScalar value; 1.45 + SkDEBUGCODE(size_t len =) this->read(&value, sizeof(SkScalar)); 1.46 + SkASSERT(sizeof(SkScalar) == len); 1.47 + return value; 1.48 +} 1.49 + 1.50 +#define SK_MAX_BYTE_FOR_U8 0xFD 1.51 +#define SK_BYTE_SENTINEL_FOR_U16 0xFE 1.52 +#define SK_BYTE_SENTINEL_FOR_U32 0xFF 1.53 + 1.54 +size_t SkStream::readPackedUInt() { 1.55 + uint8_t byte; 1.56 + if (!this->read(&byte, 1)) { 1.57 + return 0; 1.58 + } 1.59 + if (SK_BYTE_SENTINEL_FOR_U16 == byte) { 1.60 + return this->readU16(); 1.61 + } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) { 1.62 + return this->readU32(); 1.63 + } else { 1.64 + return byte; 1.65 + } 1.66 +} 1.67 + 1.68 +SkData* SkStream::readData() { 1.69 + size_t size = this->readU32(); 1.70 + if (0 == size) { 1.71 + return SkData::NewEmpty(); 1.72 + } else { 1.73 + void* buffer = sk_malloc_throw(size); 1.74 + this->read(buffer, size); 1.75 + return SkData::NewFromMalloc(buffer, size); 1.76 + } 1.77 +} 1.78 + 1.79 +////////////////////////////////////////////////////////////////////////////////////// 1.80 + 1.81 +SkWStream::~SkWStream() 1.82 +{ 1.83 +} 1.84 + 1.85 +void SkWStream::newline() 1.86 +{ 1.87 + this->write("\n", 1); 1.88 +} 1.89 + 1.90 +void SkWStream::flush() 1.91 +{ 1.92 +} 1.93 + 1.94 +bool SkWStream::writeText(const char text[]) 1.95 +{ 1.96 + SkASSERT(text); 1.97 + return this->write(text, strlen(text)); 1.98 +} 1.99 + 1.100 +bool SkWStream::writeDecAsText(int32_t dec) 1.101 +{ 1.102 + SkString tmp; 1.103 + tmp.appendS32(dec); 1.104 + return this->write(tmp.c_str(), tmp.size()); 1.105 +} 1.106 + 1.107 +bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits) 1.108 +{ 1.109 + SkString tmp; 1.110 + tmp.appendS64(dec, minDigits); 1.111 + return this->write(tmp.c_str(), tmp.size()); 1.112 +} 1.113 + 1.114 +bool SkWStream::writeHexAsText(uint32_t hex, int digits) 1.115 +{ 1.116 + SkString tmp; 1.117 + tmp.appendHex(hex, digits); 1.118 + return this->write(tmp.c_str(), tmp.size()); 1.119 +} 1.120 + 1.121 +bool SkWStream::writeScalarAsText(SkScalar value) 1.122 +{ 1.123 + SkString tmp; 1.124 + tmp.appendScalar(value); 1.125 + return this->write(tmp.c_str(), tmp.size()); 1.126 +} 1.127 + 1.128 +bool SkWStream::write8(U8CPU value) { 1.129 + uint8_t v = SkToU8(value); 1.130 + return this->write(&v, 1); 1.131 +} 1.132 + 1.133 +bool SkWStream::write16(U16CPU value) { 1.134 + uint16_t v = SkToU16(value); 1.135 + return this->write(&v, 2); 1.136 +} 1.137 + 1.138 +bool SkWStream::write32(uint32_t value) { 1.139 + return this->write(&value, 4); 1.140 +} 1.141 + 1.142 +bool SkWStream::writeScalar(SkScalar value) { 1.143 + return this->write(&value, sizeof(value)); 1.144 +} 1.145 + 1.146 +int SkWStream::SizeOfPackedUInt(size_t value) { 1.147 + if (value <= SK_MAX_BYTE_FOR_U8) { 1.148 + return 1; 1.149 + } else if (value <= 0xFFFF) { 1.150 + return 3; 1.151 + } 1.152 + return 5; 1.153 +} 1.154 + 1.155 +bool SkWStream::writePackedUInt(size_t value) { 1.156 + uint8_t data[5]; 1.157 + size_t len = 1; 1.158 + if (value <= SK_MAX_BYTE_FOR_U8) { 1.159 + data[0] = value; 1.160 + len = 1; 1.161 + } else if (value <= 0xFFFF) { 1.162 + uint16_t value16 = value; 1.163 + data[0] = SK_BYTE_SENTINEL_FOR_U16; 1.164 + memcpy(&data[1], &value16, 2); 1.165 + len = 3; 1.166 + } else { 1.167 + uint32_t value32 = value; 1.168 + data[0] = SK_BYTE_SENTINEL_FOR_U32; 1.169 + memcpy(&data[1], &value32, 4); 1.170 + len = 5; 1.171 + } 1.172 + return this->write(data, len); 1.173 +} 1.174 + 1.175 +bool SkWStream::writeStream(SkStream* stream, size_t length) { 1.176 + char scratch[1024]; 1.177 + const size_t MAX = sizeof(scratch); 1.178 + 1.179 + while (length != 0) { 1.180 + size_t n = length; 1.181 + if (n > MAX) { 1.182 + n = MAX; 1.183 + } 1.184 + stream->read(scratch, n); 1.185 + if (!this->write(scratch, n)) { 1.186 + return false; 1.187 + } 1.188 + length -= n; 1.189 + } 1.190 + return true; 1.191 +} 1.192 + 1.193 +bool SkWStream::writeData(const SkData* data) { 1.194 + if (data) { 1.195 + this->write32(data->size()); 1.196 + this->write(data->data(), data->size()); 1.197 + } else { 1.198 + this->write32(0); 1.199 + } 1.200 + return true; 1.201 +} 1.202 + 1.203 +/////////////////////////////////////////////////////////////////////////////// 1.204 + 1.205 +SkFILEStream::SkFILEStream(const char file[]) : fName(file), fOwnership(kCallerPasses_Ownership) { 1.206 + fFILE = file ? sk_fopen(fName.c_str(), kRead_SkFILE_Flag) : NULL; 1.207 +} 1.208 + 1.209 +SkFILEStream::SkFILEStream(FILE* file, Ownership ownership) 1.210 + : fFILE((SkFILE*)file) 1.211 + , fOwnership(ownership) { 1.212 +} 1.213 + 1.214 +SkFILEStream::~SkFILEStream() { 1.215 + if (fFILE && fOwnership != kCallerRetains_Ownership) { 1.216 + sk_fclose(fFILE); 1.217 + } 1.218 +} 1.219 + 1.220 +void SkFILEStream::setPath(const char path[]) { 1.221 + fName.set(path); 1.222 + if (fFILE) { 1.223 + sk_fclose(fFILE); 1.224 + fFILE = NULL; 1.225 + } 1.226 + if (path) { 1.227 + fFILE = sk_fopen(fName.c_str(), kRead_SkFILE_Flag); 1.228 + } 1.229 +} 1.230 + 1.231 +size_t SkFILEStream::read(void* buffer, size_t size) { 1.232 + if (fFILE) { 1.233 + return sk_fread(buffer, size, fFILE); 1.234 + } 1.235 + return 0; 1.236 +} 1.237 + 1.238 +bool SkFILEStream::isAtEnd() const { 1.239 + return sk_feof(fFILE); 1.240 +} 1.241 + 1.242 +bool SkFILEStream::rewind() { 1.243 + if (fFILE) { 1.244 + if (sk_frewind(fFILE)) { 1.245 + return true; 1.246 + } 1.247 + // we hit an error 1.248 + sk_fclose(fFILE); 1.249 + fFILE = NULL; 1.250 + } 1.251 + return false; 1.252 +} 1.253 + 1.254 +SkStreamAsset* SkFILEStream::duplicate() const { 1.255 + if (NULL == fFILE) { 1.256 + return new SkMemoryStream(); 1.257 + } 1.258 + 1.259 + if (NULL != fData.get()) { 1.260 + return new SkMemoryStream(fData); 1.261 + } 1.262 + 1.263 + if (!fName.isEmpty()) { 1.264 + SkAutoTUnref<SkFILEStream> that(new SkFILEStream(fName.c_str())); 1.265 + if (sk_fidentical(that->fFILE, this->fFILE)) { 1.266 + return that.detach(); 1.267 + } 1.268 + } 1.269 + 1.270 + fData.reset(SkData::NewFromFILE(fFILE)); 1.271 + if (NULL == fData.get()) { 1.272 + return NULL; 1.273 + } 1.274 + return new SkMemoryStream(fData); 1.275 +} 1.276 + 1.277 +size_t SkFILEStream::getPosition() const { 1.278 + return sk_ftell(fFILE); 1.279 +} 1.280 + 1.281 +bool SkFILEStream::seek(size_t position) { 1.282 + return sk_fseek(fFILE, position); 1.283 +} 1.284 + 1.285 +bool SkFILEStream::move(long offset) { 1.286 + return sk_fmove(fFILE, offset); 1.287 +} 1.288 + 1.289 +SkStreamAsset* SkFILEStream::fork() const { 1.290 + SkAutoTUnref<SkStreamAsset> that(this->duplicate()); 1.291 + that->seek(this->getPosition()); 1.292 + return that.detach(); 1.293 +} 1.294 + 1.295 +size_t SkFILEStream::getLength() const { 1.296 + return sk_fgetsize(fFILE); 1.297 +} 1.298 + 1.299 +const void* SkFILEStream::getMemoryBase() { 1.300 + if (NULL == fData.get()) { 1.301 + return NULL; 1.302 + } 1.303 + return fData->data(); 1.304 +} 1.305 + 1.306 +/////////////////////////////////////////////////////////////////////////////// 1.307 + 1.308 +static SkData* newFromParams(const void* src, size_t size, bool copyData) { 1.309 + if (copyData) { 1.310 + return SkData::NewWithCopy(src, size); 1.311 + } else { 1.312 + return SkData::NewWithProc(src, size, NULL, NULL); 1.313 + } 1.314 +} 1.315 + 1.316 +SkMemoryStream::SkMemoryStream() { 1.317 + fData = SkData::NewEmpty(); 1.318 + fOffset = 0; 1.319 +} 1.320 + 1.321 +SkMemoryStream::SkMemoryStream(size_t size) { 1.322 + fData = SkData::NewFromMalloc(sk_malloc_throw(size), size); 1.323 + fOffset = 0; 1.324 +} 1.325 + 1.326 +SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) { 1.327 + fData = newFromParams(src, size, copyData); 1.328 + fOffset = 0; 1.329 +} 1.330 + 1.331 +SkMemoryStream::SkMemoryStream(SkData* data) { 1.332 + if (NULL == data) { 1.333 + fData = SkData::NewEmpty(); 1.334 + } else { 1.335 + fData = data; 1.336 + fData->ref(); 1.337 + } 1.338 + fOffset = 0; 1.339 +} 1.340 + 1.341 +SkMemoryStream::~SkMemoryStream() { 1.342 + fData->unref(); 1.343 +} 1.344 + 1.345 +void SkMemoryStream::setMemoryOwned(const void* src, size_t size) { 1.346 + fData->unref(); 1.347 + fData = SkData::NewFromMalloc(src, size); 1.348 + fOffset = 0; 1.349 +} 1.350 + 1.351 +void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) { 1.352 + fData->unref(); 1.353 + fData = newFromParams(src, size, copyData); 1.354 + fOffset = 0; 1.355 +} 1.356 + 1.357 +SkData* SkMemoryStream::copyToData() const { 1.358 + fData->ref(); 1.359 + return fData; 1.360 +} 1.361 + 1.362 +SkData* SkMemoryStream::setData(SkData* data) { 1.363 + fData->unref(); 1.364 + if (NULL == data) { 1.365 + fData = SkData::NewEmpty(); 1.366 + } else { 1.367 + fData = data; 1.368 + fData->ref(); 1.369 + } 1.370 + fOffset = 0; 1.371 + return data; 1.372 +} 1.373 + 1.374 +void SkMemoryStream::skipToAlign4() { 1.375 + // cast to remove unary-minus warning 1.376 + fOffset += -(int)fOffset & 0x03; 1.377 +} 1.378 + 1.379 +size_t SkMemoryStream::read(void* buffer, size_t size) { 1.380 + size_t dataSize = fData->size(); 1.381 + 1.382 + if (size > dataSize - fOffset) { 1.383 + size = dataSize - fOffset; 1.384 + } 1.385 + if (buffer) { 1.386 + memcpy(buffer, fData->bytes() + fOffset, size); 1.387 + } 1.388 + fOffset += size; 1.389 + return size; 1.390 +} 1.391 + 1.392 +bool SkMemoryStream::isAtEnd() const { 1.393 + return fOffset == fData->size(); 1.394 +} 1.395 + 1.396 +bool SkMemoryStream::rewind() { 1.397 + fOffset = 0; 1.398 + return true; 1.399 +} 1.400 + 1.401 +SkMemoryStream* SkMemoryStream::duplicate() const { 1.402 + return SkNEW_ARGS(SkMemoryStream, (fData)); 1.403 +} 1.404 + 1.405 +size_t SkMemoryStream::getPosition() const { 1.406 + return fOffset; 1.407 +} 1.408 + 1.409 +bool SkMemoryStream::seek(size_t position) { 1.410 + fOffset = position > fData->size() 1.411 + ? fData->size() 1.412 + : position; 1.413 + return true; 1.414 +} 1.415 + 1.416 +bool SkMemoryStream::move(long offset) { 1.417 + return this->seek(fOffset + offset); 1.418 +} 1.419 + 1.420 +SkMemoryStream* SkMemoryStream::fork() const { 1.421 + SkAutoTUnref<SkMemoryStream> that(this->duplicate()); 1.422 + that->seek(fOffset); 1.423 + return that.detach(); 1.424 +} 1.425 + 1.426 +size_t SkMemoryStream::getLength() const { 1.427 + return fData->size(); 1.428 +} 1.429 + 1.430 +const void* SkMemoryStream::getMemoryBase() { 1.431 + return fData->data(); 1.432 +} 1.433 + 1.434 +const void* SkMemoryStream::getAtPos() { 1.435 + return fData->bytes() + fOffset; 1.436 +} 1.437 + 1.438 +///////////////////////////////////////////////////////////////////////////////////////////////////////// 1.439 +///////////////////////////////////////////////////////////////////////////////////////////////////////// 1.440 + 1.441 +SkFILEWStream::SkFILEWStream(const char path[]) 1.442 +{ 1.443 + fFILE = sk_fopen(path, kWrite_SkFILE_Flag); 1.444 +} 1.445 + 1.446 +SkFILEWStream::~SkFILEWStream() 1.447 +{ 1.448 + if (fFILE) { 1.449 + sk_fclose(fFILE); 1.450 + } 1.451 +} 1.452 + 1.453 +size_t SkFILEWStream::bytesWritten() const { 1.454 + return sk_ftell(fFILE); 1.455 +} 1.456 + 1.457 +bool SkFILEWStream::write(const void* buffer, size_t size) 1.458 +{ 1.459 + if (fFILE == NULL) { 1.460 + return false; 1.461 + } 1.462 + 1.463 + if (sk_fwrite(buffer, size, fFILE) != size) 1.464 + { 1.465 + SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);) 1.466 + sk_fclose(fFILE); 1.467 + fFILE = NULL; 1.468 + return false; 1.469 + } 1.470 + return true; 1.471 +} 1.472 + 1.473 +void SkFILEWStream::flush() 1.474 +{ 1.475 + if (fFILE) { 1.476 + sk_fflush(fFILE); 1.477 + } 1.478 +} 1.479 + 1.480 +//////////////////////////////////////////////////////////////////////// 1.481 + 1.482 +SkMemoryWStream::SkMemoryWStream(void* buffer, size_t size) 1.483 + : fBuffer((char*)buffer), fMaxLength(size), fBytesWritten(0) 1.484 +{ 1.485 +} 1.486 + 1.487 +bool SkMemoryWStream::write(const void* buffer, size_t size) 1.488 +{ 1.489 + size = SkMin32(size, fMaxLength - fBytesWritten); 1.490 + if (size > 0) 1.491 + { 1.492 + memcpy(fBuffer + fBytesWritten, buffer, size); 1.493 + fBytesWritten += size; 1.494 + return true; 1.495 + } 1.496 + return false; 1.497 +} 1.498 + 1.499 +//////////////////////////////////////////////////////////////////////// 1.500 + 1.501 +#define SkDynamicMemoryWStream_MinBlockSize 256 1.502 + 1.503 +struct SkDynamicMemoryWStream::Block { 1.504 + Block* fNext; 1.505 + char* fCurr; 1.506 + char* fStop; 1.507 + 1.508 + const char* start() const { return (const char*)(this + 1); } 1.509 + char* start() { return (char*)(this + 1); } 1.510 + size_t avail() const { return fStop - fCurr; } 1.511 + size_t written() const { return fCurr - this->start(); } 1.512 + 1.513 + void init(size_t size) 1.514 + { 1.515 + fNext = NULL; 1.516 + fCurr = this->start(); 1.517 + fStop = this->start() + size; 1.518 + } 1.519 + 1.520 + const void* append(const void* data, size_t size) 1.521 + { 1.522 + SkASSERT((size_t)(fStop - fCurr) >= size); 1.523 + memcpy(fCurr, data, size); 1.524 + fCurr += size; 1.525 + return (const void*)((const char*)data + size); 1.526 + } 1.527 +}; 1.528 + 1.529 +SkDynamicMemoryWStream::SkDynamicMemoryWStream() 1.530 + : fHead(NULL), fTail(NULL), fBytesWritten(0), fCopy(NULL) 1.531 +{ 1.532 +} 1.533 + 1.534 +SkDynamicMemoryWStream::~SkDynamicMemoryWStream() 1.535 +{ 1.536 + reset(); 1.537 +} 1.538 + 1.539 +void SkDynamicMemoryWStream::reset() 1.540 +{ 1.541 + this->invalidateCopy(); 1.542 + 1.543 + Block* block = fHead; 1.544 + 1.545 + while (block != NULL) { 1.546 + Block* next = block->fNext; 1.547 + sk_free(block); 1.548 + block = next; 1.549 + } 1.550 + fHead = fTail = NULL; 1.551 + fBytesWritten = 0; 1.552 +} 1.553 + 1.554 +bool SkDynamicMemoryWStream::write(const void* buffer, size_t count) 1.555 +{ 1.556 + if (count > 0) { 1.557 + this->invalidateCopy(); 1.558 + 1.559 + fBytesWritten += count; 1.560 + 1.561 + size_t size; 1.562 + 1.563 + if (fTail != NULL && fTail->avail() > 0) { 1.564 + size = SkMin32(fTail->avail(), count); 1.565 + buffer = fTail->append(buffer, size); 1.566 + SkASSERT(count >= size); 1.567 + count -= size; 1.568 + if (count == 0) 1.569 + return true; 1.570 + } 1.571 + 1.572 + size = SkMax32(count, SkDynamicMemoryWStream_MinBlockSize); 1.573 + Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); 1.574 + block->init(size); 1.575 + block->append(buffer, count); 1.576 + 1.577 + if (fTail != NULL) 1.578 + fTail->fNext = block; 1.579 + else 1.580 + fHead = fTail = block; 1.581 + fTail = block; 1.582 + } 1.583 + return true; 1.584 +} 1.585 + 1.586 +bool SkDynamicMemoryWStream::write(const void* buffer, size_t offset, size_t count) 1.587 +{ 1.588 + if (offset + count > fBytesWritten) { 1.589 + return false; // test does not partially modify 1.590 + } 1.591 + 1.592 + this->invalidateCopy(); 1.593 + 1.594 + Block* block = fHead; 1.595 + while (block != NULL) { 1.596 + size_t size = block->written(); 1.597 + if (offset < size) { 1.598 + size_t part = offset + count > size ? size - offset : count; 1.599 + memcpy(block->start() + offset, buffer, part); 1.600 + if (count <= part) 1.601 + return true; 1.602 + count -= part; 1.603 + buffer = (const void*) ((char* ) buffer + part); 1.604 + } 1.605 + offset = offset > size ? offset - size : 0; 1.606 + block = block->fNext; 1.607 + } 1.608 + return false; 1.609 +} 1.610 + 1.611 +bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count) 1.612 +{ 1.613 + if (offset + count > fBytesWritten) 1.614 + return false; // test does not partially modify 1.615 + Block* block = fHead; 1.616 + while (block != NULL) { 1.617 + size_t size = block->written(); 1.618 + if (offset < size) { 1.619 + size_t part = offset + count > size ? size - offset : count; 1.620 + memcpy(buffer, block->start() + offset, part); 1.621 + if (count <= part) 1.622 + return true; 1.623 + count -= part; 1.624 + buffer = (void*) ((char* ) buffer + part); 1.625 + } 1.626 + offset = offset > size ? offset - size : 0; 1.627 + block = block->fNext; 1.628 + } 1.629 + return false; 1.630 +} 1.631 + 1.632 +void SkDynamicMemoryWStream::copyTo(void* dst) const 1.633 +{ 1.634 + if (fCopy) { 1.635 + memcpy(dst, fCopy->data(), fBytesWritten); 1.636 + } else { 1.637 + Block* block = fHead; 1.638 + 1.639 + while (block != NULL) { 1.640 + size_t size = block->written(); 1.641 + memcpy(dst, block->start(), size); 1.642 + dst = (void*)((char*)dst + size); 1.643 + block = block->fNext; 1.644 + } 1.645 + } 1.646 +} 1.647 + 1.648 +void SkDynamicMemoryWStream::padToAlign4() 1.649 +{ 1.650 + // cast to remove unary-minus warning 1.651 + int padBytes = -(int)fBytesWritten & 0x03; 1.652 + if (padBytes == 0) 1.653 + return; 1.654 + int zero = 0; 1.655 + write(&zero, padBytes); 1.656 +} 1.657 + 1.658 +SkData* SkDynamicMemoryWStream::copyToData() const { 1.659 + if (NULL == fCopy) { 1.660 + void* buffer = sk_malloc_throw(fBytesWritten); 1.661 + this->copyTo(buffer); 1.662 + fCopy = SkData::NewFromMalloc(buffer, fBytesWritten); 1.663 + } 1.664 + fCopy->ref(); 1.665 + return fCopy; 1.666 +} 1.667 + 1.668 +void SkDynamicMemoryWStream::invalidateCopy() { 1.669 + if (fCopy) { 1.670 + fCopy->unref(); 1.671 + fCopy = NULL; 1.672 + } 1.673 +} 1.674 + 1.675 +class SkBlockMemoryRefCnt : public SkRefCnt { 1.676 +public: 1.677 + explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { } 1.678 + 1.679 + virtual ~SkBlockMemoryRefCnt() { 1.680 + SkDynamicMemoryWStream::Block* block = fHead; 1.681 + while (block != NULL) { 1.682 + SkDynamicMemoryWStream::Block* next = block->fNext; 1.683 + sk_free(block); 1.684 + block = next; 1.685 + } 1.686 + } 1.687 + 1.688 + SkDynamicMemoryWStream::Block* const fHead; 1.689 +}; 1.690 + 1.691 +class SkBlockMemoryStream : public SkStreamAsset { 1.692 +public: 1.693 + SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size) 1.694 + : fBlockMemory(SkNEW_ARGS(SkBlockMemoryRefCnt, (head))), fCurrent(head) 1.695 + , fSize(size) , fOffset(0), fCurrentOffset(0) { } 1.696 + 1.697 + SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size) 1.698 + : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead) 1.699 + , fSize(size) , fOffset(0), fCurrentOffset(0) { } 1.700 + 1.701 + virtual size_t read(void* buffer, size_t rawCount) SK_OVERRIDE { 1.702 + size_t count = rawCount; 1.703 + if (fOffset + count > fSize) { 1.704 + count = fSize - fOffset; 1.705 + } 1.706 + size_t bytesLeftToRead = count; 1.707 + while (fCurrent != NULL) { 1.708 + size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset; 1.709 + size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent); 1.710 + if (buffer) { 1.711 + memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent); 1.712 + buffer = SkTAddOffset<void>(buffer, bytesFromCurrent); 1.713 + } 1.714 + if (bytesLeftToRead <= bytesFromCurrent) { 1.715 + fCurrentOffset += bytesFromCurrent; 1.716 + fOffset += count; 1.717 + return count; 1.718 + } 1.719 + bytesLeftToRead -= bytesFromCurrent; 1.720 + fCurrent = fCurrent->fNext; 1.721 + fCurrentOffset = 0; 1.722 + } 1.723 + SkASSERT(false); 1.724 + return 0; 1.725 + } 1.726 + 1.727 + virtual bool isAtEnd() const SK_OVERRIDE { 1.728 + return fOffset == fSize; 1.729 + } 1.730 + 1.731 + virtual bool rewind() SK_OVERRIDE { 1.732 + fCurrent = fBlockMemory->fHead; 1.733 + fOffset = 0; 1.734 + fCurrentOffset = 0; 1.735 + return true; 1.736 + } 1.737 + 1.738 + virtual SkBlockMemoryStream* duplicate() const SK_OVERRIDE { 1.739 + return SkNEW_ARGS(SkBlockMemoryStream, (fBlockMemory.get(), fSize)); 1.740 + } 1.741 + 1.742 + virtual size_t getPosition() const SK_OVERRIDE { 1.743 + return fOffset; 1.744 + } 1.745 + 1.746 + virtual bool seek(size_t position) SK_OVERRIDE { 1.747 + // If possible, skip forward. 1.748 + if (position >= fOffset) { 1.749 + size_t skipAmount = position - fOffset; 1.750 + return this->skip(skipAmount) == skipAmount; 1.751 + } 1.752 + // If possible, move backward within the current block. 1.753 + size_t moveBackAmount = fOffset - position; 1.754 + if (moveBackAmount <= fCurrentOffset) { 1.755 + fCurrentOffset -= moveBackAmount; 1.756 + fOffset -= moveBackAmount; 1.757 + return true; 1.758 + } 1.759 + // Otherwise rewind and move forward. 1.760 + return this->rewind() && this->skip(position) == position; 1.761 + } 1.762 + 1.763 + virtual bool move(long offset) SK_OVERRIDE { 1.764 + return seek(fOffset + offset); 1.765 + } 1.766 + 1.767 + virtual SkBlockMemoryStream* fork() const SK_OVERRIDE { 1.768 + SkAutoTUnref<SkBlockMemoryStream> that(this->duplicate()); 1.769 + that->fCurrent = this->fCurrent; 1.770 + that->fOffset = this->fOffset; 1.771 + that->fCurrentOffset = this->fCurrentOffset; 1.772 + return that.detach(); 1.773 + } 1.774 + 1.775 + virtual size_t getLength() const SK_OVERRIDE { 1.776 + return fSize; 1.777 + } 1.778 + 1.779 + virtual const void* getMemoryBase() SK_OVERRIDE { 1.780 + if (NULL == fBlockMemory->fHead->fNext) { 1.781 + return fBlockMemory->fHead->start(); 1.782 + } 1.783 + return NULL; 1.784 + } 1.785 + 1.786 +private: 1.787 + SkAutoTUnref<SkBlockMemoryRefCnt> const fBlockMemory; 1.788 + SkDynamicMemoryWStream::Block const * fCurrent; 1.789 + size_t const fSize; 1.790 + size_t fOffset; 1.791 + size_t fCurrentOffset; 1.792 +}; 1.793 + 1.794 +SkStreamAsset* SkDynamicMemoryWStream::detachAsStream() { 1.795 + if (fCopy) { 1.796 + SkMemoryStream* stream = SkNEW_ARGS(SkMemoryStream, (fCopy)); 1.797 + this->reset(); 1.798 + return stream; 1.799 + } 1.800 + SkBlockMemoryStream* stream = SkNEW_ARGS(SkBlockMemoryStream, (fHead, fBytesWritten)); 1.801 + fHead = 0; 1.802 + this->reset(); 1.803 + return stream; 1.804 +} 1.805 + 1.806 +/////////////////////////////////////////////////////////////////////////////// 1.807 + 1.808 +void SkDebugWStream::newline() 1.809 +{ 1.810 +#if defined(SK_DEBUG) || defined(SK_DEVELOPER) 1.811 + SkDebugf("\n"); 1.812 + fBytesWritten++; 1.813 +#endif 1.814 +} 1.815 + 1.816 +bool SkDebugWStream::write(const void* buffer, size_t size) 1.817 +{ 1.818 +#if defined(SK_DEBUG) || defined(SK_DEVELOPER) 1.819 + char* s = new char[size+1]; 1.820 + memcpy(s, buffer, size); 1.821 + s[size] = 0; 1.822 + SkDebugf("%s", s); 1.823 + delete[] s; 1.824 + fBytesWritten += size; 1.825 +#endif 1.826 + return true; 1.827 +} 1.828 + 1.829 +/////////////////////////////////////////////////////////////////////////////// 1.830 +/////////////////////////////////////////////////////////////////////////////// 1.831 + 1.832 + 1.833 +static SkData* mmap_filename(const char path[]) { 1.834 + SkFILE* file = sk_fopen(path, kRead_SkFILE_Flag); 1.835 + if (NULL == file) { 1.836 + return NULL; 1.837 + } 1.838 + 1.839 + SkData* data = SkData::NewFromFILE(file); 1.840 + sk_fclose(file); 1.841 + return data; 1.842 +} 1.843 + 1.844 +SkStreamAsset* SkStream::NewFromFile(const char path[]) { 1.845 + SkAutoTUnref<SkData> data(mmap_filename(path)); 1.846 + if (data.get()) { 1.847 + return SkNEW_ARGS(SkMemoryStream, (data.get())); 1.848 + } 1.849 + 1.850 + // If we get here, then our attempt at using mmap failed, so try normal 1.851 + // file access. 1.852 + SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path)); 1.853 + if (!stream->isValid()) { 1.854 + stream->unref(); 1.855 + stream = NULL; 1.856 + } 1.857 + return stream; 1.858 +}