[dna-commits] DNA SVN: r765 - trunk/dna-common/src/main/java/org/jboss/dna/common/util.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Tue Mar 10 12:18:31 EDT 2009


Author: rhauch
Date: 2009-03-10 12:18:31 -0400 (Tue, 10 Mar 2009)
New Revision: 765

Modified:
   trunk/dna-common/src/main/java/org/jboss/dna/common/util/Base64.java
Log:
Cleaned up the Base64 code to eliminate many warnings, fix some coding errors, and improve error handling.

Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/util/Base64.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/util/Base64.java	2009-03-10 15:17:23 UTC (rev 764)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/util/Base64.java	2009-03-10 16:18:31 UTC (rev 765)
@@ -23,7 +23,17 @@
  */
 package org.jboss.dna.common.util;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.zip.GZIPInputStream;
+import org.jboss.dna.common.SystemFailureException;
 
 /**
  * <p>
@@ -318,7 +328,7 @@
         else if ((options & ORDERED) == ORDERED) return _ORDERED_ALPHABET;
         else return _STANDARD_ALPHABET;
 
-    } // end getAlphabet
+    }
 
     /**
      * Returns one of the _SOMETHING_DECODABET byte arrays depending on the options specified. It's possible, though silly, to
@@ -328,12 +338,12 @@
      * @param options The options to use in this operation
      * @return the appropriate decodabets
      */
-    private final static byte[] getDecodabet( int options ) {
+    protected final static byte[] getDecodabet( int options ) {
         if ((options & URL_SAFE) == URL_SAFE) return _URL_SAFE_DECODABET;
         else if ((options & ORDERED) == ORDERED) return _ORDERED_DECODABET;
         else return _STANDARD_DECODABET;
 
-    } // end getAlphabet
+    }
 
     /** Defeats instantiation. */
     private Base64() {
@@ -351,15 +361,14 @@
      * @param numSigBytes the number of significant bytes in your array
      * @param options The options to use in this operation
      * @return four byte array in Base64 notation.
-     * @since 1.5.1
      */
-    private static byte[] encode3to4( byte[] b4,
-                                      byte[] threeBytes,
-                                      int numSigBytes,
-                                      int options ) {
+    protected static byte[] encode3to4( byte[] b4,
+                                        byte[] threeBytes,
+                                        int numSigBytes,
+                                        int options ) {
         encode3to4(threeBytes, 0, numSigBytes, b4, 0, options);
         return b4;
-    } // end encode3to4
+    }
 
     /**
      * <p>
@@ -380,14 +389,13 @@
      * @param destOffset the index where output will be put
      * @param options The options to use in this operation
      * @return the <var>destination</var> array
-     * @since 1.3
      */
-    private static byte[] encode3to4( byte[] source,
-                                      int srcOffset,
-                                      int numSigBytes,
-                                      byte[] destination,
-                                      int destOffset,
-                                      int options ) {
+    protected static byte[] encode3to4( byte[] source,
+                                        int srcOffset,
+                                        int numSigBytes,
+                                        byte[] destination,
+                                        int destOffset,
+                                        int options ) {
         byte[] ALPHABET = getAlphabet(options);
 
         // 1 2 3
@@ -429,8 +437,8 @@
 
             default:
                 return destination;
-        } // end switch
-    } // end encode3to4
+        }
+    }
 
     /**
      * Serializes an object and returns the Base64-encoded version of that serialized object. If the object cannot be serialized
@@ -438,11 +446,11 @@
      * 
      * @param serializableObject The object to encode
      * @return The Base64-encoded object
-     * @since 1.4
+     * @throws IOException if there is an IOException while serializing
      */
-    public static String encodeObject( java.io.Serializable serializableObject ) {
+    public static String encodeObject( java.io.Serializable serializableObject ) throws IOException {
         return encodeObject(serializableObject, NO_OPTIONS);
-    } // end encodeObject
+    }
 
     /**
      * Serializes an object and returns the Base64-encoded version of that serialized object. If the object cannot be serialized
@@ -465,77 +473,60 @@
      * @return The Base64-encoded object
      * @see Base64#GZIP
      * @see Base64#DONT_BREAK_LINES
-     * @since 2.0
+     * @throws IOException if there is an IOException while serializing
      */
     public static String encodeObject( java.io.Serializable serializableObject,
-                                       int options ) {
-        // Streams
-        java.io.ByteArrayOutputStream baos = null;
-        java.io.OutputStream b64os = null;
+                                       int options ) throws IOException {
+        // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
+        java.io.ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        java.io.OutputStream b64os = new Base64.OutputStream(baos, ENCODE | options);
         java.io.ObjectOutputStream oos = null;
         java.util.zip.GZIPOutputStream gzos = null;
 
         // Isolate options
         int gzip = (options & GZIP);
-        int dontBreakLines = (options & DONT_BREAK_LINES);
-
+        boolean error = false;
         try {
-            // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
-            baos = new java.io.ByteArrayOutputStream();
-            b64os = new Base64.OutputStream(baos, ENCODE | options);
-
             // GZip?
             if (gzip == GZIP) {
                 gzos = new java.util.zip.GZIPOutputStream(b64os);
                 oos = new java.io.ObjectOutputStream(gzos);
-            } // end if: gzip
-            else oos = new java.io.ObjectOutputStream(b64os);
+            } else {
+                oos = new java.io.ObjectOutputStream(b64os);
+            }
 
             oos.writeObject(serializableObject);
-        } // end try
-        catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        } // end catch
-        finally {
-            try {
-                oos.close();
-            } catch (Exception e) {
+        } catch (IOException e) {
+            error = true;
+            throw e;
+        } finally {
+            if (oos != null) {
+                try {
+                    oos.close();
+                } catch (IOException e) {
+                    if (!error) throw e;
+                }
             }
-            try {
-                gzos.close();
-            } catch (Exception e) {
-            }
-            try {
-                b64os.close();
-            } catch (Exception e) {
-            }
-            try {
-                baos.close();
-            } catch (Exception e) {
-            }
-        } // end finally
+        }
 
         // Return value according to relevant encoding.
         try {
             return new String(baos.toByteArray(), PREFERRED_ENCODING);
-        } // end try
-        catch (java.io.UnsupportedEncodingException uue) {
+        } catch (java.io.UnsupportedEncodingException uue) {
             return new String(baos.toByteArray());
-        } // end catch
+        }
 
