1 /**\r
2 * Zlib-enabled input and output streams\r
3 *\r
4 * This is a thin wrapper of libz calls, in order\r
5 * to provide a simple interface to our developers\r
6 * for gzip input and output.\r
7 *\r
8 * Authors:\r
9 * Bob Jamison\r
10 *\r
11 * Copyright (C) 2006 Bob Jamison\r
12 *\r
13 * This library is free software; you can redistribute it and/or\r
14 * modify it under the terms of the GNU Lesser General Public\r
15 * License as published by the Free Software Foundation; either\r
16 * version 2.1 of the License, or (at your option) any later version.\r
17 *\r
18 * This library is distributed in the hope that it will be useful,\r
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
21 * Lesser General Public License for more details.\r
22 *\r
23 * You should have received a copy of the GNU Lesser General Public\r
24 * License along with this library; if not, write to the Free Software\r
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
26 */\r
27 \r
28 \r
29 \r
30 #include "gzipstream.h"\r
31 \r
32 #include "dom/util/ziptool.h"\r
33 \r
34 \r
35 namespace org\r
36 {\r
37 namespace w3c\r
38 {\r
39 namespace dom\r
40 {\r
41 namespace io\r
42 {\r
43 \r
44 \r
45 //#########################################################################\r
46 //# G Z I P I N P U T S T R E A M\r
47 //#########################################################################\r
48 \r
49 /**\r
50 *\r
51 */\r
52 GzipInputStream::GzipInputStream(InputStream &sourceStream)\r
53 : BasicInputStream(sourceStream)\r
54 {\r
55 loaded = false;\r
56 bufPos = 0;\r
57 }\r
58 \r
59 /**\r
60 *\r
61 */\r
62 GzipInputStream::~GzipInputStream()\r
63 {\r
64 close();\r
65 }\r
66 \r
67 /**\r
68 * Returns the number of bytes that can be read (or skipped over) from\r
69 * this input stream without blocking by the next caller of a method for\r
70 * this input stream.\r
71 */\r
72 int GzipInputStream::available()\r
73 {\r
74 if (closed)\r
75 return 0;\r
76 if (!loaded)\r
77 if (!load())\r
78 return 0;\r
79 return (int) buffer.size();\r
80 }\r
81 \r
82 \r
83 /**\r
84 * Closes this input stream and releases any system resources\r
85 * associated with the stream.\r
86 */\r
87 void GzipInputStream::close()\r
88 {\r
89 if (closed)\r
90 return;\r
91 \r
92 closed = true;\r
93 }\r
94 \r
95 /**\r
96 * Reads the next byte of data from the input stream. -1 if EOF\r
97 */\r
98 int GzipInputStream::get()\r
99 {\r
100 if (closed)\r
101 return -1;\r
102 \r
103 if (!loaded)\r
104 if (!load())\r
105 return -1;\r
106 \r
107 if (bufPos >= buffer.size())\r
108 return -1;\r
109 int ch = (int) buffer[bufPos++];\r
110 \r
111 return ch;\r
112 }\r
113 \r
114 /**\r
115 * Processes input. Fills read buffer.\r
116 */\r
117 bool GzipInputStream::load()\r
118 {\r
119 if (closed)\r
120 return false;\r
121 \r
122 if (loaded)\r
123 return true;\r
124 \r
125 std::vector<unsigned char> compBuf;\r
126 while (true)\r
127 {\r
128 int ch = source.get();\r
129 if (ch < 0)\r
130 break;\r
131 compBuf.push_back(ch);\r
132 }\r
133 GzipFile gz;\r
134 if (!gz.readBuffer(compBuf))\r
135 {\r
136 return -1;\r
137 }\r
138 buffer = gz.getData();\r
139 bufPos = 0;\r
140 loaded = true;\r
141 return true;\r
142 }\r
143 \r
144 \r
145 \r
146 \r
147 \r
148 \r
149 //#########################################################################\r
150 //# G Z I P O U T P U T S T R E A M\r
151 //#########################################################################\r
152 \r
153 /**\r
154 *\r
155 */\r
156 GzipOutputStream::GzipOutputStream(OutputStream &destinationStream)\r
157 : BasicOutputStream(destinationStream)\r
158 {\r
159 \r
160 closed = false;\r
161 }\r
162 \r
163 /**\r
164 *\r
165 */\r
166 GzipOutputStream::~GzipOutputStream()\r
167 {\r
168 close();\r
169 }\r
170 \r
171 /**\r
172 * Closes this output stream and releases any system resources\r
173 * associated with this stream.\r
174 */\r
175 void GzipOutputStream::close()\r
176 {\r
177 if (closed)\r
178 return;\r
179 \r
180 flush();\r
181 \r
182 closed = true;\r
183 }\r
184 \r
185 /**\r
186 * Flushes this output stream and forces any buffered output\r
187 * bytes to be written out.\r
188 */\r
189 void GzipOutputStream::flush()\r
190 {\r
191 if (closed || buffer.size()<1)\r
192 return;\r
193 \r
194 std::vector<unsigned char> compBuf;\r
195 GzipFile gz;\r
196 \r
197 gz.writeBuffer(buffer);\r
198 \r
199 std::vector<unsigned char>::iterator iter;\r
200 for (iter=compBuf.begin() ; iter!=compBuf.end() ; iter++)\r
201 {\r
202 int ch = (int) *iter;\r
203 destination.put(ch);\r
204 }\r
205 \r
206 buffer.clear();\r
207 \r
208 //printf("done\n");\r
209 \r
210 }\r
211 \r
212 \r
213 \r
214 /**\r
215 * Writes the specified byte to this output stream.\r
216 */\r
217 void GzipOutputStream::put(int ch)\r
218 {\r
219 if (closed)\r
220 {\r
221 //probably throw an exception here\r
222 return;\r
223 }\r
224 \r
225 //Add char to buffer\r
226 buffer.push_back(ch);\r
227 \r
228 }\r
229 \r
230 \r
231 \r
232 } // namespace io\r
233 } // namespace dom\r
234 } // namespace w3c\r
235 } // namespace org\r
236 \r
237 \r
238 \r
239 \r
240 //#########################################################################\r
241 //# E N D O F F I L E\r
242 //#########################################################################\r
243 \r
244 \r
245 \r