1 /*
2 * Copyright (C) 2009-2011, Pino Toscano <pino@kde.org>
3 * Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
4 * Copyright (C) 2018, 2020 Albert Astals Cid <aacid@kde.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 /**
22 \file poppler-embedded-file.h
23 */
24 #include "poppler-embedded-file.h"
25
26 #include "poppler-embedded-file-private.h"
27 #include "poppler-private.h"
28
29 #include "Object.h"
30 #include "Stream.h"
31 #include "Catalog.h"
32 #include "FileSpec.h"
33 #include "DateInfo.h"
34
35 using namespace poppler;
36
embedded_file_private(FileSpec * fs)37 embedded_file_private::embedded_file_private(FileSpec *fs) : file_spec(fs) { }
38
~embedded_file_private()39 embedded_file_private::~embedded_file_private()
40 {
41 delete file_spec;
42 }
43
create(FileSpec * fs)44 embedded_file *embedded_file_private::create(FileSpec *fs)
45 {
46 return new embedded_file(*new embedded_file_private(fs));
47 }
48
49 /**
50 \class poppler::embedded_file poppler-embedded-file.h "poppler/cpp/poppler-embedded-file.h"
51
52 Represents a file embedded in a PDF %document.
53 */
54
embedded_file(embedded_file_private & dd)55 embedded_file::embedded_file(embedded_file_private &dd) : d(&dd) { }
56
57 /**
58 Destroys the embedded file.
59 */
~embedded_file()60 embedded_file::~embedded_file()
61 {
62 delete d;
63 }
64
65 /**
66 \returns whether the embedded file is valid
67 */
is_valid() const68 bool embedded_file::is_valid() const
69 {
70 return d->file_spec->isOk();
71 }
72
73 /**
74 \returns the name of the embedded file
75 */
name() const76 std::string embedded_file::name() const
77 {
78 const GooString *goo = d->file_spec->getFileName();
79 return goo ? std::string(goo->c_str()) : std::string();
80 }
81
82 /**
83 \returns the description of the embedded file
84 */
description() const85 ustring embedded_file::description() const
86 {
87 const GooString *goo = d->file_spec->getDescription();
88 return goo ? detail::unicode_GooString_to_ustring(goo) : ustring();
89 }
90
91 /**
92 \note this is not always available in the PDF %document, in that case this
93 will return \p -1.
94
95 \returns the size of the embedded file, if known
96 */
size() const97 int embedded_file::size() const
98 {
99 const EmbFile *ef = d->file_spec->getEmbeddedFile();
100 return ef ? ef->size() : -1;
101 }
102
103 /**
104 \returns the time_t representing the modification date of the embedded file,
105 if available
106 */
modification_date() const107 time_type embedded_file::modification_date() const
108 {
109 const EmbFile *ef = d->file_spec->getEmbeddedFile();
110 const GooString *goo = ef ? ef->modDate() : nullptr;
111 return goo ? dateStringToTime(goo) : time_type(-1);
112 }
113
114 /**
115 \returns the time_t representing the creation date of the embedded file,
116 if available
117 */
creation_date() const118 time_type embedded_file::creation_date() const
119 {
120 const EmbFile *ef = d->file_spec->getEmbeddedFile();
121 const GooString *goo = ef ? ef->createDate() : nullptr;
122 return goo ? dateStringToTime(goo) : time_type(-1);
123 }
124
125 /**
126 \returns the checksum of the embedded file
127 */
checksum() const128 byte_array embedded_file::checksum() const
129 {
130 const EmbFile *ef = d->file_spec->getEmbeddedFile();
131 const GooString *cs = ef ? ef->checksum() : nullptr;
132 if (!cs) {
133 return byte_array();
134 }
135 const char *ccs = cs->c_str();
136 byte_array data(cs->getLength());
137 for (int i = 0; i < cs->getLength(); ++i) {
138 data[i] = ccs[i];
139 }
140 return data;
141 }
142
143 /**
144 \returns the MIME type of the embedded file, if available
145 */
mime_type() const146 std::string embedded_file::mime_type() const
147 {
148 const EmbFile *ef = d->file_spec->getEmbeddedFile();
149 const GooString *goo = ef ? ef->mimeType() : nullptr;
150 return goo ? std::string(goo->c_str()) : std::string();
151 }
152
153 /**
154 Reads all the data of the embedded file.
155
156 \returns the data of the embedded file
157 */
data() const158 byte_array embedded_file::data() const
159 {
160 if (!is_valid()) {
161 return byte_array();
162 }
163 EmbFile *ef = d->file_spec->getEmbeddedFile();
164 Stream *stream = ef ? ef->stream() : nullptr;
165 if (!stream) {
166 return byte_array();
167 }
168
169 stream->reset();
170 byte_array ret(1024);
171 size_t data_len = 0;
172 int i;
173 while ((i = stream->getChar()) != EOF) {
174 if (data_len == ret.size()) {
175 ret.resize(ret.size() * 2);
176 }
177 ret[data_len] = (char)i;
178 ++data_len;
179 }
180 ret.resize(data_len);
181 return ret;
182 }
183