-    } // end encode
+    }
 
     /**
      * Encodes a byte array into Base64 notation. Does not GZip-compress data.
      * 
      * @param source The data to convert
      * @return the encoded bytes
-     * @since 1.4
      */
     public static String encodeBytes( byte[] source ) {
         return encodeBytes(source, 0, source.length, NO_OPTIONS);
-    } // end encodeBytes
+    }
 
     /**
      * Encodes a byte array into Base64 notation.
@@ -557,12 +548,11 @@
      * @return the encoded bytes
      * @see Base64#GZIP
      * @see Base64#DONT_BREAK_LINES
-     * @since 2.0
      */
     public static String encodeBytes( byte[] source,
                                       int options ) {
         return encodeBytes(source, 0, source.length, options);
-    } // end encodeBytes
+    }
 
     /**
      * Encodes a byte array into Base64 notation. Does not GZip-compress data.
@@ -571,13 +561,12 @@
      * @param off Offset in array where conversion should begin
      * @param len Length of data
      * @return the encoded bytes
-     * @since 1.4
      */
     public static String encodeBytes( byte[] source,
                                       int off,
                                       int len ) {
         return encodeBytes(source, off, len, NO_OPTIONS);
-    } // end encodeBytes
+    }
 
     /**
      * Encodes a byte array into Base64 notation.
@@ -601,7 +590,6 @@
      * @return the encoded bytes
      * @see Base64#GZIP
      * @see Base64#DONT_BREAK_LINES
-     * @since 2.0
      */
     public static String encodeBytes( byte[] source,
                                       int off,
@@ -613,88 +601,76 @@
 
         // Compress?
         if (gzip == GZIP) {
-            java.io.ByteArrayOutputStream baos = null;
+            // GZip -> Base64 -> ByteArray
+            java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
+            Base64.OutputStream b64os = new Base64.OutputStream(baos, ENCODE | options);
             java.util.zip.GZIPOutputStream gzos = null;
-            Base64.OutputStream b64os = null;
 
+            boolean error = false;
             try {
-                // GZip -> Base64 -> ByteArray
-                baos = new java.io.ByteArrayOutputStream();
-                b64os = new Base64.OutputStream(baos, ENCODE | options);
                 gzos = new java.util.zip.GZIPOutputStream(b64os);
 
                 gzos.write(source, off, len);
                 gzos.close();
-            } // end try
-            catch (IOException e) {
-                e.printStackTrace();
-                return null;
-            } // end catch
-            finally {
-                try {
-                    gzos.close();
-                } catch (Exception e) {
+            } catch (IOException e) {
+                error = true;
+                throw new SystemFailureException(e); // error using reading from byte array!
+            } finally {
+                if (gzos != null) {
+                    try {
+                        gzos.close();
+                    } catch (IOException e) {
+                        if (!error) new SystemFailureException(e); // error closing streams over byte array!
+                    }
                 }
-                try {
-                    b64os.close();
-                } catch (Exception e) {
-                }
-                try {
-                    baos.close();
-                } catch (Exception e) {
-                }
-            } // end finally
+            }
 
             // Return value according to relevant encoding.
             try {
                 return new String(baos.toByteArray(), PREFERRED_ENCODING);
-            } // end try
-            catch (java.io.UnsupportedEncodingException uue) {
+            } catch (java.io.UnsupportedEncodingException uue) {
                 return new String(baos.toByteArray());
-            } // end catch
-        } // end if: compress
+            }
+        }
 
