Clover coverage report -
Coverage timestamp: Sun Oct 12 2003 22:54:40 PDT
file stats: LOC: 275   Methods: 5
NCLOC: 180   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Base64Utility.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
 
 3   
 VRMoo Common - Virtual Reality Object Oriented MUD Common Code
 4   
 Copyright (C) 2003  VRMoo Development Team
 5   
 
 6   
 
 7   
 This program is free software; you can redistribute it and/or modify
 8   
 it under the terms of the GNU General Public License as published by
 9   
 the Free Software Foundation; either version 2 of the License, or
 10   
 (at your option) any later version.
 11   
 
 12   
 This program is distributed in the hope that it will be useful,
 13   
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 14   
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15   
 GNU General Public License for more details.
 16   
 
 17   
 You should have received a copy of the GNU General Public License
 18   
 along with this program; if not, write to the Free Software
 19   
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 20   
 
 21   
 
 22   
 For information about VRMoo and its authors, please visit the website:
 23   
 http://www.vrmoo.org/
 24   
 
 25   
 */
 26   
 
 27   
 package org.vrmoo.common.util;
 28   
 
 29   
 import java.util.ArrayList;
 30   
 import java.util.List;
 31   
 
 32   
 /**
 33   
  * Utility class used to convert binary data to its Base64 representation and
 34   
  * to convert Base64 text data back to its binary form.
 35   
  *
 36   
  * @author Jeff Weston
 37   
  */
 38   
 public class Base64Utility
 39   
 {
 40   
     /**
 41   
      * Determine if we place newline characters in the Base64 output.
 42   
      */
 43   
     private static final boolean USE_NEWLINES = false;
 44   
 
 45   
     /**
 46   
      * List used for looking up the converted Base64 character set.
 47   
      */
 48   
     private static List base64Lookup;
 49   
 
 50   
     static
 51   
     {
 52  0
         base64Lookup = new ArrayList( );
 53  0
         base64Lookup.add( new Character( 'A' ) );
 54  0
         base64Lookup.add( new Character( 'B' ) );
 55  0
         base64Lookup.add( new Character( 'C' ) );
 56  0
         base64Lookup.add( new Character( 'D' ) );
 57  0
         base64Lookup.add( new Character( 'E' ) );
 58  0
         base64Lookup.add( new Character( 'F' ) );
 59  0
         base64Lookup.add( new Character( 'G' ) );
 60  0
         base64Lookup.add( new Character( 'H' ) );
 61  0
         base64Lookup.add( new Character( 'I' ) );
 62  0
         base64Lookup.add( new Character( 'J' ) );
 63  0
         base64Lookup.add( new Character( 'K' ) );
 64  0
         base64Lookup.add( new Character( 'L' ) );
 65  0
         base64Lookup.add( new Character( 'M' ) );
 66  0
         base64Lookup.add( new Character( 'N' ) );
 67  0
         base64Lookup.add( new Character( 'O' ) );
 68  0
         base64Lookup.add( new Character( 'P' ) );
 69  0
         base64Lookup.add( new Character( 'Q' ) );
 70  0
         base64Lookup.add( new Character( 'R' ) );
 71  0
         base64Lookup.add( new Character( 'S' ) );
 72  0
         base64Lookup.add( new Character( 'T' ) );
 73  0
         base64Lookup.add( new Character( 'U' ) );
 74  0
         base64Lookup.add( new Character( 'V' ) );
 75  0
         base64Lookup.add( new Character( 'W' ) );
 76  0
         base64Lookup.add( new Character( 'X' ) );
 77  0
         base64Lookup.add( new Character( 'Y' ) );
 78  0
         base64Lookup.add( new Character( 'Z' ) );
 79  0
         base64Lookup.add( new Character( 'a' ) );
 80  0
         base64Lookup.add( new Character( 'b' ) );
 81  0
         base64Lookup.add( new Character( 'c' ) );
 82  0
         base64Lookup.add( new Character( 'd' ) );
 83  0
         base64Lookup.add( new Character( 'e' ) );
 84  0
         base64Lookup.add( new Character( 'f' ) );
 85  0
         base64Lookup.add( new Character( 'g' ) );
 86  0
         base64Lookup.add( new Character( 'h' ) );
 87  0
         base64Lookup.add( new Character( 'i' ) );
 88  0
         base64Lookup.add( new Character( 'j' ) );
 89  0
         base64Lookup.add( new Character( 'k' ) );
 90  0
         base64Lookup.add( new Character( 'l' ) );
 91  0
         base64Lookup.add( new Character( 'm' ) );
 92  0
         base64Lookup.add( new Character( 'n' ) );
 93  0
         base64Lookup.add( new Character( 'o' ) );
 94  0
         base64Lookup.add( new Character( 'p' ) );
 95  0
         base64Lookup.add( new Character( 'q' ) );
 96  0
         base64Lookup.add( new Character( 'r' ) );
 97  0
         base64Lookup.add( new Character( 's' ) );
 98  0
         base64Lookup.add( new Character( 't' ) );
 99  0
         base64Lookup.add( new Character( 'u' ) );
 100  0
         base64Lookup.add( new Character( 'v' ) );
 101  0
         base64Lookup.add( new Character( 'w' ) );
 102  0
         base64Lookup.add( new Character( 'x' ) );
 103  0
         base64Lookup.add( new Character( 'y' ) );
 104  0
         base64Lookup.add( new Character( 'z' ) );
 105  0
         base64Lookup.add( new Character( '0' ) );
 106  0
         base64Lookup.add( new Character( '1' ) );
 107  0
         base64Lookup.add( new Character( '2' ) );
 108  0
         base64Lookup.add( new Character( '3' ) );
 109  0
         base64Lookup.add( new Character( '4' ) );
 110  0
         base64Lookup.add( new Character( '5' ) );
 111  0
         base64Lookup.add( new Character( '6' ) );
 112  0
         base64Lookup.add( new Character( '7' ) );
 113  0
         base64Lookup.add( new Character( '8' ) );
 114  0
         base64Lookup.add( new Character( '9' ) );
 115  0
         base64Lookup.add( new Character( '+' ) );
 116  0
         base64Lookup.add( new Character( '/' ) );
 117   
     }
 118   
 
 119   
     /**
 120   
      * Make the default constructor private since this class isn't meant to be
 121   
      * instantiated.
 122   
      */
 123  0
     private Base64Utility( )
 124   
     {
 125   
     }
 126   
 
 127   
     /**
 128   
      * Convert a given Base64 string to its binary format.
 129   
      *
 130   
      * @param base64   the Base64 string to convert
 131   
      *
 132   
      * @return the binary data encoded in the Base64 string
 133   
      */
 134  0
     public static byte[ ] toBinary( String base64 )
 135   
     {
 136  0
         if ( base64.length( ) % 4 != 0 )
 137   
         {
 138  0
             throw new IllegalArgumentException(
 139   
                     "String length is not a multiple of 4." );
 140   
         }
 141  0
         List list = new ArrayList( );
 142   
 
 143  0
         int setCount = base64.length( ) / 4;
 144   
 
 145  0
         for ( int i = 0; i < setCount; i++ )
 146   
         {
 147  0
             char c1 = base64.charAt( ( i * 4 ) + 0 );
 148  0
             char c2 = base64.charAt( ( i * 4 ) + 1 );
 149  0
             char c3 = base64.charAt( ( i * 4 ) + 2 );
 150  0
             char c4 = base64.charAt( ( i * 4 ) + 3 );
 151   
 
 152  0
             byte b1 = toBase64Byte( c1 );
 153  0
             byte b2 = toBase64Byte( c2 );
 154  0
             byte b3 = toBase64Byte( c3 );
 155  0
             byte b4 = toBase64Byte( c4 );
 156   
 
 157  0
             list.add( new Byte( ( byte ) ( ( ( b1 & 0x3F ) << 2 ) |
 158   
                                            ( ( b2 & 0x30 ) >> 4 ) ) ) );
 159   
 
 160  0
             if ( c3 != '=' )
 161   
             {
 162  0
                 list.add( new Byte( ( byte ) ( ( ( b2 & 0x0F ) << 4 ) |
 163   
                                                ( ( b3 & 0x3C ) >> 2 ) ) ) );
 164   
             }
 165   
 
 166  0
             if ( c4 != '=' )
 167   
             {
 168  0
                 list.add( new Byte( ( byte ) ( ( ( b3 & 0x03 ) << 6 ) |
 169   
                                                  ( b4 & 0x3F ) ) ) );
 170   
             }
 171   
         }
 172   
 
 173  0
         byte[ ] dataArray = new byte[ list.size( ) ];
 174  0
         for ( int i = 0; i < list.size( ); i++ )
 175   
         {
 176  0
             dataArray[ i ] = ( ( Byte ) list.get( i ) ).byteValue( );
 177   
         }
 178  0
         return dataArray;
 179   
     }
 180   
 
 181   
     /**
 182   
      * Convert a given set of binary data into its Base64 string representation.
 183   
      *
 184   
      * @param data   the binary data to convert
 185   
      *
 186   
      * @return the Base64 representation of the binary data
 187   
      */
 188  0
     public static String toBase64( byte[ ] data )
 189   
     {
 190  0
         StringBuffer buf = new StringBuffer( );
 191  0
         int setCount  = data.length / 3;
 192  0
         int remainder = data.length % 3;
 193   
 
 194  0
         for ( int i = 0; i < setCount; i++ )
 195   
         {
 196  0
             if ( ( i % 15 == 0 ) && ( i != 0 ) && ( USE_NEWLINES ) )
 197   
             {
 198  0
                 buf.append( "\r\n" );
 199   
             }
 200   
 
 201  0
             byte b1 = ( byte ) ( ( data[ ( i * 3 ) ] & 0xFC ) >> 2 );
 202  0
             byte b2 = ( byte ) ( ( ( data[ ( i * 3 )     ] & 0x03 ) << 4 ) |
 203   
                                  ( ( data[ ( i * 3 ) + 1 ] & 0xF0 ) >> 4 ) );
 204  0
             byte b3 = ( byte ) ( ( ( data[ ( i * 3 ) + 1 ] & 0x0F ) << 2 ) |
 205   
                                  ( ( data[ ( i * 3 ) + 2 ] & 0xC0 ) >> 6 ) );
 206  0
             byte b4 = ( byte ) ( data[ ( i * 3 ) + 2 ] & 0x3F );
 207   
 
 208  0
             buf.append( toBase64Character( b1 ) );
 209  0
             buf.append( toBase64Character( b2 ) );
 210  0
             buf.append( toBase64Character( b3 ) );
 211  0
             buf.append( toBase64Character( b4 ) );
 212   
         }
 213   
 
 214  0
         if ( ( remainder > 0 ) &&
 215   
              ( setCount % 15 == 0 ) &&
 216   
              ( setCount > 0 ) &&
 217   
              ( USE_NEWLINES ) )
 218   
         {
 219  0
             buf.append( "\r\n" );
 220   
         }
 221   
 
 222  0
         if ( remainder == 2 )
 223   
         {
 224  0
             byte b1 = ( byte ) ( ( data[ data.length - 2 ] & 0xFC ) >> 2 );
 225  0
             byte b2 = ( byte ) ( ( ( data[ data.length - 2 ] & 0x03 ) << 4 ) |
 226   
                                  ( ( data[ data.length - 1 ] & 0xF0 ) >> 4 ) );
 227  0
             byte b3 = ( byte ) ( ( data[ data.length - 1 ] & 0x0F ) << 2 );
 228   
 
 229  0
             buf.append( toBase64Character( b1 ) );
 230  0
             buf.append( toBase64Character( b2 ) );
 231  0
             buf.append( toBase64Character( b3 ) );
 232  0
             buf.append( "=" );
 233   
         }
 234  0
         else if ( remainder == 1 )
 235   
         {
 236  0
             byte b1 = ( byte ) ( ( data[ data.length - 1 ] & 0xFC ) >> 2 );
 237  0
             byte b2 = ( byte ) ( ( data[ data.length - 1 ] & 0x03 ) << 4 );
 238   
 
 239  0
             buf.append( toBase64Character( b1 ) );
 240  0
             buf.append( toBase64Character( b2 ) );
 241  0
             buf.append( "==" );
 242   
         }
 243   
 
 244  0
         return buf.toString( );
 245   
     }
 246   
 
 247   
     /**
 248   
      * Convert a raw byte to its associated Base64 ASCII character.
 249   
      *
 250   
      * @param b   the byte to convert
 251   
      *
 252   
      * @return the converted Base64 character
 253   
      */
 254  0
     private static char toBase64Character( byte b )
 255   
     {
 256  0
         return ( ( Character ) base64Lookup.get( b ) ).charValue( );
 257   
     }
 258   
 
 259   
     /**
 260   
      * Convert a Base64 character to its associated raw byte value.
 261   
      *
 262   
      * @param c   the character to convert
 263   
      *
 264   
      * @return the converted byte value
 265   
      */
 266  0
     private static byte toBase64Byte( char c )
 267   
     {
 268  0
         if ( c == '=' )
 269   
         {
 270  0
             return 0;
 271   
         }
 272  0
         return ( byte ) base64Lookup.indexOf( new Character( c ) );
 273   
     }
 274   
 }
 275