1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23 package com.sun.org.apache.xml.internal.security.utils; 24 25 import java.io.IOException; 26 import java.io.OutputStream; 27 28 /** 29 * A simple Unsynced ByteArrayOutputStream 30 * 31 */ 32 public class UnsyncByteArrayOutputStream extends OutputStream { 33 34 // Maximum array size. Using same value as ArrayList in OpenJDK. 35 // Integer.MAX_VALUE doesn't work on some VMs, as some header values are reserved 36 private static final int VM_ARRAY_INDEX_MAX_VALUE = Integer.MAX_VALUE - 8; 37 private static final int INITIAL_SIZE = 8192; 38 39 private byte[] buf; 40 private int size = INITIAL_SIZE; 41 private int pos; 42 UnsyncByteArrayOutputStream()43 public UnsyncByteArrayOutputStream() { 44 buf = new byte[INITIAL_SIZE]; 45 } 46 write(byte[] arg0)47 public void write(byte[] arg0) { 48 if ((VM_ARRAY_INDEX_MAX_VALUE - pos) < arg0.length) { 49 throw new OutOfMemoryError("Required length exceeds implementation limit"); 50 } 51 int newPos = pos + arg0.length; 52 if (newPos > size) { 53 expandSize(newPos); 54 } 55 System.arraycopy(arg0, 0, buf, pos, arg0.length); 56 pos = newPos; 57 } 58 write(byte[] arg0, int arg1, int arg2)59 public void write(byte[] arg0, int arg1, int arg2) { 60 if ((VM_ARRAY_INDEX_MAX_VALUE - pos) < arg2) { 61 throw new OutOfMemoryError("Required length exceeds implementation limit"); 62 } 63 int newPos = pos + arg2; 64 if (newPos > size) { 65 expandSize(newPos); 66 } 67 System.arraycopy(arg0, arg1, buf, pos, arg2); 68 pos = newPos; 69 } 70 write(int arg0)71 public void write(int arg0) { 72 if (VM_ARRAY_INDEX_MAX_VALUE - pos == 0) { 73 throw new OutOfMemoryError("Required length exceeds implementation limit"); 74 } 75 int newPos = pos + 1; 76 if (newPos > size) { 77 expandSize(newPos); 78 } 79 buf[pos++] = (byte)arg0; 80 } 81 toByteArray()82 public byte[] toByteArray() { 83 byte result[] = new byte[pos]; 84 System.arraycopy(buf, 0, result, 0, pos); 85 return result; 86 } 87 reset()88 public void reset() { 89 pos = 0; 90 } 91 92 /** 93 * Takes the contents of this stream and writes it to the output stream 94 * {@code out}. 95 * 96 * @param out 97 * an OutputStream on which to write the contents of this stream. 98 * @throws IOException 99 * if an error occurs while writing to {@code out}. 100 */ writeTo(OutputStream out)101 public void writeTo(OutputStream out) throws IOException { 102 out.write(buf, 0, pos); 103 } 104 expandSize(int newPos)105 private void expandSize(int newPos) { 106 int newSize = size; 107 while (newPos > newSize) { 108 newSize = newSize << 1; 109 // Deal with overflow 110 if (newSize < 0) { 111 newSize = VM_ARRAY_INDEX_MAX_VALUE; 112 } 113 } 114 byte newBuf[] = new byte[newSize]; 115 System.arraycopy(buf, 0, newBuf, 0, pos); 116 buf = newBuf; 117 size = newSize; 118 } 119 } 120