Index: third_party/WebKit/Source/platform/image-decoders/SegmentStream.cpp |
diff --git a/third_party/WebKit/Source/platform/image-decoders/SegmentStream.cpp b/third_party/WebKit/Source/platform/image-decoders/SegmentStream.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e8ff5cd79752892d7026dd5e044ada423626df04 |
--- /dev/null |
+++ b/third_party/WebKit/Source/platform/image-decoders/SegmentStream.cpp |
@@ -0,0 +1,106 @@ |
+// Copyright (c) 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "platform/image-decoders/SegmentStream.h" |
+ |
+namespace blink { |
+ |
+SegmentStream::SegmentStream() |
+ : m_reader(), |
+ m_position(0), |
+ m_hasReadAllContents(true), |
+ m_isCleared(true) {} |
+ |
+void SegmentStream::setReader(SegmentReader* reader, bool allContentsReceived) { |
+ m_reader = reader; |
+ if (reader) { |
+ m_hasReadAllContents = reader->size() == m_position; |
+ m_isCleared = m_position > m_reader->size(); |
+ } else { |
+ m_hasReadAllContents = true; |
+ m_isCleared = true; |
+ } |
+} |
+ |
+size_t SegmentStream::read(void* buffer, size_t size) { |
+ if (m_isCleared) |
+ return 0; |
+ |
+ size = std::min(size, m_reader->size() - m_position); |
+ |
+ size_t bytesAdvanced = 0; |
+ if (!buffer) { // skipping, not reading |
+ bytesAdvanced = size; |
+ } else { |
+ bytesAdvanced = peek(buffer, size); |
+ } |
+ |
+ m_position += bytesAdvanced; |
+ m_hasReadAllContents = m_position == m_reader->size(); |
+ |
+ return bytesAdvanced; |
+} |
+ |
+size_t SegmentStream::peek(void* buffer, size_t size) const { |
+ if (m_isCleared) |
+ return 0; |
+ |
+ size = std::min(size, m_reader->size() - m_position); |
+ |
+ size_t peekPosition = m_position; |
+ size_t totalBytesPeeked = 0; |
+ char* bufferAsCharPtr = reinterpret_cast<char*>(buffer); |
+ while (size) { |
+ const char* segment = nullptr; |
+ size_t bytesPeeked = m_reader->getSomeData(segment, peekPosition); |
+ if (!bytesPeeked) |
+ break; |
+ if (bytesPeeked > size) |
+ bytesPeeked = size; |
+ |
+ memcpy(bufferAsCharPtr, segment, bytesPeeked); |
+ bufferAsCharPtr += bytesPeeked; |
+ size -= bytesPeeked; |
+ totalBytesPeeked += bytesPeeked; |
+ peekPosition += bytesPeeked; |
+ } |
+ |
+ return totalBytesPeeked; |
+} |
+ |
+bool SegmentStream::rewind() { |
+ m_position = 0; |
+ m_hasReadAllContents = true; |
+ if (m_reader) |
+ m_hasReadAllContents = m_position == m_reader->size(); |
+ |
+ return true; |
+} |
+ |
+bool SegmentStream::seek(size_t position) { |
+ m_hasReadAllContents = true; |
+ if (m_reader) { |
+ position = std::min(position, m_reader->size()); |
+ m_hasReadAllContents = position == m_reader->size(); |
+ } |
+ m_position = position; |
+ |
+ return true; |
+} |
+ |
+bool SegmentStream::move(long offset) { |
+ long absolutePosition = m_position + offset; |
+ |
+ // clamp inside the bounds of the buffer size |
+ absolutePosition = std::max(absolutePosition, 0l); |
+ absolutePosition = |
+ std::min(static_cast<size_t>(absolutePosition), m_reader->size()); |
+ |
+ m_position = absolutePosition; |
+ m_hasReadAllContents = m_position == m_reader->size(); |
+ |
+ return true; |
+} |
+ |
+} // namespace blink |