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 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 */
30 /**
31 * Our base String stream classes. We implement these to
32 * be based on DOMString
33 *
34 * Authors:
35 * Bob Jamison <rjamison@titan.com>
36 *
37 * Copyright (C) 2004 Inkscape.org
38 *
39 * Released under GNU GPL, read the file 'COPYING' for more information
40 */
43 #include "uristream.h"
47 namespace org
48 {
49 namespace w3c
50 {
51 namespace dom
52 {
53 namespace io
54 {
58 //#########################################################################
59 //# U R I I N P U T S T R E A M / R E A D E R
60 //#########################################################################
63 /**
64 *
65 */
66 UriInputStream::UriInputStream(const URI &source)
67 throw (StreamException): uri((URI &)source)
68 {
69 init();
70 }
72 /**
73 *
74 */
75 void UriInputStream::init() throw (StreamException)
76 {
77 //get information from uri
78 scheme = uri.getScheme();
80 //printf("in scheme:'%d'\n", scheme);
81 DOMString path = uri.getPath();
82 //printf("in path:'%s'\n", path.c_str());
84 switch (scheme)
85 {
87 case URI::SCHEME_FILE:
88 {
89 inf = fopen(path.c_str(), "rb");
90 if (!inf)
91 {
92 DOMString err = "UriInputStream cannot open file ";
93 err.append(path);
94 throw StreamException(err);
95 }
96 break;
97 }
99 case URI::SCHEME_DATA:
100 {
101 data = (unsigned char *) uri.getPath().c_str();
102 //printf("in data:'%s'\n", data);
103 dataPos = 0;
104 dataLen = strlen((const char *)data);
105 break;
106 }
108 case URI::SCHEME_HTTP:
109 case URI::SCHEME_HTTPS:
110 {
111 if (!httpClient.openGet(uri))
112 {
113 DOMString err = "UriInputStream cannot open URL ";
114 err.append(uri.toString());
115 throw StreamException(err);
116 }
117 break;
118 }
120 }
122 closed = false;
123 }
129 /**
130 *
131 */
132 UriInputStream::~UriInputStream() throw(StreamException)
133 {
134 close();
135 }
137 /**
138 * Returns the number of bytes that can be read (or skipped over) from
139 * this input stream without blocking by the next caller of a method for
140 * this input stream.
141 */
142 int UriInputStream::available() throw(StreamException)
143 {
144 return 0;
145 }
148 /**
149 * Closes this input stream and releases any system resources
150 * associated with the stream.
151 */
152 void UriInputStream::close() throw(StreamException)
153 {
154 if (closed)
155 return;
157 switch (scheme)
158 {
160 case URI::SCHEME_FILE:
161 {
162 if (!inf)
163 return;
164 fflush(inf);
165 fclose(inf);
166 inf=NULL;
167 break;
168 }
170 case URI::SCHEME_DATA:
171 {
172 //do nothing
173 break;
174 }
176 case URI::SCHEME_HTTP:
177 case URI::SCHEME_HTTPS:
178 {
179 httpClient.close();
180 break;
181 }
183 }//switch
185 closed = true;
186 }
188 /**
189 * Reads the next byte of data from the input stream. -1 if EOF
190 */
191 int UriInputStream::get() throw(StreamException)
192 {
193 int retVal = -1;
194 if (closed)
195 {
196 return -1;
197 }
199 switch (scheme)
200 {
202 case URI::SCHEME_FILE:
203 {
204 if (!inf || feof(inf))
205 {
206 retVal = -1;
207 }
208 else
209 {
210 retVal = fgetc(inf);
211 }
212 break;
213 }
215 case URI::SCHEME_DATA:
216 {
217 if (dataPos >= dataLen)
218 {
219 retVal = -1;
220 }
221 else
222 {
223 retVal = data[dataPos++];
224 }
225 break;
226 }
228 case URI::SCHEME_HTTP:
229 case URI::SCHEME_HTTPS:
230 {
231 retVal = httpClient.read();
232 break;
233 }
235 }//switch
237 return retVal;
238 }
245 /**
246 *
247 */
248 UriReader::UriReader(const URI &uri) throw (StreamException)
249 {
250 inputStream = new UriInputStream(uri);
251 }
253 /**
254 *
255 */
256 UriReader::~UriReader() throw (StreamException)
257 {
258 delete inputStream;
259 }
261 /**
262 *
263 */
264 int UriReader::available() throw(StreamException)
265 {
266 return inputStream->available();
267 }
269 /**
270 *
271 */
272 void UriReader::close() throw(StreamException)
273 {
274 inputStream->close();
275 }
277 /**
278 *
279 */
280 int UriReader::get() throw(StreamException)
281 {
282 int ch = (int)inputStream->get();
283 return ch;
284 }
287 //#########################################################################
288 //# U R I O U T P U T S T R E A M / W R I T E R
289 //#########################################################################
291 /**
292 *
293 */
294 UriOutputStream::UriOutputStream(const URI &destination)
295 throw (StreamException): closed(false),
296 ownsFile(true),
297 outf(NULL),
298 uri((URI &)destination)
299 {
300 init();
301 }
304 /**
305 *
306 */
307 void UriOutputStream::init() throw(StreamException)
308 {
309 //get information from uri
310 scheme = uri.getScheme();
312 //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
313 char *cpath = NULL;
315 switch (scheme)
316 {
318 case URI::SCHEME_FILE:
319 {
320 cpath = (char *) uri.getPath().c_str();
321 //printf("out path:'%s'\n", cpath);
322 outf = fopen(cpath, "wb");
323 if (!outf)
324 {
325 DOMString err = "UriOutputStream cannot open file ";
326 err += cpath;
327 throw StreamException(err);
328 }
329 break;
330 }
332 case URI::SCHEME_DATA:
333 {
334 data = "data:";
335 break;
336 }
338 }//switch
339 }
341 /**
342 *
343 */
344 UriOutputStream::~UriOutputStream() throw(StreamException)
345 {
346 close();
347 }
349 /**
350 * Closes this output stream and releases any system resources
351 * associated with this stream.
352 */
353 void UriOutputStream::close() throw(StreamException)
354 {
355 if (closed)
356 return;
358 switch (scheme)
359 {
361 case URI::SCHEME_FILE:
362 {
363 if (!outf)
364 return;
365 fflush(outf);
366 if ( ownsFile )
367 fclose(outf);
368 outf=NULL;
369 break;
370 }
372 case URI::SCHEME_DATA:
373 {
374 uri = URI(data.c_str());
375 break;
376 }
378 }//switch
380 closed = true;
381 }
383 /**
384 * Flushes this output stream and forces any buffered output
385 * bytes to be written out.
386 */
387 void UriOutputStream::flush() throw(StreamException)
388 {
389 if (closed)
390 return;
392 switch (scheme)
393 {
395 case URI::SCHEME_FILE:
396 {
397 if (!outf)
398 return;
399 fflush(outf);
400 break;
401 }
403 case URI::SCHEME_DATA:
404 {
405 //nothing
406 break;
407 }
409 }//switch
411 }
413 /**
414 * Writes the specified byte to this output stream.
415 */
416 void UriOutputStream::put(XMLCh ch) throw(StreamException)
417 {
418 if (closed)
419 return;
421 switch (scheme)
422 {
424 case URI::SCHEME_FILE:
425 {
426 if (!outf)
427 return;
428 unsigned char uch = (unsigned char)(ch & 0xff);
429 fputc(uch, outf);
430 //fwrite(uch, 1, 1, outf);
431 break;
432 }
434 case URI::SCHEME_DATA:
435 {
436 data.push_back(ch);
437 break;
438 }
440 }//switch
442 }
448 /**
449 *
450 */
451 UriWriter::UriWriter(const URI &uri)
452 throw (StreamException)
453 {
454 outputStream = new UriOutputStream(uri);
455 }
457 /**
458 *
459 */
460 UriWriter::~UriWriter() throw (StreamException)
461 {
462 delete outputStream;
463 }
465 /**
466 *
467 */
468 void UriWriter::close() throw(StreamException)
469 {
470 outputStream->close();
471 }
473 /**
474 *
475 */
476 void UriWriter::flush() throw(StreamException)
477 {
478 outputStream->flush();
479 }
481 /**
482 *
483 */
484 void UriWriter::put(XMLCh ch) throw(StreamException)
485 {
486 int ich = (int)ch;
487 outputStream->put(ich);
488 }
494 } //namespace io
495 } //namespace dom
496 } //namespace w3c
497 } //namespace org
500 //#########################################################################
501 //# E N D O F F I L E
502 //#########################################################################