1 /*
   2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.messaging.saaj.util;
  27 
  28 import java.io.BufferedOutputStream;
  29 import java.io.IOException;
  30 import java.io.OutputStream;
  31 import java.io.InputStream;
  32 import java.io.ByteArrayInputStream;
  33 
  34 /**
  35  * Customized {@link BufferedOutputStream}.
  36  *
  37  * <p>
  38  * Compared to {@link BufferedOutputStream},
  39  * this class:
  40  *
  41  * <ol>
  42  * <li>doesn't do synchronization
  43  * <li>allows access to the raw buffer
  44  * <li>almost no parameter check
  45  */
  46 public final class ByteOutputStream extends OutputStream {
  47     /**
  48      * The buffer where data is stored.
  49      */
  50     protected byte[] buf;
  51 
  52     /**
  53      * The number of valid bytes in the buffer.
  54      */
  55     protected int count = 0;
  56 
  57     public ByteOutputStream() {
  58         this(1024);
  59     }
  60 
  61     public ByteOutputStream(int size) {
  62         buf = new byte[size];
  63     }
  64 
  65     /**
  66      * Copies all the bytes from this input into this buffer.
  67      */
  68     public void write(InputStream in) throws IOException {
  69         if (in instanceof ByteArrayInputStream) {
  70             int size = in.available();
  71             ensureCapacity(size);
  72             count += in.read(buf,count,size);
  73             return;
  74         }
  75         while(true) {
  76             int cap = buf.length-count;
  77             int sz = in.read(buf,count,cap);
  78             if(sz<0)    return;     // hit EOS
  79 
  80             count += sz;
  81             if(cap==sz)
  82                 // the buffer filled up. double the buffer
  83                 ensureCapacity(count);
  84         }
  85     }
  86 
  87     public void write(int b) {
  88         ensureCapacity(1);
  89         buf[count] = (byte) b;
  90         count++;
  91     }
  92 
  93     /**
  94      * Ensure that the buffer has at least this much space.
  95      */
  96     private void ensureCapacity(int space) {
  97         int newcount = space + count;
  98         if (newcount > buf.length) {
  99             byte[] newbuf = new byte[Math.max(buf.length << 1, newcount)];
 100             System.arraycopy(buf, 0, newbuf, 0, count);
 101             buf = newbuf;
 102         }
 103     }
 104 
 105     public void write(byte[] b, int off, int len) {
 106         ensureCapacity(len);
 107         System.arraycopy(b, off, buf, count, len);
 108         count += len;
 109     }
 110 
 111     public void write(byte[] b) {
 112         write(b, 0, b.length);
 113     }
 114 
 115     /**
 116      * Writes a string as ASCII string.
 117      */
 118     public void writeAsAscii(String s) {
 119         int len = s.length();
 120 
 121         ensureCapacity(len);
 122 
 123         int ptr = count;
 124         for( int i=0; i<len; i++ )
 125             buf[ptr++] = (byte)s.charAt(i);
 126         count = ptr;
 127     }
 128 
 129     public void writeTo(OutputStream out) throws IOException {
 130         out.write(buf, 0, count);
 131     }
 132 
 133     public void reset() {
 134         count = 0;
 135     }
 136 
 137     /**
 138      * Evil buffer reallocation method.
 139      * Don't use it unless you absolutely have to.
 140      *
 141      * @deprecated
 142      *      because this is evil!
 143      */
 144     public byte toByteArray()[] {
 145         byte[] newbuf = new byte[count];
 146         System.arraycopy(buf, 0, newbuf, 0, count);
 147         return newbuf;
 148     }
 149 
 150     public int size() {
 151         return count;
 152     }
 153 
 154     public ByteInputStream newInputStream() {
 155         return new ByteInputStream(buf,count);
 156     }
 157 
 158     /**
 159      * Converts the buffer's contents into a string, translating bytes into
 160      * characters according to the platform's default character encoding.
 161      *
 162      * @return String translated from the buffer's contents.
 163      * @since JDK1.1
 164      */
 165     public String toString() {
 166         return new String(buf, 0, count);
 167     }
 168 
 169     public void close() {
 170     }
 171 
 172     public byte[] getBytes() {
 173         return buf;
 174     }
 175 
 176 
 177     public int getCount() {
 178         return count;
 179     }
 180 }