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

Last change on this file since 4318 was 4318, checked in by martinvoosterhout, 13 years ago

Patch supplied by David Siegel on the mailing list, with editorialisation by
moi.

File size: 3.2 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 (!strcmp(name, "-"))
95        name = "/dev/stdin";
96
97    if (ext && !strcmp(ext, ".gz")) {
98        ctx->fileHandle = (void *)gzopen(name, "rb");
99        ctx->type = gzipFile;
100    } else if (ext && !strcmp(ext, ".bz2")) {
101        ctx->fileHandle = (void *)BZ2_bzopen(name, "rb");
102        ctx->type = bzip2File;
103    } else {
104        int *pfd = malloc(sizeof(pfd));
105        if (pfd) {
106            int flags = O_RDONLY;
107#ifndef 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        ctx->fileHandle = (void *)pfd;
117        ctx->type = plainFile;
118    }
119    if (!ctx->fileHandle) {
120        fprintf(stderr, "error while opening file %s\n", name);
121        exit(10);
122    }
123    ctx->buf_ptr = 0;
124    ctx->buf_fill = 0;
125    return (void *)ctx;
126}
127
128int inputClose(void *context)
129{
130    struct Input *ctx = context;
131    void *f = ctx->fileHandle;
132
133    switch(ctx->type) {
134        case plainFile:
135            close(*(int *)f);
136            free(f);
137            break;
138        case gzipFile:
139            gzclose((gzFile)f);
140            break;
141        case bzip2File:
142            BZ2_bzclose((BZFILE *)f);
143            break;
144        default:
145            fprintf(stderr, "Bad file type\n");
146            break;
147    }
148
149    free(ctx->name);
150    free(ctx);
151    return 0;
152}
Note: See TracBrowser for help on using the repository browser.