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 <string.h>
36 namespace org
37 {
38 namespace w3c
39 {
40 namespace dom
41 {
42 namespace io
43 {
47 //#########################################################################
48 //# U R I I N P U T S T R E A M / R E A D E R
49 //#########################################################################
52 /**
53 *
54 */
55 UriInputStream::UriInputStream(const URI &source)
56 throw (StreamException): uri((URI &)source)
57 {
58 init();
59 }
61 /**
62 *
63 */
64 void UriInputStream::init() throw (StreamException)
65 {
66 //get information from uri
67 scheme = uri.getScheme();
69 switch (scheme)
70 {
72 case URI::SCHEME_FILE:
73 {
74 DOMString npath = uri.getNativePath();
75 inf = fopen(npath.c_str(), "rb");
76 if (!inf)
77 {
78 DOMString err = "UriInputStream cannot open file ";
79 err.append(npath);
80 throw StreamException(err);
81 }
82 break;
83 }
85 case URI::SCHEME_DATA:
86 {
87 data = uri.getPath();
88 //printf("in data:'%s'\n", data.c_str());
89 dataPos = 0;
90 dataLen = uri.getPath().size();
91 break;
92 }
94 case URI::SCHEME_HTTP:
95 case URI::SCHEME_HTTPS:
96 {
97 if (!httpClient.openGet(uri))
98 {
99 DOMString err = "UriInputStream cannot open URL ";
100 err.append(uri.toString());
101 throw StreamException(err);
102 }
103 break;
104 }
106 }
108 closed = false;
109 }
115 /**
116 *
117 */
118 UriInputStream::~UriInputStream() throw(StreamException)
119 {
120 close();
121 }
123 /**
124 * Returns the number of bytes that can be read (or skipped over) from
125 * this input stream without blocking by the next caller of a method for
126 * this input stream.
127 */
128 int UriInputStream::available() throw(StreamException)
129 {
130 return 0;
131 }
134 /**
135 * Closes this input stream and releases any system resources
136 * associated with the stream.
137 */
138 void UriInputStream::close() throw(StreamException)
139 {
140 if (closed)
141 return;
143 switch (scheme)
144 {
146 case URI::SCHEME_FILE:
147 {
148 if (!inf)
149 return;
150 fflush(inf);
151 fclose(inf);
152 inf=NULL;
153 break;
154 }
156 case URI::SCHEME_DATA:
157 {
158 //do nothing
159 break;
160 }
162 case URI::SCHEME_HTTP:
163 case URI::SCHEME_HTTPS:
164 {
165 httpClient.close();
166 break;
167 }
169 }//switch
171 closed = true;
172 }
174 /**
175 * Reads the next byte of data from the input stream. -1 if EOF
176 */
177 int UriInputStream::get() throw(StreamException)
178 {
179 int retVal = -1;
180 if (closed)
181 {
182 return -1;
183 }
185 switch (scheme)
186 {
188 case URI::SCHEME_FILE:
189 {
190 if (!inf || feof(inf))
191 {
192 retVal = -1;
193 }
194 else
195 {
196 retVal = fgetc(inf);
197 }
198 break;
199 }
201 case URI::SCHEME_DATA:
202 {
203 if (dataPos >= dataLen)
204 {
205 retVal = -1;
206 }
207 else
208 {
209 retVal = data[dataPos++];
210 }
211 break;
212 }
214 case URI::SCHEME_HTTP:
215 case URI::SCHEME_HTTPS:
216 {
217 retVal = httpClient.read();
218 break;
219 }
221 }//switch
223 return retVal;
224 }
231 /**
232 *
233 */
234 UriReader::UriReader(const URI &uri) throw (StreamException)
235 {
236 inputStream = new UriInputStream(uri);
237 }
239 /**
240 *
241 */
242 UriReader::~UriReader() throw (StreamException)
243 {
244 delete inputStream;
245 }
247 /**
248 *
249 */
250 int UriReader::available() throw(StreamException)
251 {
252 return inputStream->available();
253 }
255 /**
256 *
257 */
258 void UriReader::close() throw(StreamException)
259 {
260 inputStream->close();
261 }
263 /**
264 *
265 */
266 int UriReader::get() throw(StreamException)
267 {
268 int ch = (int)inputStream->get();
269 return ch;
270 }
273 //#########################################################################
274 //# U R I O U T P U T S T R E A M / W R I T E R
275 //#########################################################################
277 /**
278 *
279 */
280 UriOutputStream::UriOutputStream(const URI &destination)
281 throw (StreamException): closed(false),
282 ownsFile(true),
283 outf(NULL),
284 uri((URI &)destination)
285 {
286 init();
287 }
290 /**
291 *
292 */
293 void UriOutputStream::init() throw(StreamException)
294 {
295 //get information from uri
296 scheme = uri.getScheme();
298 //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
299 char *cpath = NULL;
301 switch (scheme)
302 {
304 case URI::SCHEME_FILE:
305 {
306 cpath = (char *) uri.getNativePath().c_str();
307 //printf("out path:'%s'\n", cpath);
308 outf = fopen(cpath, "wb");
309 if (!outf)
310 {
311 DOMString err = "UriOutputStream cannot open file ";
312 err += cpath;
313 throw StreamException(err);
314 }
315 break;
316 }
318 case URI::SCHEME_DATA:
319 {
320 data = "data:";
321 break;
322 }
324 }//switch
325 }
327 /**
328 *
329 */
330 UriOutputStream::~UriOutputStream() throw(StreamException)
331 {
332 close();
333 }
335 /**
336 * Closes this output stream and releases any system resources
337 * associated with this stream.
338 */
339 void UriOutputStream::close() throw(StreamException)
340 {
341 if (closed)
342 return;
344 switch (scheme)
345 {
347 case URI::SCHEME_FILE:
348 {
349 if (!outf)
350 return;
351 fflush(outf);
352 if ( ownsFile )
353 fclose(outf);
354 outf=NULL;
355 break;
356 }
358 case URI::SCHEME_DATA:
359 {
360 uri = URI(data);
361 break;
362 }
364 }//switch
366 closed = true;
367 }
370 /**
371 * Flushes this output stream and forces any buffered output
372 * bytes to be written out.
373 */
374 void UriOutputStream::flush() throw(StreamException)
375 {
376 if (closed)
377 return;
379 switch (scheme)
380 {
382 case URI::SCHEME_FILE:
383 {
384 if (!outf)
385 return;
386 fflush(outf);
387 break;
388 }
390 case URI::SCHEME_DATA:
391 {
392 //nothing
393 break;
394 }
396 }//switch
398 }
400 /**
401 * Writes the specified byte to this output stream.
402 */
403 int UriOutputStream::put(XMLCh ch) throw(StreamException)
404 {
405 if (closed)
406 return -1;
408 switch (scheme)
409 {
411 case URI::SCHEME_FILE:
412 {
413 if (!outf)
414 return -1;
415 unsigned char uch = (unsigned char)(ch & 0xff);
416 fputc(uch, outf);
417 //fwrite(uch, 1, 1, outf);
418 break;
419 }
421 case URI::SCHEME_DATA:
422 {
423 data.push_back(ch);
424 break;
425 }
427 }//switch
428 return 1;
429 }
435 /**
436 *
437 */
438 UriWriter::UriWriter(const URI &uri)
439 throw (StreamException)
440 {
441 outputStream = new UriOutputStream(uri);
442 }
444 /**
445 *
446 */
447 UriWriter::~UriWriter() throw (StreamException)
448 {
449 delete outputStream;
450 }
452 /**
453 *
454 */
455 void UriWriter::close() throw(StreamException)
456 {
457 outputStream->close();
458 }
460 /**
461 *
462 */
463 void UriWriter::flush() throw(StreamException)
464 {
465 outputStream->flush();
466 }
468 /**
469 *
470 */
471 int UriWriter::put(XMLCh ch) throw(StreamException)
472 {
473 int ich = (int)ch;
474 if (outputStream->put(ich) < 0)
475 return -1;
476 return 1;
477 }
483 } //namespace io
484 } //namespace dom
485 } //namespace w3c
486 } //namespace org
489 //#########################################################################
490 //# E N D O F F I L E
491 //#########################################################################