mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Attached files - PDF 2.0 attributes
This commit is contained in:
@ -402,6 +402,16 @@ std::vector<PDFInteger> PDFDocumentDataLoaderDecorator::readIntegerArray(const P
|
||||
return std::vector<PDFInteger>();
|
||||
}
|
||||
|
||||
PDFObjectReference PDFDocumentDataLoaderDecorator::readReference(const PDFObject& object) const
|
||||
{
|
||||
if (object.isReference())
|
||||
{
|
||||
return object.getReference();
|
||||
}
|
||||
|
||||
return PDFObjectReference();
|
||||
}
|
||||
|
||||
PDFObjectReference PDFDocumentDataLoaderDecorator::readReferenceFromDictionary(const PDFDictionary* dictionary, const char* key) const
|
||||
{
|
||||
const PDFObject& object = dictionary->get(key);
|
||||
|
@ -307,6 +307,10 @@ public:
|
||||
/// \param object Object containing array of numbers
|
||||
std::vector<PDFInteger> readIntegerArray(const PDFObject& object) const;
|
||||
|
||||
/// Reads reference. If error occurs, then invalid reference is returned.
|
||||
/// \param object Object containing reference
|
||||
PDFObjectReference readReference(const PDFObject& object) const;
|
||||
|
||||
/// Reads reference from dictionary. If error occurs, then invalid reference is returned.
|
||||
/// \param dictionary Dictionary containing desired data
|
||||
/// \param key Entry key
|
||||
|
@ -107,6 +107,12 @@ const PDFEmbeddedFile* PDFFileSpecification::getPlatformFile() const
|
||||
PDFFileSpecification PDFFileSpecification::parse(const PDFObjectStorage* storage, PDFObject object)
|
||||
{
|
||||
PDFFileSpecification result;
|
||||
|
||||
if (object.isReference())
|
||||
{
|
||||
result.m_selfReference = object.getReference();
|
||||
}
|
||||
|
||||
object = storage->getObject(object);
|
||||
|
||||
if (object.isString())
|
||||
@ -117,7 +123,6 @@ PDFFileSpecification PDFFileSpecification::parse(const PDFObjectStorage* storage
|
||||
{
|
||||
PDFDocumentDataLoaderDecorator loader(storage);
|
||||
const PDFDictionary* dictionary = object.getDictionary();
|
||||
PDFObject collectionObject = dictionary->get("Cl");
|
||||
|
||||
result.m_fileSystem = loader.readNameFromDictionary(dictionary, "FS");
|
||||
result.m_F = loader.readStringFromDictionary(dictionary, "F");
|
||||
@ -128,15 +133,53 @@ PDFFileSpecification PDFFileSpecification::parse(const PDFObjectStorage* storage
|
||||
result.m_id = PDFFileIdentifier::parse(storage, dictionary->get("ID"));
|
||||
result.m_volatile = loader.readBooleanFromDictionary(dictionary, "V", false);
|
||||
result.m_description = loader.readTextStringFromDictionary(dictionary, "Desc", QString());
|
||||
result.m_collection = collectionObject.isReference() ? collectionObject.getReference() : PDFObjectReference();
|
||||
result.m_collection = loader.readReferenceFromDictionary(dictionary, "CI");
|
||||
result.m_thumbnailReference = loader.readReferenceFromDictionary(dictionary, "Thumb");
|
||||
result.m_encryptedPayload = dictionary->get("EP");
|
||||
|
||||
constexpr const std::array relationships = {
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "Unspecified", AssociatedFileRelationship::Unspecified },
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "Source", AssociatedFileRelationship::Source },
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "Data", AssociatedFileRelationship::Data },
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "Alternative", AssociatedFileRelationship::Alternative },
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "Supplement", AssociatedFileRelationship::Supplement },
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "EncryptedPayload", AssociatedFileRelationship::EncryptedPayload },
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "FormData", AssociatedFileRelationship::FormData },
|
||||
std::pair<const char*, AssociatedFileRelationship>{ "Schema", AssociatedFileRelationship::Schema },
|
||||
};
|
||||
|
||||
result.m_associatedFileRelationship = loader.readEnumByName(dictionary->get("AFRelationship"), relationships.begin(), relationships.end(), AssociatedFileRelationship::Unspecified);
|
||||
|
||||
PDFObject embeddedFiles = storage->getObject(dictionary->get("EF"));
|
||||
PDFObject relatedFiles = storage->getObject(dictionary->get("RF"));
|
||||
if (embeddedFiles.isDictionary())
|
||||
{
|
||||
const PDFDictionary* embeddedFilesDictionary = embeddedFiles.getDictionary();
|
||||
const PDFDictionary* relatedFilesDictionary = relatedFiles.isDictionary() ? relatedFiles.getDictionary() : nullptr;
|
||||
for (size_t i = 0; i < embeddedFilesDictionary->getCount(); ++i)
|
||||
{
|
||||
result.m_embeddedFiles[embeddedFilesDictionary->getKey(i).getString()] = PDFEmbeddedFile::parse(storage, embeddedFilesDictionary->getValue(i));
|
||||
QByteArray key = embeddedFilesDictionary->getKey(i).getString();
|
||||
result.m_embeddedFiles[key] = PDFEmbeddedFile::parse(storage, embeddedFilesDictionary->getValue(i));
|
||||
|
||||
if (relatedFilesDictionary)
|
||||
{
|
||||
PDFObject relatedFileArrayObject = storage->getObject(relatedFilesDictionary->get(key));
|
||||
if (relatedFileArrayObject.isArray())
|
||||
{
|
||||
const PDFArray* relatedFileArray = relatedFileArrayObject.getArray();
|
||||
const size_t relatedFilesCount = relatedFileArray->getCount() / 2;
|
||||
|
||||
RelatedFiles& relatedFiles = result.m_relatedFiles[key];
|
||||
relatedFiles.reserve(relatedFilesCount);
|
||||
for (size_t i = 0; i < relatedFilesCount; ++i)
|
||||
{
|
||||
RelatedFile relatedFile;
|
||||
relatedFile.name = loader.readString(relatedFileArray->getItem(2 * i));
|
||||
relatedFile.fileReference = loader.readReference(relatedFileArray->getItem(2 * i + 1));
|
||||
relatedFiles.emplace_back(qMove(relatedFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,26 @@ class PDFFORQTLIBSHARED_EXPORT PDFFileSpecification
|
||||
public:
|
||||
explicit PDFFileSpecification() = default;
|
||||
|
||||
struct RelatedFile
|
||||
{
|
||||
QByteArray name;
|
||||
PDFObjectReference fileReference;
|
||||
};
|
||||
|
||||
using RelatedFiles = std::vector<RelatedFile>;
|
||||
|
||||
enum class AssociatedFileRelationship
|
||||
{
|
||||
Unspecified,
|
||||
Source,
|
||||
Data,
|
||||
Alternative,
|
||||
Supplement,
|
||||
EncryptedPayload,
|
||||
FormData,
|
||||
Schema
|
||||
};
|
||||
|
||||
/// Returns platform file name as string. It looks into the UF, F,
|
||||
/// and platform names and selects the appropriate one. If error
|
||||
/// occurs. then empty string is returned.
|
||||
@ -92,8 +112,13 @@ public:
|
||||
const PDFFileIdentifier& getFileIdentifier() const { return m_id; }
|
||||
bool isVolatile() const { return m_volatile; }
|
||||
const QString& getDescription() const { return m_description; }
|
||||
PDFObjectReference getSelfReference() const { return m_selfReference; }
|
||||
PDFObjectReference getCollection() const { return m_collection; }
|
||||
PDFObjectReference getThumbnail() const { return m_thumbnailReference; }
|
||||
const std::map<QByteArray, PDFEmbeddedFile>& getEmbeddedFiles() const { return m_embeddedFiles; }
|
||||
const std::map<QByteArray, RelatedFiles>& getRelatedFiles() const { return m_relatedFiles; }
|
||||
const PDFObject& getEncryptedPayloadDictionary() const { return m_encryptedPayload; }
|
||||
AssociatedFileRelationship getAssociatedFileRelationship() const { return m_associatedFileRelationship; }
|
||||
|
||||
static PDFFileSpecification parse(const PDFObjectStorage* storage, PDFObject object);
|
||||
|
||||
@ -122,11 +147,25 @@ private:
|
||||
/// Description of the file (for example, if file is embedded file stream)
|
||||
QString m_description;
|
||||
|
||||
/// Self reference
|
||||
PDFObjectReference m_selfReference;
|
||||
|
||||
/// Collection item dictionary reference
|
||||
PDFObjectReference m_collection;
|
||||
|
||||
/// Thumbnail reference
|
||||
PDFObjectReference m_thumbnailReference;
|
||||
|
||||
/// Embedded files
|
||||
std::map<QByteArray, PDFEmbeddedFile> m_embeddedFiles;
|
||||
|
||||
/// Related files for embedded files
|
||||
std::map<QByteArray, RelatedFiles> m_relatedFiles;
|
||||
|
||||
/// Encrypted payload dictionary (used in document wrapper)
|
||||
PDFObject m_encryptedPayload;
|
||||
|
||||
AssociatedFileRelationship m_associatedFileRelationship = AssociatedFileRelationship::Unspecified;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
Reference in New Issue
Block a user