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;
}
}