-        // Else, don't compress. Better not to use streams at all then.
-        else {
-            // Convert option to boolean in way that code likes it.
-            boolean breakLines = dontBreakLines == 0;
+        // Otherwise, don't compress. Better not to use streams at all then.
+        // Convert option to boolean in way that code likes it.
+        boolean breakLines = dontBreakLines == 0;
 
-            int len43 = len * 4 / 3;
-            byte[] outBuff = new byte[(len43) // Main 4:3
-                                      + ((len % 3) > 0 ? 4 : 0) // Account for padding
-                                      + (breakLines ? (len43 / MAX_LINE_LENGTH) : 0)]; // New lines
-            int d = 0;
-            int e = 0;
-            int len2 = len - 2;
-            int lineLength = 0;
-            for (; d < len2; d += 3, e += 4) {
-                encode3to4(source, d + off, 3, outBuff, e, options);
+        int len43 = len * 4 / 3;
+        byte[] outBuff = new byte[(len43) // Main 4:3
+                                  + ((len % 3) > 0 ? 4 : 0) // Account for padding
+                                  + (breakLines ? (len43 / MAX_LINE_LENGTH) : 0)]; // New lines
+        int d = 0;
+        int e = 0;
+        int len2 = len - 2;
+        int lineLength = 0;
+        for (; d < len2; d += 3, e += 4) {
+            encode3to4(source, d + off, 3, outBuff, e, options);
 
-                lineLength += 4;
-                if (breakLines && lineLength == MAX_LINE_LENGTH) {
-                    outBuff[e + 4] = NEW_LINE;
-                    e++;
-                    lineLength = 0;
-                } // end if: end of line
-            } // en dfor: each piece of array
+            lineLength += 4;
+            if (breakLines && lineLength == MAX_LINE_LENGTH) {
+                outBuff[e + 4] = NEW_LINE;
+                e++;
+                lineLength = 0;
+            }
+        }
 
-            if (d < len) {
-                encode3to4(source, d + off, len - d, outBuff, e, options);
-                e += 4;
-            } // end if: some padding needed
+        if (d < len) {
+            // Padding is needed
+            encode3to4(source, d + off, len - d, outBuff, e, options);
+            e += 4;
+        }
 
-            // Return value according to relevant encoding.
-            try {
-                return new String(outBuff, 0, e, PREFERRED_ENCODING);
-            } // end try
-            catch (java.io.UnsupportedEncodingException uue) {
-                return new String(outBuff, 0, e);
-            } // end catch
+        // Return value according to relevant encoding.
+        try {
+            return new String(outBuff, 0, e, PREFERRED_ENCODING);
+        } catch (java.io.UnsupportedEncodingException uue) {
+            return new String(outBuff, 0, e);
+        }
 
-        } // end else: don't compress
+    }
 
-    } // end encodeBytes
-
     /* ********  D E C O D I N G   M E T H O D S  ******** */
 
     /**
@@ -713,13 +689,12 @@
      * @param destOffset the index where output will be put
      * @param options alphabet type is pulled from this (standard, url-safe, ordered)
      * @return the number of decoded bytes converted
-     * @since 1.3
      */
-    private static int decode4to3( byte[] source,
-                                   int srcOffset,
-                                   byte[] destination,
-                                   int destOffset,
-                                   int options ) {
+    protected static int decode4to3( byte[] source,
+                                     int srcOffset,
+                                     byte[] destination,
+                                     int destOffset,
+                                     int options ) {
         byte[] DECODABET = getDecodabet(options);
 
         // Example: Dk==
@@ -764,14 +739,15 @@
 
                 return 3;
             } catch (Exception e) {
-                System.out.println("" + source[srcOffset] + ": " + (DECODABET[source[srcOffset]]));
-                System.out.println("" + source[srcOffset + 1] + ": " + (DECODABET[source[srcOffset + 1]]));
-                System.out.println("" + source[srcOffset + 2] + ": " + (DECODABET[source[srcOffset + 2]]));
-                System.out.println("" + source[srcOffset + 3] + ": " + (DECODABET[source[srcOffset + 3]]));
-                return -1;
-            } // end catch
+                StringBuilder sb = new StringBuilder();
+                sb.append("" + source[srcOffset] + ": " + (DECODABET[source[srcOffset]]) + "\n");
+                sb.append("" + source[srcOffset + 1] + ": " + (DECODABET[source[srcOffset + 1]]) + "\n");
+                sb.append("" + source[srcOffset + 2] + ": " + (DECODABET[source[srcOffset + 2]]) + "\n");
+                sb.append("" + source[srcOffset + 3] + ": " + (DECODABET[source[srcOffset + 3]]) + "\n");
+                throw new SystemFailureException(sb.toString(), e);
+            }
         }
