1 /**
2 * Phoebe DOM Implementation.
3 *
4 * This is a C++ approximation of the W3C DOM model, which follows
5 * fairly closely the specifications in the various .idl files, copies of
6 * which are provided for reference. Most important is this one:
7 *
8 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
9 *
10 * Authors:
11 * Bob Jamison
12 *
13 * Copyright (C) 2005-2008 Bob Jamison
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2.1 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
32 #include "uristream.h"
33 #include <cstdio>
34 #include <string.h>
37 namespace org
38 {
39 namespace w3c
40 {
41 namespace dom
42 {
43 namespace io
44 {
48 //#########################################################################
49 //# U R I I N P U T S T R E A M / R E A D E R
50 //#########################################################################
53 /**
54 *
55 */
56 UriInputStream::UriInputStream(const URI &source)
57 throw (StreamException): uri((URI &)source)
58 {
59 init();
60 }
62 /**
63 *
64 */
65 void UriInputStream::init() throw (StreamException)
66 {
67 //get information from uri
68 scheme = uri.getScheme();
70 switch (scheme)
71 {
73 case URI::SCHEME_FILE:
74 {
75 DOMString npath = uri.getNativePath();
76 inf = fopen(npath.c_str(), "rb");
77 if (!inf)
78 {
79 DOMString err = "UriInputStream cannot open file ";
80 err.append(npath);
81 throw StreamException(err);
82 }
83 break;
84 }
86 case URI::SCHEME_DATA:
87 {
88 data = uri.getPath();
89 //printf("in data:'%s'\n", data.c_str());
90 dataPos = 0;
91 dataLen = uri.getPath().size();
92 break;
93 }
95 case URI::SCHEME_HTTP:
96 case URI::SCHEME_HTTPS:
97 {
98 if (!httpClient.openGet(uri))
99 {
100 DOMString err = "UriInputStream cannot open URL ";
101 err.append(uri.toString());
102 throw StreamException(err);
103 }
104 break;
105 }
107 }
109 closed = false;
110 }
116 /**
117 *
118 */
119 UriInputStream::~UriInputStream() throw(StreamException)
120 {
121 close();
122 }
124 /**
125 * Returns the number of bytes that can be read (or skipped over) from
126 * this input stream without blocking by the next caller of a method for
127 * this input stream.
128 */
129 int UriInputStream::available() throw(StreamException)
130 {
131 return 0;
132 }
135 /**
136 * Closes this input stream and releases any system resources
137 * associated with the stream.
138 */
139 void UriInputStream::close() throw(StreamException)
140 {
141 if (closed)
142 return;
144 switch (scheme)
145 {
147 case URI::SCHEME_FILE:
148 {
149 if (!inf)
150 return;
151 fflush(inf);
152 fclose(inf);
153 inf=NULL;
154 break;
155 }
157 case URI::SCHEME_DATA:
158 {
159 //do nothing
160 break;
161 }
163 case URI::SCHEME_HTTP:
164 case URI::SCHEME_HTTPS:
165 {
166 httpClient.close();
167 break;
168 }
170 }//switch
172 closed = true;
173 }
175 /**
176 * Reads the next byte of data from the input stream. -1 if EOF
177 */
178 int UriInputStream::get() throw(StreamException)
179 {
180 int retVal = -1;
181 if (closed)
182 {
183 return -1;
184 }
186 switch (scheme)
187 {
189 case URI::SCHEME_FILE:
190 {
191 if (!inf || feof(inf))
192 {
193 retVal = -1;
194 }
195 else
196 {
197 retVal = fgetc(inf);
198 }
199 break;
200 }
202 case URI::SCHEME_DATA:
203 {
204 if (dataPos >= dataLen)
205 {
206 retVal = -1;
207 }
208 else
209 {
210 retVal = data[dataPos++];
211 }
212 break;
213 }
215 case URI::SCHEME_HTTP:
216 case URI::SCHEME_HTTPS:
217 {
218 retVal = httpClient.read();
219 break;
220 }
222 }//switch
224 return retVal;
225 }
232 /**
233 *
234 */
235 UriReader::UriReader(const URI &uri) throw (StreamException)
236 {
237 inputStream = new UriInputStream(uri);
238 }
240 /**
241 *
242 */
243 UriReader::~UriReader() throw (StreamException)
244 {
245 delete inputStream;
246 }
248 /**
249 *
250 */
251 int UriReader::available() throw(StreamException)
252 {
253 return inputStream->available();
254 }
256 /**
257 *
258 */
259 void UriReader::close() throw(StreamException)
260 {
261 inputStream->close();
262 }
264 /**
265 *
266 */
267 int UriReader::get() throw(StreamException)
268 {
269 int ch = (int)inputStream->get();
270 return ch;
271 }
274 //#########################################################################
275 //# U R I O U T P U T S T R E A M / W R I T E R
276 //#########################################################################
278 /**
279 *
280 */
281 UriOutputStream::UriOutputStream(const URI &destination)
282 throw (StreamException): closed(false),
283 ownsFile(true),
284 outf(NULL),
285 uri((URI &)destination)
286 {
287 init();
288 }
291 /**
292 *
293 */
294 void UriOutputStream::init() throw(StreamException)
295 {
296 //get information from uri
297 scheme = uri.getScheme();
299 //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
300 char *cpath = NULL;
302 switch (scheme)
303 {
305 case URI::SCHEME_FILE:
306 {
307 cpath = (char *) uri.getNativePath().c_str();
308 //printf("out path:'%s'\n", cpath);
309 outf = fopen(cpath, "wb");
310 if (!outf)
311 {
312 DOMString err = "UriOutputStream cannot open file ";
313 err += cpath;
314 throw StreamException(err);
315 }
316 break;
317 }
319 case URI::SCHEME_DATA:
320 {
321 data = "data:";
322 break;
323 }
325 }//switch
326 }
328 /**
329 *
330 */
331 UriOutputStream::~UriOutputStream() throw(StreamException)
332 {
333 close();
334 }
336 /**
337 * Closes this output stream and releases any system resources
338 * associated with this stream.
339 */
340 void UriOutputStream::close() throw(StreamException)
341 {
342 if (closed)
343 return;
345 switch (scheme)
346 {
348 case URI::SCHEME_FILE:
349 {
350 if (!outf)
351 return;
352 fflush(outf);
353 if ( ownsFile )
354 fclose(outf);
355 outf=NULL;
356 break;
357 }
359 case URI::SCHEME_DATA:
360 {
361 uri = URI(data);
362 break;
363 }
365 }//switch
367 closed = true;
368 }
371 /**
372 * Flushes this output stream and forces any buffered output
373 * bytes to be written out.
374 */
375 void UriOutputStream::flush() throw(StreamException)
376 {
377 if (closed)
378 return;
380 switch (scheme)
381 {
383 case URI::SCHEME_FILE:
384 {
385 if (!outf)
386 return;
387 fflush(outf);
388 break;
389 }
391 case URI::SCHEME_DATA:
392 {
393 //nothing
394 break;
395 }
397 }//switch
399 }
401 /**
402 * Writes the specified byte to this output stream.
403 */
404 int UriOutputStream::put(XMLCh ch) throw(StreamException)
405 {
406 if (closed)
407 return -1;
409 switch (scheme)
410 {
412 case URI::SCHEME_FILE:
413 {
414 if (!outf)
415 return -1;
416 unsigned char uch = (unsigned char)(ch & 0xff);
417 fputc(uch, outf);
418 //fwrite(uch, 1, 1, outf);
419 break;
420 }
422 case URI::SCHEME_DATA:
423 {
424 data.push_back(ch);
425 break;
426 }
428 }//switch
429 return 1;
430 }
436 /**
437 *
438 */
439 UriWriter::UriWriter(const URI &uri)
440 throw (StreamException)
441 {
442 outputStream = new UriOutputStream(uri);
443 }
445 /**
446 *
447 */
448 UriWriter::~UriWriter() throw (StreamException)
449 {
450 delete outputStream;
451 }
453 /**
454 *
455 */
456 void UriWriter::close() throw(StreamException)
457 {
458 outputStream->close();
459 }
461 /**
462 *
463 */
464 void UriWriter::flush() throw(StreamException)
465 {
466 outputStream->flush();
467 }
469 /**
470 *
471 */
472 int UriWriter::put(XMLCh ch) throw(StreamException)
473 {
474 int ich = (int)ch;
475 if (outputStream->put(ich) < 0)
476 return -1;
477 return 1;
478 }
484 } //namespace io
485 } //namespace dom
486 } //namespace w3c
487 } //namespace org
490 //#########################################################################
491 //# E N D O F F I L E
492 //#########################################################################