1 48 49 package com.caucho.hessian.io; 50 51 import java.io.ByteArrayOutputStream ; 52 import java.io.IOException ; 53 import java.io.InputStream ; 54 import java.io.Reader ; 55 import java.lang.reflect.Field ; 56 import java.util.ArrayList ; 57 import java.util.Date ; 58 import java.util.HashMap ; 59 60 76 public class HessianInput extends AbstractHessianInput { 77 private static int END_OF_DATA = -2; 78 79 private static Field _detailMessageField; 80 81 protected SerializerFactory _serializerFactory; 83 84 protected ArrayList _refs; 85 86 private InputStream _is; 88 protected int _peek = -1; 90 91 private String _method; 93 94 private Reader _chunkReader; 95 private InputStream _chunkInputStream; 96 97 private Throwable _replyFault; 98 99 private StringBuffer _sbuf = new StringBuffer (); 100 101 private boolean _isLastChunk; 103 private int _chunkLength; 105 106 109 public HessianInput() 110 { 111 } 112 113 119 public HessianInput(InputStream is) 120 { 121 init(is); 122 } 123 124 127 public void setSerializerFactory(SerializerFactory factory) 128 { 129 _serializerFactory = factory; 130 } 131 132 135 public SerializerFactory getSerializerFactory() 136 { 137 return _serializerFactory; 138 } 139 140 143 public void init(InputStream is) 144 { 145 _is = is; 146 _method = null; 147 _isLastChunk = true; 148 _chunkLength = 0; 149 _peek = -1; 150 _refs = null; 151 _replyFault = null; 152 153 if (_serializerFactory == null) 154 _serializerFactory = new SerializerFactory(); 155 } 156 157 160 public String getMethod() 161 { 162 return _method; 163 } 164 165 168 public Throwable getReplyFault() 169 { 170 return _replyFault; 171 } 172 173 180 public int readCall() 181 throws IOException 182 { 183 int tag = read(); 184 185 if (tag != 'c') 186 throw error("expected hessian call ('c') at code=" + tag + " ch=" + (char) tag); 187 188 int major = read(); 189 int minor = read(); 190 191 return (major << 16) + minor; 192 } 193 194 203 public String readMethod() 204 throws IOException 205 { 206 int tag = read(); 207 208 if (tag != 'm') 209 throw error("expected hessian method ('m') at code=" + tag + " ch=" + (char) tag); 210 int d1 = read(); 211 int d2 = read(); 212 213 _isLastChunk = true; 214 _chunkLength = d1 * 256 + d2; 215 _sbuf.setLength(0); 216 int ch; 217 while ((ch = parseChar()) >= 0) 218 _sbuf.append((char) ch); 219 220 _method = _sbuf.toString(); 221 222 return _method; 223 } 224 225 235 public void startCall() 236 throws IOException 237 { 238 readCall(); 239 240 while (readHeader() != null) { 241 readObject(); 242 } 243 244 readMethod(); 245 } 246 247 256 public void completeCall() 257 throws IOException 258 { 259 int tag = read(); 260 261 if (tag == 'z') { 262 } 263 else if (tag < 0) 264 throw error("expected end of call ('z') at end of stream."); 265 else 266 throw error("expected end of call ('z') at '" + (char) tag + "'. Check method arguments and ensure method overloading is enabled if necessary"); 267 } 268 269 273 public Object readReply(Class expectedClass) 274 throws Throwable 275 { 276 int tag = read(); 277 278 if (tag != 'r') 279 error("expected hessian reply"); 280 281 int major = read(); 282 int minor = read(); 283 284 tag = read(); 285 if (tag == 'f') 286 throw prepareFault(); 287 else { 288 _peek = tag; 289 290 Object value = readObject(expectedClass); 291 292 completeValueReply(); 293 294 return value; 295 } 296 } 297 298 307 public void startReply() 308 throws Throwable 309 { 310 int tag = read(); 311 312 if (tag != 'r') 313 error("expected hessian reply"); 314 315 int major = read(); 316 int minor = read(); 317 318 tag = read(); 319 if (tag == 'f') 320 throw prepareFault(); 321 else 322 _peek = tag; 323 } 324 325 328 private Throwable prepareFault() 329 throws IOException 330 { 331 HashMap fault = readFault(); 332 333 Object detail = fault.get("detail"); 334 String message = (String ) fault.get("message"); 335 336 if (detail instanceof Throwable ) { 337 _replyFault = (Throwable ) detail; 338 339 if (message != null && _detailMessageField != null) { 340 try { 341 _detailMessageField.set(_replyFault, message); 342 } catch (Throwable e) { 343 } 344 } 345 346 return _replyFault; 347 } 348 349 else { 350 String code = (String ) fault.get("code"); 351 352 _replyFault = new HessianServiceException(message, code, detail); 353 354 return _replyFault; 355 } 356 } 357 358 367 public void completeReply() 368 throws IOException 369 { 370 int tag = read(); 371 372 if (tag != 'z') 373 error("expected end of reply"); 374 } 375 376 385 public void completeValueReply() 386 throws IOException 387 { 388 int tag = read(); 389 390 if (tag != 'z') 391 error("expected end of reply"); 392 } 393 394 401 public String readHeader() 402 throws IOException 403 { 404 int tag = read(); 405 406 if (tag == 'H') { 407 _isLastChunk = true; 408 _chunkLength = (read() << 8) + read(); 409 410 _sbuf.setLength(0); 411 int ch; 412 while ((ch = parseChar()) >= 0) 413 _sbuf.append((char) ch); 414 415 return _sbuf.toString(); 416 } 417 418 _peek = tag; 419 420 return null; 421 } 422 423 430 public void readNull() 431 throws IOException 432 { 433 int tag = read(); 434 435 switch (tag) { 436 case 'N': return; 437 438 default: 439 throw expect("null", tag); 440 } 441 } 442 443 451 public boolean readBoolean() 452 throws IOException 453 { 454 int tag = read(); 455 456 switch (tag) { 457 case 'T': return true; 458 case 'F': return false; 459 case 'I': return parseInt() == 0; 460 case 'L': return parseLong() == 0; 461 case 'D': return parseDouble() == 0.0; 462 case 'N': return false; 463 464 default: 465 throw expect("boolean", tag); 466 } 467 } 468 469 476 483 484 491 public short readShort() 492 throws IOException 493 { 494 return (short) readInt(); 495 } 496 497 504 public int readInt() 505 throws IOException 506 { 507 int tag = read(); 508 509 switch (tag) { 510 case 'T': return 1; 511 case 'F': return 0; 512 case 'I': return parseInt(); 513 case 'L': return (int) parseLong(); 514 case 'D': return (int) parseDouble(); 515 516 default: 517 throw expect("int", tag); 518 } 519 } 520 521 528 public long readLong() 529 throws IOException 530 { 531 int tag = read(); 532 533 switch (tag) { 534 case 'T': return 1; 535 case 'F': return 0; 536 case 'I': return parseInt(); 537 case 'L': return parseLong(); 538 case 'D': return (long) parseDouble(); 539 540 default: 541 throw expect("long", tag); 542 } 543 } 544 545 552 public float readFloat() 553 throws IOException 554 { 555 return (float) readDouble(); 556 } 557 558 565 public double readDouble() 566 throws IOException 567 { 568 int tag = read(); 569 570 switch (tag) { 571 case 'T': return 1; 572 case 'F': return 0; 573 case 'I': return parseInt(); 574 case 'L': return (double) parseLong(); 575 case 'D': return parseDouble(); 576 577 default: 578 throw expect("long", tag); 579 } 580 } 581 582 589 public long readUTCDate() 590 throws IOException 591 { 592 int tag = read(); 593 594 if (tag != 'd') 595 throw error("expected date"); 596 597 long b64 = read(); 598 long b56 = read(); 599 long b48 = read(); 600 long b40 = read(); 601 long b32 = read(); 602 long b24 = read(); 603 long b16 = read(); 604 long b8 = read(); 605 606 return ((b64 << 56) + 607 (b56 << 48) + 608 (b48 << 40) + 609 (b40 << 32) + 610 (b32 << 24) + 611 (b24 << 16) + 612 (b16 << 8) + 613 b8); 614 } 615 616 619 public int readChar() 620 throws IOException 621 { 622 if (_chunkLength > 0) { 623 _chunkLength--; 624 if (_chunkLength == 0 && _isLastChunk) 625 _chunkLength = END_OF_DATA; 626 627 int ch = parseUTF8Char(); 628 return ch; 629 } 630 else if (_chunkLength == END_OF_DATA) { 631 _chunkLength = 0; 632 return -1; 633 } 634 635 int tag = read(); 636 637 switch (tag) { 638 case 'N': 639 return -1; 640 641 case 'S': 642 case 's': 643 case 'X': 644 case 'x': 645 _isLastChunk = tag == 'S' || tag == 'X'; 646 _chunkLength = (read() << 8) + read(); 647 648 _chunkLength--; 649 int value = parseUTF8Char(); 650 651 if (_chunkLength == 0 && _isLastChunk) 654 _chunkLength = END_OF_DATA; 655 656 return value; 657 658 default: 659 throw new IOException ("expected 'S' at " + (char) tag); 660 } 661 } 662 663 666 public int readString(char []buffer, int offset, int length) 667 throws IOException 668 { 669 int readLength = 0; 670 671 if (_chunkLength == END_OF_DATA) { 672 _chunkLength = 0; 673 return -1; 674 } 675 else if (_chunkLength == 0) { 676 int tag = read(); 677 678 switch (tag) { 679 case 'N': 680 return -1; 681 682 case 'S': 683 case 's': 684 case 'X': 685 case 'x': 686 _isLastChunk = tag == 'S' || tag == 'X'; 687 _chunkLength = (read() << 8) + read(); 688 break; 689 690 default: 691 throw new IOException ("expected 'S' at " + (char) tag); 692 } 693 } 694 695 while (length > 0) { 696 if (_chunkLength > 0) { 697 buffer[offset++] = (char) parseUTF8Char(); 698 _chunkLength--; 699 length--; 700 readLength++; 701 } 702 else if (_isLastChunk) { 703 if (readLength == 0) 704 return -1; 705 else { 706 _chunkLength = END_OF_DATA; 707 return readLength; 708 } 709 } 710 else { 711 int tag = read(); 712 713 switch (tag) { 714 case 'S': 715 case 's': 716 case 'X': 717 case 'x': 718 _isLastChunk = tag == 'S' || tag == 'X'; 719 _chunkLength = (read() << 8) + read(); 720 break; 721 722 default: 723 throw new IOException ("expected 'S' at " + (char) tag); 724 } 725 } 726 } 727 728 if (readLength == 0) 729 return -1; 730 else if (_chunkLength > 0 || ! _isLastChunk) 731 return readLength; 732 else { 733 _chunkLength = END_OF_DATA; 734 return readLength; 735 } 736 } 737 738 745 public String readString() 746 throws IOException 747 { 748 int tag = read(); 749 750 switch (tag) { 751 case 'N': 752 return null; 753 754 case 'I': 755 return String.valueOf(parseInt()); 756 case 'L': 757 return String.valueOf(parseLong()); 758 case 'D': 759 return String.valueOf(parseDouble()); 760 761 case 'S': 762 case 's': 763 case 'X': 764 case 'x': 765 _isLastChunk = tag == 'S' || tag == 'X'; 766 _chunkLength = (read() << 8) + read(); 767 768 _sbuf.setLength(0); 769 int ch; 770 771 while ((ch = parseChar()) >= 0) 772 _sbuf.append((char) ch); 773 774 return _sbuf.toString(); 775 776 default: 777 throw expect("string", tag); 778 } 779 } 780 781 788 public org.w3c.dom.Node readNode() 789 throws IOException 790 { 791 int tag = read(); 792 793 switch (tag) { 794 case 'N': 795 return null; 796 797 case 'S': 798 case 's': 799 case 'X': 800 case 'x': 801 _isLastChunk = tag == 'S' || tag == 'X'; 802 _chunkLength = (read() << 8) + read(); 803 804 throw error("can't cope"); 805 806 default: 807 throw expect("string", tag); 808 } 809 } 810 811 818 public byte []readBytes() 819 throws IOException 820 { 821 int tag = read(); 822 823 switch (tag) { 824 case 'N': 825 return null; 826 827 case 'B': 828 case 'b': 829 _isLastChunk = tag == 'B'; 830 _chunkLength = (read() << 8) + read(); 831 832 ByteArrayOutputStream bos = new ByteArrayOutputStream (); 833 834 int data; 835 while ((data = parseByte()) >= 0) 836 bos.write(data); 837 838 return bos.toByteArray(); 839 840 default: 841 throw expect("bytes", tag); 842 } 843 } 844 845 848 public int readByte() 849 throws IOException 850 { 851 if (_chunkLength > 0) { 852 _chunkLength--; 853 if (_chunkLength == 0 && _isLastChunk) 854 _chunkLength = END_OF_DATA; 855 856 return read(); 857 } 858 else if (_chunkLength == END_OF_DATA) { 859 _chunkLength = 0; 860 return -1; 861 } 862 863 int tag = read(); 864 865 switch (tag) { 866 case 'N': 867 return -1; 868 869 case 'B': 870 case 'b': 871 _isLastChunk = tag == 'B'; 872 _chunkLength = (read() << 8) + read(); 873 874 int value = parseByte(); 875 876 if (_chunkLength == 0 && _isLastChunk) 879 _chunkLength = END_OF_DATA; 880 881 return value; 882 883 default: 884 throw new IOException ("expected 'B' at " + (char) tag); 885 } 886 } 887 888 891 public int readBytes(byte []buffer, int offset, int length) 892 throws IOException 893 { 894 int readLength = 0; 895 896 if (_chunkLength == END_OF_DATA) { 897 _chunkLength = 0; 898 return -1; 899 } 900 else if (_chunkLength == 0) { 901 int tag = read(); 902 903 switch (tag) { 904 case 'N': 905 return -1; 906 907 case 'B': 908 case 'b': 909 _isLastChunk = tag == 'B'; 910 _chunkLength = (read() << 8) + read(); 911 break; 912 913 default: 914 throw new IOException ("expected 'B' at " + (char) tag); 915 } 916 } 917 918 while (length > 0) { 919 if (_chunkLength > 0) { 920 buffer[offset++] = (byte) read(); 921 _chunkLength--; 922 length--; 923 readLength++; 924 } 925 else if (_isLastChunk) { 926 if (readLength == 0) 927 return -1; 928 else { 929 _chunkLength = END_OF_DATA; 930 return readLength; 931 } 932 } 933 else { 934 int tag = read(); 935 936 switch (tag) { 937 case 'B': 938 case 'b': 939 _isLastChunk = tag == 'B'; 940 _chunkLength = (read() << 8) + read(); 941 break; 942 943 default: 944 throw new IOException ("expected 'B' at " + (char) tag); 945 } 946 } 947 } 948 949 if (readLength == 0) 950 return -1; 951 else if (_chunkLength > 0 || ! _isLastChunk) 952 return readLength; 953 else { 954 _chunkLength = END_OF_DATA; 955 return readLength; 956 } 957 } 958 959 962 private HashMap readFault() 963 throws IOException 964 { 965 HashMap map = new HashMap (); 966 967 int code = read(); 968 for (; code > 0 && code != 'z'; code = read()) { 969 _peek = code; 970 971 Object key = readObject(); 972 Object value = readObject(); 973 974 if (key != null && value != null) 975 map.put(key, value); 976 } 977 978 if (code != 'z') 979 throw expect("fault", code); 980 981 return map; 982 } 983 984 987 public Object readObject(Class cl) 988 throws IOException 989 { 990 if (cl == null || cl == Object .class) 991 return readObject(); 992 993 int tag = read(); 994 995 switch (tag) { 996 case 'N': 997 return null; 998 999 case 'M': 1000 { 1001 String type = readType(); 1002 Deserializer reader; 1003 reader = _serializerFactory.getObjectDeserializer(type); 1004 1005 if (cl != reader.getType() && cl.isAssignableFrom(reader.getType())) 1006 return reader.readMap(this); 1007 1008 reader = _serializerFactory.getDeserializer(cl); 1009 1010 return reader.readMap(this); 1011 } 1012 1013 case 'V': 1014 { 1015 String type = readType(); 1016 int length = readLength(); 1017 1018 Deserializer reader; 1019 reader = _serializerFactory.getObjectDeserializer(type); 1020 1021 if (cl != reader.getType() && cl.isAssignableFrom(reader.getType())) 1022 return reader.readList(this, length); 1023 1024 reader = _serializerFactory.getDeserializer(cl); 1025 1026 Object v = reader.readList(this, length); 1027 1028 return v; 1029 } 1030 1031 case 'R': 1032 { 1033 int ref = parseInt(); 1034 1035 return _refs.get(ref); 1036 } 1037 1038 case 'r': 1039 { 1040 String type = readType(); 1041 String url = readString(); 1042 1043 return resolveRemote(type, url); 1044 } 1045 } 1046 1047 _peek = tag; 1048 1049 Object value = _serializerFactory.getDeserializer(cl).readObject(this); 1050 1051 return value; 1052 } 1053 1054 1058 public Object readObject() 1059 throws IOException 1060 { 1061 int tag = read(); 1062 1063 switch (tag) { 1064 case 'N': 1065 return null; 1066 1067 case 'T': 1068 return new Boolean (true); 1069 1070 case 'F': 1071 return new Boolean (false); 1072 1073 case 'I': 1074 return new Integer (parseInt()); 1075 1076 case 'L': 1077 return new Long (parseLong()); 1078 1079 case 'D': 1080 return new Double (parseDouble()); 1081 1082 case 'd': 1083 return new Date (parseLong()); 1084 1085 case 'x': 1086 case 'X': { 1087 _isLastChunk = tag == 'X'; 1088 _chunkLength = (read() << 8) + read(); 1089 1090 return parseXML(); 1091 } 1092 1093 case 's': 1094 case 'S': { 1095 _isLastChunk = tag == 'S'; 1096 _chunkLength = (read() << 8) + read(); 1097 1098 int data; 1099 _sbuf.setLength(0); 1100 1101 while ((data = parseChar()) >= 0) 1102 _sbuf.append((char) data); 1103 1104 return _sbuf.toString(); 1105 } 1106 1107 case 'b': 1108 case 'B': { 1109 _isLastChunk = tag == 'B'; 1110 _chunkLength = (read() << 8) + read(); 1111 1112 int data; 1113 ByteArrayOutputStream bos = new ByteArrayOutputStream (); 1114 1115 while ((data = parseByte()) >= 0) 1116 bos.write(data); 1117 1118 return bos.toByteArray(); 1119 } 1120 1121 case 'V': { 1122 String type = readType(); 1123 int length = readLength(); 1124 1125 return _serializerFactory.readList(this, length, type); 1126 } 1127 1128 case 'M': { 1129 String type = readType(); 1130 1131 return _serializerFactory.readMap(this, type); 1132 } 1133 1134 case 'R': { 1135 int ref = parseInt(); 1136 1137 return _refs.get(ref); 1138 } 1139 1140 case 'r': { 1141 String type = readType(); 1142 String url = readString(); 1143 1144 return resolveRemote(type, url); 1145 } 1146 1147 default: 1148 throw error("unknown code:" + (char) tag); 1149 } 1150 } 1151 1152 1155 public Object readRemote() 1156 throws IOException 1157 { 1158 String type = readType(); 1159 String url = readString(); 1160 1161 return resolveRemote(type, url); 1162 } 1163 1164 1167 public Object readRef() 1168 throws IOException 1169 { 1170 return _refs.get(parseInt()); 1171 } 1172 1173 1176 public int readListStart() 1177 throws IOException 1178 { 1179 return read(); 1180 } 1181 1182 1185 public int readMapStart() 1186 throws IOException 1187 { 1188 return read(); 1189 } 1190 1191 1194 public boolean isEnd() 1195 throws IOException 1196 { 1197 int code = read(); 1198 1199 _peek = code; 1200 1201 return (code < 0 || code == 'z'); 1202 } 1203 1204 1207 public void readEnd() 1208 throws IOException 1209 { 1210 int code = read(); 1211 1212 if (code != 'z') 1213 throw error("unknown code:" + (char) code); 1214 } 1215 1216 1219 public void readMapEnd() 1220 throws IOException 1221 { 1222 int code = read(); 1223 1224 if (code != 'z') 1225 throw error("expected end of map ('z') at '" + (char) code + "'"); 1226 } 1227 1228 1231 public void readListEnd() 1232 throws IOException 1233 { 1234 int code = read(); 1235 1236 if (code != 'z') 1237 throw error("expected end of list ('z') at '" + (char) code + "'"); 1238 } 1239 1240 1243 public int addRef(Object ref) 1244 { 1245 if (_refs == null) 1246 _refs = new ArrayList (); 1247 1248 _refs.add(ref); 1249 1250 return _refs.size() - 1; 1251 } 1252 1253 1256 public void setRef(int i, Object ref) 1257 { 1258 _refs.set(i, ref); 1259 } 1260 1261 1264 public Object resolveRemote(String type, String url) 1265 throws IOException 1266 { 1267 HessianRemoteResolver resolver = getRemoteResolver(); 1268 1269 if (resolver != null) 1270 return resolver.lookup(type, url); 1271 else 1272 return new HessianRemote(type, url); 1273 } 1274 1275 1282 public String readType() 1283 throws IOException 1284 { 1285 int code = read(); 1286 1287 if (code != 't') { 1288 _peek = code; 1289 return ""; 1290 } 1291 1292 _isLastChunk = true; 1293 _chunkLength = (read() << 8) + read(); 1294 1295 _sbuf.setLength(0); 1296 int ch; 1297 while ((ch = parseChar()) >= 0) 1298 _sbuf.append((char) ch); 1299 1300 return _sbuf.toString(); 1301 } 1302 1303 1310 public int readLength() 1311 throws IOException 1312 { 1313 int code = read(); 1314 1315 if (code != 'l') { 1316 _peek = code; 1317 return -1; 1318 } 1319 1320 return parseInt(); 1321 } 1322 1323 1330 private int parseInt() 1331 throws IOException 1332 { 1333 int b32 = read(); 1334 int b24 = read(); 1335 int b16 = read(); 1336 int b8 = read(); 1337 1338 return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8; 1339 } 1340 1341 1348 private long parseLong() 1349 throws IOException 1350 { 1351 long b64 = read(); 1352 long b56 = read(); 1353 long b48 = read(); 1354 long b40 = read(); 1355 long b32 = read(); 1356 long b24 = read(); 1357 long b16 = read(); 1358 long b8 = read(); 1359 1360 return ((b64 << 56) + 1361 (b56 << 48) + 1362 (b48 << 40) + 1363 (b40 << 32) + 1364 (b32 << 24) + 1365 (b24 << 16) + 1366 (b16 << 8) + 1367 b8); 1368 } 1369 1370 1377 private double parseDouble() 1378 throws IOException 1379 { 1380 long b64 = read(); 1381 long b56 = read(); 1382 long b48 = read(); 1383 long b40 = read(); 1384 long b32 = read(); 1385 long b24 = read(); 1386 long b16 = read(); 1387 long b8 = read(); 1388 1389 long bits = ((b64 << 56) + 1390 (b56 << 48) + 1391 (b48 << 40) + 1392 (b40 << 32) + 1393 (b32 << 24) + 1394 (b24 << 16) + 1395 (b16 << 8) + 1396 b8); 1397 1398 return Double.longBitsToDouble(bits); 1399 } 1400 1401 org.w3c.dom.Node parseXML() 1402 throws IOException 1403 { 1404 throw new UnsupportedOperationException (); 1405 } 1406 1407 1410 private int parseChar() 1411 throws IOException 1412 { 1413 while (_chunkLength <= 0) { 1414 if (_isLastChunk) 1415 return -1; 1416 1417 int code = read(); 1418 1419 switch (code) { 1420 case 's': 1421 case 'x': 1422 _isLastChunk = false; 1423 1424 _chunkLength = (read() << 8) + read(); 1425 break; 1426 1427 case 'S': 1428 case 'X': 1429 _isLastChunk = true; 1430 1431 _chunkLength = (read() << 8) + read(); 1432 break; 1433 1434 default: 1435 throw expect("string", code); 1436 } 1437 1438 } 1439 1440 _chunkLength--; 1441 1442 return parseUTF8Char(); 1443 } 1444 1445 1448 private int parseUTF8Char() 1449 throws IOException 1450 { 1451 int ch = read(); 1452 1453 if (ch < 0x80) 1454 return ch; 1455 else if ((ch & 0xe0) == 0xc0) { 1456 int ch1 = read(); 1457 int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f); 1458 1459 return v; 1460 } 1461 else if ((ch & 0xf0) == 0xe0) { 1462 int ch1 = read(); 1463 int ch2 = read(); 1464 int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f); 1465 1466 return v; 1467 } 1468 else 1469 throw error("bad utf-8 encoding"); 1470 } 1471 1472 1475 private int parseByte() 1476 throws IOException 1477 { 1478 while (_chunkLength <= 0) { 1479 if (_isLastChunk) { 1480 return -1; 1481 } 1482 1483 int code = read(); 1484 1485 switch (code) { 1486 case 'b': 1487 _isLastChunk = false; 1488 1489 _chunkLength = (read() << 8) + read(); 1490 break; 1491 1492 case 'B': 1493 _isLastChunk = true; 1494 1495 _chunkLength = (read() << 8) + read(); 1496 break; 1497 1498 default: 1499 throw expect("byte[]", code); 1500 } 1501 } 1502 1503 _chunkLength--; 1504 1505 return read(); 1506 } 1507 1508 1511 public InputStream readInputStream() 1512 throws IOException 1513 { 1514 int tag = read(); 1515 1516 switch (tag) { 1517 case 'N': 1518 return null; 1519 1520 case 'B': 1521 case 'b': 1522 _isLastChunk = tag == 'B'; 1523 _chunkLength = (read() << 8) + read(); 1524 break; 1525 1526 default: 1527 throw expect("inputStream", tag); 1528 } 1529 1530 return new InputStream () { 1531 boolean _isClosed = false; 1532 1533 public int read() 1534 throws IOException 1535 { 1536 if (_isClosed) 1537 return -1; 1538 1539 int ch = parseByte(); 1540 if (ch < 0) 1541 _isClosed = true; 1542 1543 return ch; 1544 } 1545 1546 public int read(byte []buffer, int offset, int length) 1547 throws IOException 1548 { 1549 if (_isClosed) 1550 return -1; 1551 1552 int len = HessianInput.this.read(buffer, offset, length); 1553 if (len < 0) 1554 _isClosed = true; 1555 1556 return len; 1557 } 1558 1559 public void close() 1560 throws IOException 1561 { 1562 while (read() >= 0) { 1563 } 1564 } 1565 }; 1566 } 1567 1568 1571 int read(byte []buffer, int offset, int length) 1572 throws IOException 1573 { 1574 int readLength = 0; 1575 1576 while (length > 0) { 1577 while (_chunkLength <= 0) { 1578 if (_isLastChunk) 1579 return readLength == 0 ? -1 : readLength; 1580 1581 int code = read(); 1582 1583 switch (code) { 1584 case 'b': 1585 _isLastChunk = false; 1586 1587 _chunkLength = (read() << 8) + read(); 1588 break; 1589 1590 case 'B': 1591 _isLastChunk = true; 1592 1593 _chunkLength = (read() << 8) + read(); 1594 break; 1595 1596 default: 1597 throw expect("byte[]", code); 1598 } 1599 } 1600 1601 int sublen = _chunkLength; 1602 if (length < sublen) 1603 sublen = length; 1604 1605 sublen = _is.read(buffer, offset, sublen); 1606 offset += sublen; 1607 readLength += sublen; 1608 length -= sublen; 1609 _chunkLength -= sublen; 1610 } 1611 1612 return readLength; 1613 } 1614 1615 final int read() 1616 throws IOException 1617 { 1618 if (_peek >= 0) { 1619 int value = _peek; 1620 _peek = -1; 1621 return value; 1622 } 1623 1624 int ch = _is.read(); 1625 1626 return ch; 1627 } 1628 1629 public Reader getReader() 1630 { 1631 return null; 1632 } 1633 1634 protected IOException expect(String expect, int ch) 1635 { 1636 if (ch < 0) 1637 return error("expected " + expect + " at end of file"); 1638 else 1639 return error("expected " + expect + " at " + (char) ch); 1640 } 1641 1642 protected IOException error(String message) 1643 { 1644 if (_method != null) 1645 return new HessianProtocolException(_method + ": " + message); 1646 else 1647 return new HessianProtocolException(message); 1648 } 1649 1650 static { 1651 try { 1652 _detailMessageField = Throwable .class.getDeclaredField("detailMessage"); 1653 _detailMessageField.setAccessible(true); 1654 } catch (Throwable e) { 1655 } 1656 } 1657} 1658 | Popular Tags |