source: subversion/applications/utils/planetdiff/input.c @ 30601

Last change on this file since 30601 was 4778, checked in by jonb, 12 years ago

planetdiff: Version 0.3. Ignore objects which only differ by timestamp. Turn off UTF8sanitizer. Whitelist planet.c. Prevent null de-ref if generator string is not present

File size: 3.6 KB
Line 
1#define _LARGEFILE64_SOURCE
2
3#include <stdio.h>
4#include <unistd.h>
5#include <string.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9#include <zlib.h>
10#include <bzlib.h>
11
12#include "sanitizer.h"
13#include "input.h"
14
15struct Input {
16    char *name;
17    enum { plainFile, gzipFile, bzip2File } type;
18    void *fileHandle;
19    int eof;
20    char buf[4096];
21    int buf_ptr, buf_fill;
22};
23
24int readFile(void *context, char * buffer, int len)
25{
26    struct Input *ctx = context;
27    void *f = ctx->fileHandle;
28    int l = 0;
29
30    if (ctx->eof || (len == 0))
31        return 0;
32 
33    switch(ctx->type) {
34        case plainFile:
35            l = read(*(int *)f, buffer, len);
36            break;
37        case gzipFile:
38            l = gzread((gzFile)f, buffer, len);
39            break;
40        case bzip2File:
41            l = BZ2_bzread((BZFILE *)f, buffer, len);
42            break;
43        default:
44            fprintf(stderr, "Bad file type\n");
45            break;
46    }
47
48    if (l < 0) {
49        fprintf(stderr, "File reader received error %d\n", l);
50        l = 0;
51    }
52    if (!l)
53        ctx->eof = 1;
54
55    return l;
56}
57
58char inputGetChar(void *context)
59{
60    struct Input *ctx = context;
61
62    if (ctx->buf_ptr == ctx->buf_fill) {
63        ctx->buf_fill = readFile(context, &ctx->buf[0], sizeof(ctx->buf));
64        ctx->buf_ptr = 0;
65        if (ctx->buf_fill == 0)
66            return 0;
67        if (ctx->buf_fill < 0) {
68            perror("Error while reading file");
69            exit(1);
70        }
71    }
72    //readFile(context, &c, 1);
73    return ctx->buf[ctx->buf_ptr++];
74}
75
76int inputEof(void *context)
77{
78    return ((struct Input *)context)->eof;
79}
80
81
82void *inputOpen(const char *name)
83{
84    const char *ext = strrchr(name, '.');
85    struct Input *ctx = malloc (sizeof(*ctx));
86
87    if (!ctx)
88        return NULL;
89
90    memset(ctx, 0, sizeof(*ctx));
91
92    ctx->name = strdup(name);
93
94    if (ext && !strcmp(ext, ".gz")) {
95        ctx->fileHandle = (void *)gzopen(name, "rb");
96        ctx->type = gzipFile;
97    } else if (ext && !strcmp(ext, ".bz2")) {
98        ctx->fileHandle = (void *)BZ2_bzopen(name, "rb");
99        ctx->type = bzip2File;
100    } else {
101        int *pfd = malloc(sizeof(pfd));
102        if (pfd) {
103            if (!strcmp(name, "-")) {
104                *pfd = STDIN_FILENO;
105            } else {
106                int flags = O_RDONLY;
107#ifdef O_LARGEFILE
108                flags |= O_LARGEFILE;
109#endif
110                *pfd = open(name, flags);
111                if (*pfd < 0) {
112                    free(pfd);
113                    pfd = NULL;
114                }
115            }
116        }
117        ctx->fileHandle = (void *)pfd;
118        ctx->type = plainFile;
119    }
120    if (!ctx->fileHandle) {
121        fprintf(stderr, "error while opening file %s\n", name);
122        exit(10);
123    }
124    ctx->buf_ptr = 0;
125    ctx->buf_fill = 0;
126    return (void *)ctx;
127}
128
129int inputClose(void *context)
130{
131    struct Input *ctx = context;
132    void *f = ctx->fileHandle;
133
134    switch(ctx->type) {
135        case plainFile:
136            close(*(int *)f);
137            free(f);
138            break;
139        case gzipFile:
140            gzclose((gzFile)f);
141            break;
142        case bzip2File:
143            BZ2_bzclose((BZFILE *)f);
144            break;
145        default:
146            fprintf(stderr, "Bad file type\n");
147            break;
148    }
149
150    free(ctx->name);
151    free(ctx);
152    return 0;
153}
154
155xmlTextReaderPtr inputUTF8(const char *name)
156{
157    void *ctx = inputOpen(name);
158
159    if (!ctx) {
160        fprintf(stderr, "Input reader create failed for: %s\n", name);
161        return NULL;
162    }
163
164    return xmlReaderForIO(readFile, inputClose, (void *)ctx, NULL, NULL, 0);
165}
Note: See TracBrowser for help on using the repository browser.