Code

Fix build failure
[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"
16 #include <string>
17 #include <cstring>
19 #ifdef WIN32
20 // For now to get at is_os_wide().
21 # include "extension/internal/win32.h"
22 using Inkscape::Extension::Internal::PrintWin32;
23 #endif
26 namespace Inkscape
27 {
28 namespace IO
29 {
31 /*
32  * URI scheme types
33  */
34 #define SCHEME_NONE 0
35 #define SCHEME_FILE 1
36 #define SCHEME_DATA 2
38 /*
39  * A temporary modification of Jon Cruz's portable fopen().
40  * Simplified a bit, since we will always use binary
41 */
43 #define FILE_READ  1
44 #define FILE_WRITE 2
46 static FILE *fopen_utf8name( char const *utf8name, int mode )
47 {
48     FILE *fp = NULL;
49     if (!utf8name)
50         {
51         return NULL;
52         }
53     if (mode!=FILE_READ && mode!=FILE_WRITE)
54         {
55         return NULL;
56         }
58 #ifndef WIN32
59     gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL );
60     if ( filename ) {
61         if (mode == FILE_READ)
62             fp = std::fopen(filename, "rb");
63         else
64             fp = std::fopen(filename, "wb");
65         g_free(filename);
66     }
67 #else
68     if ( PrintWin32::is_os_wide() ) {
69         gunichar2 *wideName = g_utf8_to_utf16( utf8name, -1, NULL, NULL, NULL );
70         if ( wideName )  {
71             if (mode == FILE_READ)
72                 fp = _wfopen( (wchar_t*)wideName, L"rb" );
73             else
74                 fp = _wfopen( (wchar_t*)wideName, L"wb" );
75             g_free( wideName );
76         } else {
77             gchar *safe = Inkscape::IO::sanitizeString(utf8name);
78             g_message("Unable to convert filename from UTF-8 to UTF-16 [%s]", safe);
79             g_free(safe);
80         }
81     } else {
82         gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL );
83         if ( filename ) {
84             if (mode == FILE_READ)
85                 fp = std::fopen(filename, "rb");
86             else
87                 fp = std::fopen(filename, "wb");
88             g_free(filename);
89         }
90     }
91 #endif
93     return fp;
94 }
98 //#########################################################################
99 //# U R I    I N P U T    S T R E A M    /     R E A D E R
100 //#########################################################################
103 /**
104  *
105  */
106 UriInputStream::UriInputStream(Inkscape::URI &source)
107                     throw (StreamException): uri(source)
109     //get information from uri
110     char const *schemestr = uri.getScheme();
111     scheme = SCHEME_FILE;
112     if (!schemestr || strncmp("file", schemestr, 4)==0)
113         scheme = SCHEME_FILE;
114     else if (strncmp("data", schemestr, 4)==0)
115         scheme = SCHEME_DATA;
116     //printf("in schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
117     gchar *cpath = NULL;
119     switch (scheme) {
121         case SCHEME_FILE:
122             cpath = uri.toNativeFilename();
123             //printf("in cpath:'%s'\n", cpath);
124             inf = fopen_utf8name(cpath, FILE_READ);
125             //inf = fopen(cpath, "rb");
126             g_free(cpath);
127             if (!inf) {
128                 Glib::ustring err = "UriInputStream cannot open file ";
129                 err += cpath;
130                 throw StreamException(err);
131             }
132         break;
134         case SCHEME_DATA:
135             data        = (unsigned char *) uri.getPath();
136             //printf("in data:'%s'\n", data);
137             dataPos     = 0;
138             dataLen     = strlen((const char *)data);
139         break;
141     }
142     closed = false;
145 /**
146  *
147  */
148 UriInputStream::UriInputStream(FILE *source, Inkscape::URI &uri)
149     throw (StreamException): inf(source),
150                              uri(uri)
152     scheme = SCHEME_FILE;
153     if (!inf) {
154         Glib::ustring err = "UriInputStream passed NULL";
155         throw StreamException(err);
156     }
157     closed = false;
160 /**
161  *
162  */
163 UriInputStream::~UriInputStream() throw(StreamException)
165     close();
168 /**
169  * Returns the number of bytes that can be read (or skipped over) from
170  * this input stream without blocking by the next caller of a method for
171  * this input stream.
172  */
173 int UriInputStream::available() throw(StreamException)
175     return 0;
179 /**
180  *  Closes this input stream and releases any system resources
181  *  associated with the stream.
182  */
183 void UriInputStream::close() throw(StreamException)
185     if (closed)
186         return;
188     switch (scheme) {
190         case SCHEME_FILE:
191             if (!inf)
192                 return;
193             fflush(inf);
194             fclose(inf);
195             inf=NULL;
196         break;
198         case SCHEME_DATA:
199             //do nothing
200         break;
202     }//switch
204     closed = true;
207 /**
208  * Reads the next byte of data from the input stream.  -1 if EOF
209  */
210 int UriInputStream::get() throw(StreamException)
212     int retVal = -1;
213     if (!closed)
214     {
215         switch (scheme) {
217             case SCHEME_FILE:
218                 if (!inf || feof(inf))
219                 {
220                     retVal = -1;
221                 }
222                 else
223                 {
224                     retVal = fgetc(inf);
225                 }
226                 break;
228             case SCHEME_DATA:
229                 if (dataPos >= dataLen)
230                 {
231                     retVal = -1;
232                 }
233                 else
234                 {
235                     retVal = data[dataPos++];
236                 }
237                 break;
238         }//switch
239     }
240     return retVal;
248 /**
249  *
250  */
251 UriReader::UriReader(Inkscape::URI &uri)
252                     throw (StreamException)
254     inputStream = new UriInputStream(uri);
257 /**
258  *
259  */
260 UriReader::~UriReader() throw (StreamException)
262     delete inputStream;
265 /**
266  *
267  */
268 int UriReader::available() throw(StreamException)
270     return inputStream->available();
273 /**
274  *
275  */
276 void UriReader::close() throw(StreamException)
278     inputStream->close();
281 /**
282  *
283  */
284 gunichar UriReader::get() throw(StreamException)
286     gunichar ch = (gunichar)inputStream->get();
287     return ch;
291 //#########################################################################
292 //#  U R I    O U T P U T    S T R E A M    /     W R I T E R
293 //#########################################################################
295 /**
296  * Temporary kludge
297  */
298 UriOutputStream::UriOutputStream(FILE* fp, Inkscape::URI &destination)
299                     throw (StreamException): closed(false),
300                                              ownsFile(false),
301                                              outf(fp),
302                                              uri(destination),
303                                              scheme(SCHEME_FILE)
305     if (!outf) {
306         Glib::ustring err = "UriOutputStream given null file ";
307         throw StreamException(err);
308     }
311 /**
312  *
313  */
314 UriOutputStream::UriOutputStream(Inkscape::URI &destination)
315                     throw (StreamException): closed(false),
316                                              ownsFile(true),
317                                              outf(NULL),
318                                              uri(destination),
319                                              scheme(SCHEME_FILE)
321     //get information from uri
322     char const *schemestr = uri.getScheme();
323     if (!schemestr || strncmp("file", schemestr, 4)==0)
324         scheme = SCHEME_FILE;
325     else if (strncmp("data", schemestr, 4)==0)
326         scheme = SCHEME_DATA;
327     //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme);
328     gchar *cpath = NULL;
330     switch (scheme) {
332         case SCHEME_FILE:
333             cpath = uri.toNativeFilename();
334             //printf("out path:'%s'\n", cpath);
335             outf = fopen_utf8name(cpath, FILE_WRITE);
336             //outf = fopen(cpath, "wb");
337             g_free(cpath);
338             if (!outf) {
339                 Glib::ustring err = "UriOutputStream cannot open file ";
340                 err += cpath;
341                 throw StreamException(err);
342             }
343         break;
345         case SCHEME_DATA:
346             data        = "data:";
347         break;
349     }//switch
353 /**
354  *
355  */
356 UriOutputStream::~UriOutputStream() throw(StreamException)
358     close();
361 /**
362  * Closes this output stream and releases any system resources
363  * associated with this stream.
364  */
365 void UriOutputStream::close() throw(StreamException)
367     if (closed)
368         return;
370     switch (scheme) {
372         case SCHEME_FILE:
373             if (!outf)
374                 return;
375             fflush(outf);
376             if ( ownsFile )
377                 fclose(outf);
378             outf=NULL;
379         break;
381         case SCHEME_DATA:
382             uri = URI(data.raw().c_str());
383         break;
385     }//switch
387     closed = true;
390 /**
391  *  Flushes this output stream and forces any buffered output
392  *  bytes to be written out.
393  */
394 void UriOutputStream::flush() throw(StreamException)
396     if (closed)
397         return;
399     switch (scheme) {
401         case SCHEME_FILE:
402             if (!outf)
403                 return;
404             fflush(outf);
405         break;
407         case SCHEME_DATA:
408             //nothing
409         break;
411     }//switch
415 /**
416  * Writes the specified byte to this output stream.
417  */
418 void UriOutputStream::put(int ch) throw(StreamException)
420     if (closed)
421         return;
423     unsigned char uch;
424     gunichar gch;
426     switch (scheme) {
428         case SCHEME_FILE:
429             if (!outf)
430                 return;
431             uch = (unsigned char)(ch & 0xff);
432             if (fputc(uch, outf) == EOF) {
433                 Glib::ustring err = "ERROR writing to file ";
434                 throw StreamException(err);
435             }
436             //fwrite(uch, 1, 1, outf);
437         break;
439         case SCHEME_DATA:
440             gch = (gunichar) ch;
441             data.push_back(gch);
442         break;
444     }//switch
452 /**
453  *
454  */
455 UriWriter::UriWriter(Inkscape::URI &uri)
456                     throw (StreamException)
458     outputStream = new UriOutputStream(uri);
461 /**
462  *
463  */
464 UriWriter::~UriWriter() throw (StreamException)
466     delete outputStream;
469 /**
470  *
471  */
472 void UriWriter::close() throw(StreamException)
474     outputStream->close();
477 /**
478  *
479  */
480 void UriWriter::flush() throw(StreamException)
482     outputStream->flush();
485 /**
486  *
487  */
488 void UriWriter::put(gunichar ch) throw(StreamException)
490     int ich = (int)ch;
491     outputStream->put(ich);
498 } // namespace IO
499 } // namespace Inkscape
502 //#########################################################################
503 //# E N D    O F    F I L E
504 //#########################################################################