Logo
Distributed Genetic Programming Framework
print print

File org.sfc.io.Base64.java

Here you can find all the information about the file org.sfc.io.Base64.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2005 Thomas Weise
 * 
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2005-06-17 20:01:54
 * Original Filename: org.sfc.io.Base64.java
 * Version          : 1.0.2
 * Last modification: 2006-03-07
 *                by: Thomas Weise
 * 
 * License          : GNU LESSER GENERAL PUBLIC LICENSE
 *                    Version 2.1, February 1999
 *                    You should have received a copy of this license along
 *                    with this library; if not, write to the Free Software
 *                    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *                    MA 02111-1307, USA or download the license under
 *                    http://www.gnu.org/copyleft/lesser.html.
 *                    
 * Warranty         : This software is provided "as is" without any
 *                    warranty; without even the implied warranty of
 *                    merchantability or fitness for a particular purpose.
 *                    See the Gnu Lesser General Public License for more
 *                    details.
 */

 
package org.sfc.io;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

import org.sfc.xml.XML;


/**
 * A small utility for base64 encoding and decoding.
 * It uses the RFC 2045 for internet message bodies to convert binary data
 * to a representation that will not be compromised by any transfer
 * mechanism that would probably obscure control characters and such and
 * such.
 * 
 * @author Thomas Weise 
 */

