scroggo | 19b9153 | 2016-10-24 09:03:26 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "SkStreamBuffer.h" |
| 9 | |
| 10 | SkStreamBuffer::SkStreamBuffer(SkStream* stream) |
| 11 | : fStream(stream) |
Leon Scroggins III | 932efed | 2016-12-16 11:39:51 -0500 | [diff] [blame] | 12 | , fPosition(0) |
scroggo | 19b9153 | 2016-10-24 09:03:26 -0700 | [diff] [blame] | 13 | , fBytesBuffered(0) |
Leon Scroggins III | 932efed | 2016-12-16 11:39:51 -0500 | [diff] [blame] | 14 | , fHasLengthAndPosition(stream->hasLength() && stream->hasPosition()) |
| 15 | , fTrulyBuffered(0) |
scroggo | 19b9153 | 2016-10-24 09:03:26 -0700 | [diff] [blame] | 16 | {} |
| 17 | |
Leon Scroggins III | 932efed | 2016-12-16 11:39:51 -0500 | [diff] [blame] | 18 | SkStreamBuffer::~SkStreamBuffer() { |
| 19 | fMarkedData.foreach([](size_t, SkData** data) { (*data)->unref(); }); |
| 20 | } |
| 21 | |
| 22 | const char* SkStreamBuffer::get() const { |
| 23 | SkASSERT(fBytesBuffered >= 1); |
| 24 | if (fHasLengthAndPosition && fTrulyBuffered < fBytesBuffered) { |
| 25 | const size_t bytesToBuffer = fBytesBuffered - fTrulyBuffered; |
| 26 | char* dst = SkTAddOffset<char>(const_cast<char*>(fBuffer), fTrulyBuffered); |
| 27 | SkDEBUGCODE(const size_t bytesRead =) |
| 28 | // This stream is rewindable, so it should be safe to call the non-const |
| 29 | // read() |
| 30 | const_cast<SkStream*>(fStream.get())->read(dst, bytesToBuffer); |
| 31 | SkASSERT(bytesRead == bytesToBuffer); |
| 32 | fTrulyBuffered = fBytesBuffered; |
| 33 | } |
| 34 | return fBuffer; |
| 35 | } |
| 36 | |
| 37 | bool SkStreamBuffer::buffer(size_t totalBytesToBuffer) { |
scroggo | 19b9153 | 2016-10-24 09:03:26 -0700 | [diff] [blame] | 38 | // FIXME (scroggo): What should we do if the client tries to read too much? |
| 39 | // Should not be a problem in GIF. |
Leon Scroggins III | 932efed | 2016-12-16 11:39:51 -0500 | [diff] [blame] | 40 | SkASSERT(totalBytesToBuffer <= kMaxSize); |
scroggo | 19b9153 | 2016-10-24 09:03:26 -0700 | [diff] [blame] | 41 | |
Leon Scroggins III | 932efed | 2016-12-16 11:39:51 -0500 | [diff] [blame] | 42 | if (totalBytesToBuffer <= fBytesBuffered) { |
| 43 | return true; |
| 44 | } |
| 45 | |
| 46 | if (fHasLengthAndPosition) { |
| 47 | const size_t remaining = fStream->getLength() - fStream->getPosition() + fTrulyBuffered; |
| 48 | fBytesBuffered = SkTMin(remaining, totalBytesToBuffer); |
| 49 | } else { |
| 50 | const size_t extraBytes = totalBytesToBuffer - fBytesBuffered; |
| 51 | const size_t bytesBuffered = fStream->read(fBuffer + fBytesBuffered, extraBytes); |
| 52 | fBytesBuffered += bytesBuffered; |
| 53 | } |
| 54 | return fBytesBuffered == totalBytesToBuffer; |
| 55 | } |
| 56 | |
| 57 | size_t SkStreamBuffer::markPosition() { |
| 58 | SkASSERT(fBytesBuffered >= 1); |
| 59 | if (!fHasLengthAndPosition) { |
| 60 | sk_sp<SkData> data(SkData::MakeWithCopy(fBuffer, fBytesBuffered)); |
| 61 | SkASSERT(nullptr == fMarkedData.find(fPosition)); |
| 62 | fMarkedData.set(fPosition, data.release()); |
| 63 | } |
| 64 | return fPosition; |
| 65 | } |
| 66 | |
| 67 | sk_sp<SkData> SkStreamBuffer::getDataAtPosition(size_t position, size_t length) { |
| 68 | if (!fHasLengthAndPosition) { |
| 69 | SkData** data = fMarkedData.find(position); |
| 70 | SkASSERT(data); |
| 71 | SkASSERT((*data)->size() == length); |
| 72 | return sk_ref_sp<SkData>(*data); |
| 73 | } |
| 74 | |
| 75 | SkASSERT(position + length <= fStream->getLength()); |
| 76 | |
| 77 | const size_t oldPosition = fStream->getPosition(); |
| 78 | if (!fStream->seek(position)) { |
| 79 | return nullptr; |
| 80 | } |
| 81 | |
| 82 | sk_sp<SkData> data(SkData::MakeUninitialized(length)); |
| 83 | void* dst = data->writable_data(); |
| 84 | const bool success = fStream->read(dst, length) == length; |
| 85 | fStream->seek(oldPosition); |
| 86 | return success ? data : nullptr; |
scroggo | 19b9153 | 2016-10-24 09:03:26 -0700 | [diff] [blame] | 87 | } |