You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2011/01/26 16:25:42 UTC

svn commit: r1063760 - in /commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary: Base32InputStream.java Base32OutputStream.java BasedCodec.java BasedCodecInputStream.java BasedCodecOutputStream.java

Author: sebb
Date: Wed Jan 26 15:25:42 2011
New Revision: 1063760

URL: http://svn.apache.org/viewvc?rev=1063760&view=rev
Log:
New classes for Base32 rework

Added:
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32InputStream.java   (with props)
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32OutputStream.java   (with props)
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodec.java   (with props)
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecInputStream.java   (with props)
    commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecOutputStream.java   (with props)

Added: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32InputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32InputStream.java?rev=1063760&view=auto
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32InputStream.java (added)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32InputStream.java Wed Jan 26 15:25:42 2011
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.codec.binary;
+
+import java.io.InputStream;
+
+/**
+ * Provides Base32 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength
+ * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate
+ * constructor.
+ * <p>
+ * The default behaviour of the Base32InputStream is to DECODE, whereas the default behaviour of the Base32OutputStream
+ * is to ENCODE, but this behaviour can be overridden by using a different constructor.
+ * </p>
+ * <p>
+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
+ * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
+ * </p>
+ * 
+ * @version $Revision$
+ * @see <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a>
+ * @since 1.5
+ */
+public class Base32InputStream extends BasedCodecInputStream {
+
+    /**
+     * Creates a Base32InputStream such that all data read is Base32-decoded from the original provided InputStream.
+     * 
+     * @param in
+     *            InputStream to wrap.
+     */
+    public Base32InputStream(InputStream in) {
+        this(in, false);
+    }
+
+    /**
+     * Creates a Base32InputStream such that all data read is either Base32-encoded or Base32-decoded from the original
+     * provided InputStream.
+     * 
+     * @param in
+     *            InputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data read from us, false if we should decode.
+     */
+    public Base32InputStream(InputStream in, boolean doEncode) {
+        super(in, new Base32(false), doEncode);
+    }
+
+    /**
+     * Creates a Base32InputStream such that all data read is either Base32-encoded or Base32-decoded from the original
+     * provided InputStream.
+     * 
+     * @param in
+     *            InputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data read from us, false if we should decode.
+     * @param lineLength
+     *            If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to
+     *            nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is
+     *            false, lineLength is ignored.
+     * @param lineSeparator
+     *            If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n).
+     *            If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored.
+     */
+    public Base32InputStream(InputStream in, boolean doEncode, int lineLength, byte[] lineSeparator) {
+        super(in, new Base32(lineLength, lineSeparator), doEncode);
+    }
+
+}

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32InputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32InputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32OutputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32OutputStream.java?rev=1063760&view=auto
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32OutputStream.java (added)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32OutputStream.java Wed Jan 26 15:25:42 2011
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.codec.binary;
+
+import java.io.OutputStream;
+
+/**
+ * Provides Base64 encoding and decoding in a streaming fashion (unlimited size). When encoding the default lineLength
+ * is 76 characters and the default lineEnding is CRLF, but these can be overridden by using the appropriate
+ * constructor.
+ * <p>
+ * The default behaviour of the Base64OutputStream is to ENCODE, whereas the default behaviour of the Base64InputStream
+ * is to DECODE. But this behaviour can be overridden by using a different constructor.
+ * </p>
+ * <p>
+ * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose
+ * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein.
+ * </p>
+ * <p>
+ * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
+ * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
+ * </p>
+ * 
+ * @author Apache Software Foundation
+ * @version $Id$
+ * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
+ * @since 1.4
+ */
+public class Base32OutputStream extends BasedCodecOutputStream {
+
+    /**
+     * Creates a Base64OutputStream such that all data written is Base64-encoded to the original provided OutputStream.
+     * 
+     * @param out
+     *            OutputStream to wrap.
+     */
+    public Base32OutputStream(OutputStream out) {
+        this(out, true);
+    }
+
+    /**
+     * Creates a Base64OutputStream such that all data written is either Base64-encoded or Base64-decoded to the
+     * original provided OutputStream.
+     * 
+     * @param out
+     *            OutputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data written to us, false if we should decode.
+     */
+    public Base32OutputStream(OutputStream out, boolean doEncode) {
+        super(out, new Base32(false), doEncode);
+    }
+
+    /**
+     * Creates a Base64OutputStream such that all data written is either Base64-encoded or Base64-decoded to the
+     * original provided OutputStream.
+     * 
+     * @param out
+     *            OutputStream to wrap.
+     * @param doEncode
+     *            true if we should encode all data written to us, false if we should decode.
+     * @param lineLength
+     *            If doEncode is true, each line of encoded data will contain lineLength characters (rounded down to
+     *            nearest multiple of 4). If lineLength <=0, the encoded data is not divided into lines. If doEncode is
+     *            false, lineLength is ignored.
+     * @param lineSeparator
+     *            If doEncode is true, each line of encoded data will be terminated with this byte sequence (e.g. \r\n).
+     *            If lineLength <= 0, the lineSeparator is not used. If doEncode is false lineSeparator is ignored.
+     */
+    public Base32OutputStream(OutputStream out, boolean doEncode, int lineLength, byte[] lineSeparator) {
+        super(out, new Base32(lineLength, lineSeparator), doEncode);
+    }
+
+}

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32OutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32OutputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodec.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodec.java?rev=1063760&view=auto
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodec.java (added)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodec.java Wed Jan 26 15:25:42 2011
@@ -0,0 +1,278 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package org.apache.commons.codec.binary;
+
+import org.apache.commons.codec.BinaryDecoder;
+import org.apache.commons.codec.BinaryEncoder;
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.EncoderException;
+
+public abstract class BasedCodec implements BinaryEncoder, BinaryDecoder {
+
+    /**
+     *  MIME chunk size per RFC 2045 section 6.8.
+     * 
+     * <p>
+     * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
+     * equal signs.
+     * </p>
+     * 
+     * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
+     */
+    public static final int MIME_CHUNK_SIZE = 76;
+
+    /**
+     * PEM chunk size per RFC 1421 section 4.3.2.4.
+     * 
+     * <p>
+     * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
+     * equal signs.
+     * </p>
+     * 
+     * @see <a href="http://tools.ietf.org/html/rfc1421">RFC 1421 section 4.3.2.4</a>
+     */
+    public static final int PEM_CHUNK_SIZE = 64;
+
+    private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
+
+    private static final int DEFAULT_BUFFER_SIZE = 8192;
+    /**
+     * Buffer for streaming.
+     */
+    protected byte[] buffer;
+
+    /**
+     * Position where next character should be written in the buffer.
+     */
+    protected int pos;
+
+    /**
+     * Position where next character should be read from the buffer.
+     */
+    private int readPos;
+
+    /**
+     * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless,
+     * and must be thrown away.
+     */
+    protected boolean eof;
+
+    /**
+     * Place holder for the bytes we're dealing with for our based logic. Bitwise operations store and extract the
+     * encoding or decoding from this variable.
+     */
+    protected long x;
+
+    /**
+     * Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to
+     * make sure each encoded line never goes beyond lineLength (if lineLength > 0).
+     */
+    protected int currentLinePos;
+
+    /**
+     * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding.
+     * This variable helps track that.
+     */
+    protected int modulus;
+
+    protected BasedCodec(){
+    }
+
+    /**
+     * Returns true if this object has buffered data for reading.
+     * 
+     * @return true if there is data still available for reading.
+     */
+    boolean hasData() {  // package protected for access from I/O streams
+        return this.buffer != null;
+    }
+
+    /**
+     * Returns the amount of buffered data available for reading.
+     * 
+     * @return The amount of buffered data available for reading.
+     */
+    int avail() {  // package protected for access from I/O streams
+        return buffer != null ? pos - readPos : 0;
+    }
+
+    /** Doubles our buffer. */
+    protected void resizeBuffer() {
+        if (buffer == null) {
+            buffer = new byte[DEFAULT_BUFFER_SIZE];
+            pos = 0;
+            readPos = 0;
+        } else {
+            byte[] b = new byte[buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR];
+            System.arraycopy(buffer, 0, b, 0, buffer.length);
+            buffer = b;
+        }
+    }
+
+    /**
+     * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail
+     * bytes. Returns how many bytes were actually extracted.
+     * 
+     * @param b
+     *            byte[] array to extract the buffered data into.
+     * @param bPos
+     *            position in byte[] array to start extraction at.
+     * @param bAvail
+     *            amount of bytes we're allowed to extract. We may extract fewer (if fewer are available).
+     * @return The number of bytes successfully extracted into the provided byte[] array.
+     */
+    int readResults(byte[] b, int bPos, int bAvail) {  // package protected for access from I/O streams
+        if (buffer != null) {
+            int len = Math.min(avail(), bAvail);
+            System.arraycopy(buffer, readPos, b, bPos, len);
+            readPos += len;
+            if (readPos >= pos) {
+                buffer = null;
+            }
+            return len;
+        }
+        return eof ? -1 : 0;
+    }
+
+    /**
+     * Checks if a byte value is whitespace or not.
+     * Whitespace is taken to mean: space, tab, CR, LF
+     * @param byteToCheck
+     *            the byte to check
+     * @return true if byte is whitespace, false otherwise
+     */
+    protected static boolean isWhiteSpace(byte byteToCheck) {
+        switch (byteToCheck) {
+            case ' ' :
+            case '\n' :
+            case '\r' :
+            case '\t' :
+                return true;
+            default :
+                return false;
+        }
+    }
+
+    /**
+     * Resets this Base32 object to its initial newly constructed state.
+     */
+    private void reset() {
+        buffer = null;
+        pos = 0;
+        readPos = 0;
+        currentLinePos = 0;
+        modulus = 0;
+        eof = false;
+    }
+    /**
+     * Encodes an Object using the Base32 algorithm. This method is provided in order to satisfy the requirements of the
+     * Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[].
+     * 
+     * @param pObject
+     *            Object to encode
+     * @return An object (of type byte[]) containing the Base32 encoded data which corresponds to the byte[] supplied.
+     * @throws EncoderException
+     *             if the parameter supplied is not of type byte[]
+     */
+    public Object encode(Object pObject) throws EncoderException {
+        if (!(pObject instanceof byte[])) {
+            throw new EncoderException("Parameter supplied to Base32 encode is not a byte[]");
+        }
+        return encode((byte[]) pObject);
+    }
+    /**
+     * Encodes a byte[] containing binary data, into a String containing characters in the Base32 alphabet.
+     *
+     * @param pArray
+     *            a byte array containing binary data
+     * @return A String containing only Base32 character data
+     */
+    public String encodeToString(byte[] pArray) {
+        return StringUtils.newStringUtf8(encode(pArray));
+    }
+    /**
+     * Decodes an Object using the Base32 algorithm. This method is provided in order to satisfy the requirements of the
+     * Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String.
+     * 
+     * @param pObject
+     *            Object to decode
+     * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String supplied.
+     * @throws DecoderException
+     *             if the parameter supplied is not of type byte[]
+     */
+    public Object decode(Object pObject) throws DecoderException {        
+        if (pObject instanceof byte[]) {
+            return decode((byte[]) pObject);
+        } else if (pObject instanceof String) {
+            return decode((String) pObject);
+        } else {
+            throw new DecoderException("Parameter supplied to Base32 decode is not a byte[] or a String");
+        }
+    }
+    /**
+     * Decodes a String containing characters in the Base32 alphabet.
+     *
+     * @param pArray
+     *            A String containing Base32 character data
+     * @return a byte array containing binary data
+     */
+    public byte[] decode(String pArray) {
+        return decode(StringUtils.getBytesUtf8(pArray));
+    }
+    /**
+     * Decodes a byte[] containing characters in the Base32 alphabet.
+     * 
+     * @param pArray
+     *            A byte array containing Base32 character data
+     * @return a byte array containing binary data
+     */
+    public byte[] decode(byte[] pArray) {
+        reset();
+        if (pArray == null || pArray.length == 0) {
+            return pArray;
+        }
+        decode(pArray, 0, pArray.length);
+        decode(pArray, 0, -1); // Notify decoder of EOF.
+        byte[] result = new byte[pos];
+        readResults(result, 0, result.length);
+        return result;
+    }
+    /**
+     * Encodes a byte[] containing binary data, into a byte[] containing characters in the Base32 alphabet.
+     * 
+     * @param pArray
+     *            a byte array containing binary data
+     * @return A byte array containing only Base32 character data
+     */
+    public byte[] encode(byte[] pArray) {
+        reset();        
+        if (pArray == null || pArray.length == 0) {
+            return pArray;
+        }
+        encode(pArray, 0, pArray.length);
+        encode(pArray, 0, -1); // Notify encoder of EOF.
+        byte[] buf = new byte[pos - readPos];
+        readResults(buf, 0, buf.length);
+        return buf;
+    }
+    
+    abstract void encode(byte[] pArray, int i, int length);  // package protected for access from I/O streams
+
+    abstract void decode(byte[] pArray, int i, int length); // package protected for access from I/O streams
+}

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodec.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodec.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecInputStream.java?rev=1063760&view=auto
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecInputStream.java (added)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecInputStream.java Wed Jan 26 15:25:42 2011
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package org.apache.commons.codec.binary;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BasedCodecInputStream extends FilterInputStream {
+
+    private final boolean doEncode;
+
+    private final BasedCodec basedCodec;
+
+    private final byte[] singleByte = new byte[1];
+
+    protected BasedCodecInputStream(InputStream in, BasedCodec basedCodec, boolean doEncode) {
+        super(in);
+        this.doEncode = doEncode;
+        this.basedCodec = basedCodec;
+    }
+
+    /**
+     * Reads one <code>byte</code> from this input stream.
+     * 
+     * @return the byte as an integer in the range 0 to 255. Returns -1 if EOF has been reached.
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    public int read() throws IOException {
+        int r = read(singleByte, 0, 1);
+        while (r == 0) {
+            r = read(singleByte, 0, 1);
+        }
+        if (r > 0) {
+            return singleByte[0] < 0 ? 256 + singleByte[0] : singleByte[0];
+        }
+        return -1;
+    }
+
+    /**
+     * Attempts to read <code>len</code> bytes into the specified <code>b</code> array starting at <code>offset</code>
+     * from this InputStream.
+     * 
+     * @param b
+     *            destination byte array
+     * @param offset
+     *            where to start writing the bytes
+     * @param len
+     *            maximum number of bytes to read
+     * 
+     * @return number of bytes read
+     * @throws IOException
+     *             if an I/O error occurs.
+     * @throws NullPointerException
+     *             if the byte array parameter is null
+     * @throws IndexOutOfBoundsException
+     *             if offset, len or buffer size are invalid
+     */
+    public int read(byte b[], int offset, int len) throws IOException {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if (offset < 0 || len < 0) {
+            throw new IndexOutOfBoundsException();
+        } else if (offset > b.length || offset + len > b.length) {
+            throw new IndexOutOfBoundsException();
+        } else if (len == 0) {
+            return 0;
+        } else {
+            int readLen = 0;
+            /*
+             Rationale for while-loop on (readLen == 0):
+             -----
+             Base32.readResults() usually returns > 0 or EOF (-1).  In the
+             rare case where it returns 0, we just keep trying.
+
+             This is essentially an undocumented contract for InputStream
+             implementors that want their code to work properly with
+             java.io.InputStreamReader, since the latter hates it when
+             InputStream.read(byte[]) returns a zero.  Unfortunately our
+             readResults() call must return 0 if a large amount of the data
+             being decoded was non-base32, so this while-loop enables proper
+             interop with InputStreamReader for that scenario.
+             -----
+             This is a fix for CODEC-101
+            */
+            while (readLen == 0) {
+                if (!basedCodec.hasData()) {
+                    byte[] buf = new byte[doEncode ? 4096 : 8192];
+                    int c = in.read(buf);
+                    if (doEncode) {
+                        basedCodec.encode(buf, 0, c);
+                    } else {
+                        basedCodec.decode(buf, 0, c);
+                    }
+                }
+                readLen = basedCodec.readResults(b, offset, len);
+            }
+            return readLen;
+        }
+    }
+    /**
+     * {@inheritDoc}
+     * 
+     * @return false
+     */
+    public boolean markSupported() {
+        return false; // not an easy job to support marks
+    }
+
+}

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecInputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecOutputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecOutputStream.java?rev=1063760&view=auto
==============================================================================
--- commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecOutputStream.java (added)
+++ commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecOutputStream.java Wed Jan 26 15:25:42 2011
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package org.apache.commons.codec.binary;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class BasedCodecOutputStream extends FilterOutputStream {
+
+    private final boolean doEncode;
+
+    private final BasedCodec basedCodec;
+
+    private final byte[] singleByte = new byte[1];
+
+    public BasedCodecOutputStream(OutputStream out, BasedCodec basedCodec, boolean doEncode) {
+        super(out);
+        this.basedCodec = basedCodec;
+        this.doEncode = doEncode;
+    }
+
+    /**
+     * Writes the specified <code>byte</code> to this output stream.
+     * 
+     * @param i
+     *            source byte
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    public void write(int i) throws IOException {
+        singleByte[0] = (byte) i;
+        write(singleByte, 0, 1);
+    }
+
+    /**
+     * Writes <code>len</code> bytes from the specified <code>b</code> array starting at <code>offset</code> to this
+     * output stream.
+     * 
+     * @param b
+     *            source byte array
+     * @param offset
+     *            where to start reading the bytes
+     * @param len
+     *            maximum number of bytes to write
+     * 
+     * @throws IOException
+     *             if an I/O error occurs.
+     * @throws NullPointerException
+     *             if the byte array parameter is null
+     * @throws IndexOutOfBoundsException
+     *             if offset, len or buffer size are invalid
+     */
+    public void write(byte b[], int offset, int len) throws IOException {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if (offset < 0 || len < 0) {
+            throw new IndexOutOfBoundsException();
+        } else if (offset > b.length || offset + len > b.length) {
+            throw new IndexOutOfBoundsException();
+        } else if (len > 0) {
+            if (doEncode) {
+                basedCodec.encode(b, offset, len);
+            } else {
+                basedCodec.decode(b, offset, len);
+            }
+            flush(false);
+        }
+    }
+
+    /**
+     * Flushes this output stream and forces any buffered output bytes to be written out to the stream. If propogate is
+     * true, the wrapped stream will also be flushed.
+     * 
+     * @param propogate
+     *            boolean flag to indicate whether the wrapped OutputStream should also be flushed.
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    private void flush(boolean propogate) throws IOException {
+        int avail = basedCodec.avail();
+        if (avail > 0) {
+            byte[] buf = new byte[avail];
+            int c = basedCodec.readResults(buf, 0, avail);
+            if (c > 0) {
+                out.write(buf, 0, c);
+            }
+        }
+        if (propogate) {
+            out.flush();
+        }
+    }
+
+    /**
+     * Flushes this output stream and forces any buffered output bytes to be written out to the stream.
+     * 
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    public void flush() throws IOException {
+        flush(true);
+    }
+
+    /**
+     * Closes this output stream and releases any system resources associated with the stream.
+     * 
+     * @throws IOException
+     *             if an I/O error occurs.
+     */
+    public void close() throws IOException {
+        // Notify encoder of EOF (-1).
+        if (doEncode) {
+            basedCodec.encode(singleByte, 0, -1);
+        } else {
+            basedCodec.decode(singleByte, 0, -1);
+        }
+        flush();
+        out.close();
+    }
+
+}

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCodecOutputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision



Re: svn commit: r1063760 - in /commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary: Base32InputStream.java Base32OutputStream.java BasedCodec.java BasedCodecInputStream.java BasedCodecOutputStream.java

Posted by sebb <se...@gmail.com>.
On 26 January 2011 15:31, Gary Gregory <GG...@seagullsoftware.com> wrote:
> Hi Sebb,
>
> Instead of "BasedCodec", I think "BaseN" works better. It also matches the concept from the RFC which talks about "Base-N Encodings".
>
> "Based" just sounds very odd to me.
>

These are an initial design. See separate mail to follow.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: svn commit: r1063760 - in /commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary: Base32InputStream.java Base32OutputStream.java BasedCodec.java BasedCodecInputStream.java BasedCodecOutputStream.java

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Hi Sebb,

Instead of "BasedCodec", I think "BaseN" works better. It also matches the concept from the RFC which talks about "Base-N Encodings".

"Based" just sounds very odd to me. 

Gary Gregory
Senior Software Engineer
Rocket Software
3340 Peachtree Road, Suite 820 • Atlanta, GA 30326 • USA
Tel: +1.404.760.1560
Email: ggregory@seagullsoftware.com
Web: seagull.rocketsoftware.com  



> -----Original Message-----
> From: sebb@apache.org [mailto:sebb@apache.org]
> Sent: Wednesday, January 26, 2011 10:26
> To: commits@commons.apache.org
> Subject: svn commit: r1063760 - in
> /commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary:
> Base32InputStream.java Base32OutputStream.java BasedCodec.java
> BasedCodecInputStream.java BasedCodecOutputStream.java
> 
> Author: sebb
> Date: Wed Jan 26 15:25:42 2011
> New Revision: 1063760
> 
> URL: http://svn.apache.org/viewvc?rev=1063760&view=rev
> Log:
> New classes for Base32 rework
> 
> Added:
> 
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32I
> nputStream.java   (with props)
> 
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32O
> utputStream.java   (with props)
> 
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> dec.java   (with props)
> 
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decInputStream.java   (with props)
> 
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decOutputStream.java   (with props)
> 
> Added:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32I
> nputStream.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache
> /commons/codec/binary/Base32InputStream.java?rev=1063760&view=auto
> ===========================================================================
> ===
> ---
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32I
> nputStream.java (added)
> +++
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32I
> nputStream.java Wed Jan 26 15:25:42 2011
> @@ -0,0 +1,84 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +package org.apache.commons.codec.binary;
> +
> +import java.io.InputStream;
> +
> +/**
> + * Provides Base32 encoding and decoding in a streaming fashion (unlimited
> size). When encoding the default lineLength
> + * is 76 characters and the default lineEnding is CRLF, but these can be
> overridden by using the appropriate
> + * constructor.
> + * <p>
> + * The default behaviour of the Base32InputStream is to DECODE, whereas
> the default behaviour of the Base32OutputStream
> + * is to ENCODE, but this behaviour can be overridden by using a different
> constructor.
> + * </p>
> + * <p>
> + * Since this class operates directly on byte streams, and not character
> streams, it is hard-coded to only encode/decode
> + * character encodings which are compatible with the lower 127 ASCII chart
> (ISO-8859-1, Windows-1252, UTF-8, etc).
> + * </p>
> + *
> + * @version $Revision$
> + * @see <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a>
> + * @since 1.5
> + */
> +public class Base32InputStream extends BasedCodecInputStream {
> +
> +    /**
> +     * Creates a Base32InputStream such that all data read is Base32-
> decoded from the original provided InputStream.
> +     *
> +     * @param in
> +     *            InputStream to wrap.
> +     */
> +    public Base32InputStream(InputStream in) {
> +        this(in, false);
> +    }
> +
> +    /**
> +     * Creates a Base32InputStream such that all data read is either
> Base32-encoded or Base32-decoded from the original
> +     * provided InputStream.
> +     *
> +     * @param in
> +     *            InputStream to wrap.
> +     * @param doEncode
> +     *            true if we should encode all data read from us, false if
> we should decode.
> +     */
> +    public Base32InputStream(InputStream in, boolean doEncode) {
> +        super(in, new Base32(false), doEncode);
> +    }
> +
> +    /**
> +     * Creates a Base32InputStream such that all data read is either
> Base32-encoded or Base32-decoded from the original
> +     * provided InputStream.
> +     *
> +     * @param in
> +     *            InputStream to wrap.
> +     * @param doEncode
> +     *            true if we should encode all data read from us, false if
> we should decode.
> +     * @param lineLength
> +     *            If doEncode is true, each line of encoded data will
> contain lineLength characters (rounded down to
> +     *            nearest multiple of 4). If lineLength <=0, the encoded
> data is not divided into lines. If doEncode is
> +     *            false, lineLength is ignored.
> +     * @param lineSeparator
> +     *            If doEncode is true, each line of encoded data will be
> terminated with this byte sequence (e.g. \r\n).
> +     *            If lineLength <= 0, the lineSeparator is not used. If
> doEncode is false lineSeparator is ignored.
> +     */
> +    public Base32InputStream(InputStream in, boolean doEncode, int
> lineLength, byte[] lineSeparator) {
> +        super(in, new Base32(lineLength, lineSeparator), doEncode);
> +    }
> +
> +}
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32I
> nputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:eol-style = native
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32I
> nputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:keywords = Author Date Id Revision
> 
> Added:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32O
> utputStream.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache
> /commons/codec/binary/Base32OutputStream.java?rev=1063760&view=auto
> ===========================================================================
> ===
> ---
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32O
> utputStream.java (added)
> +++
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32O
> utputStream.java Wed Jan 26 15:25:42 2011
> @@ -0,0 +1,89 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +package org.apache.commons.codec.binary;
> +
> +import java.io.OutputStream;
> +
> +/**
> + * Provides Base64 encoding and decoding in a streaming fashion (unlimited
> size). When encoding the default lineLength
> + * is 76 characters and the default lineEnding is CRLF, but these can be
> overridden by using the appropriate
> + * constructor.
> + * <p>
> + * The default behaviour of the Base64OutputStream is to ENCODE, whereas
> the default behaviour of the Base64InputStream
> + * is to DECODE. But this behaviour can be overridden by using a different
> constructor.
> + * </p>
> + * <p>
> + * This class implements section <cite>6.8. Base64 Content-Transfer-
> Encoding</cite> from RFC 2045 <cite>Multipurpose
> + * Internet Mail Extensions (MIME) Part One: Format of Internet Message
> Bodies</cite> by Freed and Borenstein.
> + * </p>
> + * <p>
> + * Since this class operates directly on byte streams, and not character
> streams, it is hard-coded to only encode/decode
> + * character encodings which are compatible with the lower 127 ASCII chart
> (ISO-8859-1, Windows-1252, UTF-8, etc).
> + * </p>
> + *
> + * @author Apache Software Foundation
> + * @version $Id$
> + * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
> + * @since 1.4
> + */
> +public class Base32OutputStream extends BasedCodecOutputStream {
> +
> +    /**
> +     * Creates a Base64OutputStream such that all data written is Base64-
> encoded to the original provided OutputStream.
> +     *
> +     * @param out
> +     *            OutputStream to wrap.
> +     */
> +    public Base32OutputStream(OutputStream out) {
> +        this(out, true);
> +    }
> +
> +    /**
> +     * Creates a Base64OutputStream such that all data written is either
> Base64-encoded or Base64-decoded to the
> +     * original provided OutputStream.
> +     *
> +     * @param out
> +     *            OutputStream to wrap.
> +     * @param doEncode
> +     *            true if we should encode all data written to us, false
> if we should decode.
> +     */
> +    public Base32OutputStream(OutputStream out, boolean doEncode) {
> +        super(out, new Base32(false), doEncode);
> +    }
> +
> +    /**
> +     * Creates a Base64OutputStream such that all data written is either
> Base64-encoded or Base64-decoded to the
> +     * original provided OutputStream.
> +     *
> +     * @param out
> +     *            OutputStream to wrap.
> +     * @param doEncode
> +     *            true if we should encode all data written to us, false
> if we should decode.
> +     * @param lineLength
> +     *            If doEncode is true, each line of encoded data will
> contain lineLength characters (rounded down to
> +     *            nearest multiple of 4). If lineLength <=0, the encoded
> data is not divided into lines. If doEncode is
> +     *            false, lineLength is ignored.
> +     * @param lineSeparator
> +     *            If doEncode is true, each line of encoded data will be
> terminated with this byte sequence (e.g. \r\n).
> +     *            If lineLength <= 0, the lineSeparator is not used. If
> doEncode is false lineSeparator is ignored.
> +     */
> +    public Base32OutputStream(OutputStream out, boolean doEncode, int
> lineLength, byte[] lineSeparator) {
> +        super(out, new Base32(lineLength, lineSeparator), doEncode);
> +    }
> +
> +}
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32O
> utputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:eol-style = native
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Base32O
> utputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:keywords = Author Date Id Revision
> 
> Added:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> dec.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache
> /commons/codec/binary/BasedCodec.java?rev=1063760&view=auto
> ===========================================================================
> ===
> ---
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> dec.java (added)
> +++
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> dec.java Wed Jan 26 15:25:42 2011
> @@ -0,0 +1,278 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + *
> + */
> +
> +package org.apache.commons.codec.binary;
> +
> +import org.apache.commons.codec.BinaryDecoder;
> +import org.apache.commons.codec.BinaryEncoder;
> +import org.apache.commons.codec.DecoderException;
> +import org.apache.commons.codec.EncoderException;
> +
> +public abstract class BasedCodec implements BinaryEncoder, BinaryDecoder {
> +
> +    /**
> +     *  MIME chunk size per RFC 2045 section 6.8.
> +     *
> +     * <p>
> +     * The {@value} character limit does not count the trailing CRLF, but
> counts all other characters, including any
> +     * equal signs.
> +     * </p>
> +     *
> +     * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section
> 6.8</a>
> +     */
> +    public static final int MIME_CHUNK_SIZE = 76;
> +
> +    /**
> +     * PEM chunk size per RFC 1421 section 4.3.2.4.
> +     *
> +     * <p>
> +     * The {@value} character limit does not count the trailing CRLF, but
> counts all other characters, including any
> +     * equal signs.
> +     * </p>
> +     *
> +     * @see <a href="http://tools.ietf.org/html/rfc1421">RFC 1421 section
> 4.3.2.4</a>
> +     */
> +    public static final int PEM_CHUNK_SIZE = 64;
> +
> +    private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
> +
> +    private static final int DEFAULT_BUFFER_SIZE = 8192;
> +    /**
> +     * Buffer for streaming.
> +     */
> +    protected byte[] buffer;
> +
> +    /**
> +     * Position where next character should be written in the buffer.
> +     */
> +    protected int pos;
> +
> +    /**
> +     * Position where next character should be read from the buffer.
> +     */
> +    private int readPos;
> +
> +    /**
> +     * Boolean flag to indicate the EOF has been reached. Once EOF has
> been reached, this object becomes useless,
> +     * and must be thrown away.
> +     */
> +    protected boolean eof;
> +
> +    /**
> +     * Place holder for the bytes we're dealing with for our based logic.
> Bitwise operations store and extract the
> +     * encoding or decoding from this variable.
> +     */
> +    protected long x;
> +
> +    /**
> +     * Variable tracks how many characters have been written to the
> current line. Only used when encoding. We use it to
> +     * make sure each encoded line never goes beyond lineLength (if
> lineLength > 0).
> +     */
> +    protected int currentLinePos;
> +
> +    /**
> +     * Writes to the buffer only occur after every 3/5 reads when
> encoding, and every 4/8 reads when decoding.
> +     * This variable helps track that.
> +     */
> +    protected int modulus;
> +
> +    protected BasedCodec(){
> +    }
> +
> +    /**
> +     * Returns true if this object has buffered data for reading.
> +     *
> +     * @return true if there is data still available for reading.
> +     */
> +    boolean hasData() {  // package protected for access from I/O streams
> +        return this.buffer != null;
> +    }
> +
> +    /**
> +     * Returns the amount of buffered data available for reading.
> +     *
> +     * @return The amount of buffered data available for reading.
> +     */
> +    int avail() {  // package protected for access from I/O streams
> +        return buffer != null ? pos - readPos : 0;
> +    }
> +
> +    /** Doubles our buffer. */
> +    protected void resizeBuffer() {
> +        if (buffer == null) {
> +            buffer = new byte[DEFAULT_BUFFER_SIZE];
> +            pos = 0;
> +            readPos = 0;
> +        } else {
> +            byte[] b = new byte[buffer.length *
> DEFAULT_BUFFER_RESIZE_FACTOR];
> +            System.arraycopy(buffer, 0, b, 0, buffer.length);
> +            buffer = b;
> +        }
> +    }
> +
> +    /**
> +     * Extracts buffered data into the provided byte[] array, starting at
> position bPos, up to a maximum of bAvail
> +     * bytes. Returns how many bytes were actually extracted.
> +     *
> +     * @param b
> +     *            byte[] array to extract the buffered data into.
> +     * @param bPos
> +     *            position in byte[] array to start extraction at.
> +     * @param bAvail
> +     *            amount of bytes we're allowed to extract. We may extract
> fewer (if fewer are available).
> +     * @return The number of bytes successfully extracted into the
> provided byte[] array.
> +     */
> +    int readResults(byte[] b, int bPos, int bAvail) {  // package
> protected for access from I/O streams
> +        if (buffer != null) {
> +            int len = Math.min(avail(), bAvail);
> +            System.arraycopy(buffer, readPos, b, bPos, len);
> +            readPos += len;
> +            if (readPos >= pos) {
> +                buffer = null;
> +            }
> +            return len;
> +        }
> +        return eof ? -1 : 0;
> +    }
> +
> +    /**
> +     * Checks if a byte value is whitespace or not.
> +     * Whitespace is taken to mean: space, tab, CR, LF
> +     * @param byteToCheck
> +     *            the byte to check
> +     * @return true if byte is whitespace, false otherwise
> +     */
> +    protected static boolean isWhiteSpace(byte byteToCheck) {
> +        switch (byteToCheck) {
> +            case ' ' :
> +            case '\n' :
> +            case '\r' :
> +            case '\t' :
> +                return true;
> +            default :
> +                return false;
> +        }
> +    }
> +
> +    /**
> +     * Resets this Base32 object to its initial newly constructed state.
> +     */
> +    private void reset() {
> +        buffer = null;
> +        pos = 0;
> +        readPos = 0;
> +        currentLinePos = 0;
> +        modulus = 0;
> +        eof = false;
> +    }
> +    /**
> +     * Encodes an Object using the Base32 algorithm. This method is
> provided in order to satisfy the requirements of the
> +     * Encoder interface, and will throw an EncoderException if the
> supplied object is not of type byte[].
> +     *
> +     * @param pObject
> +     *            Object to encode
> +     * @return An object (of type byte[]) containing the Base32 encoded
> data which corresponds to the byte[] supplied.
> +     * @throws EncoderException
> +     *             if the parameter supplied is not of type byte[]
> +     */
> +    public Object encode(Object pObject) throws EncoderException {
> +        if (!(pObject instanceof byte[])) {
> +            throw new EncoderException("Parameter supplied to Base32
> encode is not a byte[]");
> +        }
> +        return encode((byte[]) pObject);
> +    }
> +    /**
> +     * Encodes a byte[] containing binary data, into a String containing
> characters in the Base32 alphabet.
> +     *
> +     * @param pArray
> +     *            a byte array containing binary data
> +     * @return A String containing only Base32 character data
> +     */
> +    public String encodeToString(byte[] pArray) {
> +        return StringUtils.newStringUtf8(encode(pArray));
> +    }
> +    /**
> +     * Decodes an Object using the Base32 algorithm. This method is
> provided in order to satisfy the requirements of the
> +     * Decoder interface, and will throw a DecoderException if the
> supplied object is not of type byte[] or String.
> +     *
> +     * @param pObject
> +     *            Object to decode
> +     * @return An object (of type byte[]) containing the binary data which
> corresponds to the byte[] or String supplied.
> +     * @throws DecoderException
> +     *             if the parameter supplied is not of type byte[]
> +     */
> +    public Object decode(Object pObject) throws DecoderException {
> +        if (pObject instanceof byte[]) {
> +            return decode((byte[]) pObject);
> +        } else if (pObject instanceof String) {
> +            return decode((String) pObject);
> +        } else {
> +            throw new DecoderException("Parameter supplied to Base32
> decode is not a byte[] or a String");
> +        }
> +    }
> +    /**
> +     * Decodes a String containing characters in the Base32 alphabet.
> +     *
> +     * @param pArray
> +     *            A String containing Base32 character data
> +     * @return a byte array containing binary data
> +     */
> +    public byte[] decode(String pArray) {
> +        return decode(StringUtils.getBytesUtf8(pArray));
> +    }
> +    /**
> +     * Decodes a byte[] containing characters in the Base32 alphabet.
> +     *
> +     * @param pArray
> +     *            A byte array containing Base32 character data
> +     * @return a byte array containing binary data
> +     */
> +    public byte[] decode(byte[] pArray) {
> +        reset();
> +        if (pArray == null || pArray.length == 0) {
> +            return pArray;
> +        }
> +        decode(pArray, 0, pArray.length);
> +        decode(pArray, 0, -1); // Notify decoder of EOF.
> +        byte[] result = new byte[pos];
> +        readResults(result, 0, result.length);
> +        return result;
> +    }
> +    /**
> +     * Encodes a byte[] containing binary data, into a byte[] containing
> characters in the Base32 alphabet.
> +     *
> +     * @param pArray
> +     *            a byte array containing binary data
> +     * @return A byte array containing only Base32 character data
> +     */
> +    public byte[] encode(byte[] pArray) {
> +        reset();
> +        if (pArray == null || pArray.length == 0) {
> +            return pArray;
> +        }
> +        encode(pArray, 0, pArray.length);
> +        encode(pArray, 0, -1); // Notify encoder of EOF.
> +        byte[] buf = new byte[pos - readPos];
> +        readResults(buf, 0, buf.length);
> +        return buf;
> +    }
> +
> +    abstract void encode(byte[] pArray, int i, int length);  // package
> protected for access from I/O streams
> +
> +    abstract void decode(byte[] pArray, int i, int length); // package
> protected for access from I/O streams
> +}
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> dec.java
> ---------------------------------------------------------------------------
> ---
>     svn:eol-style = native
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> dec.java
> ---------------------------------------------------------------------------
> ---
>     svn:keywords = Author Date Id Revision
> 
> Added:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decInputStream.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache
> /commons/codec/binary/BasedCodecInputStream.java?rev=1063760&view=auto
> ===========================================================================
> ===
> ---
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decInputStream.java (added)
> +++
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decInputStream.java Wed Jan 26 15:25:42 2011
> @@ -0,0 +1,127 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + *
> + */
> +
> +package org.apache.commons.codec.binary;
> +
> +import java.io.FilterInputStream;
> +import java.io.IOException;
> +import java.io.InputStream;
> +
> +public class BasedCodecInputStream extends FilterInputStream {
> +
> +    private final boolean doEncode;
> +
> +    private final BasedCodec basedCodec;
> +
> +    private final byte[] singleByte = new byte[1];
> +
> +    protected BasedCodecInputStream(InputStream in, BasedCodec basedCodec,
> boolean doEncode) {
> +        super(in);
> +        this.doEncode = doEncode;
> +        this.basedCodec = basedCodec;
> +    }
> +
> +    /**
> +     * Reads one <code>byte</code> from this input stream.
> +     *
> +     * @return the byte as an integer in the range 0 to 255. Returns -1 if
> EOF has been reached.
> +     * @throws IOException
> +     *             if an I/O error occurs.
> +     */
> +    public int read() throws IOException {
> +        int r = read(singleByte, 0, 1);
> +        while (r == 0) {
> +            r = read(singleByte, 0, 1);
> +        }
> +        if (r > 0) {
> +            return singleByte[0] < 0 ? 256 + singleByte[0] :
> singleByte[0];
> +        }
> +        return -1;
> +    }
> +
> +    /**
> +     * Attempts to read <code>len</code> bytes into the specified
> <code>b</code> array starting at <code>offset</code>
> +     * from this InputStream.
> +     *
> +     * @param b
> +     *            destination byte array
> +     * @param offset
> +     *            where to start writing the bytes
> +     * @param len
> +     *            maximum number of bytes to read
> +     *
> +     * @return number of bytes read
> +     * @throws IOException
> +     *             if an I/O error occurs.
> +     * @throws NullPointerException
> +     *             if the byte array parameter is null
> +     * @throws IndexOutOfBoundsException
> +     *             if offset, len or buffer size are invalid
> +     */
> +    public int read(byte b[], int offset, int len) throws IOException {
> +        if (b == null) {
> +            throw new NullPointerException();
> +        } else if (offset < 0 || len < 0) {
> +            throw new IndexOutOfBoundsException();
> +        } else if (offset > b.length || offset + len > b.length) {
> +            throw new IndexOutOfBoundsException();
> +        } else if (len == 0) {
> +            return 0;
> +        } else {
> +            int readLen = 0;
> +            /*
> +             Rationale for while-loop on (readLen == 0):
> +             -----
> +             Base32.readResults() usually returns > 0 or EOF (-1).  In the
> +             rare case where it returns 0, we just keep trying.
> +
> +             This is essentially an undocumented contract for InputStream
> +             implementors that want their code to work properly with
> +             java.io.InputStreamReader, since the latter hates it when
> +             InputStream.read(byte[]) returns a zero.  Unfortunately our
> +             readResults() call must return 0 if a large amount of the
> data
> +             being decoded was non-base32, so this while-loop enables
> proper
> +             interop with InputStreamReader for that scenario.
> +             -----
> +             This is a fix for CODEC-101
> +            */
> +            while (readLen == 0) {
> +                if (!basedCodec.hasData()) {
> +                    byte[] buf = new byte[doEncode ? 4096 : 8192];
> +                    int c = in.read(buf);
> +                    if (doEncode) {
> +                        basedCodec.encode(buf, 0, c);
> +                    } else {
> +                        basedCodec.decode(buf, 0, c);
> +                    }
> +                }
> +                readLen = basedCodec.readResults(b, offset, len);
> +            }
> +            return readLen;
> +        }
> +    }
> +    /**
> +     * {@inheritDoc}
> +     *
> +     * @return false
> +     */
> +    public boolean markSupported() {
> +        return false; // not an easy job to support marks
> +    }
> +
> +}
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decInputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:eol-style = native
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decInputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:keywords = Author Date Id Revision
> 
> Added:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decOutputStream.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/java/org/apache
> /commons/codec/binary/BasedCodecOutputStream.java?rev=1063760&view=auto
> ===========================================================================
> ===
> ---
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decOutputStream.java (added)
> +++
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decOutputStream.java Wed Jan 26 15:25:42 2011
> @@ -0,0 +1,137 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + *
> + */
> +
> +package org.apache.commons.codec.binary;
> +
> +import java.io.FilterOutputStream;
> +import java.io.IOException;
> +import java.io.OutputStream;
> +
> +public class BasedCodecOutputStream extends FilterOutputStream {
> +
> +    private final boolean doEncode;
> +
> +    private final BasedCodec basedCodec;
> +
> +    private final byte[] singleByte = new byte[1];
> +
> +    public BasedCodecOutputStream(OutputStream out, BasedCodec basedCodec,
> boolean doEncode) {
> +        super(out);
> +        this.basedCodec = basedCodec;
> +        this.doEncode = doEncode;
> +    }
> +
> +    /**
> +     * Writes the specified <code>byte</code> to this output stream.
> +     *
> +     * @param i
> +     *            source byte
> +     * @throws IOException
> +     *             if an I/O error occurs.
> +     */
> +    public void write(int i) throws IOException {
> +        singleByte[0] = (byte) i;
> +        write(singleByte, 0, 1);
> +    }
> +
> +    /**
> +     * Writes <code>len</code> bytes from the specified <code>b</code>
> array starting at <code>offset</code> to this
> +     * output stream.
> +     *
> +     * @param b
> +     *            source byte array
> +     * @param offset
> +     *            where to start reading the bytes
> +     * @param len
> +     *            maximum number of bytes to write
> +     *
> +     * @throws IOException
> +     *             if an I/O error occurs.
> +     * @throws NullPointerException
> +     *             if the byte array parameter is null
> +     * @throws IndexOutOfBoundsException
> +     *             if offset, len or buffer size are invalid
> +     */
> +    public void write(byte b[], int offset, int len) throws IOException {
> +        if (b == null) {
> +            throw new NullPointerException();
> +        } else if (offset < 0 || len < 0) {
> +            throw new IndexOutOfBoundsException();
> +        } else if (offset > b.length || offset + len > b.length) {
> +            throw new IndexOutOfBoundsException();
> +        } else if (len > 0) {
> +            if (doEncode) {
> +                basedCodec.encode(b, offset, len);
> +            } else {
> +                basedCodec.decode(b, offset, len);
> +            }
> +            flush(false);
> +        }
> +    }
> +
> +    /**
> +     * Flushes this output stream and forces any buffered output bytes to
> be written out to the stream. If propogate is
> +     * true, the wrapped stream will also be flushed.
> +     *
> +     * @param propogate
> +     *            boolean flag to indicate whether the wrapped
> OutputStream should also be flushed.
> +     * @throws IOException
> +     *             if an I/O error occurs.
> +     */
> +    private void flush(boolean propogate) throws IOException {
> +        int avail = basedCodec.avail();
> +        if (avail > 0) {
> +            byte[] buf = new byte[avail];
> +            int c = basedCodec.readResults(buf, 0, avail);
> +            if (c > 0) {
> +                out.write(buf, 0, c);
> +            }
> +        }
> +        if (propogate) {
> +            out.flush();
> +        }
> +    }
> +
> +    /**
> +     * Flushes this output stream and forces any buffered output bytes to
> be written out to the stream.
> +     *
> +     * @throws IOException
> +     *             if an I/O error occurs.
> +     */
> +    public void flush() throws IOException {
> +        flush(true);
> +    }
> +
> +    /**
> +     * Closes this output stream and releases any system resources
> associated with the stream.
> +     *
> +     * @throws IOException
> +     *             if an I/O error occurs.
> +     */
> +    public void close() throws IOException {
> +        // Notify encoder of EOF (-1).
> +        if (doEncode) {
> +            basedCodec.encode(singleByte, 0, -1);
> +        } else {
> +            basedCodec.decode(singleByte, 0, -1);
> +        }
> +        flush();
> +        out.close();
> +    }
> +
> +}
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decOutputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:eol-style = native
> 
> Propchange:
> commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/BasedCo
> decOutputStream.java
> ---------------------------------------------------------------------------
> ---
>     svn:keywords = Author Date Id Revision
>