View Javadoc
1 /* Reattore HTTP Server 2 3 Copyright (C) 2002 Michael Hope <michaelh@juju.net.nz> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 $Id: ByteSourceSink.java,v 1.6 2003/02/17 04:17:27 michaelh Exp $ 20 */ 21 22 package juju.reattore.io.impl; 23 24 import juju.reattore.io.*; 25 26 /*** Buffer that may be used for temporary storage and which is backed 27 by a byte array. Used for storing an incomming stream for later use. 28 Concurrent read/write access is unpredictable. Concurrent read access 29 shares the same stream position and marks. 30 */ 31 public class ByteSourceSink 32 implements ByteSource, ByteSink, Comparable { 33 34 private static final int MIN_GROWTH = 128; 35 private static final int MAX_GROWTH = 4096; 36 37 private int markPos; 38 private int readPos; 39 private int writePos; 40 41 private byte[] buf = new byte[MIN_GROWTH]; 42 43 /*** Creates a new, empty source/sink */ 44 public ByteSourceSink() { 45 } 46 47 /*** Creates a new source/sink and populates it. Inefficient. For 48 convenience only. 49 50 @param initial Initial data to populate the source with. 51 */ 52 public ByteSourceSink(byte[] initial) { 53 put(initial, 0, initial.length); 54 } 55 56 /*** @see Source */ 57 public void mark() { 58 markPos = readPos; 59 } 60 61 /*** @see Source */ 62 public void reset() { 63 readPos = markPos; 64 } 65 66 /*** @see Source */ 67 public void rewind() { 68 readPos = 0; 69 } 70 71 /*** @see ByteSource */ 72 public int get() { 73 if (readPos < writePos) { 74 return buf[readPos++]; 75 } 76 else { 77 return EOF; 78 } 79 } 80 81 /*** @see ByteSource */ 82 public int get(byte[] into, int offset, int length) { 83 if (length > remaining()) { 84 length = remaining(); 85 } 86 87 assert (offset + length) <= into.length; 88 System.arraycopy(buf, readPos, into, offset, length); 89 readPos += length; 90 91 return length; 92 } 93 94 /*** @see ByteSource */ 95 public int remaining() { 96 return writePos - readPos; 97 } 98 99 /*** Grows the buffer so that it can hold atleast the given number 100 of bytes. 101 */ 102 private void grow(int toHold) { 103 if ((buf.length - writePos) > toHold) { 104 /* Have the space already */ 105 } 106 else { 107 /* We grow exponentially with fixed upper and lower 108 growths */ 109 int newSize = buf.length * 2; 110 newSize = newSize < MIN_GROWTH ? MIN_GROWTH : newSize; 111 newSize = newSize > MAX_GROWTH ? MAX_GROWTH : newSize; 112 newSize = newSize < toHold ? toHold : newSize; 113 114 byte[] newBuf = new byte[newSize]; 115 System.arraycopy(buf, 0, newBuf, 0, writePos); 116 117 buf = newBuf; 118 } 119 } 120 121 /*** @see ByteSink */ 122 public void put(int toWrite) { 123 grow(1); 124 buf[writePos++] = (byte)toWrite; 125 } 126 127 /*** @see ByteSink */ 128 public void put(byte[] from, int offset, int length) { 129 assert (offset + length) <= from.length; 130 grow(length); 131 System.arraycopy(from, offset, buf, writePos, length); 132 writePos += length; 133 } 134 135 /*** @see ByteSink */ 136 public int size() { 137 return writePos; 138 } 139 140 /*** Compacts the backing buffer to comtain just the data. 141 */ 142 public void compact() { 143 if (writePos != buf.length) { 144 byte[] newBuf = new byte[writePos]; 145 System.arraycopy(buf, 0, newBuf, 0, writePos); 146 buf = newBuf; 147 } 148 else { 149 /* Already compacted */ 150 } 151 } 152 153 /*** Returns the array backing this source/sink. 154 155 @return The backing array. 156 */ 157 public byte[] array() { 158 return buf; 159 } 160 161 /*** Compares this stream to a byte array. ByteSourceSink. 162 Primarialy used for equivalence tests in the test libs. 163 164 This instance is equivalent to a byte array if it contains the 165 same number of bytes and if every byte is the same. 166 167 @see Object#compareTo 168 */ 169 public int compareTo(Object ob) { 170 if (ob instanceof byte[]) { 171 return compare((byte[])ob); 172 } 173 else { 174 throw new ClassCastException("Can only compare with byte[]"); 175 } 176 } 177 178 private int compare(byte[] ab) { 179 if (ab.length == writePos) { 180 for (int i = 0; i < writePos; i++) { 181 int diff = buf[i] - ab[i]; 182 if (diff != 0) { 183 return diff; 184 } 185 } 186 return 0; 187 } 188 else { 189 /* Wrong length. Comparison on length. */ 190 return writePos - ab.length; 191 } 192 } 193 194 /*** @see Source */ 195 public void dispose() { 196 /* Do nothing */ 197 } 198 }

This page was automatically generated by Maven