public final  class Base64
  {
/**
 * The default table to cenvert binary data to base 64 data.
 */

  public  static  final char[]  DEFAULT_TABLE = {
    'A''B''C''D''E''F''G''H''I''J''K''L''M',
    'N''O''P''Q''R''S''T''U''V''W''X''Y''Z',
    'a''b''c''d''e''f''g''h''i''j''k''l''m',
    'n''o''p''q''r''s''t''u''v''w''x''y''z',
    '0''1''2''3''4''5''6''7''8''9''+''/'  };
/**
 * This array is a lookup table that translates 6-bit positive integer
 * index values into their "Alternate Base64 Alphabet" equivalents.
 * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
 * This alternate alphabet does not use the capital letters.  It is
 * designed for use in environments where "case folding" occurs.
 */

  public static final char[]   ALTERNATE_TABLE = {
    '!''"''#''$''%''&''\'''('')'',''-''.'':',
    ';''<''>''@''['']''^',  '`''_''{''|''}''~',
    'a''b''c''d''e''f''g',  'h''i''j''k''l''m',
    'n''o''p''q''r''s''t',  'u''v''w''x''y''z',
    '0''1''2''3''4''5''6',  '7''8''9''+''?'  };
  
  
/**
 * The default padding character.
 */

  public  static  final char    DEFAULT_PADDING     = '=';
  
/**
 * The default line break character sequence.
 */

  public  static  final char[]  DEFAULT_LINE_BREAK  =
                                      new char[] {XML.LINE_BREAK};
  
/**
 * The default line length.
 */

  public  static  final int     DEFAULT_LINE_LENGTH = 48;
  
  
/**
 * The empty char array.
 */

          static  final char[]  EMPTY_CHARS         = new char[0];
  
/**
 * The empty byte array.
 */

          static  final byte[]  EMPTY_BYTES         = new byte[0];
  
/**
 * The default line header.
 */

  public  static  final char[]  DEFAULT_LINE_HEADER = EMPTY_CHARS;
  
/**
 * The default base64 encoder/decoder.
 */

  public  static  final Base64  DEFAULT = new Base64(DEFAULT_TABLE,
                                                     DEFAULT_PADDING,
                                                     DEFAULT_LINE_BREAK,
                                                     DEFAULT_LINE_LENGTH,
                                                     DEFAULT_LINE_HEADER);
/**
 * This encoder creates "small" output, without any line breaking or line
 * heading. It should be used whenever the content will never be included
 * into any source or file which could be viewed by a human.
 */

  public  static  final Base64  SMALL   = new Base64(DEFAULT_TABLE,
                                                     DEFAULT_PADDING,
                                                     null,
                                                     -1,
                                                     null);
  
  
/**
 * The array used for binary-to-character conversation.
 */

          final char[]  m_bin_to_char     ;
/**
 * The table for character-to-binary conversation.
 */

          final int[]   m_char_to_bin     ;
  
/**
 * The padding character.
 */

          final char    m_padding         ;
  
/**
 * The line break.
 */

          final char[]  m_line_break      ;
  
/**
 * The maximum line length.
 */

          final int     m_max_line_length ;
          
/**
 * The line header.
 */

         final  char[]  m_line_header     ;
  
/**
 * Create a new Base64 encoder.
 * 
 * @param p_bin_to_char     The array used for binary-to-character encoding.
 *                          This array must contain exactly 64 characters.
 *                          If this parameter is null, the default base 64
 *                          encoding table will be used.
 * @param p_padding         The padding character to be used at the end
 *                          of sequences with lengths % 3 != 0.
 *                          If 0 is passed, the default padding will be
 *                          used. This character must no equal any of the
 *                          characters the translation table
 *                          <code>p_bin_to_char</code>.
 * @param p_line_break      The character sequence to be inserted as line
 *                          break. This parameter can be null, in that case
 *                          the default line break will be used.
 *                          Line breaking will only occure when encoding
 *                          and p_max_line_length is > 0.
 * @param p_max_line_length The maximum length of a line in characters.
 *                          If this parameter is <= 0, no line breaking
 *                          will be performed. The line length only regards
 *                          the count of data character output, neither the
 *                          line header nor the line break characters.
 * @param p_line_header     A character sequence preceeding every line of
 *                          output. If this is null, no preceeding character
 *                          sequence will be attached to the front of the
 *                          output lines. If a sequence of characters is
 *                          provided, make sure that it neither contains
 *                          the padding character nor any of the
 *                          characters the translation table
 *                          <code>p_bin_to_char</code>.
 */

  public  Base64  (char[] p_bin_to_char,
                   char   p_padding,
                   char[] p_line_break,
                   int    p_max_line_length,
                   char[] p_line_header)
    {
    super();
    
    int l_i, l_k, l_l;
    
    if(p_line_header == null)  p_line_header = DEFAULT_LINE_HEADER;
    if(p_line_break  == null)  p_line_break  = DEFAULT_LINE_BREAK;
    if(p_max_line_length <= 0) p_max_line_length = -1;
    if(p_padding     == '\0')  p_padding = DEFAULT_PADDING;
    
    if(p_bin_to_char == null)
      {
      p_bin_to_char = DEFAULT_TABLE;
      }
    else
      {    
      if(p_bin_to_char.length != 64)
        {
        throw new IllegalArgumentException();
        }
      }
    
    this.m_bin_to_char = p_bin_to_char;
    
    l_k = (p_bin_to_char[0] & 0xff);    
    for( l_i = 63; l_i > 0; l_i--)
      {
      l_l = (p_bin_to_char[l_i] & 0xff);      
      if(l_l > l_k) l_k = l_l;
      }
    
    this.m_char_to_bin = new int[l_k+1];
    
    for(l_i = l_k; l_i >= 0; l_i--)
      {
      this.m_char_to_bin[l_i] = -1;
      }
    
    for(l_i = 63; l_i >= 0; l_i--)
      {
      this.m_char_to_bin[ p_bin_to_char[l_i] & 0xff ] = l_i;
      }
    
    
    this.m_padding          = p_padding;
    l_i                     = p_line_header.length;
    
    if(l_i > 0)
      {
      this.m_line_header    = p_line_header;
      l_k                   = p_line_break.length;
      p_line_header = new char[l_k + l_i];
      System.arraycopy(p_line_break, 0, p_line_header, 0, l_k);
      System.arraycopy(this.m_line_header, 0, p_line_header, l_k, l_i);      
      p_line_break          = p_line_header;
      }
    else
      {
      this.m_line_header = null;
      }
    
    this.m_line_break       = p_line_break;
    this.m_max_line_length  = p_max_line_length;
    }
  
/**
 * Returns the lookup table for binary-to-character conversation.
 * 
 * @return  The lookup table for binary-to-character conversation.
 */

  public  final char[]  get_bin_to_char_lookup  ()
    {
    return this.m_bin_to_char;
    }
  
/**
 * Returns the lookup table for character-to-binary conversation.
 * 
 * @return  The lookup table for character-to-binary conversation.
 */

  public  final int[]   get_char_to_bin_lookup  ()
    {
    return this.m_char_to_bin;
    }
  
/**
 * Returns the padding that will be appended on odd data lengths (% 3 != 0).
 * 
 * @return The padding that will be appended on odd data lengths (% 3 != 0).
 */

  public  final char    get_padding ()
    {
    return this.m_padding;
    }
  
/**
 * Returns the line break character sequence-
 * 
 * @return The line break character sequence-
 */

  public  final char[]  get_line_break  ()
    {
    return this.m_line_break;
    }
  
/**
 * Returns the maximum length of a line in characters.
 * 
 * @return The maximum length of a line in characters.
 */

  public  final int     get_max_line_length ()
    {
    return this.m_max_line_length;    
    }
  
/**
 * Get the character sequence that will preceed any data in every line of
 * the output.
 * 
 * @return  The character sequence that will preceed any data in every line
 *          of the output.
 */

  public  final char[]  get_line_header ()
    {
    return this.m_line_header;
    }
  
    
/**
 * You can encode an array of byte to an char array base64 with this one.
 * Line breaks are inserted to apply the "maximum 76 characters per line"-
 * limit of rfc 2045. (see the section regarding that below)
 * To increase conversion speed, <code>this.m_max_line_length</code> set by
 * the constructor parameter <code>p_max_line_length</code> is approximated
 * with an accurancy of +3, meaning your line could contain more base64
 * characters then specified, but at most 3. If you want a line length that
 * is more accurate, you have to use the encoders created by
 * <code>create_encoder()</code>. 
 *
 * @param p_data    The data array.
 * @param p_start   The starting offset into this array,
 *                  where to start encoding.
 * @param p_length  The count of bytes to encode.
 * 
 * @return          An array of char containing the base64 encoded data.
 * 
 * @see #Base64(char[], char, char[], int, char[])
 * @see #create_encoder(Writer)
 * @see #m_max_line_length
 */

  public  final char[]  encode  (byte[] p_data,
                                 int    p_start,
                                 int    p_length)
    {
    int     l_i, l_j, l_l, l_rest, l_int, l_k, l_x;
    char[]  l_ret, l_line_header;

    if( (p_start > (l_i = p_data.length)) ||
      (p_length <= 0) )
      {
      return EMPTY_CHARS;
      }

    if(p_start < 0) p_start = 0;

    l_line_header = this.m_line_header;
    
    l_i -= p_start;
    if(l_i > p_length) l_i = p_length;

    l_j = ( (l_rest = (l_i % 3)) > 0) ? 1 : 0;
    l_j += l_i /= 3;

    l_x = (this.m_max_line_length >> 2);
    if(l_x > 0)
      {
      l_ret = new char[(((l_j * 4) +
             (((l_j-1)/ l_x) *
              this.m_line_break.length)) + 
              ((l_line_header != null) ? l_line_header.length : 0))];
      }
    else
      {
      l_ret = new char[((l_j * 4) + 
                       ((l_line_header != null) ? l_line_header.length : 0))];
      }

    if(l_line_header != null)
      {
      System.arraycopy(this.m_line_header, 0, l_ret, 0,
                       this.m_line_header.length);
      }
    
    l_l = 0;
    for(l_j = p_start, l_k = 0; l_i > 0; l_i--)
      {
      l_int =  (p_data[l_j++] & 0xff);
      l_int |= (p_data[l_j++] & 0xff) << 8;
      l_int |= (p_data[l_j++] & 0xff) << 16;

      l_ret[l_k++] = this.m_bin_to_char[l_int & 0x3f];      
      l_ret[l_k++] = this.m_bin_to_char[(l_int >> 6) & 0x3f];      
      l_ret[l_k++] = this.m_bin_to_char[(l_int >> 12) & 0x3f];      
      l_ret[l_k++] = this.m_bin_to_char[(l_int >> 18) & 0x3f];
      
      if((++l_l) == l_x)
        {
        System.arraycopy(this.m_line_break, 0,
                         l_ret, l_k, this.m_line_break.length);
        l_k += this.m_line_break.length;
        l_l = 0;
        }
      }

    if(l_rest > 0)
      {
      l_int = 0;
      for(l_i = 0; l_i < l_rest; l_i++)
        {
        l_int |= (p_data[l_j++] & 0xff) << (8*l_i);
        }

      l_ret[l_k++] = this.m_bin_to_char[l_int & 0x3f];      
      l_ret[l_k++] = this.m_bin_to_char[(l_int >>> 6) & 0x3f];
      
      if(l_rest > 1)
        {
        l_ret[l_k++] = this.m_bin_to_char[(l_int >>> 12) & 0x3f];
        }
      else
        {
        l_ret[l_k++] = this.m_padding;
        }
      
      l_ret[l_k++] = this.m_padding;
      }

    return l_ret;
    }


/**
 * You can decode an array of char (base64) to a byte array.
 * The char array may contain any count of whitespaces and line breaks.
 * 
 * @param p_data    The base64 data array. This data will be destroyed
 *                  during the decoding process. If you want to preserve
 *                  this array, you need to create a copy of it before
 *                  calling this method.
 * @param p_start   The starting offset into this array,
 *                  where to start decoding.
 * @param p_length  The count of bytes to decode.
 * 
 * @return          An array of byte containing the decoded data.
 */

  public  final byte[]  decode  (char[] p_data,
                                 int    p_start,
                                 int    p_length)
    {
    int     l_i, l_j, l_l, l_b, l_k, l_int, l_c;
    byte[]  l_ret;
    char    l_x;
    

    if( (p_start > (l_i = p_data.length)) ||
      (p_length <= 0) )
      {
      return EMPTY_BYTES;
      }

    if(p_start < 0) p_start = 0;

    l_i -= p_start;
    if(l_i > p_length) l_i = p_length;
    l_i += p_start;

    for(l_l = 0, l_j = p_start, l_b = 0; l_j < l_i; l_j++)
      {
      l_x = p_data[l_j];

      if(l_x == this.m_padding)
        {
        if((++l_b) > 2)
          {
          l_b = 2;
          break;
          }
        }

      l_c = (l_x & 0xff);
      if((l_c < this.m_char_to_bin.length) &&
          (this.m_char_to_bin[l_c] >= 0))
        {
        if(l_b > 0) break;
        p_data[l_l++] = l_x;
        }
      }


    l_ret = new byte[(3 * (l_i = (l_l / 4))) +
             ((l_b > 0) ? (3-l_b) : 0)];

    //if(l_b > 0) l_i--;

    for(l_j = 0, l_k = 0; l_i > 0; l_i--)
      {
      l_int = this.m_char_to_bin[p_data[l_j++]] |
          (this.m_char_to_bin[p_data[l_j++]] << 6) |
          (this.m_char_to_bin[p_data[l_j++]] << 12) |
          (this.m_char_to_bin[p_data[l_j++]] << 18);
      l_ret[l_k++] = (byte)(l_int & 0xff);
      l_ret[l_k++] = (byte)((l_int >> 8) & 0xff);
      l_ret[l_k++] = (byte)((l_int >> 16) & 0xff);
      }

    if(l_b > 0)
      {

      l_int =  this.m_char_to_bin[p_data[l_j++]] |
              (this.m_char_to_bin[p_data[l_j++]] << 6);
      l_ret[l_k++] = (byte)(l_int & 0xff);
      if(l_b == 1)
        {
        l_int |= (this.m_char_to_bin[p_data[l_j++]] << 12);
        l_ret[l_k++] = (byte)((l_int >>> 8) & 0xff);
        }
      }

    return l_ret;
    }
  
  
  
/**
 * This method creates a base64-encoder based on the settings of this
 * object.
 * 
 * @param p_destination An instance of <code>Writer</code> where the encoded
 *                      data should be written to. 
 *                      Notice: Closing the encoder will also close this
 *                      writer.
 * @return              An instance of <code>OutputStream</code> that can
 *                      be written to. All data written to that stream will
 *                      immediately be encoded and written to the writer
 *                      <code>p_destination</code>. When the returned
 *                      <code>OutputStream</code> is closed, all output
 *                      that is still available will be flushed. Padding
 *                      characters will be appended then if needed.                      
 */

  public  final ReferenceCountedOutputStream  create_encoder (
                                    final Writer p_destination)
    {
    return new Encoder(p_destination);
    }
  
/**
 * This method creates a base64-decoder based on the settings of this
 * object.
 * 
 * @param p_destination An instance of <code>OutputStream</code> where the
 *                      decoded data should be written to.
 *                      Notice: Closing this decoder will also close the
 *                              output stream. 
 * @return              An instance of <code>Writer</code> that can
 *                      be written to. All data written to that stream will
 *                      immediately be decoded and written to the output
 *                      stream <code>p_destination</code>. When the returned
 *                      <code>Writer</code> is closed, all output
 *                      that is still available will be flushed. The decoder
 *                      will automatically be closed when a padding-
 *                      character is encountered.               
 */

  public  final ReferenceCountedWriter create_decoder (
                                      final OutputStream p_destination)
    {
    return new Decoder(p_destination);
    }
  
/**
 * This encoder can be used as a normal output stream, where the data
 * written to it will immediately be base64-encoded to a writer.
 *
 * @author Thomas Weise
 */

  private final class Encoder extends     ReferenceCountedOutputStream
    { 
/**
 * The destination writer.
 */

    private final Writer  m_writer      ;
/**
 * The integer buffer for the data store.
 */

    private       int     m_buffer      ;
/**
 * The current buffer length.
 */

    private       int     m_buffer_len  ;
/**
 * The current line length.
 */

    private       int     m_line_length ;  
    
/**
 * Create a new <code>Encoder</code> based on the settings of the
 * enclosing Base64 instance.
 * 
 * @param p_destination The writer to write the encoded content to.
 */

    private Encoder (final  Writer p_destination)
      {
      super();      
      
      this.m_writer       = p_destination;
      this.m_buffer       = 0;
      this.m_buffer_len   = 0;
      this.m_line_length  = 0;
      
      if(Base64.this.m_line_header != null)
        {
        try
          {
          p_destination.write(Base64.this.m_line_header);
          }
        catch(Throwable l_t)
          {
          //
          }
        }
      }
    
/**
 * Writes the specified byte to this output stream. The general 
 * contract for <code>write</code> is that one byte is written 
 * to the output stream. The byte to be written is the eight 
 * low-order bits of the argument <code>b</code>. The 24 
 * high-order bits of <code>b</code> are ignored.
 * <p>
 * Subclasses of <code>OutputStream</code> must provide an 
 * implementation for this method. 
 *
 * @param      p_byte   the <code>byte</code>.
 * @exception  IOException  if an I/O error occurs. In particular, 
 *             an <code>IOException</code> may be thrown if the 
 *             output stream has been closed.
 */

    @Override
    public synchronized final  void write  (int p_byte) throws IOException
      {
      int l_bl;
      
      l_bl    = this.m_buffer_len;      
      p_byte  = (this.m_buffer | ((p_byte & 0xff) << (l_bl << 3)));
      
      if(l_bl < 2)
        {        
        l_bl++;
        }
      else
        {        
        for(l_bl = 4; l_bl > 0; l_bl--)
          {
          this.print(Base64.this.m_bin_to_char[p_byte & 0x3f]);
          p_byte >>= 6;              
          }        
        }
      
      
      this.m_buffer_len = l_bl;
      this.m_buffer     = p_byte;
      }

/**
 * Print the specified character to the internal writer.
 * @param p_ch  The character to print.
 * @throws  IOException Can come from the writer.
 */

    private final void  print (char p_ch) throws  IOException
      {
      
      if(Base64.this.m_max_line_length > 0)
        {
        this.m_line_length++;
        
        if(this.m_line_length > Base64.this.m_max_line_length)
          {
          this.m_writer.write(Base64.this.m_line_break);
          this.m_line_length = 1;
          }
        }
      
      this.m_writer.write(p_ch);
      }
    
/**
 * The internal dispose method.
 * @throws  IOException If the underlying was closed and caused an
 *                      IOException.
 */

    @Override
    protected final void  dispose () throws IOException
      {
      int l_bl, l_b, l_i;
      
      try
        {
        try
          {
          l_bl = this.m_buffer_len;            
          if(l_bl > 0)
            {
            
            l_b = this.m_buffer;
                        
            for(l_i = 3; l_i >= 0; l_i--)
              {
                         
              if(l_bl >= 0)
                {
                this.print(Base64.this.m_bin_to_char[l_b & 0x3f]);
                l_b >>= 6;
                }
              else
                {
                this.print(Base64.this.m_padding);
                }
              l_bl--;
              }
            }
          }
        finally
          {
          this.m_writer.close();
          } 
        }
      finally
        {
        super.dispose();
        }
      }  
    }
  
/**
 * This decoder can be used as a normal writer, where the data
 * written to it will immediately be base64-decoded to an output-stream.
 *
 * @author Thomas Weise
 */

  private final class Decoder extends ReferenceCountedWriter
    {
/**
 * The ouput-stream to write to.
 */

    private final OutputStream  m_output      ;
/**
 * The integer buffer for the data store.
 */

    private       int           m_buffer      ;
/**
 * The current buffer length.
 */

    private       int           m_buffer_len  ;
    
/**
 * Create a new decoder with an output stream assigned to it.
 * 
 * @param p_output  The output-stream assigned to the decoder.
 */

    private Decoder (final  OutputStream p_output)
      {
      super();
      this.m_output       = p_output;
      this.m_buffer       = 0;
      this.m_buffer_len   = 0;
      }
    
/**
 * Return the name of the character encoding being used by this stream.
 *
 * <p> If the encoding has an historical name then that name is returned;
 * otherwise the encoding's canonical name is returned.
 *
 * <p> If this instance was created with the  constructor then the returned
 * name, being unique for the encoding, may differ from the name passed to
 * the constructor.  This method may return <tt>null</tt> if the stream has
 * been closed. </p>
 *
 * @return The historical name of this encoding, or possibly
 *         <code>null</code> if the stream has been closed
 */

    @Override
    public  final String  get_encoding  ()
      {
      return XML.PREFERED_ENCODING;
      }
    
    
/**
 * Write a single character.  The character to be written is contained in
 * the 16 low-order bits of the given integer value; the 16 high-order bits
 * are ignored.
 *
 * <p> Subclasses that intend to support efficient single-character output
 * should override this method.
 *
 * @param p_c  int specifying a character to be written.
 * @exception  IOException  If an I/O error occurs
 */

    private final  void do_write(int p_c) throws IOException
      {
      int l_bl;
      
      p_c &= 0xff;
      
      if(p_c ==  Base64.this.m_padding)
        {
        this.close();
        }
      else
        {
        if(p_c <  Base64.this.m_char_to_bin.length)         
          {
          p_c = Base64.this.m_char_to_bin[p_c];
          if(p_c >= 0)
            {
            l_bl = this.m_buffer_len;
            p_c  = (this.m_buffer | (p_c << (6 * l_bl)));
            
            if(l_bl >= 3)
              {
              for(l_bl = 3; l_bl > 0; l_bl--)
                {
                this.m_output.write(p_c & 0xff);
                p_c >>= 8;
                }
              }
            else
              {
              l_bl++;
              }
            
            
            this.m_buffer_len = l_bl;
            this.m_buffer     = p_c;
            }
          
          }
        }    
      }
    
/**
 * Write a portion of an array of characters.
 *
 * @param  p_cbuf  Array of characters
 * @param  p_off   Offset from which to start writing characters
 * @param  p_len   Number of characters to write
 *
 * @exception  IOException  If an I/O error occurs
 */

    @Override
    public final  void write( char  p_cbuf[],
                              int   p_off,
                              int   p_len) throws IOException
      {
      synchronized(this.lock)
        {
        while(p_len > 0)
          {
          this.do_write(p_cbuf[p_off++]);
          p_len--;
          }
        }
      }
  
/**
 * Flush the stream.  If the stream has saved any characters from the
 * various write() methods in a buffer, write them immediately to their
 * intended destination.  Then, if that destination is another character or
 * byte stream, flush it.  Thus one flush() invocation will flush all the
 * buffers in a chain of Writers and OutputStreams.
 * <p>
 * If the intended destination of this stream is an abstraction provided by
 * the underlying operating system, for example a file, then flushing the
 * stream guarantees only that bytes previously written to the stream are
 * passed to the operating system for writing; it does not guarantee that
 * they are actually written to a physical device such as a disk drive.
 *
 */

    @Override
    public final  void flush()
      {
      //
      }
   
    
/**
 * Dispose this reference counted writer.
 * @throws  IOException If the underlying was closed and caused an
 *                      IOException.
 */

    @Override
    protected final void  dispose () throws IOException
      {
      int l_b;
      
      try
        {
        if(this.m_buffer_len > 0)
          {
          l_b = this.m_buffer;
          this.m_output.write(l_b & 0xff);
          l_b >>= 8;
          if(this.m_buffer_len > 2)
            {
            this.m_output.write(l_b & 0xff);
            }
          }
        }
      finally
        {
        try
          {
          this.m_output.close();
          }
        finally
          {
          super.dispose();
          }
        }   
      }
  
    }

  }

