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, 2022 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
35using namespace poppler;
36
37embedded_file_private::embedded_file_private(std::unique_ptr<FileSpec> &&fs) : file_spec(std::move(fs)) { }
38
39embedded_file *embedded_file_private::create(std::unique_ptr<FileSpec> &&fs)
40{
41 return new embedded_file(*new embedded_file_private(std::move(fs)));
42}
43
44/**
45 \class poppler::embedded_file poppler-embedded-file.h "poppler/cpp/poppler-embedded-file.h"
46
47 Represents a file embedded in a PDF %document.
48 */
49
50embedded_file::embedded_file(embedded_file_private &dd) : d(&dd) { }
51
52/**
53 Destroys the embedded file.
54 */
55embedded_file::~embedded_file()
56{
57 delete d;
58}
59
60/**
61 \returns whether the embedded file is valid
62 */
63bool embedded_file::is_valid() const
64{
65 return d->file_spec->isOk();
66}
67
68/**
69 \returns the name of the embedded file
70 */
71std::string embedded_file::name() const
72{
73 const GooString *goo = d->file_spec->getFileName();
74 return goo ? std::string(goo->c_str()) : std::string();
75}
76
77/**
78 \returns the description of the embedded file
79 */
80ustring embedded_file::description() const
81{
82 const GooString *goo = d->file_spec->getDescription();
83 return goo ? detail::unicode_GooString_to_ustring(str: goo) : ustring();
84}
85
86/**
87 \note this is not always available in the PDF %document, in that case this
88 will return \p -1.
89
90 \returns the size of the embedded file, if known
91 */
92int embedded_file::size() const
93{
94 const EmbFile *ef = d->file_spec->getEmbeddedFile();
95 return ef ? ef->size() : -1;
96}
97
98/**
99 \returns the time_type representing the modification date of the embedded file,
100 if available
101 */
102time_type embedded_file::modification_date() const
103{
104 const EmbFile *ef = d->file_spec->getEmbeddedFile();
105 const GooString *goo = ef ? ef->modDate() : nullptr;
106 return goo ? static_cast<time_type>(dateStringToTime(dateString: goo)) : time_type(-1);
107}
108
109/**
110 \returns the time_type representing the creation date of the embedded file,
111 if available
112 */
113time_type embedded_file::creation_date() const
114{
115 const EmbFile *ef = d->file_spec->getEmbeddedFile();
116 const GooString *goo = ef ? ef->createDate() : nullptr;
117 return goo ? static_cast<time_type>(dateStringToTime(dateString: goo)) : time_type(-1);
118}
119
120/**
121 \returns the time_t representing the modification date of the embedded file,
122 if available
123 */
124time_t embedded_file::modification_date_t() const
125{
126 const EmbFile *ef = d->file_spec->getEmbeddedFile();
127 const GooString *goo = ef ? ef->modDate() : nullptr;
128 return goo ? dateStringToTime(dateString: goo) : time_t(-1);
129}
130
131/**
132 \returns the time_t representing the creation date of the embedded file,
133 if available
134 */
135time_t embedded_file::creation_date_t() const
136{
137 const EmbFile *ef = d->file_spec->getEmbeddedFile();
138 const GooString *goo = ef ? ef->createDate() : nullptr;
139 return goo ? dateStringToTime(dateString: goo) : time_t(-1);
140}
141
142/**
143 \returns the checksum of the embedded file
144 */
145byte_array embedded_file::checksum() const
146{
147 const EmbFile *ef = d->file_spec->getEmbeddedFile();
148 const GooString *cs = ef ? ef->checksum() : nullptr;
149 if (!cs) {
150 return byte_array();
151 }
152 const char *ccs = cs->c_str();
153 byte_array data(cs->getLength());
154 for (int i = 0; i < cs->getLength(); ++i) {
155 data[i] = ccs[i];
156 }
157 return data;
158}
159
160/**
161 \returns the MIME type of the embedded file, if available
162 */
163std::string embedded_file::mime_type() const
164{
165 const EmbFile *ef = d->file_spec->getEmbeddedFile();
166 const GooString *goo = ef ? ef->mimeType() : nullptr;
167 return goo ? std::string(goo->c_str()) : std::string();
168}
169
170/**
171 Reads all the data of the embedded file.
172
173 \returns the data of the embedded file
174 */
175byte_array embedded_file::data() const
176{
177 if (!is_valid()) {
178 return byte_array();
179 }
180 EmbFile *ef = d->file_spec->getEmbeddedFile();
181 Stream *stream = ef ? ef->stream() : nullptr;
182 if (!stream) {
183 return byte_array();
184 }
185
186 stream->reset();
187 byte_array ret(1024);
188 size_t data_len = 0;
189 int i;
190 while ((i = stream->getChar()) != EOF) {
191 if (data_len == ret.size()) {
192 ret.resize(new_size: ret.size() * 2);
193 }
194 ret[data_len] = (char)i;
195 ++data_len;
196 }
197 ret.resize(new_size: data_len);
198 return ret;
199}
200

source code of poppler/cpp/poppler-embedded-file.cpp