Code

Tweaked smaller size to be 3/4ths the menu size
[inkscape.git] / src / io / uristream.cpp
1 /**
2  * Our base String stream classes.  We implement these to
3  * be based on Glib::ustring
4  *
5  * Authors:
6  *   Bob Jamison <rjamison@titan.com>
7  *
8  * Copyright (C) 2004 Inkscape.org
9  *
10  * Released under GNU GPL, read the file 'COPYING' for more information
11  */
14 #include "uristream.h"
15 #include "sys.h"
17 #ifdef WIN32
18 // For now to get at is_os_wide().
19 # include "extension/internal/win32.h"
20 using Inkscape::Extension::Internal::PrintWin32;
21 #endif
24 namespace Inkscape
25 {
26 namespace IO
27 {
29 /*
30  * URI scheme types
31  */
32 #define SCHEME_NONE 0
33 #define SCHEME_FILE 1
34 #define SCHEME_DATA 2
36 /*
37  * A temporary modification of Jon Cruz's portable fopen().
38  * Simplified a bit, since we will always use binary
39 */
41 #define FILE_READ  1
42 #define FILE_WRITE 2
44 static FILE *fopen_utf8name( char const *utf8name, int mode )
45 {
46     FILE *fp = NULL;
47     if (!utf8name)
48         {
49         return NULL;
50         }
51     if (mode!=FILE_READ && mode!=FILE_WRITE)
52         {
53         return NULL;
54         }
56 #ifndef WIN32
57     gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL );
58     if ( filename ) {
59         if (mode == FILE_READ)
60             fp = std::fopen(filename, "rb");
61         else
62             fp = std::fopen(filename, "wb");
63         g_free(filename);
64     }
65 #else
66     if ( PrintWin32::is_os_wide() ) {
67         gunichar2 *wideName = g_utf8_to_utf16( utf8name, -1, NULL, NULL, NULL );
68         if ( wideName )  {
69             if (mode == FILE_READ)
70                 fp = _wfopen( (wchar_t*)wideName, L"rb" );
71             else
72                 fp = _wfopen( (wchar_t*)wideName, L"wb" );
73             g_free( wideName );
74         } else {
75             gchar *safe = Inkscape::IO::sanitizeString(utf8name);
76             g_message("Unable to convert filename from UTF-8 to UTF-16 [%s]", safe);
77             g_free(safe);
78         }
79     } else {
80         gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL );
81         if ( filename ) {
82             if (mode == FILE_READ)
83                 fp = std::fopen(filename, "rb");
84             else
85                 fp = std::fopen(filename, "wb");
86             g_free(filename);
87         }
88     }
89 #endif
91     return fp;
92 }
96 //#########################################################################
97 //# U R I    I N P U T    S T R E A M    /     R E A D E R
98 //#########################################################################
101 /**
102  *
103  */
104 UriInputStream::UriInputStream(Inkscape::URI &source)
105                     throw (StreamException): uri(source)
107     //get information from uri
108     char *schemestr = (char *) uri.getScheme();
109     scheme = SCHEME_FILE;
110     if (!schemestr || strncmp("file", schemestr, 4)==0)
111         scheme = SCHEME_FILE;
112     else if (strncmp("data", schemestr, 4)==0)
113         scheme = SCHEME_DATA;
114     //printf("in schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
115     char *cpath = NULL;
117     switch (scheme) {
119         case SCHEME_FILE:
120             cpath     = (char *) uri.toNativeFilename();
121             //printf("in cpath:'%s'\n", cpath);
122             inf = fopen_utf8name(cpath, FILE_READ);
123             //inf = fopen(cpath, "rb");
124             g_free(cpath);
125             if (!inf) {
126                 Glib::ustring err = "UriInputStream cannot open file ";
127                 err += cpath;
128                 throw StreamException(err);
129             }
130         break;
132         case SCHEME_DATA:
133             data        = (unsigned char *) uri.getPath();
134             //printf("in data:'%s'\n", data);
135             dataPos     = 0;
136             dataLen     = strlen((const char *)data);
137         break;
139     }
140     closed = false;
143 /**
144  *
145  */
146 UriInputStream::UriInputStream(FILE *source, Inkscape::URI &uri)
147     throw (StreamException): inf(source),
148                              uri(uri)
150     scheme = SCHEME_FILE;
151     if (!inf) {
152         Glib::ustring err = "UriInputStream passed NULL";
153         throw StreamException(err);
154     }
155     closed = false;
158 /**
159  *
160  */
161 UriInputStream::~UriInputStream() throw(StreamException)
163     close();
166 /**
167  * Returns the number of bytes that can be read (or skipped over) from
168  * this input stream without blocking by the next caller of a method for
169  * this input stream.
170  */
171 int UriInputStream::available() throw(StreamException)
173     return 0;
177 /**
178  *  Closes this input stream and releases any system resources
179  *  associated with the stream.
180  */
181 void UriInputStream::close() throw(StreamException)
183     if (closed)
184         return;
186     switch (scheme) {
188         case SCHEME_FILE:
189             if (!inf)
190                 return;
191             fflush(inf);
192             fclose(inf);
193             inf=NULL;
194         break;
196         case SCHEME_DATA:
197             //do nothing
198         break;
200     }//switch
202     closed = true;
205 /**
206  * Reads the next byte of data from the input stream.  -1 if EOF
207  */
208 int UriInputStream::get() throw(StreamException)
210     int retVal = -1;
211     if (!closed)
212     {
213         switch (scheme) {
215             case SCHEME_FILE:
216                 if (!inf || feof(inf))
217                 {
218                     retVal = -1;
219                 }
220                 else
221                 {
222                     retVal = fgetc(inf);
223                 }
224                 break;
226             case SCHEME_DATA:
227                 if (dataPos >= dataLen)
228                 {
229                     retVal = -1;
230                 }
231                 else
232                 {
233                     retVal = data[dataPos++];
234                 }
235                 break;
236         }//switch
237     }
238     return retVal;
246 /**
247  *
248  */
249 UriReader::UriReader(Inkscape::URI &uri)
250                     throw (StreamException)
252     inputStream = new UriInputStream(uri);
255 /**
256  *
257  */
258 UriReader::~UriReader() throw (StreamException)
260     delete inputStream;
263 /**
264  *
265  */
266 int UriReader::available() throw(StreamException)
268     return inputStream->available();
271 /**
272  *
273  */
274 void UriReader::close() throw(StreamException)
276     inputStream->close();
279 /**
280  *
281  */
282 gunichar UriReader::get() throw(StreamException)
284     gunichar ch = (gunichar)inputStream->get();
285     return ch;
289 //#########################################################################
290 //#  U R I    O U T P U T    S T R E A M    /     W R I T E R
291 //#########################################################################
293 /**
294  * Temporary kludge
295  */
296 UriOutputStream::UriOutputStream(FILE* fp, Inkscape::URI &destination)
297                     throw (StreamException): closed(false),
298                                              ownsFile(false),
299                                              outf(fp),
300                                              uri(destination),
301                                              scheme(SCHEME_FILE)
303     if (!outf) {
304         Glib::ustring err = "UriOutputStream given null file ";
305         throw StreamException(err);
306     }
309 /**
310  *
311  */
312 UriOutputStream::UriOutputStream(Inkscape::URI &destination)
313                     throw (StreamException): closed(false),
314                                              ownsFile(true),
315                                              outf(NULL),
316                                              uri(destination),
317                                              scheme(SCHEME_FILE)
319     //get information from uri
320     char *schemestr = (char *) uri.getScheme();
321     if (!schemestr || strncmp("file", schemestr, 4)==0)
322         scheme = SCHEME_FILE;
323     else if (strncmp("data", schemestr, 4)==0)
324         scheme = SCHEME_DATA;
325     //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
326     char *cpath = NULL;
328     switch (scheme) {
330         case SCHEME_FILE:
331             cpath     = (char *) uri.toNativeFilename();
332             //printf("out path:'%s'\n", cpath);
333             outf = fopen_utf8name(cpath, FILE_WRITE);
334             //outf = fopen(cpath, "wb");
335             g_free(cpath);
336             if (!outf) {
337                 Glib::ustring err = "UriOutputStream cannot open file ";
338                 err += cpath;
339                 throw StreamException(err);
340             }
341         break;
343         case SCHEME_DATA:
344             data        = "data:";
345         break;
347     }//switch
351 /**
352  *
353  */
354 UriOutputStream::~UriOutputStream() throw(StreamException)
356     close();
359 /**
360  * Closes this output stream and releases any system resources
361  * associated with this stream.
362  */
363 void UriOutputStream::close() throw(StreamException)
365     if (closed)
366         return;
368     switch (scheme) {
370         case SCHEME_FILE:
371             if (!outf)
372                 return;
373             fflush(outf);
374             if ( ownsFile )
375                 fclose(outf);
376             outf=NULL;
377         break;
379         case SCHEME_DATA:
380             uri = URI(data.raw().c_str());
381         break;
383     }//switch
385     closed = true;
388 /**
389  *  Flushes this output stream and forces any buffered output
390  *  bytes to be written out.
391  */
392 void UriOutputStream::flush() throw(StreamException)
394     if (closed)
395         return;
397     switch (scheme) {
399         case SCHEME_FILE:
400             if (!outf)
401                 return;
402             fflush(outf);
403         break;
405         case SCHEME_DATA:
406             //nothing
407         break;
409     }//switch
413 /**
414  * Writes the specified byte to this output stream.
415  */
416 void UriOutputStream::put(int ch) throw(StreamException)
418     if (closed)
419         return;
421     unsigned char uch;
422     gunichar gch;
424     switch (scheme) {
426         case SCHEME_FILE:
427             if (!outf)
428                 return;
429             uch = (unsigned char)(ch & 0xff);
430             fputc(uch, outf);
431             //fwrite(uch, 1, 1, outf);
432         break;
434         case SCHEME_DATA:
435             gch = (gunichar) ch;
436             data.push_back(gch);
437         break;
439     }//switch
447 /**
448  *
449  */
450 UriWriter::UriWriter(Inkscape::URI &uri)
451                     throw (StreamException)
453     outputStream = new UriOutputStream(uri);
456 /**
457  *
458  */
459 UriWriter::~UriWriter() throw (StreamException)
461     delete outputStream;
464 /**
465  *
466  */
467 void UriWriter::close() throw(StreamException)
469     outputStream->close();
472 /**
473  *
474  */
475 void UriWriter::flush() throw(StreamException)
477     outputStream->flush();
480 /**
481  *
482  */
483 void UriWriter::put(gunichar ch) throw(StreamException)
485     int ich = (int)ch;
486     outputStream->put(ich);
493 } // namespace IO
494 } // namespace Inkscape
497 //#########################################################################
498 //# E N D    O F    F I L E
499 //#########################################################################