-    } // end decodeToBytes
+    }
 
     /**
      * Very low-level access to decoding ASCII characters in the form of a byte array. Does not support automatically gunzipping
@@ -782,7 +758,6 @@
      * @param len The length of characters to decode
      * @param options The options to use in this operation
      * @return decoded data
-     * @since 1.3
      */
     public static byte[] decode( byte[] source,
                                  int off,
@@ -803,38 +778,37 @@
             sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits
             sbiDecode = DECODABET[sbiCrop];
 
-            if (sbiDecode >= WHITE_SPACE_ENC) // White space, Equals sign or better
-            {
+            if (sbiDecode >= WHITE_SPACE_ENC) {
+                // White space, Equals sign or better
                 if (sbiDecode >= EQUALS_SIGN_ENC) {
+                    // Equal sign or better
                     b4[b4Posn++] = sbiCrop;
                     if (b4Posn > 3) {
+                        // build a quartet
                         outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options);
                         b4Posn = 0;
 
                         // If that was the equals sign, break out of 'for' loop
                         if (sbiCrop == EQUALS_SIGN) break;
-                    } // end if: quartet built
+                    }
 
-                } // end if: equals sign or better
+                }
 
-            } // end if: white space, equals sign or better
-            else {
-                System.err.println("Bad Base64 input character at " + i + ": " + source[i] + "(decimal)");
-                return null;
-            } // end else:
-        } // each input character
+            } else {
+                throw new SystemFailureException("Bad Base64 input character at " + i + ": " + source[i] + "(decimal)");
+            }
+        }
 
         byte[] out = new byte[outBuffPosn];
         System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
         return out;
-    } // end decode
+    }
 
     /**
      * Decodes data from Base64 notation, automatically detecting gzip-compressed data and decompressing it.
      * 
      * @param s the string to decode
      * @return the decoded data
-     * @since 1.4
      */
     public static byte[] decode( String s ) {
         return decode(s, NO_OPTIONS);
@@ -846,18 +820,15 @@
      * @param s the string to decode
      * @param options encode options such as URL_SAFE
      * @return the decoded data
-     * @since 1.4
      */
     public static byte[] decode( String s,
                                  int options ) {
         byte[] bytes;
         try {
             bytes = s.getBytes(PREFERRED_ENCODING);
-        } // end try
-        catch (java.io.UnsupportedEncodingException uee) {
+        } catch (java.io.UnsupportedEncodingException uee) {
             bytes = s.getBytes();
-        } // end catch
-        // </change>
+        }
 
         // Decode
         bytes = decode(bytes, 0, bytes.length, options);
@@ -866,93 +837,86 @@
         // GZIP Magic Two-Byte Number: 0x8b1f (35615)
         if (bytes != null && bytes.length >= 4) {
 
-            int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
-            if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head) {
-                java.io.ByteArrayInputStream bais = null;
-                java.util.zip.GZIPInputStream gzis = null;
-                java.io.ByteArrayOutputStream baos = null;
+            int head = (bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
+            if (GZIPInputStream.GZIP_MAGIC == head) {
+                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                GZIPInputStream gzis = null;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 byte[] buffer = new byte[2048];
                 int length = 0;
 
                 try {
-                    baos = new java.io.ByteArrayOutputStream();
-                    bais = new java.io.ByteArrayInputStream(bytes);
                     gzis = new java.util.zip.GZIPInputStream(bais);
-
                     while ((length = gzis.read(buffer)) >= 0) {
                         baos.write(buffer, 0, length);
-                    } // end while: reading input
+                    }
 
                     // No error? Get new bytes.
                     bytes = baos.toByteArray();
 
-                } // end try
-                catch (IOException e) {
+                } catch (IOException e) {
                     // Just return originally-decoded bytes
                 } // end catch
                 finally {
+                    boolean error = false;
                     try {
-                        baos.close();
-                    } catch (Exception e) {
+                        if (gzis != null) {
+                            try {
+                                gzis.close();
+                            } catch (IOException e) {
+                                throw new SystemFailureException(e); // bad problems with JRE if this doesn't work
+                            }
+                        }
+                    } finally {
+                        try {
+                            bais.close();
+                        } catch (Exception e) {
+                            if (!error) throw new SystemFailureException(e); // bad problems with JRE if this doesn't work
+                        }
                     }
-                    try {
-                        gzis.close();
-                    } catch (Exception e) {
-                    }
-                    try {
-                        bais.close();
-                    } catch (Exception e) {
-                    }
-                } // end finally
+                }
 
-            } // end if: gzipped
-        } // end if: bytes.length >= 2
+            }
+        }
 
         return bytes;
-    } // end decode
+    }
 
     /**
      * Attempts to decode Base64 data and deserialize a Java Object within. Returns <tt>null</tt> if there was an error.
      * 
      * @param encodedObject The Base64 data to decode
      * @return The decoded and deserialized object
-     * @since 1.5
+     * @throws IOException if there is an error deserializing the encoded object
+     * @throws ClassNotFoundException if the class for the deserialized object could not be found
      */
-    public static Object decodeToObject( String encodedObject ) {
+    public static Object decodeToObject( String encodedObject ) throws IOException, ClassNotFoundException {
         // Decode and gunzip if necessary
         byte[] objBytes = decode(encodedObject);
 
-        java.io.ByteArrayInputStream bais = null;
-        java.io.ObjectInputStream ois = null;
+        ByteArrayInputStream bais = new ByteArrayInputStream(objBytes);
+        ObjectInputStream ois = new ObjectInputStream(bais);
         Object obj = null;
 
+        boolean error = false;
         try {
-            bais = new java.io.ByteArrayInputStream(objBytes);
-            ois = new java.io.ObjectInputStream(bais);
-
             obj = ois.readObject();
-        } // end try
-        catch (IOException e) {
-            e.printStackTrace();
-            obj = null;
-        } // end catch
-        catch (java.lang.ClassNotFoundException e) {
-            e.printStackTrace();
-            obj = null;
-        } // end catch
-        finally {
+        } catch (IOException e) {
+            error = true;
+            throw e;
+        } catch (java.lang.ClassNotFoundException e) {
+            error = true;
+            throw e;
+        } finally {
             try {
-                bais.close();
-            } catch (Exception e) {
-            }
-            try {
                 ois.close();
-            } catch (Exception e) {
+            } catch (IOException e) {
+                if (!error) throw e;
             }
-        } // end finally
+        }
 
         return obj;
-    } // end decodeObject
+    }
 
     /**
      * Convenience method for encoding data to a file.
@@ -960,227 +924,212 @@
      * @param dataToEncode byte array of data to encode in base64 form
      * @param filename Filename for saving encoded data
      * @return <tt>true</tt> if successful, <tt>false</tt> otherwise
-     * @since 2.1
+     * @throws IOException if there is a problem writing to the file
      */
     public static boolean encodeToFile( byte[] dataToEncode,
-                                        String filename ) {
-        boolean success = false;
-        Base64.OutputStream bos = null;
+                                        String filename ) throws IOException {
+        boolean error = false;
+        Base64.OutputStream bos = new Base64.OutputStream(new java.io.FileOutputStream(filename), Base64.ENCODE);
+
         try {
-            bos = new Base64.OutputStream(new java.io.FileOutputStream(filename), Base64.ENCODE);
             bos.write(dataToEncode);
-            success = true;
-        } // end try
-        catch (IOException e) {
-
-            success = false;
-        } // end catch: IOException
-        finally {
+            return true;
+        } catch (IOException e) {
+            error = true;
+            throw e;
+        } finally {
             try {
                 bos.close();
-            } catch (Exception e) {
+            } catch (IOException e) {
+                if (!error) throw e;
             }
-        } // end finally
+        }
+    }
 
-        return success;
-    } // end encodeToFile
-
     /**
      * Convenience method for decoding data to a file.
      * 
      * @param dataToDecode Base64-encoded data as a string
      * @param filename Filename for saving decoded data
      * @return <tt>true</tt> if successful, <tt>false</tt> otherwise
-     * @since 2.1
+     * @throws IOException if there is a problem writing to the file
      */
     public static boolean decodeToFile( String dataToDecode,
-                                        String filename ) {
-        boolean success = false;
-        Base64.OutputStream bos = null;
+                                        String filename ) throws IOException {
+        boolean error = false;
+        Base64.OutputStream bos = new Base64.OutputStream(new FileOutputStream(filename), Base64.DECODE);
         try {
-            bos = new Base64.OutputStream(new java.io.FileOutputStream(filename), Base64.DECODE);
             bos.write(dataToDecode.getBytes(PREFERRED_ENCODING));
-            success = true;
-        } // end try
-        catch (IOException e) {
-            success = false;
-        } // end catch: IOException
-        finally {
+            return true;
+        } catch (IOException e) {
+            error = true;
+            throw e;
+        } finally {
             try {
                 bos.close();
-            } catch (Exception e) {
+            } catch (IOException e) {
+                if (!error) throw e;
             }
-        } // end finally
+        }
+    }
 
-        return success;
-    } // end decodeToFile
-
     /**
      * Convenience method for reading a base64-encoded file and decoding it.
      * 
      * @param filename Filename for reading encoded data
      * @return decoded byte array or null if unsuccessful
-     * @since 2.1
+     * @throws IOException if there is a problem reading from the file
      */
-    public static byte[] decodeFromFile( String filename ) {
-        byte[] decodedData = null;
-        Base64.InputStream bis = null;
-        try {
-            // Set up some useful variables
-            java.io.File file = new java.io.File(filename);
-            byte[] buffer = null;
-            int length = 0;
-            int numBytes = 0;
+    public static byte[] decodeFromFile( String filename ) throws IOException {
+        // Set up some useful variables
+        byte[] buffer = null;
+        int length = 0;
+        int numBytes = 0;
 
-            // Check for size of file
-            if (file.length() > Integer.MAX_VALUE) {
-                System.err.println("File is too big for this convenience method (" + file.length() + " bytes).");
-                return null;
-            } // end if: file too big for int index
+        File file = new File(filename);
+        Base64.InputStream bis = new Base64.InputStream(new BufferedInputStream(new FileInputStream(file)), Base64.DECODE);
+
+        boolean error = false;
+        try {
             buffer = new byte[(int)file.length()];
 
-            // Open a stream
-            bis = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(file)), Base64.DECODE);
-
             // Read until done
-            while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
+            while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {
                 length += numBytes;
+            }
 
             // Save in a variable to return
-            decodedData = new byte[length];
+            byte[] decodedData = new byte[length];
             System.arraycopy(buffer, 0, decodedData, 0, length);
-
-        } // end try
-        catch (IOException e) {
-            System.err.println("Error decoding from file " + filename);
-        } // end catch: IOException
-        finally {
+            return decodedData;
+        } catch (IOException e) {
+            error = true;
+            throw e;
+        } finally {
             try {
                 bis.close();
-            } catch (Exception e) {
+            } catch (IOException e) {
+                if (!error) throw e;
             }
-        } // end finally
+        }
+    }
 
