1 17 18 package org.apache.tomcat.util.buf; 19 20 import java.text.*; 21 import java.util.*; 22 import java.io.Serializable ; 23 import java.io.IOException ; 24 25 37 public final class MessageBytes implements Cloneable , Serializable { 38 private int type = T_NULL; 40 41 public static final int T_NULL = 0; 42 44 public static final int T_STR = 1; 45 47 public static final int T_BYTES = 2; 48 50 public static final int T_CHARS = 3; 51 52 private int hashCode=0; 53 private boolean hasHashCode=false; 55 56 private boolean caseSensitive=true; 58 59 private ByteChunk byteC=new ByteChunk(); 61 private CharChunk charC=new CharChunk(); 62 63 private String strValue; 65 private boolean hasStrValue=false; 68 69 74 public MessageBytes() { 75 } 76 77 79 public static MessageBytes newInstance() { 80 return factory.newInstance(); 81 } 82 83 85 public void setCaseSenitive( boolean b ) { 86 caseSensitive=b; 87 } 88 89 public MessageBytes getClone() { 90 try { 91 return (MessageBytes)this.clone(); 92 } catch( Exception ex) { 93 return null; 94 } 95 } 96 97 public boolean isNull() { 98 return byteC.isNull() && charC.isNull() && ! hasStrValue; 100 } 102 103 106 public void recycle() { 107 type=T_NULL; 108 byteC.recycle(); 109 charC.recycle(); 110 111 strValue=null; 112 caseSensitive=true; 113 114 hasStrValue=false; 115 hasHashCode=false; 116 hasIntValue=false; 117 hasLongValue=false; 118 hasDateValue=false; 119 } 120 121 122 129 public void setBytes(byte[] b, int off, int len) { 130 byteC.setBytes( b, off, len ); 131 type=T_BYTES; 132 hasStrValue=false; 133 hasHashCode=false; 134 hasIntValue=false; 135 hasLongValue=false; 136 hasDateValue=false; 137 } 138 139 143 public void setEncoding( String enc ) { 144 if( !byteC.isNull() ) { 145 charC.recycle(); 147 hasStrValue=false; 148 } 149 byteC.setEncoding(enc); 150 } 151 152 159 public void setChars( char[] c, int off, int len ) { 160 charC.setChars( c, off, len ); 161 type=T_CHARS; 162 hasStrValue=false; 163 hasHashCode=false; 164 hasIntValue=false; 165 hasLongValue=false; 166 hasDateValue=false; 167 } 168 169 173 public void resetStringValue() { 174 if( type != T_STR ) { 175 hasStrValue=false; 178 strValue=null; 179 } 180 } 181 182 185 public void setString( String s ) { 186 if (s == null) 187 return; 188 strValue=s; 189 hasStrValue=true; 190 hasHashCode=false; 191 hasIntValue=false; 192 hasLongValue=false; 193 hasDateValue=false; 194 type=T_STR; 195 } 196 197 199 201 public String toString() { 202 if( hasStrValue ) return strValue; 203 204 switch (type) { 205 case T_CHARS: 206 strValue=charC.toString(); 207 hasStrValue=true; 208 return strValue; 209 case T_BYTES: 210 strValue=byteC.toString(); 211 hasStrValue=true; 212 return strValue; 213 } 214 return null; 215 } 216 217 221 public int getType() { 222 return type; 223 } 224 225 229 public ByteChunk getByteChunk() { 230 return byteC; 231 } 232 233 237 public CharChunk getCharChunk() { 238 return charC; 239 } 240 241 245 public String getString() { 246 return strValue; 247 } 248 249 251 public void toBytes() { 252 if( ! byteC.isNull() ) { 253 type=T_BYTES; 254 return; 255 } 256 toString(); 257 type=T_BYTES; 258 byte bb[] = strValue.getBytes(); 259 byteC.setBytes(bb, 0, bb.length); 260 } 261 262 265 public void toChars() { 266 if( ! charC.isNull() ) { 267 type=T_CHARS; 268 return; 269 } 270 toString(); 272 type=T_CHARS; 273 char cc[]=strValue.toCharArray(); 274 charC.setChars(cc, 0, cc.length); 275 } 276 277 278 283 public int getLength() { 284 if(type==T_BYTES) 285 return byteC.getLength(); 286 if(type==T_CHARS) { 287 return charC.getLength(); 288 } 289 if(type==T_STR) 290 return strValue.length(); 291 toString(); 292 if( strValue==null ) return 0; 293 return strValue.length(); 294 } 295 296 298 303 public boolean equals(String s) { 304 if( ! caseSensitive ) 305 return equalsIgnoreCase( s ); 306 switch (type) { 307 case T_STR: 308 if( strValue==null && s!=null) return false; 309 return strValue.equals( s ); 310 case T_CHARS: 311 return charC.equals( s ); 312 case T_BYTES: 313 return byteC.equals( s ); 314 default: 315 return false; 316 } 317 } 318 319 324 public boolean equalsIgnoreCase(String s) { 325 switch (type) { 326 case T_STR: 327 if( strValue==null && s!=null) return false; 328 return strValue.equalsIgnoreCase( s ); 329 case T_CHARS: 330 return charC.equalsIgnoreCase( s ); 331 case T_BYTES: 332 return byteC.equalsIgnoreCase( s ); 333 default: 334 return false; 335 } 336 } 337 338 public boolean equals(MessageBytes mb) { 339 switch (type) { 340 case T_STR: 341 return mb.equals( strValue ); 342 } 343 344 if( mb.type != T_CHARS && 345 mb.type!= T_BYTES ) { 346 return equals( mb.toString() ); 348 } 349 350 354 if( mb.type == T_CHARS && type==T_CHARS ) { 355 return charC.equals( mb.charC ); 356 } 357 if( mb.type==T_BYTES && type== T_BYTES ) { 358 return byteC.equals( mb.byteC ); 359 } 360 if( mb.type== T_CHARS && type== T_BYTES ) { 361 return byteC.equals( mb.charC ); 362 } 363 if( mb.type== T_BYTES && type== T_CHARS ) { 364 return mb.byteC.equals( charC ); 365 } 366 return true; 368 } 369 370 371 375 public boolean startsWith(String s) { 376 switch (type) { 377 case T_STR: 378 return strValue.startsWith( s ); 379 case T_CHARS: 380 return charC.startsWith( s ); 381 case T_BYTES: 382 return byteC.startsWith( s ); 383 default: 384 return false; 385 } 386 } 387 388 393 public boolean startsWithIgnoreCase(String s, int pos) { 394 switch (type) { 395 case T_STR: 396 if( strValue==null ) return false; 397 if( strValue.length() < pos + s.length() ) return false; 398 399 for( int i=0; i<s.length(); i++ ) { 400 if( Ascii.toLower( s.charAt( i ) ) != 401 Ascii.toLower( strValue.charAt( pos + i ))) { 402 return false; 403 } 404 } 405 return true; 406 case T_CHARS: 407 return charC.startsWithIgnoreCase( s, pos ); 408 case T_BYTES: 409 return byteC.startsWithIgnoreCase( s, pos ); 410 default: 411 return false; 412 } 413 } 414 415 416 417 public int hashCode() { 419 if( hasHashCode ) return hashCode; 420 int code = 0; 421 422 if( caseSensitive ) 423 code=hash(); 424 else 425 code=hashIgnoreCase(); 426 hashCode=code; 427 hasHashCode=true; 428 return code; 429 } 430 431 private int hash() { 433 int code=0; 434 switch (type) { 435 case T_STR: 436 for (int i = 0; i < strValue.length(); i++) { 438 code = code * 37 + strValue.charAt( i ); 439 } 440 return code; 441 case T_CHARS: 442 return charC.hash(); 443 case T_BYTES: 444 return byteC.hash(); 445 default: 446 return 0; 447 } 448 } 449 450 private int hashIgnoreCase() { 452 int code=0; 453 switch (type) { 454 case T_STR: 455 for (int i = 0; i < strValue.length(); i++) { 456 code = code * 37 + Ascii.toLower(strValue.charAt( i )); 457 } 458 return code; 459 case T_CHARS: 460 return charC.hashIgnoreCase(); 461 case T_BYTES: 462 return byteC.hashIgnoreCase(); 463 default: 464 return 0; 465 } 466 } 467 468 public int indexOf(char c) { 469 return indexOf( c, 0); 470 } 471 472 public int indexOf(String s, int starting) { 475 toString(); 476 return strValue.indexOf( s, starting ); 477 } 478 479 public int indexOf(String s) { 482 return indexOf( s, 0 ); 483 } 484 485 public int indexOfIgnoreCase(String s, int starting) { 486 toString(); 487 String upper=strValue.toUpperCase(); 488 String sU=s.toUpperCase(); 489 return upper.indexOf( sU, starting ); 490 } 491 492 497 public int indexOf(char c, int starting) { 498 switch (type) { 499 case T_STR: 500 return strValue.indexOf( c, starting ); 501 case T_CHARS: 502 return charC.indexOf( c, starting); 503 case T_BYTES: 504 return byteC.indexOf( c, starting ); 505 default: 506 return -1; 507 } 508 } 509 510 513 public void duplicate( MessageBytes src ) throws IOException 514 { 515 switch( src.getType() ) { 516 case MessageBytes.T_BYTES: 517 type=T_BYTES; 518 ByteChunk bc=src.getByteChunk(); 519 byteC.allocate( 2 * bc.getLength(), -1 ); 520 byteC.append( bc ); 521 break; 522 case MessageBytes.T_CHARS: 523 type=T_CHARS; 524 CharChunk cc=src.getCharChunk(); 525 charC.allocate( 2 * cc.getLength(), -1 ); 526 charC.append( cc ); 527 break; 528 case MessageBytes.T_STR: 529 type=T_STR; 530 String sc=src.getString(); 531 this.setString( sc ); 532 break; 533 } 534 } 535 536 private int intValue; 541 private boolean hasIntValue=false; 542 private long longValue; 543 private boolean hasLongValue=false; 544 private Date dateValue; 545 private boolean hasDateValue=false; 546 547 552 public void setTime(long t, DateFormat df) { 553 recycle(); 555 if( dateValue==null) 556 dateValue=new Date(t); 557 else 558 dateValue.setTime(t); 559 if( df==null ) 560 strValue=DateTool.format1123(dateValue); 561 else 562 strValue=DateTool.format1123(dateValue,df); 563 hasStrValue=true; 564 hasDateValue=true; 565 type=T_STR; 566 } 567 568 public void setTime(long t) { 569 setTime( t, null ); 570 } 571 572 574 public void setInt(int i) { 575 byteC.allocate(16, 32); 576 int current = i; 577 byte[] buf = byteC.getBuffer(); 578 int start = 0; 579 int end = 0; 580 if (i == 0) { 581 buf[end++] = (byte) '0'; 582 } 583 if (i < 0) { 584 current = -i; 585 buf[end++] = (byte) '-'; 586 } 587 while (current > 0) { 588 int digit = current % 10; 589 current = current / 10; 590 buf[end++] = HexUtils.HEX[digit]; 591 } 592 byteC.setOffset(0); 593 byteC.setEnd(end); 594 end--; 596 if (i < 0) { 597 start++; 598 } 599 while (end > start) { 600 byte temp = buf[start]; 601 buf[start] = buf[end]; 602 buf[end] = temp; 603 start++; 604 end--; 605 } 606 intValue=i; 607 hasStrValue=false; 608 hasHashCode=false; 609 hasIntValue=true; 610 hasLongValue=false; 611 hasDateValue=false; 612 type=T_BYTES; 613 } 614 615 617 public void setLong(long l) { 618 byteC.allocate(32, 64); 619 long current = l; 620 byte[] buf = byteC.getBuffer(); 621 int start = 0; 622 int end = 0; 623 if (l == 0) { 624 buf[end++] = (byte) '0'; 625 } 626 if (l < 0) { 627 current = -l; 628 buf[end++] = (byte) '-'; 629 } 630 while (current > 0) { 631 int digit = (int) (current % 10); 632 current = current / 10; 633 buf[end++] = HexUtils.HEX[digit]; 634 } 635 byteC.setOffset(0); 636 byteC.setEnd(end); 637 end--; 639 if (l < 0) { 640 start++; 641 } 642 while (end > start) { 643 byte temp = buf[start]; 644 buf[start] = buf[end]; 645 buf[end] = temp; 646 start++; 647 end--; 648 } 649 longValue=l; 650 hasStrValue=false; 651 hasHashCode=false; 652 hasIntValue=false; 653 hasLongValue=true; 654 hasDateValue=false; 655 type=T_BYTES; 656 } 657 658 662 public long getTime() 663 { 664 if( hasDateValue ) { 665 if( dateValue==null) return -1; 666 return dateValue.getTime(); 667 } 668 669 long l=DateTool.parseDate( this ); 670 if( dateValue==null) 671 dateValue=new Date(l); 672 else 673 dateValue.setTime(l); 674 hasDateValue=true; 675 return l; 676 } 677 678 679 682 public int getInt() 683 { 684 if( hasIntValue ) 685 return intValue; 686 687 switch (type) { 688 case T_BYTES: 689 intValue=byteC.getInt(); 690 break; 691 default: 692 intValue=Integer.parseInt(toString()); 693 } 694 hasIntValue=true; 695 return intValue; 696 } 697 698 701 public long getLong() { 702 if( hasLongValue ) 703 return longValue; 704 705 switch (type) { 706 case T_BYTES: 707 longValue=byteC.getLong(); 708 break; 709 default: 710 longValue=Long.parseLong(toString()); 711 } 712 713 hasLongValue=true; 714 return longValue; 715 716 } 717 718 720 private static MessageBytesFactory factory=new MessageBytesFactory(); 721 722 public static void setFactory( MessageBytesFactory mbf ) { 723 factory=mbf; 724 } 725 726 public static class MessageBytesFactory { 727 protected MessageBytesFactory() { 728 } 729 public MessageBytes newInstance() { 730 return new MessageBytes(); 731 } 732 } 733 } 734 | Popular Tags |