1 // Copyright 2017 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fpdfapi/parser/cpdf_seekablemultistream.h" 8 9 #include <algorithm> 10 #include <utility> 11 12 #include "core/fpdfapi/parser/cpdf_stream.h" 13 #include "core/fpdfapi/parser/cpdf_stream_acc.h" 14 #include "core/fxcrt/fx_safe_types.h" 15 #include "core/fxcrt/notreached.h" 16 #include "core/fxcrt/span_util.h" 17 #include "core/fxcrt/stl_util.h" 18 CPDF_SeekableMultiStream(std::vector<RetainPtr<const CPDF_Stream>> streams)19CPDF_SeekableMultiStream::CPDF_SeekableMultiStream( 20 std::vector<RetainPtr<const CPDF_Stream>> streams) { 21 for (auto& pStream : streams) { 22 m_Data.push_back(pdfium::MakeRetain<CPDF_StreamAcc>(std::move(pStream))); 23 m_Data.back()->LoadAllDataFiltered(); 24 } 25 } 26 27 CPDF_SeekableMultiStream::~CPDF_SeekableMultiStream() = default; 28 GetSize()29FX_FILESIZE CPDF_SeekableMultiStream::GetSize() { 30 FX_SAFE_FILESIZE dwSize = 0; 31 for (const auto& acc : m_Data) 32 dwSize += acc->GetSize(); 33 return dwSize.ValueOrDie(); 34 } 35 ReadBlockAtOffset(pdfium::span<uint8_t> buffer,FX_FILESIZE offset)36bool CPDF_SeekableMultiStream::ReadBlockAtOffset(pdfium::span<uint8_t> buffer, 37 FX_FILESIZE offset) { 38 int32_t iCount = fxcrt::CollectionSize<int32_t>(m_Data); 39 int32_t index = 0; 40 while (index < iCount) { 41 const auto& acc = m_Data[index]; 42 FX_FILESIZE dwSize = acc->GetSize(); 43 if (offset < dwSize) 44 break; 45 46 offset -= dwSize; 47 index++; 48 } 49 while (index < iCount) { 50 auto acc_span = m_Data[index]->GetSpan(); 51 size_t dwRead = std::min<size_t>(buffer.size(), acc_span.size() - offset); 52 buffer = fxcrt::spancpy(buffer, acc_span.subspan(offset, dwRead)); 53 if (buffer.empty()) 54 return true; 55 56 offset = 0; 57 index++; 58 } 59 return false; 60 } 61 GetPosition()62FX_FILESIZE CPDF_SeekableMultiStream::GetPosition() { 63 return 0; 64 } 65 IsEOF()66bool CPDF_SeekableMultiStream::IsEOF() { 67 return false; 68 } 69 Flush()70bool CPDF_SeekableMultiStream::Flush() { 71 NOTREACHED_NORETURN(); 72 } 73 WriteBlock(pdfium::span<const uint8_t> buffer)74bool CPDF_SeekableMultiStream::WriteBlock(pdfium::span<const uint8_t> buffer) { 75 NOTREACHED_NORETURN(); 76 } 77