source: subversion/applications/utils/export/osm2pgsql/input.c @ 9252

Last change on this file since 9252 was 7397, checked in by martinvoosterhout, 12 years ago

Try harder to get large file pointers working

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