-        return decodedData;
-    } // end decodeFromFile
-
     /**
      * Convenience method for reading a binary file and base64-encoding it.
      * 
      * @param filename Filename for reading binary data
      * @return base64-encoded string or null if unsuccessful
-     * @since 2.1
+     * @throws IOException if there is a problem reading from the file
      */
-    public static String encodeFromFile( String filename ) {
-        String encodedData = null;
-        Base64.InputStream bis = null;
-        try {
-            // Set up some useful variables
-            java.io.File file = new java.io.File(filename);
-            byte[] buffer = new byte[Math.max((int)(file.length() * 1.4), 40)]; // Need max() for math on small files (v2.2.1)
-            int length = 0;
-            int numBytes = 0;
+    public static String encodeFromFile( String filename ) throws IOException {
+        File file = new File(filename);
+        Base64.InputStream bis = new Base64.InputStream(new BufferedInputStream(new FileInputStream(file)), Base64.ENCODE);
 
-            // Open a stream
-            bis = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(file)), Base64.ENCODE);
+        // Set up some useful variables
+        byte[] buffer = new byte[Math.max((int)(file.length() * 1.4), 40)]; // Need max() for math on small files (v2.2.1)
+        int length = 0;
+        int numBytes = 0;
 
+        boolean error = false;
+        try {
             // Read until done
-            while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
+            while ((numBytes = bis.read(buffer, length, 4096)) >= 0) {
                 length += numBytes;
-
-            // Save in a variable to return
-            encodedData = new String(buffer, 0, length, Base64.PREFERRED_ENCODING);
-
-        } // end try
-        catch (IOException e) {
-            System.err.println("Error encoding from file " + filename);
-        } // end catch: IOException
-        finally {
+            }
+            return new String(buffer, 0, length, Base64.PREFERRED_ENCODING);
+        } catch (IOException e) {
+            error = true;
+            throw e;
+        } finally {
             try {
                 bis.close();
-            } catch (Exception e) {
+            } catch (IOException e) {
+                if (!error) throw e;
             }
-        } // end finally
+        }
+    }
 
-        return encodedData;
-    } // end encodeFromFile
-
     /**
      * Reads <tt>infile</tt> and encodes it to <tt>outfile</tt>.
      * 
      * @param infile Input file
      * @param outfile Output file
      * @return true if the operation is successful
-     * @since 2.2
+     * @throws IOException if there is a problem reading or writing either file
      */
     public static boolean encodeFileToFile( String infile,
-                                            String outfile ) {
-        boolean success = false;
-        java.io.InputStream in = null;
-        java.io.OutputStream out = null;
+                                            String outfile ) throws IOException {
+        InputStream in = new Base64.InputStream(new BufferedInputStream(new FileInputStream(infile)), Base64.ENCODE);
+        java.io.OutputStream out = new BufferedOutputStream(new FileOutputStream(outfile));
+
+        boolean error = false;
         try {
-            in = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(infile)), Base64.ENCODE);
-            out = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outfile));
             byte[] buffer = new byte[65536]; // 64K
             int read = -1;
             while ((read = in.read(buffer)) >= 0) {
                 out.write(buffer, 0, read);
-            } // end while: through file
-            success = true;
-        } catch (IOException exc) {
-            exc.printStackTrace();
+            }
+            return true;
+        } catch (IOException e) {
+            error = true;
+            throw e;
         } finally {
             try {
-                in.close();
-            } catch (Exception exc) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    if (!error) throw e;
+                }
+            } finally {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    if (!error) throw e;
+                }
             }
-            try {
-                out.close();
-            } catch (Exception exc) {
-            }
-        } // end finally
+        }
+    }
 
-        return success;
-    } // end encodeFileToFile
-
     /**
      * Reads <tt>infile</tt> and decodes it to <tt>outfile</tt>.
      * 
      * @param infile Input file
      * @param outfile Output file
      * @return true if the operation is successful
-     * @since 2.2
+     * @throws IOException if there is a problem reading or writing either file
      */
     public static boolean decodeFileToFile( String infile,
-                                            String outfile ) {
-        boolean success = false;
-        java.io.InputStream in = null;
-        java.io.OutputStream out = null;
+                                            String outfile ) throws IOException {
+        java.io.InputStream in = new Base64.InputStream(new BufferedInputStream(new FileInputStream(infile)), Base64.DECODE);
+        java.io.OutputStream out = new java.io.BufferedOutputStream(new FileOutputStream(outfile));
+        boolean error = false;
         try {
-            in = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(infile)), Base64.DECODE);
-            out = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outfile));
             byte[] buffer = new byte[65536]; // 64K
             int read = -1;
             while ((read = in.read(buffer)) >= 0) {
                 out.write(buffer, 0, read);
-            } // end while: through file
-            success = true;
-        } catch (IOException exc) {
-            exc.printStackTrace();
+            }
+            return true;
+        } catch (IOException e) {
+            error = true;
+            throw e;
         } finally {
             try {
-                in.close();
-            } catch (Exception exc) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    if (!error) throw e;
+                }
+            } finally {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    if (!error) throw e;
+                }
             }
