| Index: src/core/SkStream.cpp
|
| ===================================================================
|
| --- src/core/SkStream.cpp (revision 10125)
|
| +++ src/core/SkStream.cpp (working copy)
|
| @@ -661,6 +661,125 @@
|
| }
|
| }
|
|
|
| +class SkBlockMemoryRefCnt : public SkRefCnt {
|
| +public:
|
| + SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }
|
| +
|
| + virtual ~SkBlockMemoryRefCnt() {
|
| + SkDynamicMemoryWStream::Block* block = fHead;
|
| + while (block != NULL) {
|
| + SkDynamicMemoryWStream::Block* next = block->fNext;
|
| + sk_free(block);
|
| + block = next;
|
| + }
|
| + }
|
| +
|
| + SkDynamicMemoryWStream::Block* const fHead;
|
| +};
|
| +
|
| +class SkBlockMemoryStream : public SkStreamAsset {
|
| +public:
|
| + SkBlockMemoryStream(SkDynamicMemoryWStream::Block* head, size_t size)
|
| + : fBlockMemory(new SkBlockMemoryRefCnt(head)), fCurrent(head), fSize(size)
|
| + , fOffset(0), fCurrentOffset(0) { }
|
| +
|
| + SkBlockMemoryStream(SkBlockMemoryRefCnt* headRef, size_t size)
|
| + : fBlockMemory(SkRef(headRef)), fCurrent(fBlockMemory->fHead), fSize(size)
|
| + , fOffset(0), fCurrentOffset(0) { }
|
| +
|
| + virtual size_t read(void* buffer, size_t rawCount) SK_OVERRIDE {
|
| + size_t count = rawCount;
|
| + if (fOffset + count > fSize) {
|
| + count = fSize - fOffset;
|
| + }
|
| + size_t bytesLeftToRead = count;
|
| + while (fCurrent != NULL) {
|
| + size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
|
| + size_t bytesFromCurrent = bytesLeftToRead <= bytesLeftInCurrent
|
| + ? bytesLeftToRead : bytesLeftInCurrent;
|
| + if (buffer) {
|
| + memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
|
| + }
|
| + if (bytesLeftToRead <= bytesFromCurrent) {
|
| + fCurrentOffset += bytesFromCurrent;
|
| + fOffset += count;
|
| + return count;
|
| + }
|
| + bytesLeftToRead -= bytesFromCurrent;
|
| + buffer = (void*) ((char* ) buffer + bytesFromCurrent);
|
| + fCurrent = fCurrent->fNext;
|
| + fCurrentOffset = 0;
|
| + }
|
| + SkASSERT(false);
|
| + return 0;
|
| + }
|
| +
|
| + virtual bool isAtEnd() const SK_OVERRIDE {
|
| + return fOffset == fSize;
|
| + }
|
| +
|
| + virtual bool rewind() SK_OVERRIDE {
|
| + fCurrent = fBlockMemory->fHead;
|
| + fCurrentOffset = 0;
|
| + fOffset = 0;
|
| + return true;
|
| + }
|
| + virtual SkBlockMemoryStream* duplicate() const SK_OVERRIDE {
|
| + return new SkBlockMemoryStream(fBlockMemory.get(), fSize);
|
| + }
|
| +
|
| + virtual size_t getPosition() const SK_OVERRIDE {
|
| + return fOffset;
|
| + }
|
| + virtual bool seek(size_t position) SK_OVERRIDE {
|
| + if (position >= fOffset) {
|
| + size_t skipAmount = position - fOffset;
|
| + return this->skip(skipAmount) == skipAmount;
|
| + }
|
| + return this->rewind() && this->skip(position) == position;
|
| + }
|
| + virtual bool move(long offset) SK_OVERRIDE {
|
| + return seek(fOffset + offset);
|
| + }
|
| + virtual SkBlockMemoryStream* fork() const SK_OVERRIDE {
|
| + SkAutoTUnref<SkBlockMemoryStream> that(this->duplicate());
|
| + that->fOffset = this->fOffset;
|
| + that->fCurrent = this->fCurrent;
|
| + that->fCurrentOffset = this->fCurrentOffset;
|
| + return that.detach();
|
| + }
|
| +
|
| + virtual size_t getLength() const SK_OVERRIDE {
|
| + return fSize;
|
| + }
|
| +
|
| + virtual const void* getMemoryBase() SK_OVERRIDE {
|
| + if (fBlockMemory->fHead->fNext == NULL) {
|
| + return fBlockMemory->fHead->start();
|
| + }
|
| + return false;
|
| + }
|
| +
|
| +private:
|
| + SkAutoTUnref<SkBlockMemoryRefCnt> fBlockMemory;
|
| + SkDynamicMemoryWStream::Block const * fCurrent;
|
| + size_t const fSize;
|
| + size_t fOffset;
|
| + size_t fCurrentOffset;
|
| +};
|
| +
|
| +SkStreamAsset* SkDynamicMemoryWStream::detatchAsStream() {
|
| + if (fCopy) {
|
| + SkMemoryStream* stream = new SkMemoryStream(fCopy);
|
| + this->reset();
|
| + return stream;
|
| + }
|
| + SkBlockMemoryStream* stream = new SkBlockMemoryStream(fHead, fBytesWritten);
|
| + fHead = 0;
|
| + this->reset();
|
| + return stream;
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| void SkDebugWStream::newline()
|
|
|