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. :)
# [EMAIL PROTECTED] 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 <[EMAIL PROTECTED]>
#
#
--
SPY My girlfriend asked me which one I like better.
pub 1024/3CAE01D5 1994/11/03 Dustin Sallings <[EMAIL PROTECTED]>
| 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. ____________