1 16 17 package org.apache.catalina.cluster.io; 18 19 import java.io.ByteArrayInputStream ; 20 import java.io.ByteArrayOutputStream ; 21 import java.util.zip.GZIPInputStream ; 22 import java.util.zip.GZIPOutputStream ; 23 24 42 public class XByteBuffer 43 { 44 45 public static org.apache.commons.logging.Log log = 46 org.apache.commons.logging.LogFactory.getLog( XByteBuffer.class ); 47 48 51 public static final byte[] START_DATA = {70,76,84,50,48,48,50}; 52 53 56 public static final byte[] END_DATA = {84,76,70,50,48,48,51}; 57 58 61 static final int DEF_SIZE = 1024; 62 63 66 static final int DEF_EXT = 1024; 67 68 71 protected byte[] buf = null; 72 73 76 protected int bufSize = 0; 77 78 81 protected boolean compress = true ; 82 83 87 public XByteBuffer(int size) { 88 buf = new byte[size]; 89 } 90 91 94 public XByteBuffer() { 95 this(DEF_SIZE); 96 } 97 98 102 public XByteBuffer(boolean compress) { 103 this(DEF_SIZE); 104 this.compress = compress ; 105 } 106 107 110 public byte[] getBytes() { 111 byte[] b = new byte[bufSize]; 112 System.arraycopy(buf,0,b,0,bufSize); 113 return b; 114 } 115 116 119 public void clear() { 120 bufSize = 0; 121 } 122 123 131 public boolean append(byte[] b, int off, int len) { 132 if ((off < 0) || (off > b.length) || (len < 0) || 133 ((off + len) > b.length) || ((off + len) < 0)) { 134 throw new IndexOutOfBoundsException (); 135 } else if (len == 0) { 136 return false; 137 } 138 139 int newcount = bufSize + len; 140 if (newcount > buf.length) { 141 byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; 142 System.arraycopy(buf, 0, newbuf, 0, bufSize); 143 buf = newbuf; 144 } 145 System.arraycopy(b, off, buf, bufSize, len); 146 bufSize = newcount; 147 148 if (bufSize > START_DATA.length && (firstIndexOf(buf,0,START_DATA)==-1)){ 149 bufSize = 0; 150 log.error("Discarded the package, invalid header"); 151 return false; 152 } 153 return true; 154 } 155 156 157 162 public int countPackages() 163 { 164 int cnt = 0; 165 int pos = START_DATA.length; 166 int start = 0; 167 168 while ( start < bufSize ) { 169 int index = XByteBuffer.firstIndexOf(buf,start,START_DATA); 171 if ( index != start || ((bufSize-start)<10) ) break; 174 int size = toInt(buf, pos); 176 pos = start + START_DATA.length + 4 + size; 179 if ( (pos + END_DATA.length) > bufSize) break; 180 int newpos = firstIndexOf(buf, pos, END_DATA); 182 if (newpos != pos) break; 184 cnt++; 186 start = pos + END_DATA.length; 188 pos = start + START_DATA.length; 189 } 190 return cnt; 191 } 192 193 197 public boolean doesPackageExist() { 198 return (countPackages()>0); 199 } 200 201 207 public byte[] extractPackage(boolean clearFromBuffer) 208 throws java.io.IOException { 209 int psize = countPackages(); 210 if (psize == 0) 211 throw new java.lang.IllegalStateException ( 212 "No package exists in XByteBuffer"); 213 int size = toInt(buf, START_DATA.length); 214 byte[] data = new byte[size]; 215 System.arraycopy(buf, START_DATA.length + 4, data, 0, size); 216 if (clearFromBuffer) { 217 int totalsize = START_DATA.length + 4 + size + END_DATA.length; 218 bufSize = bufSize - totalsize; 219 System.arraycopy(buf, totalsize, buf, 0, bufSize); 220 } 221 byte[] result; 222 if (compress) { ByteArrayInputStream bin = 225 new ByteArrayInputStream (data); 226 GZIPInputStream gin = 227 new GZIPInputStream (bin); 228 byte[] tmp = new byte[1024]; 229 int length = gin.read(tmp); 230 result = new byte[0]; 231 while (length > 0) { 232 byte[] tmpdata = result; 233 result = new byte[result.length + length]; 234 System.arraycopy(tmpdata, 0, result, 0, tmpdata.length); 235 System.arraycopy(tmp, 0, result, tmpdata.length, length); 236 length = gin.read(tmp); 237 } 238 gin.close(); 239 } else { result = data; 241 } 242 return result; 243 } 244 245 252 public static int toInt(byte[] b,int off){ 253 return ( ( (int) b[off+3]) & 0xFF) + 254 ( ( ( (int) b[off+2]) & 0xFF) << 8) + 255 ( ( ( (int) b[off+1]) & 0xFF) << 16) + 256 ( ( ( (int) b[off+0]) & 0xFF) << 24); 257 } 258 259 266 public static long toLong(byte[] b,int off){ 267 return ( ( (long) b[off+7]) & 0xFF) + 268 ( ( ( (long) b[off+6]) & 0xFF) << 8) + 269 ( ( ( (long) b[off+5]) & 0xFF) << 16) + 270 ( ( ( (long) b[off+4]) & 0xFF) << 24) + 271 ( ( ( (long) b[off+3]) & 0xFF) << 32) + 272 ( ( ( (long) b[off+2]) & 0xFF) << 40) + 273 ( ( ( (long) b[off+1]) & 0xFF) << 48) + 274 ( ( ( (long) b[off+0]) & 0xFF) << 56); 275 } 276 277 282 public static byte[] toBytes(int n) { 283 byte[] b = new byte[4]; 284 b[3] = (byte) (n); 285 n >>>= 8; 286 b[2] = (byte) (n); 287 n >>>= 8; 288 b[1] = (byte) (n); 289 n >>>= 8; 290 b[0] = (byte) (n); 291 return b; 292 } 293 294 299 public static byte[] toBytes(long n) { 300 byte[] b = new byte[8]; 301 b[7] = (byte) (n); 302 n >>>= 8; 303 b[6] = (byte) (n); 304 n >>>= 8; 305 b[5] = (byte) (n); 306 n >>>= 8; 307 b[4] = (byte) (n); 308 n >>>= 8; 309 b[3] = (byte) (n); 310 n >>>= 8; 311 b[2] = (byte) (n); 312 n >>>= 8; 313 b[1] = (byte) (n); 314 n >>>= 8; 315 b[0] = (byte) (n); 316 return b; 317 } 318 319 326 public static int firstIndexOf(byte[] src, int srcOff, byte[] find){ 327 int result = -1; 328 if (find.length > src.length) return result; 329 if (find.length == 0 || src.length == 0) return result; 330 if (srcOff >= src.length ) throw new java.lang.ArrayIndexOutOfBoundsException (); 331 boolean found = false; 332 int srclen = src.length; 333 int findlen = find.length; 334 byte first = find[0]; 335 int pos = srcOff; 336 while (!found) { 337 while (pos < srclen){ 339 if (first == src[pos]) 340 break; 341 pos++; 342 } 343 if (pos >= srclen) 344 return -1; 345 346 if ( (srclen - pos) < findlen) 349 return -1; 350 found = true; 352 for (int i = 1; ( (i < findlen) && found); i++) 353 found = found && (find[i] == src[pos + i]); 354 if (found) 355 result = pos; 356 else if ( (srclen - pos) < findlen) 357 return -1; else 359 pos++; 360 } 361 return result; 362 } 363 364 370 public static byte[] createDataPackage(byte[] indata, boolean compress) 371 throws java.io.IOException { 372 byte[] data; 373 if (compress) { 374 ByteArrayOutputStream bout = new ByteArrayOutputStream ( 375 indata.length / 2); 376 GZIPOutputStream gout = new GZIPOutputStream (bout); 377 gout.write(indata); 378 gout.flush(); 379 gout.close(); 380 data = bout.toByteArray(); 381 } else { 382 data = indata; 383 } 384 byte[] result = new byte[START_DATA.length + 4 + data.length 385 + END_DATA.length]; 386 System.arraycopy(START_DATA, 0, result, 0, START_DATA.length); 387 System.arraycopy(toBytes(data.length), 0, result, START_DATA.length, 4); 388 System.arraycopy(data, 0, result, START_DATA.length + 4, data.length); 389 System.arraycopy(END_DATA, 0, result, START_DATA.length + 4 390 + data.length, END_DATA.length); 391 392 return result; 393 394 } 395 396 public static void main(String [] args) throws Exception { 398 log.info("Before="+Integer.MAX_VALUE); 399 byte[] d = toBytes(Integer.MAX_VALUE); 400 log.info("After="+toInt(d,0)); 401 402 403 log.info("Before="+Long.MAX_VALUE); 404 d = toBytes(Long.MAX_VALUE); 405 log.info("After="+toLong(d,0)); 406 407 log.info("Before=" + 4564564); 408 d = toBytes((long)4564564); 409 log.info("After=" + toLong(d, 0)); 410 411 byte[] d1 = createDataPackage(new byte[] {1},true); 412 byte[] d2 = createDataPackage(new byte[] {2},true); 413 byte[] d3 = createDataPackage(new byte[] {3},true); 414 byte[] test = new byte[d1.length+d2.length+d3.length+5]; 415 System.arraycopy(d1,0,test,0,d1.length); 416 System.arraycopy(d2,0,test,d1.length,d2.length); 417 System.arraycopy(d3,0,test,d2.length+d1.length,d3.length); 418 printBuf(d1); 419 printBuf(d2); 420 printBuf(d3); 421 printBuf(test); 422 XByteBuffer b = new XByteBuffer(); 423 b.append(test,0,test.length); 424 int s = b.countPackages(); 425 log.info("Nr of packages="+s); 426 while ( s > 0 ) { 427 d = b.extractPackage(true); 428 log.info("Package d1="); 429 printBuf(d); 430 s--; 431 } 433 } 434 435 public static void printBuf(byte[] b) { 436 StringBuffer buf = new StringBuffer (); 437 for ( int i=0; i<b.length; i++ ) { 438 buf.append(b[i] + " "); 439 } 440 log.info(buf); 441 } 442 443 } 444 | Popular Tags |