Commit 996d2e17 authored by Carlos Garcia Campos's avatar Carlos Garcia Campos

Unify multiple File Specification parsers

parent 31f3eb2d
......@@ -143,6 +143,7 @@ set(poppler_SRCS
poppler/Decrypt.cc
poppler/Dict.cc
poppler/Error.cc
poppler/FileSpec.cc
poppler/FontEncodingTables.cc
poppler/Form.cc
poppler/FontInfo.cc
......@@ -272,6 +273,7 @@ if(ENABLE_XPDF_HEADERS)
poppler/Decrypt.h
poppler/Dict.h
poppler/Error.h
poppler/FileSpec.h
poppler/FontEncodingTables.h
poppler/FontInfo.h
poppler/Form.h
......
//========================================================================
//
// FileSpec.cc
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
//
// 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"
GBool getFileSpecName (Object *fileSpec, Object *fileName)
{
if (fileSpec->isString()) {
fileSpec->copy(fileName);
return gTrue;
}
if (fileSpec->isDict()) {
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();
fileSpec->dictLookup("F", fileName);
if (fileName->isString()) {
return gTrue;
}
fileName->free();
}
return gFalse;
}
GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName)
{
if (fileSpec->isString()) {
fileSpec->copy(fileName);
return gTrue;
}
Object obj1;
GooString *name;
name = NULL;
if (fileSpec->isDict()) {
#ifdef WIN32
if (!fileSpec->dictLookup("DOS", &obj1)->isString()) {
#else
if (!fileSpec->dictLookup("Unix", &obj1)->isString()) {
#endif
obj1.free();
fileSpec->dictLookup("F", &obj1);
}
if (obj1.isString()) {
name = obj1.getString()->copy();
} else {
error(-1, "Illegal file spec in link");
}
obj1.free();
// error
} else {
error(-1, "Illegal file spec in link");
}
// system-dependent path manipulation
if (name) {
#ifdef WIN32
int i, j;
// "//...." --> "\...."
// "/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);
}
}
#else
// no manipulation needed for Unix
#endif
} else {
return gFalse;
}
fileName->initString (name);
return gTrue;
}
//========================================================================
//
// FileSpec.h
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
//
// 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
//
//========================================================================
#ifndef FILE_SPEC_H
#define FILE_SPEC_H
#include "goo/gtypes.h"
#include "Object.h"
GBool getFileSpecName (Object *fileSpec, Object *fileName);
GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName);
#endif /* FILE_SPEC_H */
......@@ -40,6 +40,7 @@
#include "Link.h"
#include "Sound.h"
#include "Movie.h"
#include "FileSpec.h"
//------------------------------------------------------------------------
// LinkAction
......@@ -136,90 +137,6 @@ LinkAction *LinkAction::parseAction(Object *obj, GooString *baseURI) {
return action;
}
GooString *LinkAction::getFileSpecName(Object *fileSpecObj) {
GooString *name;
Object obj1;
name = NULL;
// string
if (fileSpecObj->isString()) {
name = fileSpecObj->getString()->copy();
// dictionary
} else if (fileSpecObj->isDict()) {
#ifdef WIN32
if (!fileSpecObj->dictLookup("DOS", &obj1)->isString()) {
#else
if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) {
#endif
obj1.free();
fileSpecObj->dictLookup("F", &obj1);
}
if (obj1.isString()) {
name = obj1.getString()->copy();
} else {
error(-1, "Illegal file spec in link");
}
obj1.free();
// error
} else {
error(-1, "Illegal file spec in link");
}
// system-dependent path manipulation
if (name) {
#ifdef WIN32
int i, j;
// "//...." --> "\...."
// "/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);
}
}
#else
// no manipulation needed for Unix
#endif
}
return name;
}
//------------------------------------------------------------------------
// LinkDest
//------------------------------------------------------------------------
......@@ -505,7 +422,10 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
namedDest = NULL;
// get file name
fileName = getFileSpecName(fileSpecObj);
Object obj1;
getFileSpecNameForPlatform (fileSpecObj, &obj1);
fileName = obj1.getString()->copy();
obj1.free();
// named destination
if (destObj->isName()) {
......@@ -542,20 +462,24 @@ LinkGoToR::~LinkGoToR() {
//------------------------------------------------------------------------
LinkLaunch::LinkLaunch(Object *actionObj) {
Object obj1, obj2;
Object obj1, obj2, obj3;
fileName = NULL;
params = NULL;
if (actionObj->isDict()) {
if (!actionObj->dictLookup("F", &obj1)->isNull()) {
fileName = getFileSpecName(&obj1);
getFileSpecNameForPlatform (&obj1, &obj3);
fileName = obj3.getString()->copy();
obj3.free();
} else {
obj1.free();
#ifdef WIN32
if (actionObj->dictLookup("Win", &obj1)->isDict()) {
obj1.dictLookup("F", &obj2);
fileName = getFileSpecName(&obj2);
getFileSpecNameForPlatform (&obj2, &obj3);
fileName = obj3.getString()->copy();
obj3.free();
obj2.free();
if (obj1.dictLookup("P", &obj2)->isString()) {
params = obj2.getString()->copy();
......@@ -569,7 +493,9 @@ LinkLaunch::LinkLaunch(Object *actionObj) {
//~ just like the Win dictionary until they say otherwise.
if (actionObj->dictLookup("Unix", &obj1)->isDict()) {
obj1.dictLookup("F", &obj2);
fileName = getFileSpecName(&obj2);
getFileSpecNameForPlatform (&obj2, &obj3);
fileName = obj3.getString()->copy();
obj3.free();
obj2.free();
if (obj1.dictLookup("P", &obj2)->isString()) {
params = obj2.getString()->copy();
......
......@@ -70,10 +70,6 @@ public:
// Parse an action dictionary.
static LinkAction *parseAction(Object *obj, GooString *baseURI = NULL);
// Extract a file name from a file specification (string or
// dictionary).
static GooString *getFileSpecName(Object *fileSpecObj);
};
//------------------------------------------------------------------------
......
......@@ -155,6 +155,7 @@ poppler_include_HEADERS = \
Decrypt.h \
Dict.h \
Error.h \
FileSpec.h \
FontEncodingTables.h \
FontInfo.h \
Form.h \
......@@ -224,6 +225,7 @@ libpoppler_la_SOURCES = \
Decrypt.cc \
Dict.cc \
Error.cc \
FileSpec.cc \
FontEncodingTables.cc \
Form.cc \
FontInfo.cc \
......
......@@ -54,6 +54,7 @@
#include "Annot.h"
#include "XRef.h"
#include "PreScanOutputDev.h"
#include "FileSpec.h"
#if HAVE_SPLASH
# include "splash/Splash.h"
# include "splash/SplashBitmap.h"
......@@ -5647,7 +5648,7 @@ void PSOutputDev::opiBegin20(GfxState *state, Dict *dict) {
writePS("%%Distilled\n");
dict->lookup("F", &obj1);
if (getFileSpec(&obj1, &obj2)) {
if (getFileSpecName(&obj1, &obj2)) {
writePSFmt("%%ImageFileName: {0:t}\n", obj2.getString());
obj2.free();
}
......@@ -5763,7 +5764,7 @@ void PSOutputDev::opiBegin13(GfxState *state, Dict *dict) {
writePS("opiMatrix setmatrix\n");
dict->lookup("F", &obj1);
if (getFileSpec(&obj1, &obj2)) {
if (getFileSpecName(&obj1, &obj2)) {
writePSFmt("%ALDImageFileName: {0:t}\n", obj2.getString());
obj2.free();
}
......@@ -6014,36 +6015,6 @@ void PSOutputDev::opiEnd(GfxState *state, Dict *opiDict) {
}
}
}
GBool PSOutputDev::getFileSpec(Object *fileSpec, Object *fileName) {
if (fileSpec->isString()) {
fileSpec->copy(fileName);
return gTrue;
}
if (fileSpec->isDict()) {
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();
fileSpec->dictLookup("F", fileName);
if (fileName->isString()) {
return gTrue;
}
fileName->free();
}
return gFalse;
}
#endif // OPI_SUPPORT
void PSOutputDev::type3D0(GfxState *state, double wx, double wy) {
......
......@@ -319,7 +319,6 @@ private:
void opiBegin13(GfxState *state, Dict *dict);
void opiTransform(GfxState *state, double x0, double y0,
double *x1, double *y1);
GBool getFileSpec(Object *fileSpec, Object *fileName);
#endif
void cvtFunction(Function *func);
void writePSChar(char c);
......
......@@ -20,7 +20,7 @@
#include "Object.h"
#include "Sound.h"
#include "Stream.h"
#include "Link.h"
#include "FileSpec.h"
Sound *Sound::parseSound(Object *obj)
{
......@@ -65,9 +65,12 @@ Sound::Sound(Object *obj, bool readAttrs)
Dict *dict = streamObj->getStream()->getDict();
dict->lookup("F", &tmp);
if (!tmp.isNull()) {
Object obj1;
// valid 'F' key -> external file
kind = soundExternal;
fileName = LinkAction::getFileSpecName(&tmp);
getFileSpecNameForPlatform (&tmp, &obj1);
fileName = obj1.getString()->copy();
obj1.free();
} else {
// no file specification, then the sound data have to be
// extracted from the stream
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment