rhoegg 2003/02/03 19:47:42 Modified: src/java/org/apache/xmlrpc Tag: XMLRPC_1_2_BRANCH Base64.java Log: Latest version of Base64 from Martin Redington: - appends CRLF to the output of encode to mimic perl behavior - discards non base 64 characters - 2x performance improvement in decode ---------------------------------------------------------------------- Revision Changes Path No revision No revision 1.4.2.3 +30 -43 xml-rpc/src/java/org/apache/xmlrpc/Base64.java Index: Base64.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/Base64.java,v retrieving revision 1.4.2.2 retrieving revision 1.4.2.3 diff -u -r1.4.2.2 -r1.4.2.3 --- Base64.java 4 Feb 2003 02:48:28 -0000 1.4.2.2 +++ Base64.java 4 Feb 2003 03:47:42 -0000 1.4.2.3 @@ -187,7 +187,7 @@ int nbrChunks = (CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE)); - encodedDataLength += (nbrChunks - 1) * CHUNK_SEPARATOR.length; + encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length; encodedData = new byte[encodedDataLength]; byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; @@ -232,7 +232,7 @@ System.arraycopy(CHUNK_SEPARATOR, 0, encodedData, encodedIndex, CHUNK_SEPARATOR.length); chunksSoFar++; - nextSeparatorIndex = (CHUNK_SIZE * (chunksSoFar + 1)) + + nextSeparatorIndex = (CHUNK_SIZE * (chunksSoFar + 1)) + (chunksSoFar * CHUNK_SEPARATOR.length); encodedIndex += CHUNK_SEPARATOR.length; } @@ -271,6 +271,11 @@ encodedData[encodedIndex + 3] = PAD; } + // we also add a separator to the end of the final chunk. + if(chunksSoFar < nbrChunks) + System.arraycopy(CHUNK_SEPARATOR, 0, encodedData, + encodedDataLength - CHUNK_SEPARATOR.length, CHUNK_SEPARATOR.length); + return encodedData; } @@ -353,16 +358,20 @@ /** * Discards any whitespace from a base-64 encoded block. * + * Any other non-base-64 characters will be silently + * discarded. This complies with the RFC, although a warning or + * exception would also be RFC compliant (and is actually + * recommended). + * * @param data The base-64 encoded data to discard the whitespace * from. * @return The data, less whitespace (see RFC 2045). */ static byte[] discardWhitespace(byte[] data) { - // Locate any regions of whitespace within our data. - int nbrToDiscard = 0; - Vector discardRegions = new Vector(); - boolean discarding = false; + byte groomedData[] = new byte[data.length]; + int bytesCopied = 0; + for (int i = 0; i < data.length; i++) { switch (data[i]) @@ -371,45 +380,23 @@ case (byte) '\n': case (byte) '\r': case (byte) '\t': - if (!discarding) - { - int[] region = { i, data.length }; - discardRegions.addElement(region); - discarding = true; - } - nbrToDiscard++; break; - default: - if (discarding) - { - // End region to discard. - ((int []) discardRegions.lastElement())[1] = i; - discarding = false; + if(isBase64(data[i])){ + groomedData[bytesCopied++] = data[i]; + } + else{ + // according to the RFC, we could raise a warning + // or exception here } } } - if (nbrToDiscard > 0) - { - // Groom whitespace from the data. - byte[] groomed = new byte[data.length - nbrToDiscard]; - int srcOffset = 0; - int destOffset = 0; - int[] region = null; - Enumeration enum = discardRegions.elements(); - while (enum.hasMoreElements()) - { - region = (int []) enum.nextElement(); - int len = region[0] - srcOffset; - System.arraycopy(data, srcOffset, groomed, destOffset, len); - destOffset += len; - srcOffset = region[1]; - } - System.arraycopy(data, srcOffset, groomed, destOffset, - data.length - region[1]); - data = groomed; - } - return data; + byte packedData[] = new byte[bytesCopied]; + + System.arraycopy(groomedData, 0, packedData, + 0, bytesCopied); + + return packedData; } }