1 57 58 package org.enhydra.apache.xerces.utils; 59 60 import java.io.IOException ; 61 import java.io.InputStream ; 62 63 87 public final class ChunkyByteArray extends InputStream { 88 89 96 public ChunkyByteArray(InputStream is) throws IOException { 97 fInputStream = is; 98 fill(); 99 } 100 101 106 public int read() throws IOException { 107 if (fData == null) 108 return fInputStream == null ? -1 : fInputStream.read(); 109 int b = (int)(fData[0][fOffset]); 110 if (++fOffset == fLength) { 111 fData = null; 112 if (fLength < CHUNK_SIZE) 113 fInputStream = null; 114 } 115 return b; 116 } 117 118 128 public int read(byte buffer[], int offset, int length) throws IOException { 129 int bytesLeft = fLength - fOffset; 130 if (bytesLeft == 0) 131 return fInputStream == null ? -1 : fInputStream.read(buffer, offset, length); 132 if (length <= 0) 133 return 0; 134 byte[] chunk = fData[0]; 135 if (length >= bytesLeft) { 136 length = bytesLeft; 137 if (fLength < CHUNK_SIZE) 138 fInputStream = null; 139 } 140 if (buffer == null) { 141 fOffset += length; 142 return length; 143 } 144 int stop = offset + length; 145 do { 146 buffer[offset++] = chunk[fOffset++]; 147 } while (offset < stop); 148 return length; 149 } 150 151 155 public void rewind() { 156 fOffset = 0; 157 } 158 159 165 public byte byteAt(int offset) throws IOException { 166 int chunk = offset >> CHUNK_SHIFT; 167 int index = offset & CHUNK_MASK; 168 try { 169 return fData[chunk][index]; 170 } catch (NullPointerException ex) { 171 } catch (ArrayIndexOutOfBoundsException e) { 173 byte newdata[][] = new byte[fData.length * 2][]; 175 System.arraycopy(fData, 0, newdata, 0, fData.length); 176 fData = newdata; 177 } 178 if (index == 0) { 179 fill(); 180 return fData[chunk][index]; 181 } 182 return 0; 183 } 184 185 192 public boolean atEOF(int offset) { 193 return(offset > fLength); 194 } 195 196 197 198 203 public void close() throws IOException { 204 if ( fInputStream != null ) { 205 fInputStream.close(); 206 fInputStream = null; } 208 } 209 210 211 private void fill() throws IOException { 215 int bufnum = fLength >> CHUNK_SHIFT; 216 byte[] data = new byte[CHUNK_SIZE]; 217 fData[bufnum] = data; 218 int offset = 0; 219 int capacity = CHUNK_SIZE; 220 int result = 0; 221 do { 222 result = fInputStream.read(data, offset, capacity); 223 if (result == -1) { 224 data[offset] = (byte)0xff; 225 fInputStream.close(); 226 fInputStream = null; 227 break; 228 } 229 if (result > 0) { 230 fLength += result; 231 offset += result; 232 capacity -= result; 233 } 234 } while (capacity > 0); 235 } 236 private static final int CHUNK_SHIFT = 14; private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT); 241 private static final int CHUNK_MASK = CHUNK_SIZE - 1; 242 private static final int INITIAL_CHUNK_COUNT = (1 << (20 - CHUNK_SHIFT)); private InputStream fInputStream = null; 247 private byte[][] fData = new byte[INITIAL_CHUNK_COUNT][]; 248 private int fLength = 0; 249 private int fOffset = 0; } 251 | Popular Tags |