1 24 25 package com.mckoi.util; 26 27 import java.io.FilterInputStream ; 28 import java.io.IOException ; 29 import java.io.EOFException ; 30 import java.io.InputStream ; 31 32 40 41 public final class LengthMarkedBufferedInputStream extends FilterInputStream { 42 43 46 private static int INITIAL_BUFFER_SIZE = 512; 47 48 51 private InputStream in; 52 53 56 private byte[] buf; 57 58 61 private int count; 62 63 67 private int marked_length; 68 69 72 private int marked_index; 73 74 77 public LengthMarkedBufferedInputStream(InputStream in) { 78 super(in); 79 this.in = in; 80 buf = new byte[INITIAL_BUFFER_SIZE]; 81 count = 0; 82 marked_length = -1; 83 marked_index = -1; 84 } 85 86 90 private void ensureCapacity(int new_size) { 91 int old_size = buf.length; 92 if (new_size > old_size) { 93 int cap = (old_size * 3)/2 + 1; 94 if (cap < new_size) 95 cap = new_size; 96 byte[] old_buf = buf; 97 buf = new byte[cap]; 98 System.arraycopy(old_buf, 0, buf, 0, count - 0); 101 } 102 } 103 104 110 private void handleEndReached() { 111 System.arraycopy(buf, marked_index, buf, 0, count - marked_length); 117 count -= marked_length; 118 119 marked_length = -1; 121 marked_index = -1; 122 } 123 124 126 public synchronized int read() throws IOException { 127 if (marked_index == -1) { 128 throw new IOException ("No mark has been read yet."); 129 } 130 if (marked_index >= marked_length) { 131 String debug_msg = "Read over end of length marked buffer. "; 132 debug_msg += "(marked_index=" + marked_index; 133 debug_msg += ",marked_length=" + marked_length + ")"; 134 debug_msg += ")"; 135 throw new IOException (debug_msg); 136 } 137 int n = buf[marked_index++] & 0x0FF; 138 if (marked_index >= marked_length) { 139 handleEndReached(); 140 } 141 return n; 142 } 143 144 public synchronized int read(byte[] b, int off, int len) throws IOException { 145 if (marked_index == -1) { 146 throw new IOException ("No mark has been read yet."); 147 } 148 int read_upto = marked_index + len; 149 if (read_upto > marked_length) { 150 String debug_msg = "Read over end of length marked buffer. "; 151 debug_msg += "(marked_index=" + marked_index; 152 debug_msg += ",len=" + len; 153 debug_msg += ",marked_length=" + marked_length + ")"; 154 throw new IOException (debug_msg); 155 } 156 System.arraycopy(buf, marked_index, b, off, len); 157 marked_index = read_upto; 158 if (marked_index >= marked_length) { 159 handleEndReached(); 160 } 161 return len; 162 } 163 164 public synchronized int available() throws IOException { 165 if (marked_length >= 0) { 168 return (marked_length - marked_index); 169 } 170 return 0; 171 } 172 173 public boolean markSupported() { 174 return false; 175 } 176 177 179 189 public synchronized boolean pollForCommand(int max_size) throws IOException { 190 if (marked_length == -1) { 191 int available = in.available(); 192 if (count > 0 || available > 0) { 195 if ((count + available) > max_size) { 196 throw new IOException ("Marked length is greater than max size ( " + 197 (count + available) + " > " + max_size + " )"); 198 } 199 200 ensureCapacity(count + available); 201 int read_in = in.read(buf, count, available); 202 203 210 211 if (read_in == -1) { 212 throw new EOFException (); 213 } 214 count = count + read_in; 215 216 221 if (count >= 4) { 223 int length_marker = (((buf[0] & 0x0FF) << 24) + 224 ((buf[1] & 0x0FF) << 16) + 225 ((buf[2] & 0x0FF) << 8) + 226 ((buf[3] & 0x0FF) << 0)); 227 if (count >= length_marker + 4) { 228 marked_length = length_marker + 4; 231 marked_index = 4; 232 return true; 236 } 237 } 238 } 239 } 240 return false; 241 } 242 243 246 public synchronized void blockForCommand() throws IOException { 247 while (true) { 248 249 if (count >= 4) { 251 int length_marker = (((buf[0] & 0x0FF) << 24) + 252 ((buf[1] & 0x0FF) << 16) + 253 ((buf[2] & 0x0FF) << 8) + 254 ((buf[3] & 0x0FF) << 0)); 255 if (count >= length_marker + 4) { 256 marked_length = length_marker + 4; 259 marked_index = 4; 260 return; 263 } 264 } 265 266 if (count >= buf.length) { 268 ensureCapacity(count + INITIAL_BUFFER_SIZE); 269 } 270 int read_in = in.read(buf, count, buf.length - count); 272 if (read_in == -1) { 273 throw new EOFException (); 274 } 275 count += read_in; 276 } 277 } 278 279 } 280 | Popular Tags |