Súbor: [Platon] / cpdf / parse.c (stiahnutie)
Revízia 1.10, Tue Oct 8 19:46:49 2002 UTC (21 years, 6 months ago) by lynx
Zmeny od 1.9: +55 -20
[lines]
Parser for multiple trailers and xref tables;
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "cpdf.h"
#include "parse.h"
#include "utils.h"
/* function compute number of locations of char c from buffer to character c
*/
int strlenc(char *buffer, char c, char to)
{
int i = 0;
while (*buffer && *buffer != to) {
if (*buffer == c)
i++;
buffer++;
}
return i;
}
/* function compute lenght of string to char to
*/
int strlento(char *buffer, char to)
{
int i = 0;
while (*buffer && *buffer != to) {
i++;
buffer++;
}
return i;
}
/* convert hex to bin
*/
char *hex(char *buffer)
{
char *hex_array, *end;
char num[5] = { '0', 'x', '\0', '\0', '\0' };
int i;
if (*buffer != '<')
return NULL;
if ((i = strlento(buffer + 1, '>') >> 1) == 0)
return NULL;
end = hex_array = (char *) xmalloc(i);
for (buffer++; *buffer != '>'; hex_array++) {
num[2] = *buffer;
if (*(buffer + 1) == '>') {
num[3] = '0';
buffer++;
} else {
num[3] = *(buffer + 1);
buffer += 2;
}
*hex_array = (char) strtoul((char *) &num, NULL, 16);
}
return end;
}
/* interpreter for special characters in name string */
char *name(char *buffer)
{
char *ret, *end;
char num[5] = { '0', 'x', '\0', '\0', '\0' };
if (*buffer != '/')
return NULL;
if (memchr(buffer, '#', MAXNAMELEN) == NULL)
return buffer;
end = ret = (char *) xmalloc(MAXNAMELEN);
while (*buffer && *buffer != ' ') {
if (*buffer == '#') {
num[2] = *(buffer + 1);
num[3] = *(buffer + 2);
*ret = (char) strtoul((char *) &num, NULL, 16);
ret++;
buffer += 3;
}
*ret = *buffer;
ret++;
buffer++;
}
return end;
}
/* parse arrays */
char **array(char *buffer)
{
char **ret = NULL;
int end = 1, len, index = 0;
if (*buffer != '[')
return NULL;
ret[index] = (char *) xmalloc(1);
*ret[index] = '[';
index++;
buffer += 2;
do {
if (*buffer == ']')
end--;
if (*buffer == '[')
end++;
len = strlento(buffer, ' ');
ret[index] = (char *) xmalloc(len);
strncpy(ret[index], buffer, len);
buffer += len + 1;
index++;
} while (end > 0);
return ret;
}
#define BUFLEN 255
void read_obj(long offset)
{
char buffer[BUFLEN];
int obj_num, size = 0;
struct object *obj =
(struct object *) xcalloc(sizeof(struct object), 1);
fseek(fp, offset, SEEK_SET);
fget(buffer, BUFLEN, fp);
sscanf(buffer, "%d ", &obj_num);
fget(buffer, BUFLEN, fp);
while (!strstr(buffer, "endobj")) {
size += strlen(buffer) + 1;
obj->unparsed = resize(obj->unparsed, size);
strcat(obj->unparsed, buffer);
fget(buffer, BUFLEN, fp);
}
object[obj_num] = obj;
return;
}
/* obj->type = UNKNOWN;
obj->obj = NULL;
if(!strstr(&buffer[0],"<<")) {
obj->type = NOTYPE;
obj->obj = fill_data();
}
while (buffer[0] != '>' && buffer[1] != '>'
&& obj->type == UNKNOWN) {
if (!strncmp(&buffer[0], "/Type", 5)) {
if (!strncmp(&buffer[7], "Page", 4)) {
obj->type = PAGE;
}
if (!strncmp(&buffer[7], "Pages", 5)) {
obj->type = PAGES;
}
if (!strncmp(&buffer[7], "Catalog", 7)) {
obj->type = CATALOG;
}
if (!strncmp(&buffer[7], "Encoding", 8)) {
obj->type = ENCODING;
}
if (!strncmp(&buffer[7], "XObject", 7)) {
obj->type = XOBJECT;
}
}
if (!strncmp(&buffer[0], "/Font", 5)) {
obj->type = FONT;
}
if (!strncmp(&buffer[0], "stream", 7)) {
obj->type = CONTENT;
}
fget(&buffer[0], BUFLEN, fp);
}*/
void add_obj(char *s)
{
long offset, old_off;
sscanf(s, "%ld ", &offset);
old_off = ftell(fp);
read_obj(offset);
fseek(fp, old_off, SEEK_SET);
}
long get_startxref(void)
{
char startxref[XREFLINE];
long offset;
int i = XREFLINE - 2;
startxref[XREFLINE - 1] = '\0';
fstat(fp->_fileno, &fpstat);
offset = fpstat.st_size - 8;
fseek(fp, offset, SEEK_SET);
while (1) {
startxref[i] = fgetc(fp);
if (startxref[i] == '\r' || startxref[i] == '\n')
break;
i--;
offset--;
fseek(fp, offset, SEEK_SET);
}
return strtoul(&startxref[i + 1], NULL, 10);
}
/* find objects */
void xref(void)
{
char xref[XREFLINE];
long offset = 0;
offset = get_startxref();
fseek(fp, offset, SEEK_SET);
fget(xref, XREFLINE, fp);
if (strstr(xref, "xref") == NULL) {
/* error */
return;
}
object = (struct object **) xmalloc(sizeof(struct object));
obj_count = 1;
{
int entry[2];
do {
fget(xref, XREFLINE, fp);
sscanf(xref, "%d %d", &entry[0], &entry[1]);
if (entry[0] + entry[1] > obj_count) {
object =
(struct object **) realloc(object,
entry[0] +
entry[1] + 1);
obj_count = entry[0] + entry[1];
}
if (!entry[0])
fseek(fp, 20, SEEK_CUR);
fget(xref, XREFLINE, fp);
while (strncmp(xref, "trailer", 7)) {
add_obj(&xref[0]);
fget(xref, XREFLINE, fp);
}
fseek(fp, 3, SEEK_CUR);
fget(xref, XREFLINE, fp);
trailer.prev = 0;
while (xref[0] != '>' && xref[1] != '>') {
if (!strncmp(xref, "/Root", 5))
sscanf(xref, "/Root %d 0 R\n",
&trailer.root);
if (!strncmp(xref, "/Info", 5))
sscanf(xref, "/Info %d 0 R\n",
&trailer.info);
if (!strncmp(xref, "/Prev", 5))
sscanf(xref, "/Prev %ld",
&trailer.prev);
fget(xref, XREFLINE, fp);
}
if (!trailer.prev)
break;
fseek(fp, trailer.prev, SEEK_SET);
} while (1);
}
return;
}
int parse_pdf(void)
{
xref();
return 0;
}
Platon Group <platon@platon.sk> http://platon.sk/
|