~ubuntu-branches/ubuntu/oneiric/libxml-java/oneiric

« back to all changes in this revision

Viewing changes to source/org/jfree/xmlns/parser/Base64.java

  • Committer: Bazaar Package Importer
  • Author(s): Rene Engelhard
  • Date: 2007-08-21 00:19:22 UTC
  • Revision ID: james.westby@ubuntu.com-20070821001922-9khxrso03tk3c5i2
Tags: upstream-0.9.5
ImportĀ upstreamĀ versionĀ 0.9.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * =========================================
 
3
 * LibXML : a free Java layouting library
 
4
 * =========================================
 
5
 *
 
6
 * Project Info:  http://reporting.pentaho.org/libxml/
 
7
 *
 
8
 * (C) Copyright 2006, by Object Refinery Ltd, Pentaho Corporation and Contributors.
 
9
 *
 
10
 * This library is free software; you can redistribute it and/or modify it under the terms
 
11
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 
12
 * either version 2.1 of the License, or (at your option) any later version.
 
13
 *
 
14
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 
15
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
16
 * See the GNU Lesser General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public License along with this
 
19
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 
20
 * Boston, MA 02111-1307, USA.
 
21
 *
 
22
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 
23
 * in the United States and other countries.]
 
24
 *
 
25
 *
 
26
 * ------------
 
27
 * $Id: Base64.java,v 1.3 2007/04/01 13:46:34 taqua Exp $
 
28
 * ------------
 
29
 * (C) Copyright 2006, by Pentaho Corporation.
 
30
 */
 
31
package org.jfree.xmlns.parser;
 
32
 
 
33
/**
 
34
 * Provides encoding of raw bytes to base64-encoded characters, and decoding of
 
35
 * base64 characters to raw bytes. date: 06 August 1998 modified: 14 February
 
36
 * 2000 modified: 22 September 2000
 
37
 *
 
38
 * @author Kevin Kelley (kelley@ruralnet.net)
 
39
 * @version 1.3
 
40
 */
 
41
public class Base64
 
