You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by dl...@apache.org on 2002/11/01 23:06:10 UTC
cvs commit: xml-rpc/src/test/org/apache/xmlrpc Base64Test.java
dlr 2002/11/01 14:06:10
Modified: src/java/org/apache/xmlrpc Base64.java
src/test/org/apache/xmlrpc Base64Test.java
Log:
* Base64.java
Added a new discardWhitespace(byte[]) function which is called at
the beginning of decode(byte[]) to perform pre-processing on its
arguments. Filtering whitespace the body of decode() would be both
more memory and CPU-efficient, but I'm not comfortable enough with
the the code to make that invasive of a change. I'm curious what
the Tomcat folks are doing here these days.
I noticed that encode() isn't line wrapping at 76 characters --
should we log this as a problem? What effect is this going to have
on our interop?
* Base64Test.java
Renamed the mis-named testWriter() to testBase64(). Implemented
more tests for encoding/decoding using output from Perl's
MIME::Base64 module.
http://issues.apache.org/bugzilla/show_bug.cgi?id=9931
Revision Changes Path
1.4 +75 -4 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.3
retrieving revision 1.4
diff -u -u -r1.3 -r1.4
--- Base64.java 20 Mar 2002 15:11:03 -0000 1.3
+++ Base64.java 1 Nov 2002 22:06:10 -0000 1.4
@@ -63,6 +63,9 @@
*
*/
+import java.util.Enumeration;
+import java.util.Vector;
+
/**
* This class provides encode/decode for RFC 2045 Base64 as defined by
* RFC 2045, N. Freed and N. Borenstein. <a
@@ -71,7 +74,8 @@
* Internet Message Bodies. Reference 1996
*
* @author Jeffrey Rodriguez
- * @version $Id$
+ * @author Daniel Rall
+ * @since 1.2
*/
public final class Base64
{
@@ -254,6 +258,10 @@
*/
public static byte[] decode( byte[] base64Data )
{
+ // RFC 2045 suggests line wrapping at (no more than) 76
+ // characters -- we may have embedded whitespace.
+ base64Data = discardWhitespace(base64Data);
+
// handle the edge case, so we don't have to worry about it later
if(base64Data.length == 0) { return new byte[0]; }
@@ -316,5 +324,68 @@
encodedIndex += 3;
}
return decodedData;
+ }
+
+ /**
+ * Discards any whitespace from a base-64 encoded block.
+ *
+ * @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;
+ for (int i = 0; i < data.length; i++)
+ {
+ switch (data[i])
+ {
+ case (byte) ' ':
+ 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 (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;
}
}
1.7 +30 -1 xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java
Index: Base64Test.java
===================================================================
RCS file: /home/cvs/xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -u -r1.6 -r1.7
--- Base64Test.java 27 Sep 2002 23:40:42 -0000 1.6
+++ Base64Test.java 1 Nov 2002 22:06:10 -0000 1.7
@@ -75,6 +75,29 @@
"foo bar\nbaz"
};
+ private static final String UNENCODED =
+ "This module provides functions to encode and decode\n" +
+ "strings into the Base64 encoding specified in RFC 2045 -\n" +
+ "MIME (Multipurpose Internet Mail Extensions). The Base64\n" +
+ "encoding is designed to represent arbitrary sequences of\n" +
+ "octets in a form that need not be humanly readable. A\n" +
+ "65-character subset ([A-Za-z0-9+/=]) of US-ASCII is used,\n" +
+ "enabling 6 bits to be represented per printable character.";
+
+ /**
+ * The string <code>UNENCODED</code> after being encoded by Perl's
+ * MIME::Base64 module.
+ */
+ private static final String ENCODED =
+ "VGhpcyBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRvIGVuY29kZSBhbmQgZGVjb2RlCnN0cmlu\n" +
+ "Z3MgaW50byB0aGUgQmFzZTY0IGVuY29kaW5nIHNwZWNpZmllZCBpbiBSRkMgMjA0NSAtCk1JTUUg\n" +
+ "KE11bHRpcHVycG9zZSBJbnRlcm5ldCBNYWlsIEV4dGVuc2lvbnMpLiBUaGUgQmFzZTY0CmVuY29k\n" +
+ "aW5nIGlzIGRlc2lnbmVkIHRvIHJlcHJlc2VudCBhcmJpdHJhcnkgc2VxdWVuY2VzIG9mCm9jdGV0\n" +
+ "cyBpbiBhIGZvcm0gdGhhdCBuZWVkIG5vdCBiZSBodW1hbmx5IHJlYWRhYmxlLiBBCjY1LWNoYXJh\n" +
+ "Y3RlciBzdWJzZXQgKFtBLVphLXowLTkrLz1dKSBvZiBVUy1BU0NJSSBpcyB1c2VkLAplbmFibGlu\n" +
+ "ZyA2IGJpdHMgdG8gYmUgcmVwcmVzZW50ZWQgcGVyIHByaW50YWJsZSBjaGFyYWN0ZXIu";
+
+
/**
* Constructor
*/
@@ -91,7 +114,7 @@
return new TestSuite(Base64Test.class);
}
- public void testWriter()
+ public void testBase64()
throws Exception
{
try
@@ -107,6 +130,12 @@
assertEquals(raw, decoded);
assertEquals(TEST_DATA[i], new String(decoded));
}
+
+ // FIXME: The Base64.encode() function doesn't wrap at 76 chars.
+ //assertEquals(Base64.encode(UNENCODED.getBytes()),
+ // ENCODED.getBytes());
+ assertEquals(UNENCODED.getBytes(),
+ Base64.decode(ENCODED.getBytes()));
}
catch (Exception e)
{
Re: cvs commit: xml-rpc/src/test/org/apache/xmlrpc Base64Test.java
Posted by Dustin Sallings <du...@spy.net>.
Around 14:17 on Nov 1, 2002, Daniel Rall said:
# I'd love it if people of comments on this, and/or time to kick the
# tires. Also, if anyone has any ideas regarding line wrapping for
# encode(), by all means please speak up...
I'll try to give it a shot in a bit. I'm currently using a custom
build of the jar for my app that includes the code I sent in when I
originally complained. :)
Regarding the line wrapping, it seems like it's probably the right
thing to do. The spec does say that lines should be 76 characters. While
that was for a different reason, and it does waste some space, it's
probably better to be closer to the spec.
As far as skipping whitespace in the decode rather than
prefiltering it, I was also a bit uncomfortable with the existing code
(not to put words in your mouth, just that I wasn't tasked with being
comfortable with it), which is why I just replaced it with a known working
coder. It does do some things in a way that may be more efficient than
the one I submitted, but I don't feel that it's entirely correct. If it
doesn't corrupt my images anymore, then great. :)
# dlr@apache.org writes:
#
# > dlr 2002/11/01 14:06:10
# >
# > Modified: src/java/org/apache/xmlrpc Base64.java
# > src/test/org/apache/xmlrpc Base64Test.java
# > Log:
# > * Base64.java
# > Added a new discardWhitespace(byte[]) function which is called at
# > the beginning of decode(byte[]) to perform pre-processing on its
# > arguments. Filtering whitespace the body of decode() would be both
# > more memory and CPU-efficient, but I'm not comfortable enough with
# > the the code to make that invasive of a change. I'm curious what
# > the Tomcat folks are doing here these days.
# >
# > I noticed that encode() isn't line wrapping at 76 characters --
# > should we log this as a problem? What effect is this going to have
# > on our interop?
# >
# > * Base64Test.java
# > Renamed the mis-named testWriter() to testBase64(). Implemented
# > more tests for encoding/decoding using output from Perl's
# > MIME::Base64 module.
# >
# > http://issues.apache.org/bugzilla/show_bug.cgi?id=9931
# >
# > Revision Changes Path
# > 1.4 +75 -4 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.3
# > retrieving revision 1.4
# > diff -u -u -r1.3 -r1.4
# > --- Base64.java 20 Mar 2002 15:11:03 -0000 1.3
# > +++ Base64.java 1 Nov 2002 22:06:10 -0000 1.4
# > @@ -63,6 +63,9 @@
# > *
# > */
# >
# > +import java.util.Enumeration;
# > +import java.util.Vector;
# > +
# > /**
# > * This class provides encode/decode for RFC 2045 Base64 as defined by
# > * RFC 2045, N. Freed and N. Borenstein. <a
# > @@ -71,7 +74,8 @@
# > * Internet Message Bodies. Reference 1996
# > *
# > * @author Jeffrey Rodriguez
# > - * @version $Id$
# > + * @author Daniel Rall
# > + * @since 1.2
# > */
# > public final class Base64
# > {
# > @@ -254,6 +258,10 @@
# > */
# > public static byte[] decode( byte[] base64Data )
# > {
# > + // RFC 2045 suggests line wrapping at (no more than) 76
# > + // characters -- we may have embedded whitespace.
# > + base64Data = discardWhitespace(base64Data);
# > +
# > // handle the edge case, so we don't have to worry about it later
# > if(base64Data.length == 0) { return new byte[0]; }
# >
# > @@ -316,5 +324,68 @@
# > encodedIndex += 3;
# > }
# > return decodedData;
# > + }
# > +
# > + /**
# > + * Discards any whitespace from a base-64 encoded block.
# > + *
# > + * @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;
# > + for (int i = 0; i < data.length; i++)
# > + {
# > + switch (data[i])
# > + {
# > + case (byte) ' ':
# > + 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 (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;
# > }
# > }
# >
# >
# >
# > 1.7 +30 -1 xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java
# >
# > Index: Base64Test.java
# > ===================================================================
# > RCS file: /home/cvs/xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java,v
# > retrieving revision 1.6
# > retrieving revision 1.7
# > diff -u -u -r1.6 -r1.7
# > --- Base64Test.java 27 Sep 2002 23:40:42 -0000 1.6
# > +++ Base64Test.java 1 Nov 2002 22:06:10 -0000 1.7
# > @@ -75,6 +75,29 @@
# > "foo bar\nbaz"
# > };
# >
# > + private static final String UNENCODED =
# > + "This module provides functions to encode and decode\n" +
# > + "strings into the Base64 encoding specified in RFC 2045 -\n" +
# > + "MIME (Multipurpose Internet Mail Extensions). The Base64\n" +
# > + "encoding is designed to represent arbitrary sequences of\n" +
# > + "octets in a form that need not be humanly readable. A\n" +
# > + "65-character subset ([A-Za-z0-9+/=]) of US-ASCII is used,\n" +
# > + "enabling 6 bits to be represented per printable character.";
# > +
# > + /**
# > + * The string <code>UNENCODED</code> after being encoded by Perl's
# > + * MIME::Base64 module.
# > + */
# > + private static final String ENCODED =
# > + "VGhpcyBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRvIGVuY29kZSBhbmQgZGVjb2RlCnN0cmlu\n" +
# > + "Z3MgaW50byB0aGUgQmFzZTY0IGVuY29kaW5nIHNwZWNpZmllZCBpbiBSRkMgMjA0NSAtCk1JTUUg\n" +
# > + "KE11bHRpcHVycG9zZSBJbnRlcm5ldCBNYWlsIEV4dGVuc2lvbnMpLiBUaGUgQmFzZTY0CmVuY29k\n" +
# > + "aW5nIGlzIGRlc2lnbmVkIHRvIHJlcHJlc2VudCBhcmJpdHJhcnkgc2VxdWVuY2VzIG9mCm9jdGV0\n" +
# > + "cyBpbiBhIGZvcm0gdGhhdCBuZWVkIG5vdCBiZSBodW1hbmx5IHJlYWRhYmxlLiBBCjY1LWNoYXJh\n" +
# > + "Y3RlciBzdWJzZXQgKFtBLVphLXowLTkrLz1dKSBvZiBVUy1BU0NJSSBpcyB1c2VkLAplbmFibGlu\n" +
# > + "ZyA2IGJpdHMgdG8gYmUgcmVwcmVzZW50ZWQgcGVyIHByaW50YWJsZSBjaGFyYWN0ZXIu";
# > +
# > +
# > /**
# > * Constructor
# > */
# > @@ -91,7 +114,7 @@
# > return new TestSuite(Base64Test.class);
# > }
# >
# > - public void testWriter()
# > + public void testBase64()
# > throws Exception
# > {
# > try
# > @@ -107,6 +130,12 @@
# > assertEquals(raw, decoded);
# > assertEquals(TEST_DATA[i], new String(decoded));
# > }
# > +
# > + // FIXME: The Base64.encode() function doesn't wrap at 76 chars.
# > + //assertEquals(Base64.encode(UNENCODED.getBytes()),
# > + // ENCODED.getBytes());
# > + assertEquals(UNENCODED.getBytes(),
# > + Base64.decode(ENCODED.getBytes()));
# > }
# > catch (Exception e)
# > {
# >
# >
# >
#
# --
#
# Daniel Rall <dl...@finemaltcoding.com>
#
#
--
SPY My girlfriend asked me which one I like better.
pub 1024/3CAE01D5 1994/11/03 Dustin Sallings <du...@spy.net>
| Key fingerprint = 87 02 57 08 02 D0 DA D6 C8 0F 3E 65 51 98 D8 BE
L_______________________ I hope the answer won't upset her. ____________
Re: cvs commit: xml-rpc/src/test/org/apache/xmlrpc Base64Test.java
Posted by Dustin Sallings <du...@spy.net>.
Around 14:17 on Nov 1, 2002, Daniel Rall said:
# I'd love it if people of comments on this, and/or time to kick the
# tires. Also, if anyone has any ideas regarding line wrapping for
# encode(), by all means please speak up...
I'll try to give it a shot in a bit. I'm currently using a custom
build of the jar for my app that includes the code I sent in when I
originally complained. :)
Regarding the line wrapping, it seems like it's probably the right
thing to do. The spec does say that lines should be 76 characters. While
that was for a different reason, and it does waste some space, it's
probably better to be closer to the spec.
As far as skipping whitespace in the decode rather than
prefiltering it, I was also a bit uncomfortable with the existing code
(not to put words in your mouth, just that I wasn't tasked with being
comfortable with it), which is why I just replaced it with a known working
coder. It does do some things in a way that may be more efficient than
the one I submitted, but I don't feel that it's entirely correct. If it
doesn't corrupt my images anymore, then great. :)
# dlr@apache.org writes:
#
# > dlr 2002/11/01 14:06:10
# >
# > Modified: src/java/org/apache/xmlrpc Base64.java
# > src/test/org/apache/xmlrpc Base64Test.java
# > Log:
# > * Base64.java
# > Added a new discardWhitespace(byte[]) function which is called at
# > the beginning of decode(byte[]) to perform pre-processing on its
# > arguments. Filtering whitespace the body of decode() would be both
# > more memory and CPU-efficient, but I'm not comfortable enough with
# > the the code to make that invasive of a change. I'm curious what
# > the Tomcat folks are doing here these days.
# >
# > I noticed that encode() isn't line wrapping at 76 characters --
# > should we log this as a problem? What effect is this going to have
# > on our interop?
# >
# > * Base64Test.java
# > Renamed the mis-named testWriter() to testBase64(). Implemented
# > more tests for encoding/decoding using output from Perl's
# > MIME::Base64 module.
# >
# > http://issues.apache.org/bugzilla/show_bug.cgi?id=9931
# >
# > Revision Changes Path
# > 1.4 +75 -4 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.3
# > retrieving revision 1.4
# > diff -u -u -r1.3 -r1.4
# > --- Base64.java 20 Mar 2002 15:11:03 -0000 1.3
# > +++ Base64.java 1 Nov 2002 22:06:10 -0000 1.4
# > @@ -63,6 +63,9 @@
# > *
# > */
# >
# > +import java.util.Enumeration;
# > +import java.util.Vector;
# > +
# > /**
# > * This class provides encode/decode for RFC 2045 Base64 as defined by
# > * RFC 2045, N. Freed and N. Borenstein. <a
# > @@ -71,7 +74,8 @@
# > * Internet Message Bodies. Reference 1996
# > *
# > * @author Jeffrey Rodriguez
# > - * @version $Id$
# > + * @author Daniel Rall
# > + * @since 1.2
# > */
# > public final class Base64
# > {
# > @@ -254,6 +258,10 @@
# > */
# > public static byte[] decode( byte[] base64Data )
# > {
# > + // RFC 2045 suggests line wrapping at (no more than) 76
# > + // characters -- we may have embedded whitespace.
# > + base64Data = discardWhitespace(base64Data);
# > +
# > // handle the edge case, so we don't have to worry about it later
# > if(base64Data.length == 0) { return new byte[0]; }
# >
# > @@ -316,5 +324,68 @@
# > encodedIndex += 3;
# > }
# > return decodedData;
# > + }
# > +
# > + /**
# > + * Discards any whitespace from a base-64 encoded block.
# > + *
# > + * @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;
# > + for (int i = 0; i < data.length; i++)
# > + {
# > + switch (data[i])
# > + {
# > + case (byte) ' ':
# > + 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 (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;
# > }
# > }
# >
# >
# >
# > 1.7 +30 -1 xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java
# >
# > Index: Base64Test.java
# > ===================================================================
# > RCS file: /home/cvs/xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java,v
# > retrieving revision 1.6
# > retrieving revision 1.7
# > diff -u -u -r1.6 -r1.7
# > --- Base64Test.java 27 Sep 2002 23:40:42 -0000 1.6
# > +++ Base64Test.java 1 Nov 2002 22:06:10 -0000 1.7
# > @@ -75,6 +75,29 @@
# > "foo bar\nbaz"
# > };
# >
# > + private static final String UNENCODED =
# > + "This module provides functions to encode and decode\n" +
# > + "strings into the Base64 encoding specified in RFC 2045 -\n" +
# > + "MIME (Multipurpose Internet Mail Extensions). The Base64\n" +
# > + "encoding is designed to represent arbitrary sequences of\n" +
# > + "octets in a form that need not be humanly readable. A\n" +
# > + "65-character subset ([A-Za-z0-9+/=]) of US-ASCII is used,\n" +
# > + "enabling 6 bits to be represented per printable character.";
# > +
# > + /**
# > + * The string <code>UNENCODED</code> after being encoded by Perl's
# > + * MIME::Base64 module.
# > + */
# > + private static final String ENCODED =
# > + "VGhpcyBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRvIGVuY29kZSBhbmQgZGVjb2RlCnN0cmlu\n" +
# > + "Z3MgaW50byB0aGUgQmFzZTY0IGVuY29kaW5nIHNwZWNpZmllZCBpbiBSRkMgMjA0NSAtCk1JTUUg\n" +
# > + "KE11bHRpcHVycG9zZSBJbnRlcm5ldCBNYWlsIEV4dGVuc2lvbnMpLiBUaGUgQmFzZTY0CmVuY29k\n" +
# > + "aW5nIGlzIGRlc2lnbmVkIHRvIHJlcHJlc2VudCBhcmJpdHJhcnkgc2VxdWVuY2VzIG9mCm9jdGV0\n" +
# > + "cyBpbiBhIGZvcm0gdGhhdCBuZWVkIG5vdCBiZSBodW1hbmx5IHJlYWRhYmxlLiBBCjY1LWNoYXJh\n" +
# > + "Y3RlciBzdWJzZXQgKFtBLVphLXowLTkrLz1dKSBvZiBVUy1BU0NJSSBpcyB1c2VkLAplbmFibGlu\n" +
# > + "ZyA2IGJpdHMgdG8gYmUgcmVwcmVzZW50ZWQgcGVyIHByaW50YWJsZSBjaGFyYWN0ZXIu";
# > +
# > +
# > /**
# > * Constructor
# > */
# > @@ -91,7 +114,7 @@
# > return new TestSuite(Base64Test.class);
# > }
# >
# > - public void testWriter()
# > + public void testBase64()
# > throws Exception
# > {
# > try
# > @@ -107,6 +130,12 @@
# > assertEquals(raw, decoded);
# > assertEquals(TEST_DATA[i], new String(decoded));
# > }
# > +
# > + // FIXME: The Base64.encode() function doesn't wrap at 76 chars.
# > + //assertEquals(Base64.encode(UNENCODED.getBytes()),
# > + // ENCODED.getBytes());
# > + assertEquals(UNENCODED.getBytes(),
# > + Base64.decode(ENCODED.getBytes()));
# > }
# > catch (Exception e)
# > {
# >
# >
# >
#
# --
#
# Daniel Rall <dl...@finemaltcoding.com>
#
#
--
SPY My girlfriend asked me which one I like better.
pub 1024/3CAE01D5 1994/11/03 Dustin Sallings <du...@spy.net>
| Key fingerprint = 87 02 57 08 02 D0 DA D6 C8 0F 3E 65 51 98 D8 BE
L_______________________ I hope the answer won't upset her. ____________
Re: cvs commit: xml-rpc/src/test/org/apache/xmlrpc Base64Test.java
Posted by Daniel Rall <dl...@finemaltcoding.com>.
I'd love it if people of comments on this, and/or time to kick the
tires. Also, if anyone has any ideas regarding line wrapping for
encode(), by all means please speak up...
dlr@apache.org writes:
> dlr 2002/11/01 14:06:10
>
> Modified: src/java/org/apache/xmlrpc Base64.java
> src/test/org/apache/xmlrpc Base64Test.java
> Log:
> * Base64.java
> Added a new discardWhitespace(byte[]) function which is called at
> the beginning of decode(byte[]) to perform pre-processing on its
> arguments. Filtering whitespace the body of decode() would be both
> more memory and CPU-efficient, but I'm not comfortable enough with
> the the code to make that invasive of a change. I'm curious what
> the Tomcat folks are doing here these days.
>
> I noticed that encode() isn't line wrapping at 76 characters --
> should we log this as a problem? What effect is this going to have
> on our interop?
>
> * Base64Test.java
> Renamed the mis-named testWriter() to testBase64(). Implemented
> more tests for encoding/decoding using output from Perl's
> MIME::Base64 module.
>
> http://issues.apache.org/bugzilla/show_bug.cgi?id=9931
>
> Revision Changes Path
> 1.4 +75 -4 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.3
> retrieving revision 1.4
> diff -u -u -r1.3 -r1.4
> --- Base64.java 20 Mar 2002 15:11:03 -0000 1.3
> +++ Base64.java 1 Nov 2002 22:06:10 -0000 1.4
> @@ -63,6 +63,9 @@
> *
> */
>
> +import java.util.Enumeration;
> +import java.util.Vector;
> +
> /**
> * This class provides encode/decode for RFC 2045 Base64 as defined by
> * RFC 2045, N. Freed and N. Borenstein. <a
> @@ -71,7 +74,8 @@
> * Internet Message Bodies. Reference 1996
> *
> * @author Jeffrey Rodriguez
> - * @version $Id$
> + * @author Daniel Rall
> + * @since 1.2
> */
> public final class Base64
> {
> @@ -254,6 +258,10 @@
> */
> public static byte[] decode( byte[] base64Data )
> {
> + // RFC 2045 suggests line wrapping at (no more than) 76
> + // characters -- we may have embedded whitespace.
> + base64Data = discardWhitespace(base64Data);
> +
> // handle the edge case, so we don't have to worry about it later
> if(base64Data.length == 0) { return new byte[0]; }
>
> @@ -316,5 +324,68 @@
> encodedIndex += 3;
> }
> return decodedData;
> + }
> +
> + /**
> + * Discards any whitespace from a base-64 encoded block.
> + *
> + * @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;
> + for (int i = 0; i < data.length; i++)
> + {
> + switch (data[i])
> + {
> + case (byte) ' ':
> + 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 (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;
> }
> }
>
>
>
> 1.7 +30 -1 xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java
>
> Index: Base64Test.java
> ===================================================================
> RCS file: /home/cvs/xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java,v
> retrieving revision 1.6
> retrieving revision 1.7
> diff -u -u -r1.6 -r1.7
> --- Base64Test.java 27 Sep 2002 23:40:42 -0000 1.6
> +++ Base64Test.java 1 Nov 2002 22:06:10 -0000 1.7
> @@ -75,6 +75,29 @@
> "foo bar\nbaz"
> };
>
> + private static final String UNENCODED =
> + "This module provides functions to encode and decode\n" +
> + "strings into the Base64 encoding specified in RFC 2045 -\n" +
> + "MIME (Multipurpose Internet Mail Extensions). The Base64\n" +
> + "encoding is designed to represent arbitrary sequences of\n" +
> + "octets in a form that need not be humanly readable. A\n" +
> + "65-character subset ([A-Za-z0-9+/=]) of US-ASCII is used,\n" +
> + "enabling 6 bits to be represented per printable character.";
> +
> + /**
> + * The string <code>UNENCODED</code> after being encoded by Perl's
> + * MIME::Base64 module.
> + */
> + private static final String ENCODED =
> + "VGhpcyBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRvIGVuY29kZSBhbmQgZGVjb2RlCnN0cmlu\n" +
> + "Z3MgaW50byB0aGUgQmFzZTY0IGVuY29kaW5nIHNwZWNpZmllZCBpbiBSRkMgMjA0NSAtCk1JTUUg\n" +
> + "KE11bHRpcHVycG9zZSBJbnRlcm5ldCBNYWlsIEV4dGVuc2lvbnMpLiBUaGUgQmFzZTY0CmVuY29k\n" +
> + "aW5nIGlzIGRlc2lnbmVkIHRvIHJlcHJlc2VudCBhcmJpdHJhcnkgc2VxdWVuY2VzIG9mCm9jdGV0\n" +
> + "cyBpbiBhIGZvcm0gdGhhdCBuZWVkIG5vdCBiZSBodW1hbmx5IHJlYWRhYmxlLiBBCjY1LWNoYXJh\n" +
> + "Y3RlciBzdWJzZXQgKFtBLVphLXowLTkrLz1dKSBvZiBVUy1BU0NJSSBpcyB1c2VkLAplbmFibGlu\n" +
> + "ZyA2IGJpdHMgdG8gYmUgcmVwcmVzZW50ZWQgcGVyIHByaW50YWJsZSBjaGFyYWN0ZXIu";
> +
> +
> /**
> * Constructor
> */
> @@ -91,7 +114,7 @@
> return new TestSuite(Base64Test.class);
> }
>
> - public void testWriter()
> + public void testBase64()
> throws Exception
> {
> try
> @@ -107,6 +130,12 @@
> assertEquals(raw, decoded);
> assertEquals(TEST_DATA[i], new String(decoded));
> }
> +
> + // FIXME: The Base64.encode() function doesn't wrap at 76 chars.
> + //assertEquals(Base64.encode(UNENCODED.getBytes()),
> + // ENCODED.getBytes());
> + assertEquals(UNENCODED.getBytes(),
> + Base64.decode(ENCODED.getBytes()));
> }
> catch (Exception e)
> {
>
>
>
--
Daniel Rall <dl...@finemaltcoding.com>
Re: cvs commit: xml-rpc/src/test/org/apache/xmlrpc Base64Test.java
Posted by Daniel Rall <dl...@finemaltcoding.com>.
I'd love it if people of comments on this, and/or time to kick the
tires. Also, if anyone has any ideas regarding line wrapping for
encode(), by all means please speak up...
dlr@apache.org writes:
> dlr 2002/11/01 14:06:10
>
> Modified: src/java/org/apache/xmlrpc Base64.java
> src/test/org/apache/xmlrpc Base64Test.java
> Log:
> * Base64.java
> Added a new discardWhitespace(byte[]) function which is called at
> the beginning of decode(byte[]) to perform pre-processing on its
> arguments. Filtering whitespace the body of decode() would be both
> more memory and CPU-efficient, but I'm not comfortable enough with
> the the code to make that invasive of a change. I'm curious what
> the Tomcat folks are doing here these days.
>
> I noticed that encode() isn't line wrapping at 76 characters --
> should we log this as a problem? What effect is this going to have
> on our interop?
>
> * Base64Test.java
> Renamed the mis-named testWriter() to testBase64(). Implemented
> more tests for encoding/decoding using output from Perl's
> MIME::Base64 module.
>
> http://issues.apache.org/bugzilla/show_bug.cgi?id=9931
>
> Revision Changes Path
> 1.4 +75 -4 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.3
> retrieving revision 1.4
> diff -u -u -r1.3 -r1.4
> --- Base64.java 20 Mar 2002 15:11:03 -0000 1.3
> +++ Base64.java 1 Nov 2002 22:06:10 -0000 1.4
> @@ -63,6 +63,9 @@
> *
> */
>
> +import java.util.Enumeration;
> +import java.util.Vector;
> +
> /**
> * This class provides encode/decode for RFC 2045 Base64 as defined by
> * RFC 2045, N. Freed and N. Borenstein. <a
> @@ -71,7 +74,8 @@
> * Internet Message Bodies. Reference 1996
> *
> * @author Jeffrey Rodriguez
> - * @version $Id$
> + * @author Daniel Rall
> + * @since 1.2
> */
> public final class Base64
> {
> @@ -254,6 +258,10 @@
> */
> public static byte[] decode( byte[] base64Data )
> {
> + // RFC 2045 suggests line wrapping at (no more than) 76
> + // characters -- we may have embedded whitespace.
> + base64Data = discardWhitespace(base64Data);
> +
> // handle the edge case, so we don't have to worry about it later
> if(base64Data.length == 0) { return new byte[0]; }
>
> @@ -316,5 +324,68 @@
> encodedIndex += 3;
> }
> return decodedData;
> + }
> +
> + /**
> + * Discards any whitespace from a base-64 encoded block.
> + *
> + * @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;
> + for (int i = 0; i < data.length; i++)
> + {
> + switch (data[i])
> + {
> + case (byte) ' ':
> + 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 (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;
> }
> }
>
>
>
> 1.7 +30 -1 xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java
>
> Index: Base64Test.java
> ===================================================================
> RCS file: /home/cvs/xml-rpc/src/test/org/apache/xmlrpc/Base64Test.java,v
> retrieving revision 1.6
> retrieving revision 1.7
> diff -u -u -r1.6 -r1.7
> --- Base64Test.java 27 Sep 2002 23:40:42 -0000 1.6
> +++ Base64Test.java 1 Nov 2002 22:06:10 -0000 1.7
> @@ -75,6 +75,29 @@
> "foo bar\nbaz"
> };
>
> + private static final String UNENCODED =
> + "This module provides functions to encode and decode\n" +
> + "strings into the Base64 encoding specified in RFC 2045 -\n" +
> + "MIME (Multipurpose Internet Mail Extensions). The Base64\n" +
> + "encoding is designed to represent arbitrary sequences of\n" +
> + "octets in a form that need not be humanly readable. A\n" +
> + "65-character subset ([A-Za-z0-9+/=]) of US-ASCII is used,\n" +
> + "enabling 6 bits to be represented per printable character.";
> +
> + /**
> + * The string <code>UNENCODED</code> after being encoded by Perl's
> + * MIME::Base64 module.
> + */
> + private static final String ENCODED =
> + "VGhpcyBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRvIGVuY29kZSBhbmQgZGVjb2RlCnN0cmlu\n" +
> + "Z3MgaW50byB0aGUgQmFzZTY0IGVuY29kaW5nIHNwZWNpZmllZCBpbiBSRkMgMjA0NSAtCk1JTUUg\n" +
> + "KE11bHRpcHVycG9zZSBJbnRlcm5ldCBNYWlsIEV4dGVuc2lvbnMpLiBUaGUgQmFzZTY0CmVuY29k\n" +
> + "aW5nIGlzIGRlc2lnbmVkIHRvIHJlcHJlc2VudCBhcmJpdHJhcnkgc2VxdWVuY2VzIG9mCm9jdGV0\n" +
> + "cyBpbiBhIGZvcm0gdGhhdCBuZWVkIG5vdCBiZSBodW1hbmx5IHJlYWRhYmxlLiBBCjY1LWNoYXJh\n" +
> + "Y3RlciBzdWJzZXQgKFtBLVphLXowLTkrLz1dKSBvZiBVUy1BU0NJSSBpcyB1c2VkLAplbmFibGlu\n" +
> + "ZyA2IGJpdHMgdG8gYmUgcmVwcmVzZW50ZWQgcGVyIHByaW50YWJsZSBjaGFyYWN0ZXIu";
> +
> +
> /**
> * Constructor
> */
> @@ -91,7 +114,7 @@
> return new TestSuite(Base64Test.class);
> }
>
> - public void testWriter()
> + public void testBase64()
> throws Exception
> {
> try
> @@ -107,6 +130,12 @@
> assertEquals(raw, decoded);
> assertEquals(TEST_DATA[i], new String(decoded));
> }
> +
> + // FIXME: The Base64.encode() function doesn't wrap at 76 chars.
> + //assertEquals(Base64.encode(UNENCODED.getBytes()),
> + // ENCODED.getBytes());
> + assertEquals(UNENCODED.getBytes(),
> + Base64.decode(ENCODED.getBytes()));
> }
> catch (Exception e)
> {
>
>
>
--
Daniel Rall <dl...@finemaltcoding.com>