Code

Translations. French translation minor update.
[inkscape.git] / src / dom / io / base64stream.cpp
1 /**
2  * Phoebe DOM Implementation.
3  *
4  * Base64-enabled input and output streams
5  *
6  * This class allows easy encoding and decoding
7  * of Base64 data with a stream interface, hiding
8  * the implementation from the user.
9  *
10  * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
11  *
12  * Authors:
13  *   Bob Jamison
14  *
15  * Copyright (C) 2006 Bob Jamison
16  *
17  *  This library is free software; you can redistribute it and/or
18  *  modify it under the terms of the GNU Lesser General Public
19  *  License as published by the Free Software Foundation; either
20  *  version 2.1 of the License, or (at your option) any later version.
21  *
22  *  This library is distributed in the hope that it will be useful,
23  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
24  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  *  Lesser General Public License for more details.
26  *
27  *  You should have received a copy of the GNU Lesser General Public
28  *  License along with this library; if not, write to the Free Software
29  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
30  */
34 #include "base64stream.h"
37 namespace org
38 {
39 namespace w3c
40 {
41 namespace dom
42 {
43 namespace io
44 {
47 //#########################################################################
48 //# B A S E 6 4    I N P U T    S T R E A M
49 //#########################################################################
51 static int base64decode[] =
52 {
53 /*00*/    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
54 /*08*/    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
55 /*10*/    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
56 /*18*/    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
57 /*20*/    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
58 /*28*/    -1,   -1,   -1,   62,   -1,   -1,   -1,   63,
59 /*30*/    52,   53,   54,   55,   56,   57,   58,   59,
60 /*38*/    60,   61,   -1,   -1,   -1,   -1,   -1,   -1,
61 /*40*/    -1,    0,    1,    2,    3,    4,    5,    6,
62 /*48*/     7,    8,    9,   10,   11,   12,   13,   14,
63 /*50*/    15,   16,   17,   18,   19,   20,   21,   22,
64 /*58*/    23,   24,   25,   -1,   -1,   -1,   -1,   -1,
65 /*60*/    -1,   26,   27,   28,   29,   30,   31,   32,
66 /*68*/    33,   34,   35,   36,   37,   38,   39,   40,
67 /*70*/    41,   42,   43,   44,   45,   46,   47,   48,
68 /*78*/    49,   50,   51,   -1,   -1,   -1,   -1,   -1
69 };
72 /**
73  *
74  */
75 Base64InputStream::Base64InputStream(InputStream &sourceStream)
76                     : BasicInputStream(sourceStream)
77 {
78     outCount = 0;
79     padCount = 0;
80     closed   = false;
81     done     = false;
82 }
84 /**
85  *
86  */
87 Base64InputStream::~Base64InputStream()
88 {
89     close();
90 }
92 /**
93  * Returns the number of bytes that can be read (or skipped over) from
94  * this input stream without blocking by the next caller of a method for
95  * this input stream.
96  */
97 int Base64InputStream::available()
98 {
99     if (closed )
100         return 0;
101     int len = source.available() * 2 / 3;
102     return len;
106 /**
107  *  Closes this input stream and releases any system resources
108  *  associated with the stream.
109  */
110 void Base64InputStream::close()
112     if (closed)
113         return;
114     source.close();
115     closed = true;
118 /**
119  * Reads the next byte of data from the input stream.  -1 if EOF
120  */
121 int Base64InputStream::get()
123     if (closed)
124         return -1;
126     if (outCount - padCount > 0)
127         {
128         return outBytes[3-(outCount--)];
129         }
131     if (done)
132         return -1;
134     int inBytes[4];
135     int inCount = 0;
136     while (inCount < 4)
137         {
138         int ch = source.get();
139         if (ch < 0)
140             {
141             while (inCount < 4)  //pad if needed
142                 {
143                 inBytes[inCount++] = 0;
144                 padCount++;
145                 }
146             done = true;
147             break;
148             }
149         if (isspace(ch)) //ascii whitespace
150             {
151             //nothing
152             }
153         else if (ch == '=') //padding
154             {
155             inBytes[inCount++] = 0;
156             padCount++;
157             }
158         else
159             {
160             int byteVal = base64decode[ch & 0x7f];
161             //printf("char:%c %d\n", ch, byteVal);
162             if (byteVal < 0)
163                 {
164                 //Bad lookup value
165                 }
166             inBytes[inCount++] = byteVal;
167             }
168         }
170     outBytes[0] = ((inBytes[0]<<2) & 0xfc) | ((inBytes[1]>>4) & 0x03);
171     outBytes[1] = ((inBytes[1]<<4) & 0xf0) | ((inBytes[2]>>2) & 0x0f);
172     outBytes[2] = ((inBytes[2]<<6) & 0xc0) | ((inBytes[3]   ) & 0x3f);
174     outCount = 3;
176     //try again
177     if (outCount - padCount > 0)
178         {
179         return outBytes[3-(outCount--)];
180         }
182     return -1;
187 //#########################################################################
188 //# B A S E 6 4    O U T P U T    S T R E A M
189 //#########################################################################
191 static char const *base64encode =
192     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
194 /**
195  *
196  */
197 Base64OutputStream::Base64OutputStream(OutputStream &destinationStream)
198                      : BasicOutputStream(destinationStream)
200     column      = 0;
201     columnWidth = 72;
202     outBuf      = 0L;
203     bitCount    = 0;
206 /**
207  *
208  */
209 Base64OutputStream::~Base64OutputStream()
211     close();
214 /**
215  * Closes this output stream and releases any system resources
216  * associated with this stream.
217  */
218 void Base64OutputStream::close()
220     if (closed)
221         return;
223     //get any last bytes (1 or 2) out of the buffer
224     if (bitCount == 16)
225         {
226         outBuf <<= 2;  //pad to make 18 bits
228         int indx  = (int)((outBuf & 0x0003f000L) >> 12);
229         int obyte = (int)base64encode[indx & 63];
230         putCh(obyte);
232         indx      = (int)((outBuf & 0x00000fc0L) >>  6);
233         obyte     = (int)base64encode[indx & 63];
234         putCh(obyte);
236         indx      = (int)((outBuf & 0x0000003fL)      );
237         obyte     = (int)base64encode[indx & 63];
238         putCh(obyte);
240         putCh('=');
241         }
242     else if (bitCount == 8)
243         {
244         outBuf <<= 4; //pad to make 12 bits
246         int indx  = (int)((outBuf & 0x00000fc0L) >>  6);
247         int obyte = (int)base64encode[indx & 63];
248         putCh(obyte);
250         indx      = (int)((outBuf & 0x0000003fL)      );
251         obyte     = (int)base64encode[indx & 63];
252         putCh(obyte);
254         putCh('=');
255         putCh('=');
256         }
258     if (columnWidth > 0) //if <=0, no newlines
259         destination.put('\n');
261     destination.close();
262     closed = true;
265 /**
266  *  Flushes this output stream and forces any buffered output
267  *  bytes to be written out.
268  */
269 void Base64OutputStream::flush()
271     if (closed)
272         return;
273     //dont flush here.  do it on close()
274     destination.flush();
277 /**
278  * Private. Put a char to the output stream, checking for line length
279  */
280 void Base64OutputStream::putCh(int ch)
282     destination.put(ch);
283     column++;
284     if (columnWidth > 0 && column >= columnWidth)
285         {
286         destination.put('\n');
287         column = 0;
288         }
292 /**
293  * Writes the specified byte to this output stream.
294  */
295 int Base64OutputStream::put(XMLCh ch)
297     if (closed)
298         {
299         //probably throw an exception here
300         return -1;
301         }
303     outBuf   <<=  8;
304     outBuf   |=  (ch & 0xff);
305     bitCount +=  8;
306     if (bitCount >= 24)
307         {
308         int indx  = (int)((outBuf & 0x00fc0000L) >> 18);
309         int obyte = (int)base64encode[indx & 63];
310         putCh(obyte);
312         indx      = (int)((outBuf & 0x0003f000L) >> 12);
313         obyte     = (int)base64encode[indx & 63];
314         putCh(obyte);
316         indx      = (int)((outBuf & 0x00000fc0L) >>  6);
317         obyte     = (int)base64encode[indx & 63];
318         putCh(obyte);
320         indx      = (int)((outBuf & 0x0000003fL)      );
321         obyte     = (int)base64encode[indx & 63];
322         putCh(obyte);
324         bitCount = 0;
325         outBuf   = 0L;
326         }
328     return 1;
333 }  //namespace io
334 }  //namespace dom
335 }  //namespace w3c
336 }  //namespace org
339 //#########################################################################
340 //# E N D    O F    F I L E
341 //#########################################################################