42
{
 
43
 
 
44
  private Base64()
 
45
  {
 
46
  }
 
47
 
 
48
  /**
 
49
   * returns an array of base64-encoded characters to represent the passed
 
50
   * data array.
 
51
   *
 
52
   * @param data the array of bytes to encode
 
53
   * @return base64-coded character array.
 
54
   */
 
55
  public static char[] encode(final byte[] data)
 
56
  {
 
57
    final char[] out = new char[((data.length + 2) / 3) * 4];
 
58
 
 
59
    //
 
60
    // 3 bytes encode to 4 chars.  Output is always an even
 
61
    // multiple of 4 characters.
 
62
    //
 
63
    for (int i = 0, index = 0; i < data.length; i += 3, index += 4)
 
64
    {
 
65
      boolean quad = false;
 
66
      boolean trip = false;
 
67
 
 
68
      int val = (0xFF & data[i]);
 
69
      val <<= 8;
 
70
      if ((i + 1) < data.length)
 
71
      {
 
72
        val |= (0xFF & data[i + 1]);
 
73
        trip = true;
 
74
      }
 
75
      val <<= 8;
 
76
      if ((i + 2) < data.length)
 
77
      {
 
78
        val |= (0xFF & data[i + 2]);
 
79
        quad = true;
 
80
      }
 
81
      out[index + 3] = Base64.ALPHABET[(quad ? (val & 0x3F) : 64)];
 
82
      val >>= 6;
 
83
      out[index + 2] = Base64.ALPHABET[(trip ? (val & 0x3F) : 64)];
 
84
      val >>= 6;
 
85
      out[index + 1] = Base64.ALPHABET[val & 0x3F];
 
86
      val >>= 6;
 
87
      out[index + 0] = Base64.ALPHABET[val & 0x3F];
 
88
    }
 
89
    return out;
 
90
  }
 
91
 
 
92
  /**
 
93
   * Decodes a BASE-64 encoded stream to recover the original data. White
 
94
   * space before and after will be trimmed away, but no other manipulation of
 
95
   * the input will be performed.
 
96
   * <p/>
 
97
   * As of version 1.2 this method will properly handle input containing junk
 
98
   * characters (newlines and the like) rather than throwing an error. It does
 
99
   * this by pre-parsing the input and generating from that a count of VALID
 
100
   * input characters.
 
101
   *
 
102
   * @param data the character data.
 
103
   * @return The decoded data.
 
104
   */
 
105
  public static byte[] decode(final char[] data)
 
106
  {
 
107
    // as our input could contain non-BASE64 data (newlines,
 
108
    // whitespace of any sort, whatever) we must first adjust
 
109
    // our count of USABLE data so that...
 
110
    // (a) we don't misallocate the output array, and
 
111
    // (b) think that we miscalculated our data length
 
112
    //     just because of extraneous throw-away junk
 
113
 
 
114
    int tempLen = data.length;
 
115
    for (int ix = 0; ix < data.length; ix++)
 
116
    {
 
117
      if ((data[ix] > 255) || Base64.CODES[data[ix]] < 0)
 
118
      {
 
119
        --tempLen; // ignore non-valid chars and padding
 
120
      }
 
121
    }
 
122
    // calculate required length:
 
123
    //  -- 3 bytes for every 4 valid base64 chars
 
124
    //  -- plus 2 bytes if there are 3 extra base64 chars,
 
125
    //     or plus 1 byte if there are 2 extra.
 
126
 
 
127
    int len = (tempLen / 4) * 3;
 
128
    if ((tempLen % 4) == 3)
 
129
    {
 
130
      len += 2;
 
131
    }
 
132
    if ((tempLen % 4) == 2)
 
133
    {
 
134
      len += 1;
 
135
    }
 
136
 
 
137
    final byte[] out = new byte[len];
 
138
 
 
139
 
 
140
    int shift = 0; // # of excess bits stored in accum
 
141
    int accum = 0; // excess bits
 
142
    int index = 0;
 
143
 
 
144
    // we now go through the entire array (NOT using the 'tempLen' value)
 
145
    for (int ix = 0; ix < data.length; ix++)
 
146
    {
 
147
      final int value = (data[ix] > 255) ? -1 : Base64.CODES[data[ix]];
 
148
 
 
149
      if (value >= 0)
 
150
      { // skip over non-code
 
151
        accum <<= 6; // bits shift up by 6 each time thru
 
152
        shift += 6; // loop, with new bits being put in
 
153
        accum |= value; // at the bottom.
 
154
        if (shift >= 8)
 
155
        { // whenever there are 8 or more shifted in,
 
156
          shift -= 8; // write them out (from the top, leaving any
 
157
          out[index] = // excess at the bottom for next iteration.
 
158
              (byte) ((accum >> shift) & 0xff);
 
159
          index += 1;
 
160
        }
 
161
      }
 
162
      // we will also have skipped processing a padding null byte ('=') here;
 
163
      // these are used ONLY for padding to an even length and do not legally
 
164
      // occur as encoded data. for this reason we can ignore the fact that
 
165
      // no index++ operation occurs in that special case: the out[] array is
 
166
      // initialized to all-zero bytes to start with and that works to our
 
167
      // advantage in this combination.
 
168
    }
 
169
 
 
170
    // if there is STILL something wrong we just have to throw up now!
 
171
    if (index != out.length)
 
172
    {
 
173
      throw new Error("Miscalculated data length (wrote "
 
174
          + index + " instead of " + out.length + ")");
 
175
    }
 
176
 
 
177
    return out;
 
178
  }
 
179
 
 
180
 
 
181
  //
 
182
  // code characters for values 0..63
 
183
  //
 
184
  private static char[] ALPHABET =
 
185
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
 
186
 
 
187
  //
 
188
  // lookup table for converting base64 characters to value in range 0..63
 
189
  //
 
190
  private static byte[] CODES = new byte[256];
 
191
 
 
192
  static
 
193
  {
 
194
    for (int i = 0; i < 256; i++)
 
195
    {
 
196
      Base64.CODES[i] = -1;
 
197
    }
 
198
    for (int i = 'A'; i <= 'Z'; i++)
 
199
    {
 
200
      Base64.CODES[i] = (byte) (i - 'A');
 
201
    }
 
202
    for (int i = 'a'; i <= 'z'; i++)
 
203
    {
 
204
      Base64.CODES[i] = (byte) (26 + i - 'a');
 
205
    }
 
206
    for (int i = '0'; i <= '9'; i++)
 
207
    {
 
208
      Base64.CODES[i] = (byte) (52 + i - '0');
 
209
    }
 
210
    Base64.CODES['+'] = 62;
 
211
    Base64.CODES['/'] = 63;
 
212
  }
 
213
 
 
214
//
 
215
//
 
216
//    ///////////////////////////////////////////////////
 
217
//    // remainder (main method and helper functions) is
 
218
//    // for testing purposes only, feel free to clip it.
 
219
//    ///////////////////////////////////////////////////
 
220
//
 
221
//    /**
 
222
//     * Entry point.
 
223
//     *
 
224
//     * @param args  the command line arguments.
 
225
//     */
 
226
//    public static void main(final String[] args) {
 
227
//        boolean decode = false;
 
228
//
 
229
//        if (args.length == 0) {
 
230
//            System.out.println("usage:  java Base64 [-d[ecode]] filename");
 
231
//            System.exit(0);
 
232
//        }
 
233
//        for (int i = 0; i < args.length; i++) {
 
234
//            if ("-decode".equalsIgnoreCase(args[i])) {
 
235
//                decode = true;
 
236
//            }
 
237
//            else if ("-d".equalsIgnoreCase(args[i])) {
 
238
//                decode = true;
 
239
//            }
 
240
//        }
 
241
//
 
242
//        final String filename = args[args.length - 1];
 
243
//        final File file = new File(filename);
 
244
//        if (!file.exists()) {
 
245
//            System.out.println("Error:  file '" + filename + "' doesn't exist!");
 
246
//            System.exit(0);
 
247
//        }
 
248
//
 
249
//        if (decode) {
 
250
//            final char[] encoded = org.jfree.xmlns.parser.Base64.readChars(file);
 
251
//            final byte[] decoded = org.jfree.xmlns.parser.Base64.decode(encoded);
 
252
//            org.jfree.xmlns.parser.Base64.writeBytes(file, decoded);
 
253
//        }
 
254
//        else {
 
255
//            final byte[] decoded = org.jfree.xmlns.parser.Base64.readBytes(file);
 
256
//            final char[] encoded = org.jfree.xmlns.parser.Base64.encode(decoded);
 
257
//            org.jfree.xmlns.parser.Base64.writeChars(file, encoded);
 
258
//        }
 
259
//    }
 
260
//
 
261
//    private static byte[] readBytes(final File file) {
 
262
//        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
263
//        try {
 
264
//            final InputStream fis = new FileInputStream(file);
 
265
//            final InputStream is = new BufferedInputStream(fis);
 
266
//
 
267
//            int count;
 
268
//            final byte[] buf = new byte[16384];
 
269
//            while ((count = is.read(buf)) != -1) {
 
270
//                if (count > 0) {
 
271
//                    baos.write(buf, 0, count);
 
272
//                }
 
273
//            }
 
274
//            is.close();
 
275
//        }
 
276
//        catch (Exception e) {
 
277
//            e.printStackTrace();
 
278
//        }
 
279
//
 
280
//        return baos.toByteArray();
 
281
//    }
 
282
//
 
283
//    private static char[] readChars(final File file) {
 
284
//        final CharArrayWriter caw = new CharArrayWriter();
 
285
//        try {
 
286
//            final Reader fr = new FileReader(file);
 
287
//            final Reader in = new BufferedReader(fr);
 
288
//            int count;
 
289
//            final char[] buf = new char[16384];
 
290
//            while ((count = in.read(buf)) != -1) {
 
291
//                if (count > 0) {
 
292
//                    caw.write(buf, 0, count);
 
293
//                }
 
294
//            }
 
295
//            in.close();
 
296
//        }
 
297
//        catch (Exception e) {
 
298
//            e.printStackTrace();
 
299
//        }
 
300
//
 
301
//        return caw.toCharArray();
 
302
//    }
 
303
//
 
304
//    private static void writeBytes(final File file, final byte[] data) {
 
305
//        try {
 
306
//            final OutputStream fos = new FileOutputStream(file);
 
307
//            final OutputStream os = new BufferedOutputStream(fos);
 
308
//            os.write(data);
 
309
//            os.close();
 
310
//        }
 
311
//        catch (Exception e) {
 
312
//            e.printStackTrace();
 
313
//        }
 
314
//    }
 
315
//
 
316
//    private static void writeChars(final File file, final char[] data) {
 
317
//        try {
 
318
//            final Writer fos = new FileWriter(file);
 
319
//            final Writer os = new BufferedWriter(fos);
 
320
//            os.write(data);
 
321
//            os.close();
 
322
//        }
 
323
//        catch (Exception e) {
 
324
//            e.printStackTrace();
 
325
//        }
 
326
//    }
 
327
//    ///////////////////////////////////////////////////
 
328
//    // end of test code.
 
329
//    ///////////////////////////////////////////////////
 
330
//
 
331
}