You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2004/07/19 18:54:58 UTC

cvs commit: ws-axis/java/src/org/apache/axis/utils ByteArrayOutputStream.java ByteArray.java

dims        2004/07/19 09:54:58

  Modified:    java/src/org/apache/axis/utils ByteArray.java
  Added:       java/src/org/apache/axis/utils ByteArrayOutputStream.java
  Log:
  Switching to commons' BOAS as per Nishant's suggestion (http://marc.theaimsgroup.com/?l=axis-dev&m=109005726207800&w=2)
  
  Revision  Changes    Path
  1.4       +105 -155  ws-axis/java/src/org/apache/axis/utils/ByteArray.java
  
  Index: ByteArray.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/utils/ByteArray.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ByteArray.java	14 Jun 2004 15:47:21 -0000	1.3
  +++ ByteArray.java	19 Jul 2004 16:54:58 -0000	1.4
  @@ -39,9 +39,8 @@
       protected static boolean DEFAULT_ENABLE_BACKING_STORE = true;
       protected static int WORKING_BUFFER_SIZE = 8192;
   
  -    protected byte cache[] = null;
  -    protected int cache_fp = 0;
  -    protected double cache_increment = DEFAULT_CACHE_INCREMENT;
  +    protected org.apache.axis.utils.ByteArrayOutputStream cache = null;
  +
       protected int max_size = 0;
       protected File bs_handle = null;
       protected OutputStream bs_stream = null;
  @@ -49,65 +48,63 @@
       protected boolean enableBackingStore = DEFAULT_ENABLE_BACKING_STORE;
   
       public boolean isEnableBackingStore() {
  -      return enableBackingStore;
  +        return enableBackingStore;
       }
   
       public void setEnableBackingStore(boolean enableBackingStore) {
  -      this.enableBackingStore = enableBackingStore;
  +        this.enableBackingStore = enableBackingStore;
       }
   
       public static boolean isDEFAULT_ENABLE_BACKING_STORE() {
  -      return DEFAULT_ENABLE_BACKING_STORE;
  +        return DEFAULT_ENABLE_BACKING_STORE;
       }
   
  -    public static void setDEFAULT_ENABLE_BACKING_STORE(boolean DEFAULT_ENABLE_BACKING_STORE) {
  -      ByteArray.DEFAULT_ENABLE_BACKING_STORE = DEFAULT_ENABLE_BACKING_STORE;
  +    public static void setDEFAULT_ENABLE_BACKING_STORE(
  +            boolean DEFAULT_ENABLE_BACKING_STORE) {
  +        ByteArray.DEFAULT_ENABLE_BACKING_STORE = DEFAULT_ENABLE_BACKING_STORE;
       }
   
       public static int getDEFAULT_RESIDENT_SIZE() {
  -      return DEFAULT_RESIDENT_SIZE;
  +        return DEFAULT_RESIDENT_SIZE;
       }
   
       public static void setDEFAULT_RESIDENT_SIZE(int DEFAULT_RESIDENT_SIZE) {
  -      ByteArray.DEFAULT_RESIDENT_SIZE = DEFAULT_RESIDENT_SIZE;
  +        ByteArray.DEFAULT_RESIDENT_SIZE = DEFAULT_RESIDENT_SIZE;
       }
   
       public static double getDEFAULT_CACHE_INCREMENT() {
  -      return DEFAULT_CACHE_INCREMENT;
  +        return DEFAULT_CACHE_INCREMENT;
       }
   
  -    public static void setDEFAULT_CACHE_INCREMENT(double DEFAULT_CACHE_INCREMENT) {
  -      ByteArray.DEFAULT_CACHE_INCREMENT = DEFAULT_CACHE_INCREMENT;
  +    public static void setDEFAULT_CACHE_INCREMENT(
  +            double DEFAULT_CACHE_INCREMENT) {
  +        ByteArray.DEFAULT_CACHE_INCREMENT = DEFAULT_CACHE_INCREMENT;
       }
   
  -
  -
       static {
  -      String value;
  -
  -      value = AxisProperties.getProperty(AxisEngine.PROP_BYTE_BUFFER_CACHE_INCREMENT,
  -                                                ""+DEFAULT_CACHE_INCREMENT);
  -      DEFAULT_CACHE_INCREMENT=Double.parseDouble(value);
  -
  -      value = AxisProperties.getProperty(AxisEngine.PROP_BYTE_BUFFER_RESIDENT_MAX_SIZE,
  -                                                ""+DEFAULT_RESIDENT_SIZE);
  -      DEFAULT_RESIDENT_SIZE=Integer.parseInt(value);
  -
  -      value = AxisProperties.getProperty(AxisEngine.PROP_BYTE_BUFFER_WORK_BUFFER_SIZE,
  -                                                ""+WORKING_BUFFER_SIZE);
  -      WORKING_BUFFER_SIZE=Integer.parseInt(value);
  -
  -      value = AxisProperties.getProperty(AxisEngine.PROP_BYTE_BUFFER_BACKING,
  -                                                ""+DEFAULT_ENABLE_BACKING_STORE);
  -      if (value.equalsIgnoreCase("true") ||
  -          value.equals("1") ||
  -          value.equalsIgnoreCase("yes") )
  -      {
  -        DEFAULT_ENABLE_BACKING_STORE=true;
  -      }
  -      else {
  -        DEFAULT_ENABLE_BACKING_STORE=false;
  -      }
  +        String value;
  +        value = AxisProperties.getProperty(
  +                AxisEngine.PROP_BYTE_BUFFER_CACHE_INCREMENT,
  +                "" + DEFAULT_CACHE_INCREMENT);
  +        DEFAULT_CACHE_INCREMENT = Double.parseDouble(value);
  +        value = AxisProperties.getProperty(
  +                AxisEngine.PROP_BYTE_BUFFER_RESIDENT_MAX_SIZE,
  +                "" + DEFAULT_RESIDENT_SIZE);
  +        DEFAULT_RESIDENT_SIZE = Integer.parseInt(value);
  +        value = AxisProperties.getProperty(
  +                AxisEngine.PROP_BYTE_BUFFER_WORK_BUFFER_SIZE,
  +                "" + WORKING_BUFFER_SIZE);
  +        WORKING_BUFFER_SIZE = Integer.parseInt(value);
  +        value =
  +                AxisProperties.getProperty(AxisEngine.PROP_BYTE_BUFFER_BACKING,
  +                        "" + DEFAULT_ENABLE_BACKING_STORE);
  +        if (value.equalsIgnoreCase("true") ||
  +                value.equals("1") ||
  +                value.equalsIgnoreCase("yes")) {
  +            DEFAULT_ENABLE_BACKING_STORE = true;
  +        } else {
  +            DEFAULT_ENABLE_BACKING_STORE = false;
  +        }
       }
   
       /**
  @@ -119,8 +116,8 @@
   
       /**
        * Constructor ByteArray
  -     * 
  -     * @param max_resident_size 
  +     *
  +     * @param max_resident_size
        */
       public ByteArray(int max_resident_size) {
           this(0, max_resident_size);
  @@ -128,9 +125,9 @@
   
       /**
        * Constructor ByteArray
  -     * 
  -     * @param probable_size     
  -     * @param max_resident_size 
  +     *
  +     * @param probable_size
  +     * @param max_resident_size
        */
       public ByteArray(int probable_size, int max_resident_size) {
           if (probable_size > max_resident_size) {
  @@ -139,15 +136,15 @@
           if (probable_size < WORKING_BUFFER_SIZE) {
               probable_size = WORKING_BUFFER_SIZE;
           }
  -        cache = new byte[probable_size];
  +        cache = new org.apache.axis.utils.ByteArrayOutputStream(probable_size);
           max_size = max_resident_size;
       }
   
       /**
        * Method write
  -     * 
  -     * @param bytes 
  -     * @throws IOException 
  +     *
  +     * @param bytes
  +     * @throws IOException
        */
       public void write(byte bytes[]) throws IOException {
           count += bytes.length;
  @@ -156,11 +153,11 @@
   
       /**
        * Method write
  -     * 
  -     * @param bytes  
  -     * @param start  
  -     * @param length 
  -     * @throws IOException 
  +     *
  +     * @param bytes
  +     * @param start
  +     * @param length
  +     * @throws IOException
        */
       public void write(byte bytes[], int start, int length) throws IOException {
           count += length;
  @@ -168,21 +165,19 @@
               increaseCapacity(length);
           }
           if (cache != null) {
  -            System.arraycopy(bytes, start, cache, cache_fp, length);
  -            cache_fp += length;
  -        } else if (bs_stream!=null) {
  +            cache.write(bytes, start, length);
  +        } else if (bs_stream != null) {
               bs_stream.write(bytes, start, length);
  -        }
  -        else {
  -          throw new IOException("ByteArray does not have a backing store!");
  +        } else {
  +            throw new IOException("ByteArray does not have a backing store!");
           }
       }
   
       /**
        * Method write
  -     * 
  -     * @param b 
  -     * @throws IOException 
  +     *
  +     * @param b
  +     * @throws IOException
        */
       public void write(int b) throws IOException {
           count += 1;
  @@ -190,19 +185,18 @@
               increaseCapacity(1);
           }
           if (cache != null) {
  -            cache[cache_fp++] = (byte) b;
  -        } else if (bs_stream!=null) {
  +            cache.write(b);
  +        } else if (bs_stream != null) {
               bs_stream.write(b);
  -        }
  -        else {
  -          throw new IOException("ByteArray does not have a backing store!");
  +        } else {
  +            throw new IOException("ByteArray does not have a backing store!");
           }
       }
   
       /**
        * Method close
  -     * 
  -     * @throws IOException 
  +     *
  +     * @throws IOException
        */
       public void close() throws IOException {
           if (bs_stream != null) {
  @@ -213,8 +207,8 @@
   
       /**
        * Method size
  -     * 
  -     * @return 
  +     *
  +     * @return
        */
       public long size() {
           return count;
  @@ -222,8 +216,8 @@
   
       /**
        * Method flush
  -     * 
  -     * @throws IOException 
  +     *
  +     * @throws IOException
        */
       public void flush() throws IOException {
           if (bs_stream != null) {
  @@ -233,59 +227,22 @@
   
       /**
        * Method increaseCapacity
  -     * 
  -     * @param count 
  -     * @throws IOException 
  +     *
  +     * @param count
  +     * @throws IOException
        */
       protected void increaseCapacity(int count) throws IOException {
           if (cache == null) {
               return;
           }
  -        int new_fp = cache_fp + count;
  -        if (new_fp < cache.length) {
  +        if (count + cache.size() <= max_size) {
               return;
  -        }
  -
  -        if (new_fp < max_size) {
  -            grow(count);
  -        }
  -        else if (enableBackingStore) {
  +        } else if (enableBackingStore) {
               switchToBackingStore();
  -        }
  -        else {
  -            throw new IOException("ByteArray can not increase capacity by "+count+
  -                " due to max size limit of "+max_size);
  -        }
  -    }
  -
  -    /**
  -     * Method growMemCache
  -     * 
  -     * @param count 
  -     * @throws IOException 
  -     */
  -    protected void grow(int count) throws IOException {
  -        int new_fp = cache_fp + count;
  -        int new_size = (int) (cache.length * cache_increment);
  -        if (new_size < cache_fp + WORKING_BUFFER_SIZE) {
  -            new_size = cache_fp + WORKING_BUFFER_SIZE;
  -        }
  -        if (new_size < new_fp) {
  -            new_size = new_fp;
  -        }
  -        try {
  -            byte new_mem_cache[] = new byte[new_size];
  -            System.arraycopy(cache, 0, new_mem_cache, 0, cache_fp);
  -            cache = new_mem_cache;
  -        } catch (OutOfMemoryError e) {
  -            // Couldn't allocate a new, bigger vector!
  -            // That's fine, we'll just switch to backing-store mode.
  -            if (enableBackingStore) {
  -              switchToBackingStore();
  -            }
  -            else {
  -              throw new IOException("ByteArray exhausted memory: "+e.getMessage());
  -            }
  +        } else {
  +            throw new IOException("ByteArray can not increase capacity by " +
  +                    count +
  +                    " due to max size limit of " + max_size);
           }
       }
   
  @@ -294,7 +251,6 @@
        */
       public synchronized void discardBuffer() {
           cache = null;
  -        cache_fp = 0;
           if (bs_stream != null) {
               try {
                   bs_stream.close();
  @@ -308,18 +264,16 @@
   
       /**
        * Method makeInputStream
  -     * 
  -     * @return 
  -     * @throws IOException           
  -     * @throws FileNotFoundException 
  +     *
  +     * @return
  +     * @throws IOException
  +     * @throws FileNotFoundException
        */
       protected InputStream makeInputStream()
               throws IOException, FileNotFoundException {
           close();
           if (cache != null) {
  -            byte[] v = cache;
  -            int fp = cache_fp;
  -            return new ByteArrayInputStream(v, 0, fp);
  +            return new ByteArrayInputStream(cache.toByteArray());
           } else if (bs_handle != null) {
               return createBackingStoreInputStream();
           } else {
  @@ -336,34 +290,30 @@
   
       /**
        * Method switchToBackingStore
  -     * 
  -     * @throws IOException 
  +     *
  +     * @throws IOException
        */
       protected void switchToBackingStore() throws IOException {
           bs_handle = File.createTempFile("Axis", ".msg");
           bs_handle.createNewFile();
           bs_handle.deleteOnExit();
           bs_stream = new FileOutputStream(bs_handle);
  -        if (cache_fp > 0) {
  -            bs_stream.write(cache, 0, cache_fp);
  -        }
  +        bs_stream.write(cache.toByteArray());
           cache = null;
  -        cache_fp = 0;
       }
   
  -
  -  /**
  -   *  Method getBackingStoreFileName
  -   *
  -   * @throws IOException
  -   */
  -  public String getBackingStoreFileName() throws IOException {
  -    String fileName = null;
  -    if (bs_handle!=null) {
  -      fileName=bs_handle.getCanonicalPath();
  +    /**
  +     * Method getBackingStoreFileName
  +     *
  +     * @throws IOException
  +     */
  +    public String getBackingStoreFileName() throws IOException {
  +        String fileName = null;
  +        if (bs_handle != null) {
  +            fileName = bs_handle.getCanonicalPath();
  +        }
  +        return fileName;
       }
  -    return fileName;
  -  }
   
       /**
        * Method discardBackingStore
  @@ -377,9 +327,9 @@
   
       /**
        * Method createBackingStoreInputStream
  -     * 
  -     * @return 
  -     * @throws FileNotFoundException 
  +     *
  +     * @return
  +     * @throws FileNotFoundException
        */
       protected InputStream createBackingStoreInputStream()
               throws FileNotFoundException {
  @@ -393,9 +343,9 @@
   
       /**
        * Method toByteArray
  -     * 
  -     * @return 
  -     * @throws IOException 
  +     *
  +     * @return
  +     * @throws IOException
        */
       public byte[] toByteArray() throws IOException {
           InputStream inp = this.makeInputStream();
  @@ -413,9 +363,9 @@
   
       /**
        * Method writeTo
  -     * 
  -     * @param os 
  -     * @throws IOException 
  +     *
  +     * @param os
  +     * @throws IOException
        */
       public void writeTo(OutputStream os) throws IOException {
           InputStream inp = this.makeInputStream();
  
  
  
  1.1                  ws-axis/java/src/org/apache/axis/utils/ByteArrayOutputStream.java
  
  Index: ByteArrayOutputStream.java
  ===================================================================
  /*
   * Copyright 2003,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.axis.utils;
  
  import java.io.IOException;
  import java.io.OutputStream;
  import java.io.UnsupportedEncodingException;
  import java.util.List;
  
  /**
   * This class implements an output stream in which the data is
   * written into a byte array. The buffer automatically grows as data
   * is written to it.
   * <p/>
   * The data can be retrieved using <code>toByteArray()</code> and
   * <code>toString()</code>.
   * <p/>
   * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
   * this class can be called after the stream has been closed without
   * generating an <tt>IOException</tt>.
   * <p/>
   * This is an alternative implementation of the java.io.ByteArrayOutputStream
   * class. The original implementation only allocates 32 bytes at the beginning.
   * As this class is designed for heavy duty it starts at 1024 bytes. In contrast
   * to the original it doesn't reallocate the whole memory block but allocates
   * additional buffers. This way no buffers need to be garbage collected and
   * the contents don't have to be copied to the new buffer. This class is
   * designed to behave exactly like the original. The only exception is the
   * deprecated toString(int) method that has been ignored.
   *
   * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
   * @version $Id: ByteArrayOutputStream.java,v 1.1 2004/07/19 16:54:58 dims Exp $
   */
  public class ByteArrayOutputStream extends OutputStream {
  
      private List buffers = new java.util.ArrayList();
      private int currentBufferIndex;
      private int filledBufferSum;
      private byte[] currentBuffer;
      private int count;
  
      /**
       * Creates a new byte array output stream. The buffer capacity is
       * initially 1024 bytes, though its size increases if necessary.
       */
      public ByteArrayOutputStream() {
          this(1024);
      }
  
      /**
       * Creates a new byte array output stream, with a buffer capacity of
       * the specified size, in bytes.
       *
       * @param size the initial size.
       * @throws IllegalArgumentException if size is negative.
       */
      public ByteArrayOutputStream(int size) {
          if (size < 0) {
              throw new IllegalArgumentException(
                      Messages.getMessage("illegalArgumentException01",
                              Integer.toString(size)));
          }
          needNewBuffer(size);
      }
  
      private byte[] getBuffer(int index) {
          return (byte[]) buffers.get(index);
      }
  
      private void needNewBuffer(int newcount) {
          if (currentBufferIndex < buffers.size() - 1) {
              //Recycling old buffer
              filledBufferSum += currentBuffer.length;
              currentBufferIndex++;
              currentBuffer = getBuffer(currentBufferIndex);
          } else {
              //Creating new buffer
              int newBufferSize;
              if (currentBuffer == null) {
                  newBufferSize = newcount;
                  filledBufferSum = 0;
              } else {
                  newBufferSize = Math.max(currentBuffer.length << 1,
                          newcount - filledBufferSum);
                  filledBufferSum += currentBuffer.length;
              }
              currentBufferIndex++;
              currentBuffer = new byte[newBufferSize];
              buffers.add(currentBuffer);
          }
      }
  
      /**
       * @see java.io.OutputStream#write(byte[], int, int)
       */
      public synchronized void write(byte[] b, int off, int len) {
          if ((off < 0)
                  || (off > b.length)
                  || (len < 0)
                  || ((off + len) > b.length)
                  || ((off + len) < 0)) {
              throw new IndexOutOfBoundsException(
                      Messages.getMessage("indexOutOfBoundsException00"));
          } else if (len == 0) {
              return;
          }
          int newcount = count + len;
          int remaining = len;
          int inBufferPos = count - filledBufferSum;
          while (remaining > 0) {
              int part = Math.min(remaining, currentBuffer.length - inBufferPos);
              System.arraycopy(b, off + len - remaining, currentBuffer,
                      inBufferPos, part);
              remaining -= part;
              if (remaining > 0) {
                  needNewBuffer(newcount);
                  inBufferPos = 0;
              }
          }
          count = newcount;
      }
  
      /**
       * Calls the write(byte[]) method.
       *
       * @see java.io.OutputStream#write(int)
       */
      public synchronized void write(int b) {
          write(new byte[]{(byte) b}, 0, 1);
      }
  
      /**
       * @see java.io.ByteArrayOutputStream#size()
       */
      public int size() {
          return count;
      }
  
      /**
       * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
       * this class can be called after the stream has been closed without
       * generating an <tt>IOException</tt>.
       *
       * @throws IOException in case an I/O error occurs
       */
      public void close() throws IOException {
          //nop
      }
  
      /**
       * @see java.io.ByteArrayOutputStream#reset()
       */
      public synchronized void reset() {
          count = 0;
          filledBufferSum = 0;
          currentBufferIndex = 0;
          currentBuffer = getBuffer(currentBufferIndex);
      }
  
      /**
       * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
       */
      public synchronized void writeTo(OutputStream out) throws IOException {
          int remaining = count;
          for (int i = 0; i < buffers.size(); i++) {
              byte[] buf = getBuffer(i);
              int c = Math.min(buf.length, remaining);
              out.write(buf, 0, c);
              remaining -= c;
              if (remaining == 0) {
                  break;
              }
          }
      }
  
      /**
       * @see java.io.ByteArrayOutputStream#toByteArray()
       */
      public synchronized byte toByteArray()[] {
          int remaining = count;
          int pos = 0;
          byte newbuf[] = new byte[count];
          for (int i = 0; i < buffers.size(); i++) {
              byte[] buf = getBuffer(i);
              int c = Math.min(buf.length, remaining);
              System.arraycopy(buf, 0, newbuf, pos, c);
              pos += c;
              remaining -= c;
              if (remaining == 0) {
                  break;
              }
          }
          return newbuf;
      }
  
      /**
       * @see java.io.ByteArrayOutputStream#toString()
       */
      public String toString() {
          return new String(toByteArray());
      }
  
      /**
       * @see java.io.ByteArrayOutputStream#toString(String)
       */
      public String toString(String enc) throws UnsupportedEncodingException {
          return new String(toByteArray(), enc);
      }
  
  }