Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_filespec.cpp
Go to the documentation of this file.
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#include "core/fpdfdoc/cpdf_filespec.h"
8
9#include <array>
10#include <iterator>
11#include <utility>
12
13#include "build/build_config.h"
14#include "constants/stream_dict_common.h"
15#include "core/fpdfapi/parser/cpdf_dictionary.h"
16#include "core/fpdfapi/parser/cpdf_name.h"
17#include "core/fpdfapi/parser/cpdf_object.h"
18#include "core/fpdfapi/parser/cpdf_stream.h"
19#include "core/fpdfapi/parser/cpdf_string.h"
20#include "core/fpdfapi/parser/fpdf_parser_decode.h"
21#include "core/fxcrt/check.h"
22#include "core/fxcrt/compiler_specific.h"
23#include "core/fxcrt/fx_system.h"
24#include "core/fxcrt/notreached.h"
25
26namespace {
27
28#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
29WideString ChangeSlashToPlatform(WideStringView str) {
30 WideString result;
31 for (auto wch : str) {
32 if (wch == '/') {
33#if BUILDFLAG(IS_APPLE)
34 result += L':';
35#else
36 result += L'\\';
37#endif
38 } else {
39 result += wch;
40 }
41 }
42 return result;
43}
44
45WideString ChangeSlashToPDF(WideStringView str) {
46 WideString result;
47 for (auto wch : str) {
48 if (wch == '\\' || wch == ':') {
49 result += L'/';
50 } else {
51 result += wch;
52 }
53 }
54 return result;
55}
56#endif // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
57
58} // namespace
59
61 : m_pObj(std::move(pObj)) {
62 DCHECK(m_pObj);
63}
64
65CPDF_FileSpec::~CPDF_FileSpec() = default;
66
68 if (filepath.IsEmpty()) {
69 return WideString();
70 }
71#if BUILDFLAG(IS_APPLE)
72 WideStringView view = filepath.AsStringView();
73 if (view.First(sizeof("/Mac") - 1) == WideStringView(L"/Mac")) {
74 return ChangeSlashToPlatform(view.Substr(1));
75 }
76 return ChangeSlashToPlatform(view);
77#elif BUILDFLAG(IS_WIN)
78 WideStringView view = filepath.AsStringView();
79 if (view[0] != L'/') {
80 return ChangeSlashToPlatform(view);
81 }
82 if (view[1] == L'/') {
83 return ChangeSlashToPlatform(view.Substr(1));
84 }
85 if (view[2] == L'/') {
86 WideString result;
87 result += view[1];
88 result += L':';
89 result += ChangeSlashToPlatform(view.Substr(2));
90 return result;
91 }
92 WideString result;
93 result += L'\\';
94 result += ChangeSlashToPlatform(view);
95 return result;
96#else
97 return filepath;
98#endif
99}
100
102 WideString csFileName;
103 if (const CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
104 RetainPtr<const CPDF_String> pUF =
105 ToString(pDict->GetDirectObjectFor("UF"));
106 if (pUF)
107 csFileName = pUF->GetUnicodeText();
108 if (csFileName.IsEmpty()) {
109 RetainPtr<const CPDF_String> pK =
110 ToString(pDict->GetDirectObjectFor(pdfium::stream::kF));
111 if (pK)
112 csFileName = WideString::FromDefANSI(pK->GetString().AsStringView());
113 }
114 if (pDict->GetByteStringFor("FS") == "URL")
115 return csFileName;
116
117 if (csFileName.IsEmpty()) {
118 for (const auto* key : {"DOS", "Mac", "Unix"}) {
119 RetainPtr<const CPDF_String> pValue =
120 ToString(pDict->GetDirectObjectFor(key));
121 if (pValue) {
122 csFileName =
123 WideString::FromDefANSI(pValue->GetString().AsStringView());
124 break;
125 }
126 }
127 }
128 } else if (const CPDF_String* pString = m_pObj->AsString()) {
129 csFileName = WideString::FromDefANSI(pString->GetString().AsStringView());
130 }
131 return DecodeFileName(csFileName);
132}
133
134RetainPtr<const CPDF_Stream> CPDF_FileSpec::GetFileStream() const {
135 const CPDF_Dictionary* pDict = m_pObj->AsDictionary();
136 if (!pDict)
137 return nullptr;
138
139 // Get the embedded files dictionary.
140 RetainPtr<const CPDF_Dictionary> pFiles = pDict->GetDictFor("EF");
141 if (!pFiles)
142 return nullptr;
143
144 // List of keys to check for the file specification string.
145 // Follows the same precedence order as GetFileName().
146 static constexpr std::array<const char*, 5> kKeys = {
147 {"UF", "F", "DOS", "Mac", "Unix"}};
148 size_t end = pDict->GetByteStringFor("FS") == "URL" ? 2 : std::size(kKeys);
149 for (size_t i = 0; i < end; ++i) {
150 ByteString key = kKeys[i];
151 if (!pDict->GetUnicodeTextFor(key).IsEmpty()) {
152 RetainPtr<const CPDF_Stream> pStream = pFiles->GetStreamFor(key);
153 if (pStream)
154 return pStream;
155 }
156 }
157 return nullptr;
158}
159
161 RetainPtr<const CPDF_Stream> pStream = GetFileStream();
162 return pStream ? pStream->GetDict()->GetDictFor("Params") : nullptr;
163}
164
166 return pdfium::WrapRetain(
167 const_cast<CPDF_Dictionary*>(GetParamsDict().Get()));
168}
169
171 if (filepath.IsEmpty()) {
172 return WideString();
173 }
174#if BUILDFLAG(IS_WIN)
175 WideStringView view = filepath.AsStringView();
176 if (view[1] == L':') {
177 WideString result(L'/');
178 result += view[0];
179 if (view[2] != L'\\') {
180 result += L'/';
181 }
182 result += ChangeSlashToPDF(view.Substr(2));
183 return result;
184 }
185 if (view[0] == L'\\' && view[1] == L'\\') {
186 return ChangeSlashToPDF(view.Substr(1));
187 }
188 if (view[0] == L'\\') {
189 return L'/' + ChangeSlashToPDF(view);
190 }
191 return ChangeSlashToPDF(view);
192#elif BUILDFLAG(IS_APPLE)
193 WideStringView view = filepath.AsStringView();
194 if (view.First(sizeof("Mac") - 1).EqualsASCII("Mac")) {
195 return L'/' + ChangeSlashToPDF(view);
196 }
197 return ChangeSlashToPDF(view);
198#else
199 return filepath;
200#endif
201}
fxcrt::ByteString ByteString
Definition bytestring.h:180
#define DCHECK
Definition check.h:33
WideString GetUnicodeTextFor(const ByteString &key) const
ByteString GetByteStringFor(const ByteString &key) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
RetainPtr< CPDF_Dictionary > GetMutableParamsDict()
RetainPtr< const CPDF_Dictionary > GetParamsDict() const
WideString GetFileName() const
static WideString DecodeFileName(const WideString &filepath)
CPDF_FileSpec(RetainPtr< const CPDF_Object > pObj)
RetainPtr< const CPDF_Stream > GetFileStream() const
static WideString EncodeFileName(const WideString &filepath)
ByteString GetString() const override
bool operator==(const char *ptr) const
WideString()=default
static WideString FromDefANSI(ByteStringView str)
fxcrt::WideString WideString
Definition widestring.h:207