-            try {
-                out.close();
-            } catch (Exception exc) {
-            }
-        } // end finally
+        }
+    }
 
-        return success;
-    } // end decodeFileToFile
-
     /* ********  I N N E R   C L A S S   I N P U T S T R E A M  ******** */
 
     /**
@@ -1188,7 +1137,6 @@
      * encode/decode to/from Base64 notation on the fly.
      * 
      * @see Base64
-     * @since 1.3
      */
     public static class InputStream extends java.io.FilterInputStream {
         private boolean encode; // Encoding or decoding
@@ -1199,7 +1147,6 @@
         private int lineLength;
         private boolean breakLines; // Break lines at less than 80 characters
         private int options; // Record options used to create the stream.
-        private byte[] alphabet; // Local copies to avoid extra method calls
         private byte[] decodabet; // Local copies to avoid extra method calls
 
         /**
@@ -1210,7 +1157,7 @@
          */
         public InputStream( java.io.InputStream in ) {
             this(in, DECODE);
-        } // end constructor
+        }
 
         /**
          * Constructs a {@link Base64.InputStream} in either ENCODE or DECODE mode.
@@ -1231,7 +1178,6 @@
          * @see Base64#ENCODE
          * @see Base64#DECODE
          * @see Base64#DONT_BREAK_LINES
-         * @since 2.0
          */
         public InputStream( java.io.InputStream in,
                             int options ) {
@@ -1243,9 +1189,8 @@
             this.position = -1;
             this.lineLength = 0;
             this.options = options; // Record for later, mostly to determine which alphabet to use
-            this.alphabet = getAlphabet(options);
             this.decodabet = getDecodabet(options);
-        } // end constructor
+        }
 
         /**
          * Reads enough of the input stream to convert to/from Base64 and returns the next byte.
@@ -1269,25 +1214,21 @@
                             if (b >= 0) {
                                 b3[i] = (byte)b;
                                 numBinaryBytes++;
-                            } // end if: not end of stream
-
-                        } // end try: read
-                        catch (IOException e) {
+                            }
+                        } catch (IOException e) {
                             // Only a problem if we got no data at all.
                             if (i == 0) throw e;
-
-                        } // end catch
-                    } // end for: each needed input byte
-
+                        }
+                    }
                     if (numBinaryBytes > 0) {
+                        // got data
                         encode3to4(b3, 0, numBinaryBytes, buffer, 0, options);
                         position = 0;
                         numSigBytes = 4;
-                    } // end if: got data
-                    else {
+                    } else {
                         return -1;
-                    } // end else
-                } // end if: encoding
+                    }
+                }
 
                 // Else decoding
                 else {
@@ -1303,23 +1244,22 @@
                         if (b < 0) break; // Reads a -1 if end of stream
 
                         b4[i] = (byte)b;
-                    } // end for: each needed input byte
+                    }
 
                     if (i == 4) {
+                        // got four characters
                         numSigBytes = decode4to3(b4, 0, buffer, 0, options);
                         position = 0;
-                    } // end if: got four characters
-                    else if (i == 0) {
+                    } else if (i == 0) {
+                        // padded correctly
                         return -1;
-                    } // end else if: also padded correctly
-                    else {
+                    } else {
                         // Must have broken out from above.
                         throw new IOException("Improperly padded Base64 input.");
-                    } // end
+                    }
+                }
+            }
 
-                } // end else: decode
-            } // end else: get data
-
             // Got data?
             if (position >= 0) {
                 // End of relevant data?
@@ -1328,27 +1268,21 @@
                 if (encode && breakLines && lineLength >= MAX_LINE_LENGTH) {
                     lineLength = 0;
                     return '\n';
-                } // end if
-                else {
-                    lineLength++; // This isn't important when decoding
-                    // but throwing an extra "if" seems
-                    // just as wasteful.
+                }
+                lineLength++; // This isn't important when decoding
+                // but throwing an extra "if" seems
+                // just as wasteful.
 
-                    int b = buffer[position++];
+                int b = buffer[position++];
 
-                    if (position >= bufferLength) position = -1;
+                if (position >= bufferLength) position = -1;
 
-                    return b & 0xFF; // This is how you "cast" a byte that's
-                    // intended to be unsigned.
-                } // end else
-            } // end if: position >= 0
+                return b & 0xFF; // This is how you "cast" a byte that's intended to be unsigned.
+            }
 
-            // Else error
-            else {
-                // When JDK1.4 is more accepted, use an assertion here.
-                throw new IOException("Error in Base64 code reading stream.");
-            } // end else
-        } // end read
+            // When JDK1.4 is more accepted, use an assertion here.
+            throw new IOException("Error in Base64 code reading stream.");
+        }
 
         /**
          * Calls {@link #read()} repeatedly until the end of stream is reached or <var>len</var> bytes are read. Returns number of
@@ -1375,12 +1309,12 @@
 
                 if (b >= 0) dest[off + i] = (byte)b;
                 else if (i == 0) return -1;
-                else break; // Out of 'for' loop
-            } // end for: each byte read
+                else break;
+            }
             return i;
-        } // end read
+        }
 
-    } // end inner class InputStream
+    }
 
     /* ********  I N N E R   C L A S S   O U T P U T S T R E A M  ******** */
 
