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 switch (scheme)
81 {
83 case URI::SCHEME_FILE:
84 {
85 DOMString npath = uri.getNativePath();
86 inf = fopen(npath.c_str(), "rb");
87 if (!inf)
88 {
89 DOMString err = "UriInputStream cannot open file ";
90 err.append(npath);
91 throw StreamException(err);
92 }
93 break;
94 }
96 case URI::SCHEME_DATA:
97 {
98 DOMString path = uri.getPath();
99 data = (unsigned char *) uri.getPath().c_str();
100 //printf("in data:'%s'\n", data);
101 dataPos = 0;
102 dataLen = strlen((const char *)data);
103 break;
104 }
106 case URI::SCHEME_HTTP:
107 case URI::SCHEME_HTTPS:
108 {
109 if (!httpClient.openGet(uri))
110 {
111 DOMString err = "UriInputStream cannot open URL ";
112 err.append(uri.toString());
113 throw StreamException(err);
114 }
115 break;
116 }
118 }
120 closed = false;
121 }
127 /**
128 *
129 */
130 UriInputStream::~UriInputStream() throw(StreamException)
131 {
132 close();
133 }
135 /**
136 * Returns the number of bytes that can be read (or skipped over) from
137 * this input stream without blocking by the next caller of a method for
138 * this input stream.
139 */
140 int UriInputStream::available() throw(StreamException)
141 {
142 return 0;
143 }
146 /**
147 * Closes this input stream and releases any system resources
148 * associated with the stream.
149 */
150 void UriInputStream::close() throw(StreamException)
151 {
152 if (closed)
153 return;
155 switch (scheme)
156 {
158 case URI::SCHEME_FILE:
159 {
160 if (!inf)
161 return;
162 fflush(inf);
163 fclose(inf);
164 inf=NULL;
165 break;
166 }
168 case URI::SCHEME_DATA:
169 {
170 //do nothing
171 break;
172 }
174 case URI::SCHEME_HTTP:
175 case URI::SCHEME_HTTPS:
176 {
177 httpClient.close();
178 break;
179 }
181 }//switch
183 closed = true;
184 }
186 /**
187 * Reads the next byte of data from the input stream. -1 if EOF
188 */
189 int UriInputStream::get() throw(StreamException)
190 {
191 int retVal = -1;
192 if (closed)
193 {
194 return -1;
195 }
197 switch (scheme)
198 {
200 case URI::SCHEME_FILE:
201 {
202 if (!inf || feof(inf))
203 {
204 retVal = -1;
205 }
206 else
207 {
208 retVal = fgetc(inf);
209 }
210 break;
211 }
213 case URI::SCHEME_DATA:
214 {
215 if (dataPos >= dataLen)
216 {
217 retVal = -1;
218 }
219 else
220 {
221 retVal = data[dataPos++];
222 }
223 break;
224 }
226 case URI::SCHEME_HTTP:
227 case URI::SCHEME_HTTPS:
228 {
229 retVal = httpClient.read();
230 break;
231 }
233 }//switch
235 return retVal;
236 }
243 /**
244 *
245 */
246 UriReader::UriReader(const URI &uri) throw (StreamException)
247 {
248 inputStream = new UriInputStream(uri);
249 }
251 /**
252 *
253 */
254 UriReader::~UriReader() throw (StreamException)
255 {
256 delete inputStream;
257 }
259 /**
260 *
261 */
262 int UriReader::available() throw(StreamException)
263 {
264 return inputStream->available();
265 }
267 /**
268 *
269 */
270 void UriReader::close() throw(StreamException)
271 {
272 inputStream->close();
273 }
275 /**
276 *
277 */
278 int UriReader::get() throw(StreamException)
279 {
280 int ch = (int)inputStream->get();
281 return ch;
282 }
285 //#########################################################################
286 //# U R I O U T P U T S T R E A M / W R I T E R
287 //#########################################################################
289 /**
290 *
291 */
292 UriOutputStream::UriOutputStream(const URI &destination)
293 throw (StreamException): closed(false),
294 ownsFile(true),
295 outf(NULL),
296 uri((URI &)destination)
297 {
298 init();
299 }
302 /**
303 *
304 */
305 void UriOutputStream::init() throw(StreamException)
306 {
307 //get information from uri
308 scheme = uri.getScheme();
310 //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
311 char *cpath = NULL;
313 switch (scheme)
314 {
316 case URI::SCHEME_FILE:
317 {
318 cpath = (char *) uri.getNativePath().c_str();
319 //printf("out path:'%s'\n", cpath);
320 outf = fopen(cpath, "wb");
321 if (!outf)
322 {
323 DOMString err = "UriOutputStream cannot open file ";
324 err += cpath;
325 throw StreamException(err);
326 }
327 break;
328 }
330 case URI::SCHEME_DATA:
331 {
332 data = "data:";
333 break;
334 }
336 }//switch
337 }
339 /**
340 *
341 */
342 UriOutputStream::~UriOutputStream() throw(StreamException)
343 {
344 close();
345 }
347 /**
348 * Closes this output stream and releases any system resources
349 * associated with this stream.
350 */
351 void UriOutputStream::close() throw(StreamException)
352 {
353 if (closed)
354 return;
356 switch (scheme)
357 {
359 case URI::SCHEME_FILE:
360 {
361 if (!outf)
362 return;
363 fflush(outf);
364 if ( ownsFile )
365 fclose(outf);
366 outf=NULL;
367 break;
368 }
370 case URI::SCHEME_DATA:
371 {
372 uri = URI(data.c_str());
373 break;
374 }
376 }//switch
378 closed = true;
379 }
381 /**
382 * Flushes this output stream and forces any buffered output
383 * bytes to be written out.
384 */
385 void UriOutputStream::flush() throw(StreamException)
386 {
387 if (closed)
388 return;
390 switch (scheme)
391 {
393 case URI::SCHEME_FILE:
394 {
395 if (!outf)
396 return;
397 fflush(outf);
398 break;
399 }
401 case URI::SCHEME_DATA:
402 {
403 //nothing
404 break;
405 }
407 }//switch
409 }
411 /**
412 * Writes the specified byte to this output stream.
413 */
414 int UriOutputStream::put(XMLCh ch) throw(StreamException)
415 {
416 if (closed)
417 return -1;
419 switch (scheme)
420 {
422 case URI::SCHEME_FILE:
423 {
424 if (!outf)
425 return -1;
426 unsigned char uch = (unsigned char)(ch & 0xff);
427 fputc(uch, outf);
428 //fwrite(uch, 1, 1, outf);
429 break;
430 }
432 case URI::SCHEME_DATA:
433 {
434 data.push_back(ch);
435 break;
436 }
438 }//switch
439 return 1;
440 }
446 /**
447 *
448 */
449 UriWriter::UriWriter(const URI &uri)
450 throw (StreamException)
451 {
452 outputStream = new UriOutputStream(uri);
453 }
455 /**
456 *
457 */
458 UriWriter::~UriWriter() throw (StreamException)
459 {
460 delete outputStream;
461 }
463 /**
464 *
465 */
466 void UriWriter::close() throw(StreamException)
467 {
468 outputStream->close();
469 }
471 /**
472 *
473 */
474 void UriWriter::flush() throw(StreamException)
475 {
476 outputStream->flush();
477 }
479 /**
480 *
481 */
482 int UriWriter::put(XMLCh ch) throw(StreamException)
483 {
484 int ich = (int)ch;
485 if (outputStream->put(ich) < 0)
486 return -1;
487 return 1;
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 //#########################################################################