org.shlublu.javax.data
Class Base64InputStream

java.lang.Object
  |
  +--java.io.InputStream
        |
        +--java.io.FilterInputStream
              |
              +--org.shlublu.javax.data.Base64InputStream

public class Base64InputStream
extends java.io.FilterInputStream

RFC 2045 compliant Base 64 stream decoder.
This stream filters a given InputStream

The data is decoded following the calls of read() or read(byte[],int,int). Due to the fact that code can contain linebreaks, LF and CR are silentely ignored.
Code can also terminate by 1 or 2 padding characters.

The consequence is that the available() method may return a larger number than the actual number of available bytes, since this method returns the maximal expected value.

0 is the only certified value for available(). To test the return values of read(), read(byte[]) and read(byte[],int,int) is required to detect the actual end of code.

Since:
0.7
See Also:
Base64

Fields inherited from class java.io.FilterInputStream
in
 
Constructor Summary
Base64InputStream(java.io.InputStream istream)
          Create this filter using the given InputStream
 
Method Summary
 int available()
          Returns the number of bytes that can be decoded from this input stream without blocking.
 void close()
          Closes this input stream and releases any system resources associated with the stream.
 void mark(int readlimit)
          Do nothing, since marks aren't supported
 boolean markSupported()
          Always return false, since marks aren't supported
 int read()
          Decode the next byte of data from this input stream.
 int read(byte[] abyStorage, int iStartOffset, int iLength)
          Decode up to iLength bytes of data into the given array.
 void reset()
          Always throw an exception, since marks aren't supported
 long skip(long iNbToSkip)
          Not applicable to this stream, always return 0
 
Methods inherited from class java.io.FilterInputStream
read
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Base64InputStream

public Base64InputStream(java.io.InputStream istream)
Create this filter using the given InputStream
Parameters:
istream - The stream to filter
Method Detail

available

public int available()
              throws java.io.IOException
Returns the number of bytes that can be decoded from this input stream without blocking.

If the embedded stream have strictly less that 4 digits available, we have no bytes available at all for now and 0 is returned. This is due to the fact that we need 4 digits to produce 3 bytes.

Is we have 4 or more digits to read, we assume that the code is correct, with no linebreaks or unexpected characters. We have 3 bytes per 4 digits, except for the last quantum for which we have 1 to 3 digits, without beeing able to know without reading it.
We'll return in this case the maximal number of available decoded bytes : nb_quanta * 3

The last alternative is when we left the internal buffer non empty : ie. when we did read a number of bytes non-multiple of three.
In this case, decoded bytes in excess were generated but not returned yet, so they're added to the potential of the remaining stream. This is due to the fact that decoded bytes are generated by quantas of three decoded bytes each.
Overrides:
available in class java.io.FilterInputStream

close

public void close()
           throws java.io.IOException
Closes this input stream and releases any system resources associated with the stream.
Overrides:
close in class java.io.FilterInputStream

read

public int read()
         throws java.io.IOException
Decode the next byte of data from this input stream. Line breaks in base 64 code are silentely ignored.
Due to the fact that the available() method may return an excessive value, to check the return value of read() is required.
Overrides:
read in class java.io.FilterInputStream
Returns:
A decoded byte, or -1 if none available
See Also:
available()

read

public int read(byte[] abyStorage,
                int iStartOffset,
                int iLength)
         throws java.io.IOException
Decode up to iLength bytes of data into the given array.
Line breaks in base 64 code are silentely ignored. If some of them are encountered, the end of stream can be reached sooner than announced by available(). For this reason, to check the read(byte[],int,int) return value is required, and so for super.read(byte[]).
Overrides:
read in class java.io.FilterInputStream
Parameters:
abyStorage - The array used to store decoded data
iStartOffset - The index to begin to store at
iLength - The maximal length to be decoded
Returns:
The number of decoded bytes
See Also:
available(), FilterInputStream.read(byte[])

skip

public long skip(long iNbToSkip)
          throws java.io.IOException
Not applicable to this stream, always return 0
Overrides:
skip in class java.io.FilterInputStream
Parameters:
iNbToSkip - The number of bytes to skip
Returns:
The number of skipped bytes, which is alway zero

mark

public void mark(int readlimit)
Do nothing, since marks aren't supported
Overrides:
mark in class java.io.FilterInputStream

reset

public void reset()
           throws java.io.IOException
Always throw an exception, since marks aren't supported
Overrides:
reset in class java.io.FilterInputStream

markSupported

public boolean markSupported()
Always return false, since marks aren't supported
Overrides:
markSupported in class java.io.FilterInputStream