@@ -1401,7 +1335,6 @@
         private byte[] b4; // Scratch used in a few places
         private boolean suspendEncoding;
         private int options; // Record for later
-        private byte[] alphabet; // Local copies to avoid extra method calls
         private byte[] decodabet; // Local copies to avoid extra method calls
 
         /**
@@ -1447,7 +1380,6 @@
             this.suspendEncoding = false;
             this.b4 = new byte[4];
             this.options = options;
-            this.alphabet = getAlphabet(options);
             this.decodabet = getDecodabet(options);
         } // end constructor
 
@@ -1465,7 +1397,7 @@
             if (suspendEncoding) {
                 super.out.write(theByte);
                 return;
-            } // end if: supsended
+            }
 
             // Encode?
             if (encode) {
@@ -1481,27 +1413,25 @@
                     } // end if: end of line
 
                     position = 0;
-                } // end if: enough to output
-            } // end if: encoding
+                }
+            }
 
             // Else, Decoding
             else {
                 // Meaningful Base64 character?
                 if (decodabet[theByte & 0x7f] > WHITE_SPACE_ENC) {
                     buffer[position++] = (byte)theByte;
-                    if (position >= bufferLength) // Enough to output.
-                    {
+                    if (position >= bufferLength) { // Enough to output.
                         int len = Base64.decode4to3(buffer, 0, b4, 0, options);
                         out.write(b4, 0, len);
                         // out.write( Base64.decode4to3( buffer ) );
                         position = 0;
-                    } // end if: enough to output
-                } // end if: meaningful base64 character
-                else if (decodabet[theByte & 0x7f] != WHITE_SPACE_ENC) {
+                    }
+                } else if (decodabet[theByte & 0x7f] != WHITE_SPACE_ENC) {
                     throw new IOException("Invalid character in Base64 data.");
-                } // end else: not white space either
-            } // end else: decoding
-        } // end write
+                }
+            }
+        }
 
         /**
          * Calls {@link #write(int)} repeatedly until <var>len</var> bytes are written.
@@ -1520,14 +1450,13 @@
             if (suspendEncoding) {
                 super.out.write(theBytes, off, len);
                 return;
-            } // end if: supsended
+            }
 
             for (int i = 0; i < len; i++) {
                 write(theBytes[off + i]);
-            } // end for: each byte written
+            }
+        }
 
-        } // end write
-
         /**
          * Method added by PHIL. [Thanks, PHIL. -Rob] This pads the buffer without closing the stream.
          * 
@@ -1538,14 +1467,12 @@
                 if (encode) {
                     out.write(encode3to4(b4, buffer, position, options));
                     position = 0;
-                } // end if: encoding
-                else {
+                } else {
                     throw new IOException("Base64 input not properly padded.");
-                } // end else: decoding
-            } // end if: buffer partially full
+                }
+            }
+        }
 
-        } // end flush
-
         /**
          * Flushes and closes (I think, in the superclass) the stream.
          * 
@@ -1554,17 +1481,19 @@
          */
         @Override
         public void close() throws IOException {
-            // 1. Ensure that pending characters are written
-            flushBase64();
+            try {
+                // 1. Ensure that pending characters are written
+                flushBase64();
+            } finally {
+                // 2. Actually close the stream
+                // Base class both flushes and closes.
+                super.close();
 
-            // 2. Actually close the stream
-            // Base class both flushes and closes.
-            super.close();
+                buffer = null;
+                out = null;
+            }
+        }
 
-            buffer = null;
-            out = null;
-        } // end close
-
         /**
          * Suspends encoding of the stream. May be helpful if you need to embed a piece of base640-encoded data in a stream.
          * 
@@ -1574,7 +1503,7 @@
         public void suspendEncoding() throws IOException {
             flushBase64();
             this.suspendEncoding = true;
-        } // end suspendEncoding
+        }
 
         /**
          * Resumes encoding of the stream. May be helpful if you need to embed a piece of base640-encoded data in a stream.
@@ -1583,8 +1512,6 @@
          */
         public void resumeEncoding() {
             this.suspendEncoding = false;
-        } // end resumeEncoding
-
-    } // end inner class OutputStream
-
-} // end class Base64
+        }
+    }
+}




More information about the dna-commits mailing list