diff options
Diffstat (limited to 'Build/source/libs/poppler/poppler-0.28.0/poppler/FileSpec.cc')
-rw-r--r-- | Build/source/libs/poppler/poppler-0.28.0/poppler/FileSpec.cc | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/Build/source/libs/poppler/poppler-0.28.0/poppler/FileSpec.cc b/Build/source/libs/poppler/poppler-0.28.0/poppler/FileSpec.cc new file mode 100644 index 00000000000..bac1eaea0d7 --- /dev/null +++ b/Build/source/libs/poppler/poppler-0.28.0/poppler/FileSpec.cc @@ -0,0 +1,295 @@ +//======================================================================== +// +// FileSpec.cc +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2008-2009 Carlos Garcia Campos <carlosgc@gnome.org> +// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net> +// Copyright (C) 2012 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2012 Hib Eris <hib@hiberis.nl> +// +// To see a description of the changes please see the Changelog file that +// came with your tarball or type make ChangeLog if you are building from git +// +//======================================================================== + +//======================================================================== +// +// Most of the code from Link.cc and PSOutputDev.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include <config.h> + +#include "FileSpec.h" + +EmbFile::EmbFile(Object *efStream) +{ + m_size = -1; + m_createDate = NULL; + m_modDate = NULL; + m_checksum = NULL; + m_mimetype = NULL; + + efStream->copy(&m_objStr); + + if (efStream->isStream()) { + // dataDict corresponds to Table 3.41 in the PDF1.6 spec. + Dict *dataDict = efStream->streamGetDict(); + + // subtype is normally the mimetype + Object subtypeName; + if (dataDict->lookup("Subtype", &subtypeName)->isName()) { + m_mimetype = new GooString(subtypeName.getName()); + } + subtypeName.free(); + + // paramDict corresponds to Table 3.42 in the PDF1.6 spec + Object paramDict; + if (dataDict->lookup("Params", ¶mDict)->isDict()) { + Object paramObj; + if (paramDict.dictLookup("ModDate", ¶mObj)->isString()) + m_modDate = new GooString(paramObj.getString()); + paramObj.free(); + + if (paramDict.dictLookup("CreationDate", ¶mObj)->isString()) + m_createDate = new GooString(paramObj.getString()); + paramObj.free(); + + if (paramDict.dictLookup("Size", ¶mObj)->isInt()) + m_size = paramObj.getInt(); + paramObj.free(); + + if (paramDict.dictLookup("CheckSum", ¶mObj)->isString()) + m_checksum = new GooString(paramObj.getString()); + paramObj.free(); + } + paramDict.free(); + } +} + +EmbFile::~EmbFile() +{ + delete m_createDate; + delete m_modDate; + delete m_checksum; + delete m_mimetype; + m_objStr.free(); +} + +GBool EmbFile::save(const char *path) { + FILE *f; + GBool ret; + + if (!(f = fopen(path, "wb"))) { + return gFalse; + } + ret = save2(f); + fclose(f); + return ret; +} + +GBool EmbFile::save2(FILE *f) { + int c; + + m_objStr.streamReset(); + while ((c = m_objStr.streamGetChar()) != EOF) { + fputc(c, f); + } + return gTrue; +} + +FileSpec::FileSpec(Object *fileSpecA) +{ + ok = gTrue; + fileName = NULL; + platformFileName = NULL; + embFile = NULL; + desc = NULL; + fileSpecA->copy(&fileSpec); + + Object obj1; + if (!getFileSpecName(fileSpecA, &obj1)) { + ok = gFalse; + obj1.free(); + error(errSyntaxError, -1, "Invalid FileSpec"); + return; + } + + fileName = obj1.getString()->copy(); + obj1.free(); + + if (fileSpec.isDict()) { + if (fileSpec.dictLookup("EF", &obj1)->isDict()) { + if (!obj1.dictLookupNF("F", &fileStream)->isRef()) { + ok = gFalse; + fileStream.free(); + error(errSyntaxError, -1, "Invalid FileSpec: Embedded file stream is not an indirect reference"); + obj1.free(); + return; + } + } + obj1.free(); + } + + if (fileSpec.dictLookup("Desc", &obj1)->isString()) + desc = obj1.getString()->copy(); + obj1.free(); +} + +FileSpec::~FileSpec() +{ + fileSpec.free(); + fileStream.free(); + delete fileName; + delete platformFileName; + delete embFile; + delete desc; +} + +EmbFile *FileSpec::getEmbeddedFile() +{ + if(!ok) + return NULL; + + if (embFile) + return embFile; + + Object obj1; + XRef *xref = fileSpec.getDict()->getXRef(); + embFile = new EmbFile(fileStream.fetch(xref, &obj1)); + obj1.free(); + + return embFile; +} + +GooString *FileSpec::getFileNameForPlatform() +{ + if (platformFileName) + return platformFileName; + + Object obj1; + if (getFileSpecNameForPlatform(&fileSpec, &obj1)) + platformFileName = obj1.getString()->copy(); + obj1.free(); + + return platformFileName; +} + +GBool getFileSpecName (Object *fileSpec, Object *fileName) +{ + if (fileSpec->isString()) { + fileSpec->copy(fileName); + return gTrue; + } + + if (fileSpec->isDict()) { + fileSpec->dictLookup("UF", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("F", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("DOS", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("Mac", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("Unix", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + } + return gFalse; +} + +GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName) +{ + if (fileSpec->isString()) { + fileSpec->copy(fileName); + return gTrue; + } + + if (fileSpec->isDict()) { + if (!fileSpec->dictLookup("UF", fileName)->isString ()) { + fileName->free(); + if (!fileSpec->dictLookup("F", fileName)->isString ()) { + fileName->free(); +#ifdef _WIN32 + const char *platform = "DOS"; +#else + const char *platform = "Unix"; +#endif + if (!fileSpec->dictLookup(platform, fileName)->isString ()) { + fileName->free(); + error(errSyntaxError, -1, "Illegal file spec"); + return gFalse; + } + } + } + } else { + error(errSyntaxError, -1, "Illegal file spec"); + return gFalse; + } + + // system-dependent path manipulation +#ifdef _WIN32 + int i, j; + GooString *name = fileName->getString(); + // "//...." --> "\...." + // "/x/...." --> "x:\...." + // "/server/share/...." --> "\\server\share\...." + // convert escaped slashes to slashes and unescaped slashes to backslashes + i = 0; + if (name->getChar(0) == '/') { + if (name->getLength() >= 2 && name->getChar(1) == '/') { + name->del(0); + i = 0; + } else if (name->getLength() >= 2 && + ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') || + (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) && + (name->getLength() == 2 || name->getChar(2) == '/')) { + name->setChar(0, name->getChar(1)); + name->setChar(1, ':'); + i = 2; + } else { + for (j = 2; j < name->getLength(); ++j) { + if (name->getChar(j-1) != '\\' && + name->getChar(j) == '/') { + break; + } + } + if (j < name->getLength()) { + name->setChar(0, '\\'); + name->insert(0, '\\'); + i = 2; + } + } + } + for (; i < name->getLength(); ++i) { + if (name->getChar(i) == '/') { + name->setChar(i, '\\'); + } else if (name->getChar(i) == '\\' && + i+1 < name->getLength() && + name->getChar(i+1) == '/') { + name->del(i); + } + } +#endif /* _WIN32 */ + + return gTrue; +} |