1 9 package org.jboss.portal.setup.util; 10 11 import java.io.IOException ; 12 import java.io.InputStream ; 13 import java.io.OutputStream ; 14 import java.io.UnsupportedEncodingException ; 15 import java.nio.ByteBuffer ; 16 import java.util.ArrayList ; 17 import java.util.List ; 18 19 33 public class GrowableByteBuffer 34 { 35 36 39 private List m_bufferList = null; 40 41 44 private int m_bufferIndex = 0; 45 46 49 private boolean m_isReadable = false; 50 51 54 private boolean m_closed = false; 55 56 59 private int m_bytesWritten = 0; 60 61 64 private int m_maximumBytes = -1; 65 66 69 private int m_bufferSize = DEFAULT_BUFFER_SIZE; 70 71 74 private static final int DEFAULT_BUFFER_SIZE = 32 * 1000; 75 76 77 81 public GrowableByteBuffer() 82 { 83 m_bufferList = new ArrayList (); 84 85 addBuffer(); 86 } 87 88 95 public GrowableByteBuffer(int bufferSize) 96 { 97 m_bufferList = new ArrayList (); 98 m_bufferSize = bufferSize; 99 100 addBuffer(); 101 } 102 103 112 public GrowableByteBuffer(int bufferSize, int maximumBytes) 113 { 114 m_bufferList = new ArrayList (); 115 m_bufferSize = bufferSize; 116 m_maximumBytes = maximumBytes; 117 118 addBuffer(); 119 } 120 121 124 public byte[] getBytes() throws IOException 125 { 126 if (!m_isReadable) 127 { 128 throw new IOException ("The buffer is not in a readable state"); 129 } 130 131 if (m_bytesWritten == 0) 132 { 133 return new byte[0]; 134 } 135 136 byte[] allBytes = new byte[m_bytesWritten]; 138 read(allBytes, 0, m_bytesWritten); 139 140 return allBytes; 141 } 142 143 144 157 public String toString(String encoding) 158 throws IOException , UnsupportedEncodingException 159 { 160 if (encoding == null) 161 { 162 throw new IllegalArgumentException ("Encoding cannot be null"); 163 } 164 165 byte[] allBytes = getBytes(); 167 168 return new String (allBytes, encoding); 169 170 } 171 172 public void write(byte b) throws IOException 173 { 174 if (m_isReadable || m_closed) 175 { 176 throw new IOException ("The OutputStream has already been closed"); 177 } 178 if (m_maximumBytes != -1 && (m_bytesWritten >= m_maximumBytes)) 179 { 180 throw new IOException ("The buffer is full"); 181 } 182 ByteBuffer currentBuffer = (ByteBuffer )m_bufferList.get(m_bufferIndex); 183 if (!currentBuffer.hasRemaining()) 184 { 185 currentBuffer = addBuffer(); 186 m_bufferIndex++; 187 } 188 m_bytesWritten++; 189 } 190 191 198 public void write(int b) 199 throws IOException 200 { 201 write((byte)(0xff & b)); 202 } 203 204 210 public void write(byte b[], int off, int len) 211 throws IOException 212 { 213 if (m_isReadable || m_closed) 214 { 215 throw new IOException ("The OutputStream has already been closed"); 216 } 217 218 if (m_maximumBytes != -1 && (m_bytesWritten + len >= m_maximumBytes)) 219 { 220 throw new IOException ("The buffer is full"); 221 } 222 223 ByteBuffer currentBuffer = (ByteBuffer )m_bufferList.get(m_bufferIndex); 224 225 int writeCount = 0; 226 int bOffset = off; 227 while (writeCount < len) 228 { 229 int remaining = currentBuffer.remaining(); 231 if (remaining > 0) 232 { 233 int currentLen = Math.min(remaining, len - writeCount); 235 currentBuffer.put(b, bOffset, currentLen); 236 writeCount += currentLen; 237 bOffset += currentLen; 238 239 continue; 240 } 241 242 currentBuffer = addBuffer(); 244 m_bufferIndex++; 245 } 246 247 m_bytesWritten += writeCount; 248 } 249 250 257 public int read() 258 throws IOException 259 { 260 if (m_closed) 261 { 262 throw new IOException ("The InputStream has already been closed"); 263 } 264 265 if (!m_isReadable) 266 { 267 throw new IOException ("The buffer is not in a readable state; close the OutputStream first"); 268 } 269 270 ByteBuffer currentBuffer = (ByteBuffer )m_bufferList.get(m_bufferIndex); 271 272 if (!currentBuffer.hasRemaining()) 274 { 275 if (m_bufferIndex == m_bufferList.size() - 1) 277 { 278 return -1; 279 } 280 281 m_bufferIndex++; 282 currentBuffer = (ByteBuffer )m_bufferList.get(m_bufferIndex); 283 currentBuffer.flip(); 284 } 285 286 if (currentBuffer.position() > currentBuffer.limit()) 288 { 289 throw new IOException ("position exceeded limit"); 290 } 291 292 return (int)currentBuffer.get(); 293 } 294 295 300 public int read(byte b[], int off, int len) 301 throws IOException 302 { 303 if (b == null) 304 { 305 throw new NullPointerException ("b argument is null"); 306 } 307 308 if (m_closed) 309 { 310 throw new IOException ("The InputStream has already been closed"); 311 } 312 313 if (!m_isReadable) 314 { 315 throw new IOException ("The buffer is not in a readable state; close the OutputStream first"); 316 } 317 318 ByteBuffer currentBuffer = (ByteBuffer )m_bufferList.get(m_bufferIndex); 319 320 int readCount = 0; 321 int bOffset = off; 322 while (readCount < len) 323 { 324 int remaining = currentBuffer.remaining(); 326 if (remaining > 0) 327 { 328 int currentLen = Math.min(remaining, len - readCount); 330 currentBuffer.get(b, bOffset, currentLen); 331 readCount += currentLen; 332 bOffset += currentLen; 333 334 continue; 335 } 336 337 if (m_bufferIndex == m_bufferList.size() - 1) 339 { 340 return (readCount == 0) ? -1 : readCount; 341 } 342 343 m_bufferIndex++; 345 currentBuffer = (ByteBuffer )m_bufferList.get(m_bufferIndex); 346 currentBuffer.flip(); 347 } 348 349 return (readCount == 0) ? -1 : readCount; 350 } 351 352 353 356 public void inputStreamClose() 357 { 358 m_closed = true; 359 } 360 363 public void flip() 364 { 365 if (m_isReadable) 366 { 367 throw new IllegalStateException ("The buffer has already been flipped into read mode"); 368 } 369 370 m_isReadable = true; 371 m_bufferIndex = 0; 372 373 ByteBuffer currentBuffer = (ByteBuffer )m_bufferList.get(m_bufferIndex); 374 currentBuffer.flip(); 375 } 376 377 378 379 382 383 385 private ByteBuffer addBuffer() 386 { 387 ByteBuffer buf = ByteBuffer.allocate(m_bufferSize); 388 m_bufferList.add(buf); 389 390 return buf; 391 } 392 393 394 395 } 396 | Popular Tags |