aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/old/ps_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/old/ps_extractor.c')
-rw-r--r--src/plugins/old/ps_extractor.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/plugins/old/ps_extractor.c b/src/plugins/old/ps_extractor.c
new file mode 100644
index 0000000..7fdb9d6
--- /dev/null
+++ b/src/plugins/old/ps_extractor.c
@@ -0,0 +1,197 @@
1/*
2 This file is part of libextractor.
3 (C) 2002, 2003, 2009 Vidyut Samanta and Christian Grothoff
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21#include "platform.h"
22#include "extractor.h"
23
24
25static char *
26readline (const char *data, size_t size, size_t pos)
27{
28 size_t end;
29 char *res;
30
31 while ((pos < size) &&
32 ((data[pos] == (char) 0x0d) || (data[pos] == (char) 0x0a)))
33 pos++;
34
35 if (pos >= size)
36 return NULL; /* end of file */
37 end = pos;
38 while ((end < size) &&
39 (data[end] != (char) 0x0d) && (data[end] != (char) 0x0a))
40 end++;
41 res = malloc (end - pos + 1);
42 if (res == NULL)
43 return NULL;
44 memcpy (res, &data[pos], end - pos);
45 res[end - pos] = '\0';
46
47 return res;
48}
49
50
51static int
52testmeta (char *line,
53 const char *match,
54 enum EXTRACTOR_MetaType type,
55 EXTRACTOR_MetaDataProcessor proc,
56 void *proc_cls)
57{
58 char *key;
59
60 if ( (strncmp (line, match, strlen (match)) == 0) &&
61 (strlen (line) > strlen (match)) )
62 {
63 if ((line[strlen (line) - 1] == ')') && (line[strlen (match)] == '('))
64 {
65 key = &line[strlen (match) + 1];
66 key[strlen (key) - 1] = '\0'; /* remove ")" */
67 }
68 else
69 {
70 key = &line[strlen (match)];
71 }
72 if (0 != proc (proc_cls,
73 "ps",
74 type,
75 EXTRACTOR_METAFORMAT_UTF8,
76 "text/plain",
77 key,
78 strlen (key)+1))
79 return 1;
80 }
81 return 0;
82}
83
84typedef struct
85{
86 const char *prefix;
87 enum EXTRACTOR_MetaType type;
88} Matches;
89
90static Matches tests[] = {
91 {"%%Title: ", EXTRACTOR_METATYPE_TITLE},
92 {"%%Author: ", EXTRACTOR_METATYPE_AUTHOR_NAME},
93 {"%%Version: ", EXTRACTOR_METATYPE_REVISION_NUMBER},
94 {"%%Creator: ", EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE},
95 {"%%CreationDate: ", EXTRACTOR_METATYPE_CREATION_DATE},
96 {"%%Pages: ", EXTRACTOR_METATYPE_PAGE_COUNT},
97 {"%%Orientation: ", EXTRACTOR_METATYPE_PAGE_ORIENTATION},
98 {"%%DocumentPaperSizes: ", EXTRACTOR_METATYPE_PAPER_SIZE},
99 {"%%PageOrder: ", EXTRACTOR_METATYPE_PAGE_ORDER},
100 {"%%LanguageLevel: ", EXTRACTOR_METATYPE_FORMAT_VERSION},
101 {"%%Magnification: ", EXTRACTOR_METATYPE_MAGNIFICATION},
102
103 /* Also widely used but not supported since they
104 probably make no sense:
105 "%%BoundingBox: ",
106 "%%DocumentNeededResources: ",
107 "%%DocumentSuppliedResources: ",
108 "%%DocumentProcSets: ",
109 "%%DocumentData: ", */
110
111 {NULL, 0}
112};
113
114#define PS_HEADER "%!PS-Adobe"
115
116/* mimetype = application/postscript */
117int
118EXTRACTOR_ps_extract (const char *data,
119 size_t size,
120 EXTRACTOR_MetaDataProcessor proc,
121 void *proc_cls,
122 const char *options)
123{
124 size_t pos;
125 char *line;
126 int i;
127 int lastLine;
128 int ret;
129
130 pos = strlen (PS_HEADER);
131 if ( (size < pos) ||
132 (0 != strncmp (PS_HEADER,
133 data,
134 pos)) )
135 return 0;
136 ret = 0;
137
138 if (0 != proc (proc_cls,
139 "ps",
140 EXTRACTOR_METATYPE_MIMETYPE,
141 EXTRACTOR_METAFORMAT_UTF8,
142 "text/plain",
143 "application/postscript",
144 strlen ("application/postscript")+1))
145 return 1;
146 /* skip rest of first line */
147 while ((pos < size) && (data[pos] != '\n'))
148 pos++;
149
150 lastLine = -1;
151 line = NULL;
152 /* while Windows-PostScript does not seem to (always?) put
153 "%%EndComments", this should allow us to not read through most of
154 the file for all the sane applications... For Windows-generated
155 PS files, we will bail out at the end of the file. */
156 while ( (line == NULL) ||
157 (0 != strncmp ("%%EndComments", line, strlen ("%%EndComments"))) )
158 {
159 if (line != NULL)
160 free (line);
161 line = readline (data, size, pos);
162 if (line == NULL)
163 break;
164 i = 0;
165 while (tests[i].prefix != NULL)
166 {
167 ret = testmeta (line, tests[i].prefix, tests[i].type, proc, proc_cls);
168 if (ret != 0)
169 break;
170 i++;
171 }
172 if (ret != 0)
173 break;
174
175 /* %%+ continues previous meta-data type... */
176 if ( (lastLine != -1) && (0 == strncmp (line, "%%+ ", strlen ("%%+ "))))
177 {
178 ret = testmeta (line, "%%+ ", tests[lastLine].type, proc, proc_cls);
179 }
180 else
181 {
182 /* update "previous" type */
183 if (tests[i].prefix == NULL)
184 lastLine = -1;
185 else
186 lastLine = i;
187 }
188 if (pos + strlen (line) + 1 <= pos)
189 break; /* overflow */
190 pos += strlen (line) + 1; /* skip newline, too; guarantee progress! */
191 }
192 if (line != NULL)
193 free (line);
194 return ret;
195}
196
197/* end of ps_extractor.c */