source: subversion/applications/utils/coastcheck/input.c @ 9744

Last change on this file since 9744 was 6729, checked in by martinvoosterhout, 12 years ago

Initial commit of the coastline checker. It's been used for a while now
successfully.

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