//RFC 2045                Internet Message Bodies            November 1996
//
//
//6.8.  Base64 Content-Transfer-Encoding
//
//   The Base64 Content-Transfer-Encoding is designed to represent
//   arbitrary sequences of octets in a form that need not be humanly
//   readable.  The encoding and decoding algorithms are simple, but the
//   encoded data are consistently only about 33 percent larger than the
//   unencoded data.  This encoding is virtually identical to the one used
//   in Privacy Enhanced Mail (PEM) applications, as defined in RFC 1421.
//
//   A 65-character subset of US-ASCII is used, enabling 6 bits to be
//   represented per printable character. (The extra 65th character, "=",
//   is used to signify a special processing function.)
//
//   NOTE:  This subset has the important property that it is represented
//   identically in all versions of ISO 646, including US-ASCII, and all
//   characters in the subset are also represented identically in all
//   versions of EBCDIC. Other popular encodings, such as the encoding
//   used by the uuencode utility, Macintosh binhex 4.0 [RFC-1741], and
//   the base85 encoding specified as part of Level 2 PostScript, do not
//   share these properties, and thus do not fulfill the portability
//   requirements a binary transport encoding for mail must meet.
//
//   The encoding process represents 24-bit groups of input bits as output
//   strings of 4 encoded characters.  Proceeding from left to right, a
//   24-bit input group is formed by concatenating 3 8bit input groups.
//   These 24 bits are then treated as 4 concatenated 6-bit groups, each
//   of which is translated into a single digit in the base64 alphabet.
//   When encoding a bit stream via the base64 encoding, the bit stream
//   must be presumed to be ordered with the most-significant-bit first.
//   That is, the first bit in the stream will be the high-order bit in
//   the first 8bit byte, and the eighth bit will be the low-order bit in
//   the first 8bit byte, and so on.
//
//   Each 6-bit group is used as an index into an array of 64 printable
//   characters.  The character referenced by the index is placed in the
//   output string.  These characters, identified in Table 1, below, are
//   selected so as to be universally representable, and the set excludes
//   characters with particular significance to SMTP (e.g., ".", CR, LF)
//   and to the multipart boundary delimiters defined in RFC 2046 (e.g.,
//   "-").
//
//
//
//
//
//
//
//
//
//
//
//Freed & Borenstein          Standards Track                    [Page 24]
//
//RFC 2045                Internet Message Bodies            November 1996
//
//
//                    Table 1: The Base64 Alphabet
//
//     Value Encoding  Value Encoding  Value Encoding  Value Encoding
//         0 A            17 R            34 i            51 z
//         1 B            18 S            35 j            52 0
//         2 C            19 T            36 k            53 1
//         3 D            20 U            37 l            54 2
//         4 E            21 V            38 m            55 3
//         5 F            22 W            39 n            56 4
//         6 G            23 X            40 o            57 5
//         7 H            24 Y            41 p            58 6
//         8 I            25 Z            42 q            59 7
//         9 J            26 a            43 r            60 8
//        10 K            27 b            44 s            61 9
//        11 L            28 c            45 t            62 +
//        12 M            29 d            46 u            63 /
//        13 N            30 e            47 v
//        14 O            31 f            48 w         (pad) =
//        15 P            32 g            49 x
//        16 Q            33 h            50 y
//
//   The encoded output stream must be represented in lines of no more
//   than 76 characters each.  All line breaks or other characters not
//   found in Table 1 must be ignored by decoding software.  In base64
//   data, characters other than those in Table 1, line breaks, and other
//   white space probably indicate a transmission error, about which a
//   warning message or even a message rejection might be appropriate
//   under some circumstances.
//
//   Special processing is performed if fewer than 24 bits are available
//   at the end of the data being encoded.  A full encoding quantum is
//   always completed at the end of a body.  When fewer than 24 input bits
//   are available in an input group, zero bits are added (on the right)
//   to form an integral number of 6-bit groups.  Padding at the end of
//   the data is performed using the "=" character.  Since all base64
//   input is an integral number of octets, only the following cases can
//   arise: (1) the final quantum of encoding input is an integral
//   multiple of 24 bits; here, the final unit of encoded output will be
//   an integral multiple of 4 characters with no "=" padding, (2) the
//   final quantum of encoding input is exactly 8 bits; here, the final
//   unit of encoded output will be two characters followed by two "="
//   padding characters, or (3) the final quantum of encoding input is
//   exactly 16 bits; here, the final unit of encoded output will be three
//   characters followed by one "=" padding character.
//
//   Because it is used only for padding at the end of the data, the
//   occurrence of any "=" characters may be taken as evidence that the
//   end of the data has been reached (without truncation in transit).  No
//
//
//
//Freed & Borenstein          Standards Track                    [Page 25]
//
//RFC 2045                Internet Message Bodies            November 1996
//
//
//   such assurance is possible, however, when the number of octets
//   transmitted was a multiple of three and no "=" characters are
//   present.
//
//   Any characters outside of the base64 alphabet are to be ignored in
//   base64-encoded data.
//
//   Care must be taken to use the proper octets for line breaks if base64
//   encoding is applied directly to text material that has not been
//   converted to canonical form.  In particular, text line breaks must be
//   converted into CRLF sequences prior to base64 encoding.  The
//   important thing to note is that this may be done directly by the
//   encoder rather than in a prior canonicalization step in some
//   implementations.
//
//   NOTE: There is no need to worry about quoting potential boundary
//   delimiters within base64-encoded bodies within multipart entities
//   because no hyphen characters are used in the base64 encoding.

File Information:

file name:Base64.java
package:org.sfc.io
qualified name:org.sfc.io.Base64.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/sfc/io/Base64.java
size:34.088 KB (34907 B)
uploaded: 2018-01-07 12:03:36 GMT+0000
last update: 2006-03-07 04:20:28 GMT+0000
last access: 2018-04-23 22:59:53 GMT+0000

statistics online since 2006-01-02.   RSS Feed
Contact us by sending an email to tweise@gmx.de to receive further information, to report errors, or to join our project.
All content on this site (http://dgpf.sourceforge.net/) is LGPL-licensed.
http://dgpf.sourceforge.net/scripts/source/source.php last modified at 2018-01-07 12:03:34 GMT+0000 served at 2018-04-23 22:59:53 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo