You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@xml.apache.org by sn...@apache.org on 2002/10/04 04:06:17 UTC

cvs commit: xml-soap/java/src/org/apache/soap/encoding/soapenc Base64.java

snichol     2002/10/03 19:06:17

  Modified:    java/test/encoding/soapenc PackageTests.java
               java/src/org/apache/soap/encoding/soapenc Base64.java
  Added:       java/test/encoding/soapenc Base64Test.java
  Log:
  Submitted by: Pavel Ausianik <Pa...@epam.com>
  Reviewed by: Scott Nichol
  
  Base64 encoded parameters decoded too slow. See
  http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12510
  
  Revision  Changes    Path
  1.3       +1 -0      xml-soap/java/test/encoding/soapenc/PackageTests.java
  
  Index: PackageTests.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/test/encoding/soapenc/PackageTests.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PackageTests.java	21 May 2001 01:22:33 -0000	1.2
  +++ PackageTests.java	4 Oct 2002 02:06:17 -0000	1.3
  @@ -24,6 +24,7 @@
           suite.addTestSuite(FloatDeserializerTest.class);
           suite.addTestSuite(FloatObjectDeserializerTest.class);
           suite.addTestSuite(DecimalDeserializerTest.class);
  +        suite.addTestSuite(Base64Test.class);
   
           return suite;
       }
  
  
  
  1.1                  xml-soap/java/test/encoding/soapenc/Base64Test.java
  
  Index: Base64Test.java
  ===================================================================
  package test.encoding.soapenc;
  
  import javax.xml.parsers.*;  // JAXP interfaces
  import org.w3c.dom.*;
  import org.apache.soap.util.Bean;
  import org.apache.soap.util.xml.Deserializer;
  import java.io.ByteArrayInputStream;
  import org.apache.soap.encoding.soapenc.Base64;
  import java.math.BigDecimal;
  
  import junit.framework.TestCase;
  import junit.framework.Assert;
  
  /**
   * @author Pavel Ausianik &lt;Pavel_Ausianik@epam.com&gt;
   */
  public class Base64Test extends TestCase
  {
      public static void assertEquals(String message, byte[] expected, byte[] actual)
      {
        if(expected == null && actual == null)
            return;
        if(expected == null || actual == null)
          fail(message);
        if(expected != null && expected == actual)
            return;
        if (expected.length != actual.length)
          fail(message);
        int len = expected.length;
        for (int i=0; i<len; i++)
          if (expected[i] != actual[i]) {
             fail(message);
             break;
          }
      }
      public Base64Test(String name)
      {
          super(name);
      }
  
      public void testArrays() throws Exception
      {
        for (int i=0; i<1000; i++)
        {
          byte testArray[] = new byte[i];
          for (int j=0; j<i; j++)
            testArray[j] = (byte)j;
          String out = Base64.encode(testArray);
          byte resultArray[] =  Base64.decode(out);
          assertEquals("testArray fails", testArray, resultArray);
          char charArray[] = out.toCharArray();
          resultArray =  Base64.decode(charArray, 0, charArray.length);
          assertEquals("testArray fails", testArray, resultArray);
        }
      }
  
  }
  
  
  
  1.3       +60 -25    xml-soap/java/src/org/apache/soap/encoding/soapenc/Base64.java
  
  Index: Base64.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/encoding/soapenc/Base64.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Base64.java	8 May 2002 14:43:08 -0000	1.2
  +++ Base64.java	4 Oct 2002 02:06:17 -0000	1.3
  @@ -23,15 +23,16 @@
   /**
    *
    * @author TAMURA Kent &lt;kent@trl.ibm.co.jp&gt;
  + * @author Pavel Ausianik &lt;Pavel_Ausianik@epam.com&gt;
    */
   public class Base64 {
       private static final char[] S_BASE64CHAR = {
  -        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 
  -        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 
  -        'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 
  -        'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
  -        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 
  -        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 
  +        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  +        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  +        'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  +        'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  +        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
  +        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
           '8', '9', '+', '/'
       };
       private static final char S_BASE64PAD = '=';
  @@ -99,27 +100,45 @@
           return ret;
       }
   
  +    public static final int BUF_SIZE =  256;
       /**
        * Decode the base64 data.
        * @param data The base64 encoded data to be decoded
        * @return The decoded data
        */
       public static byte[] decode(String data) {
  -        char[] ibuf = new char[4];
           int ibufcount = 0;
  -        byte[] obuf = new byte[data.length()/4*3+3];
  +        int slen = data.length();
  +        char[] ibuf = new char[slen < BUF_SIZE ? slen : BUF_SIZE];
  +        byte[] obuf = new byte[slen/4*3+3];
           int obufcount = 0;
  -        for (int i = 0;  i < data.length();  i ++) {
  -            char ch = data.charAt(i);
  -            if (ch == S_BASE64PAD
  -                || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
  +        int blen = 0;
  +
  +        for (int i = 0;  i < slen;  i +=BUF_SIZE ) {
  +            // buffer may contain unprocessed characters from previous step
  +            if (i + BUF_SIZE  <= slen)  {
  +              data.getChars(i, i+BUF_SIZE , ibuf, ibufcount);
  +              blen = BUF_SIZE+ibufcount;
  +            } else {
  +              data.getChars(i, slen, ibuf, ibufcount);
  +              blen = slen - i+ibufcount;
  +            }
  +
  +            for (int j=ibufcount; j<blen; j++) {
  +              char ch = ibuf[j];
  +              if (ch == S_BASE64PAD
  +                  || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
                   ibuf[ibufcount++] = ch;
  -                if (ibufcount == ibuf.length) {
  -                    ibufcount = 0;
  -                    obufcount += decode0(ibuf, obuf, obufcount);
  +
  +                // as soon as we have 4 chars process them
  +                if (ibufcount == 4) {
  +                  ibufcount = 0;
  +                  obufcount += decode0(ibuf, obuf, obufcount);
                   }
  +              }
               }
           }
  +
           if (obufcount == obuf.length)
               return obuf;
           byte[] ret = new byte[obufcount];
  @@ -160,19 +179,35 @@
        *                written
        */
       public static void decode(String data, OutputStream ostream) throws IOException {
  -        char[] ibuf = new char[4];
  -        int ibufcount = 0;
  +        char[] ibuf = new char[BUF_SIZE + 4];
           byte[] obuf = new byte[3];
  -        for (int i = 0;  i < data.length();  i ++) {
  -            char ch = data.charAt(i);
  -            if (ch == S_BASE64PAD
  -                || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
  +        int slen = data.length();
  +        int blen = 0;
  +        int ibufcount = 0;
  +
  +        for (int i = 0;  i < slen;  i +=BUF_SIZE ) {
  +            // buffer may contain unprocessed characters from previous step
  +            if (i + BUF_SIZE  <= slen)  {
  +              data.getChars(i, i+BUF_SIZE , ibuf, ibufcount);
  +              blen = BUF_SIZE+ibufcount;
  +            } else {
  +              data.getChars(i, slen, ibuf, ibufcount);
  +              blen = slen - i+ibufcount;
  +            }
  +
  +            for (int j=ibufcount; j<blen; j++) {
  +              char ch = ibuf[j];
  +              if (ch == S_BASE64PAD
  +                  || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) {
                   ibuf[ibufcount++] = ch;
  -                if (ibufcount == ibuf.length) {
  -                    ibufcount = 0;
  -                    int obufcount = decode0(ibuf, obuf, 0);
  -                    ostream.write(obuf, 0, obufcount);
  +
  +                // as sson as we have 4 chars process them
  +                if (ibufcount == 4) {
  +                  ibufcount = 0;
  +                  int obufcount = decode0(ibuf, obuf, 0);
  +                  ostream.write(obuf, 0, obufcount);
                   }
  +              }
               }
           }
       }
  
  
  

--
To unsubscribe, e-mail:   <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>