1 // Copyright 2016 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 #ifndef CORE_FPDFAPI_PARSER_CPDF_STREAM_H_ 8 #define CORE_FPDFAPI_PARSER_CPDF_STREAM_H_ 9 10 #include <stdint.h> 11 12 #include <memory> 13 #include <set> 14 15 #include "core/fpdfapi/parser/cpdf_object.h" 16 #include "core/fxcrt/data_vector.h" 17 #include "core/fxcrt/fx_string_wrappers.h" 18 #include "core/fxcrt/retain_ptr.h" 19 #include "third_party/abseil-cpp/absl/types/variant.h" 20 21 class IFX_SeekableReadStream; 22 23 class CPDF_Stream final : public CPDF_Object { 24 public: 25 static constexpr int kFileBufSize = 512; 26 27 CONSTRUCT_VIA_MAKE_RETAIN; 28 29 // CPDF_Object: 30 Type GetType() const override; 31 RetainPtr<CPDF_Object> Clone() const override; 32 WideString GetUnicodeText() const override; 33 CPDF_Stream* AsMutableStream() override; 34 bool WriteTo(IFX_ArchiveStream* archive, 35 const CPDF_Encryptor* encryptor) const override; 36 37 size_t GetRawSize() const; 38 // Can only be called when stream is memory-based. 39 // This is meant to be used by CPDF_StreamAcc only. 40 // Other callers should use CPDF_StreamAcc to access data in all cases. 41 pdfium::span<const uint8_t> GetInMemoryRawData() const; 42 43 // Copies span or stream into internally-owned buffer. 44 void SetData(pdfium::span<const uint8_t> pData); 45 void SetDataFromStringstream(fxcrt::ostringstream* stream); 46 47 void TakeData(DataVector<uint8_t> data); 48 49 // Set data and remove "Filter" and "DecodeParms" fields from stream 50 // dictionary. Copies span or stream into internally-owned buffer. 51 void SetDataAndRemoveFilter(pdfium::span<const uint8_t> pData); 52 void SetDataFromStringstreamAndRemoveFilter(fxcrt::ostringstream* stream); 53 54 void InitStreamFromFile(RetainPtr<IFX_SeekableReadStream> file); 55 56 // Can only be called when a stream is not memory-based. 57 DataVector<uint8_t> ReadAllRawData() const; 58 IsFileBased()59 bool IsFileBased() const { 60 return absl::holds_alternative<RetainPtr<IFX_SeekableReadStream>>(data_); 61 } IsMemoryBased()62 bool IsMemoryBased() const { 63 return absl::holds_alternative<DataVector<uint8_t>>(data_); 64 } 65 bool HasFilter() const; 66 67 private: 68 friend class CPDF_Dictionary; 69 70 // Initializes with empty data and /Length set to 0 in `dict`. 71 // `dict` must be non-null and be a direct object. 72 explicit CPDF_Stream(RetainPtr<CPDF_Dictionary> dict); 73 74 // Copies `span` and `stream`, respectively. Creates a new dictionary with the 75 // /Length set. 76 explicit CPDF_Stream(pdfium::span<const uint8_t> span); 77 explicit CPDF_Stream(fxcrt::ostringstream* stream); 78 79 // Reads data from `file`. `dict` will have its /Length set based on `file`. 80 // `dict` must be non-null and be a direct object. 81 CPDF_Stream(RetainPtr<IFX_SeekableReadStream> file, 82 RetainPtr<CPDF_Dictionary> dict); 83 84 // Takes `data`. 85 // `dict` must be non-null and be a direct object. 86 CPDF_Stream(DataVector<uint8_t> data, RetainPtr<CPDF_Dictionary> dict); 87 ~CPDF_Stream() override; 88 89 const CPDF_Dictionary* GetDictInternal() const override; 90 RetainPtr<CPDF_Object> CloneNonCyclic( 91 bool bDirect, 92 std::set<const CPDF_Object*>* pVisited) const override; 93 94 void SetLengthInDict(int length); 95 96 absl::variant<RetainPtr<IFX_SeekableReadStream>, DataVector<uint8_t>> data_; 97 RetainPtr<CPDF_Dictionary> dict_; 98 }; 99 ToStream(CPDF_Object * obj)100inline CPDF_Stream* ToStream(CPDF_Object* obj) { 101 return obj ? obj->AsMutableStream() : nullptr; 102 } 103 ToStream(const CPDF_Object * obj)104inline const CPDF_Stream* ToStream(const CPDF_Object* obj) { 105 return obj ? obj->AsStream() : nullptr; 106 } 107 ToStream(RetainPtr<CPDF_Object> obj)108inline RetainPtr<CPDF_Stream> ToStream(RetainPtr<CPDF_Object> obj) { 109 return RetainPtr<CPDF_Stream>(ToStream(obj.Get())); 110 } 111 ToStream(RetainPtr<const CPDF_Object> obj)112inline RetainPtr<const CPDF_Stream> ToStream(RetainPtr<const CPDF_Object> obj) { 113 return RetainPtr<const CPDF_Stream>(ToStream(obj.Get())); 114 } 115 116 #endif // CORE_FPDFAPI_PARSER_CPDF_STREAM_H_ 117