1 48 49 package com.caucho.hessian.io; 50 51 import java.io.IOException ; 52 import java.io.OutputStream ; 53 import java.util.IdentityHashMap ; 54 55 75 public class HessianOutput extends AbstractHessianOutput { 76 protected OutputStream os; 78 private IdentityHashMap _refs; 80 private int _version = 1; 81 82 88 public HessianOutput(OutputStream os) 89 { 90 init(os); 91 } 92 93 96 public HessianOutput() 97 { 98 } 99 100 103 public void init(OutputStream os) 104 { 105 this.os = os; 106 107 _refs = null; 108 109 if (_serializerFactory == null) 110 _serializerFactory = new SerializerFactory(); 111 } 112 113 116 public void setVersion(int version) 117 { 118 _version = version; 119 } 120 121 124 public void call(String method, Object []args) 125 throws IOException 126 { 127 startCall(method); 128 129 if (args != null) { 130 for (int i = 0; i < args.length; i++) 131 writeObject(args[i]); 132 } 133 134 completeCall(); 135 } 136 137 149 public void startCall(String method) 150 throws IOException 151 { 152 os.write('c'); 153 os.write(_version); 154 os.write(0); 155 156 os.write('m'); 157 int len = method.length(); 158 os.write(len >> 8); 159 os.write(len); 160 printString(method, 0, len); 161 } 162 163 173 public void startCall() 174 throws IOException 175 { 176 os.write('c'); 177 os.write(0); 178 os.write(1); 179 } 180 181 190 public void writeMethod(String method) 191 throws IOException 192 { 193 os.write('m'); 194 int len = method.length(); 195 os.write(len >> 8); 196 os.write(len); 197 printString(method, 0, len); 198 } 199 200 207 public void completeCall() 208 throws IOException 209 { 210 os.write('z'); 211 } 212 213 222 public void startReply() 223 throws IOException 224 { 225 os.write('r'); 226 os.write(1); 227 os.write(0); 228 } 229 230 239 public void completeReply() 240 throws IOException 241 { 242 os.write('z'); 243 } 244 245 252 public void writeHeader(String name) 253 throws IOException 254 { 255 int len = name.length(); 256 257 os.write('H'); 258 os.write(len >> 8); 259 os.write(len); 260 261 printString(name); 262 } 263 264 285 public void writeFault(String code, String message, Object detail) 286 throws IOException 287 { 288 os.write('f'); 289 writeString("code"); 290 writeString(code); 291 292 writeString("message"); 293 writeString(message); 294 295 if (detail != null) { 296 writeString("detail"); 297 writeObject(detail); 298 } 299 os.write('z'); 300 } 301 302 305 public void writeObject(Object object) 306 throws IOException 307 { 308 if (object == null) { 309 writeNull(); 310 return; 311 } 312 313 Serializer serializer; 314 315 serializer = _serializerFactory.getSerializer(object.getClass()); 316 317 serializer.writeObject(object, this); 318 } 319 320 331 public boolean writeListBegin(int length, String type) 332 throws IOException 333 { 334 os.write('V'); 335 336 if (type != null) { 337 os.write('t'); 338 printLenString(type); 339 } 340 341 if (length >= 0) { 342 os.write('l'); 343 os.write(length >> 24); 344 os.write(length >> 16); 345 os.write(length >> 8); 346 os.write(length); 347 } 348 349 return true; 350 } 351 352 355 public void writeListEnd() 356 throws IOException 357 { 358 os.write('z'); 359 } 360 361 370 public void writeMapBegin(String type) 371 throws IOException 372 { 373 os.write('M'); 374 os.write('t'); 375 printLenString(type); 376 } 377 378 381 public void writeMapEnd() 382 throws IOException 383 { 384 os.write('z'); 385 } 386 387 395 public void writeRemote(String type, String url) 396 throws IOException 397 { 398 os.write('r'); 399 os.write('t'); 400 printLenString(type); 401 os.write('S'); 402 printLenString(url); 403 } 404 405 416 public void writeBoolean(boolean value) 417 throws IOException 418 { 419 if (value) 420 os.write('T'); 421 else 422 os.write('F'); 423 } 424 425 435 public void writeInt(int value) 436 throws IOException 437 { 438 os.write('I'); 439 os.write(value >> 24); 440 os.write(value >> 16); 441 os.write(value >> 8); 442 os.write(value); 443 } 444 445 455 public void writeLong(long value) 456 throws IOException 457 { 458 os.write('L'); 459 os.write((byte) (value >> 56)); 460 os.write((byte) (value >> 48)); 461 os.write((byte) (value >> 40)); 462 os.write((byte) (value >> 32)); 463 os.write((byte) (value >> 24)); 464 os.write((byte) (value >> 16)); 465 os.write((byte) (value >> 8)); 466 os.write((byte) (value)); 467 } 468 469 479 public void writeDouble(double value) 480 throws IOException 481 { 482 long bits = Double.doubleToLongBits(value); 483 484 os.write('D'); 485 os.write((byte) (bits >> 56)); 486 os.write((byte) (bits >> 48)); 487 os.write((byte) (bits >> 40)); 488 os.write((byte) (bits >> 32)); 489 os.write((byte) (bits >> 24)); 490 os.write((byte) (bits >> 16)); 491 os.write((byte) (bits >> 8)); 492 os.write((byte) (bits)); 493 } 494 495 504 public void writeUTCDate(long time) 505 throws IOException 506 { 507 os.write('d'); 508 os.write((byte) (time >> 56)); 509 os.write((byte) (time >> 48)); 510 os.write((byte) (time >> 40)); 511 os.write((byte) (time >> 32)); 512 os.write((byte) (time >> 24)); 513 os.write((byte) (time >> 16)); 514 os.write((byte) (time >> 8)); 515 os.write((byte) (time)); 516 } 517 518 528 public void writeNull() 529 throws IOException 530 { 531 os.write('N'); 532 } 533 534 550 public void writeString(String value) 551 throws IOException 552 { 553 if (value == null) { 554 os.write('N'); 555 } 556 else { 557 int length = value.length(); 558 int offset = 0; 559 560 while (length > 0x8000) { 561 int sublen = 0x8000; 562 563 char tail = value.charAt(offset + sublen - 1); 565 566 if (0xd800 <= tail && tail <= 0xdbff) 567 sublen--; 568 569 os.write('s'); 570 os.write(sublen >> 8); 571 os.write(sublen); 572 573 printString(value, offset, sublen); 574 575 length -= sublen; 576 offset += sublen; 577 } 578 579 os.write('S'); 580 os.write(length >> 8); 581 os.write(length); 582 583 printString(value, offset, length); 584 } 585 } 586 587 603 public void writeString(char []buffer, int offset, int length) 604 throws IOException 605 { 606 if (buffer == null) { 607 os.write('N'); 608 } 609 else { 610 while (length > 0x8000) { 611 int sublen = 0x8000; 612 613 char tail = buffer[offset + sublen - 1]; 615 616 if (0xd800 <= tail && tail <= 0xdbff) 617 sublen--; 618 619 os.write('s'); 620 os.write(sublen >> 8); 621 os.write(sublen); 622 623 printString(buffer, offset, sublen); 624 625 length -= sublen; 626 offset += sublen; 627 } 628 629 os.write('S'); 630 os.write(length >> 8); 631 os.write(length); 632 633 printString(buffer, offset, length); 634 } 635 } 636 637 653 public void writeBytes(byte []buffer) 654 throws IOException 655 { 656 if (buffer == null) 657 os.write('N'); 658 else 659 writeBytes(buffer, 0, buffer.length); 660 } 661 662 678 public void writeBytes(byte []buffer, int offset, int length) 679 throws IOException 680 { 681 if (buffer == null) { 682 os.write('N'); 683 } 684 else { 685 while (length > 0x8000) { 686 int sublen = 0x8000; 687 688 os.write('b'); 689 os.write(sublen >> 8); 690 os.write(sublen); 691 692 os.write(buffer, offset, sublen); 693 694 length -= sublen; 695 offset += sublen; 696 } 697 698 os.write('B'); 699 os.write(length >> 8); 700 os.write(length); 701 os.write(buffer, offset, length); 702 } 703 } 704 705 711 public void writeByteBufferStart() 712 throws IOException 713 { 714 } 715 716 723 public void writeByteBufferPart(byte []buffer, int offset, int length) 724 throws IOException 725 { 726 while (length > 0) { 727 int sublen = length; 728 729 if (0x8000 < sublen) 730 sublen = 0x8000; 731 732 os.write('b'); 733 os.write(sublen >> 8); 734 os.write(sublen); 735 736 os.write(buffer, offset, sublen); 737 738 length -= sublen; 739 offset += sublen; 740 } 741 } 742 743 750 public void writeByteBufferEnd(byte []buffer, int offset, int length) 751 throws IOException 752 { 753 writeBytes(buffer, offset, length); 754 } 755 756 765 public void writeRef(int value) 766 throws IOException 767 { 768 os.write('R'); 769 os.write(value >> 24); 770 os.write(value >> 16); 771 os.write(value >> 8); 772 os.write(value); 773 } 774 775 782 public void writePlaceholder() 783 throws IOException 784 { 785 os.write('P'); 786 } 787 788 793 public boolean addRef(Object object) 794 throws IOException 795 { 796 if (_refs == null) 797 _refs = new IdentityHashMap (); 798 799 Integer ref = (Integer ) _refs.get(object); 800 801 if (ref != null) { 802 int value = ref.intValue(); 803 804 writeRef(value); 805 return true; 806 } 807 else { 808 _refs.put(object, new Integer (_refs.size())); 809 810 return false; 811 } 812 } 813 814 817 public boolean removeRef(Object obj) 818 throws IOException 819 { 820 if (_refs != null) { 821 _refs.remove(obj); 822 823 return true; 824 } 825 else 826 return false; 827 } 828 829 832 public boolean replaceRef(Object oldRef, Object newRef) 833 throws IOException 834 { 835 Integer value = (Integer ) _refs.remove(oldRef); 836 837 if (value != null) { 838 _refs.put(newRef, value); 839 return true; 840 } 841 else 842 return false; 843 } 844 845 850 public void printLenString(String v) 851 throws IOException 852 { 853 if (v == null) { 854 os.write(0); 855 os.write(0); 856 } 857 else { 858 int len = v.length(); 859 os.write(len >> 8); 860 os.write(len); 861 862 printString(v, 0, len); 863 } 864 } 865 866 871 public void printString(String v) 872 throws IOException 873 { 874 printString(v, 0, v.length()); 875 } 876 877 882 public void printString(String v, int offset, int length) 883 throws IOException 884 { 885 for (int i = 0; i < length; i++) { 886 char ch = v.charAt(i + offset); 887 888 if (ch < 0x80) 889 os.write(ch); 890 else if (ch < 0x800) { 891 os.write(0xc0 + ((ch >> 6) & 0x1f)); 892 os.write(0x80 + (ch & 0x3f)); 893 } 894 else { 895 os.write(0xe0 + ((ch >> 12) & 0xf)); 896 os.write(0x80 + ((ch >> 6) & 0x3f)); 897 os.write(0x80 + (ch & 0x3f)); 898 } 899 } 900 } 901 902 907 public void printString(char []v, int offset, int length) 908 throws IOException 909 { 910 for (int i = 0; i < length; i++) { 911 char ch = v[i + offset]; 912 913 if (ch < 0x80) 914 os.write(ch); 915 else if (ch < 0x800) { 916 os.write(0xc0 + ((ch >> 6) & 0x1f)); 917 os.write(0x80 + (ch & 0x3f)); 918 } 919 else { 920 os.write(0xe0 + ((ch >> 12) & 0xf)); 921 os.write(0x80 + ((ch >> 6) & 0x3f)); 922 os.write(0x80 + (ch & 0x3f)); 923 } 924 } 925 } 926 } 927 | Popular Tags |