SVN checkout 11/12/2010
[monav:monav.git] / plugins / osmimporter / bz2input.h
1 /*
2 Copyright 2010  Christian Vetter veaac.fdirct@gmail.com
3
4 This file is part of MoNav.
5
6 MoNav is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 MoNav is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with MoNav.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef BZ2INPUT_H
21 #define BZ2INPUT_H
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <bzlib.h>
26 #include <libxml/xmlreader.h>
27 #include <QtDebug>
28
29 struct Context {
30         FILE* file;
31         BZFILE* bz2;
32         bool closed;
33         int error;
34         unsigned char unused[BZ_MAX_UNUSED];
35 };
36
37 static bool nextStream( Context* context )
38 {
39         char* unusedPointer;
40         int numberOfUnused;
41
42         BZ2_bzReadGetUnused( &context->error, context->bz2, (void**) &unusedPointer, &numberOfUnused );
43         if ( context->error != BZ_OK )
44                 return false;
45
46         for ( int i = 0; i < numberOfUnused; i++ )
47                 context->unused[i] = unusedPointer[i];
48
49         BZ2_bzReadClose( &context->error, context->bz2 );
50         if ( context->error != BZ_OK )
51                 return false;
52
53         context->bz2 = BZ2_bzReadOpen( &context->error, context->file, 0, 0, context->unused, numberOfUnused );
54         if ( context->error != BZ_OK || context->bz2 == NULL )
55                 return false;
56
57         return true;
58 }
59
60 static int readFile( void* pointer, char* buffer, int len )
61 {
62         Context* context = (Context*) pointer;
63         if ( len == 0 || context->closed )
64                 return 0;
65
66         int read = 0;
67         while( read != len ) {
68                 read += BZ2_bzRead( &context->error, context->bz2, buffer + read, len - read );
69                 if ( context->error == BZ_OK )
70                         break;
71
72                 if ( context->error == BZ_STREAM_END ) {
73                         if ( !nextStream( context ) ) {
74                                 context->closed = true;
75                                 break;
76                         }
77                         continue;
78                 }
79
80                 context->closed = true;
81
82                 if ( context->error == BZ_UNEXPECTED_EOF )
83                         return read;
84                 return 0;
85         }
86         return read;
87 }
88
89 static int inputClose( void *pointer )
90 {
91         Context* context = (Context*) pointer;
92         BZ2_bzReadClose( &context->error, context->bz2 );
93         fclose( context->file );
94         delete context;
95         return 0;
96 }
97
98 static xmlTextReaderPtr getBz2Reader( const char* name )
99 {
100         Context* context = new Context;
101         context->closed = false;
102         context->file = fopen( name, "r" );
103         int error;
104         context->bz2 = BZ2_bzReadOpen( &error, context->file, 0, 0, NULL, 0 );
105         if ( context->bz2 == NULL || context->file == NULL ) {
106                 delete context;
107                 return NULL;
108         }
109
110         return xmlReaderForIO( readFile, inputClose, (void*) context, NULL, NULL, 0 );
111 }
112
113 #endif // BZ2INPUT_H