1 29 30 package com.caucho.quercus.env; 31 32 import com.caucho.quercus.QuercusException; 33 import com.caucho.quercus.expr.Expr; 34 import com.caucho.quercus.expr.StringLiteralExpr; 35 import com.caucho.quercus.program.AbstractFunction; 36 import com.caucho.vfs.WriteStream; 37 38 import java.io.IOException ; 39 import java.io.ObjectInputStream ; 40 import java.io.ObjectOutputStream ; 41 import java.io.Serializable ; 42 import java.util.*; 43 44 47 public class ObjectExtValue extends ObjectValue 48 implements Serializable 49 { 50 private static final StringValue TO_STRING = new StringValueImpl("__toString"); 51 52 private static final int DEFAULT_SIZE = 16; 53 54 private QuercusClass _cl; 55 56 private Entry []_entries; 57 private int _hashMask; 58 59 private int _size; 60 61 public ObjectExtValue(QuercusClass cl) 62 { 63 _cl = cl; 64 65 init(); 66 } 67 68 private void init() 69 { 70 _entries = new Entry[DEFAULT_SIZE]; 71 _hashMask = _entries.length - 1; 72 } 73 74 85 86 89 public String getName() 90 { 91 return _cl.getName(); 92 } 93 94 97 public String getParentName() 98 { 99 return _cl.getParentName(); 100 } 101 102 105 public QuercusClass getQuercusClass() 106 { 107 return _cl; 108 } 109 110 113 public String getType() 114 { 115 return "object"; 116 } 117 118 121 public boolean toBoolean() 122 { 123 return true; 124 } 125 126 129 public boolean isA(String name) 130 { 131 return _cl.isA(name); 132 } 133 134 137 public boolean isObject() 138 { 139 return true; 140 } 141 142 145 public long toLong() 146 { 147 return 1; 148 } 149 150 153 public double toDouble() 154 { 155 return toLong(); 156 } 157 158 161 public int getSize() 162 { 163 return _size; 164 } 165 166 169 @Override 170 public Value getField(Env env, String key) 171 { 172 int capacity = _entries.length; 173 174 int hashMask = _hashMask; 175 int hash = key.hashCode() & hashMask; 176 177 int count = capacity; 178 for (; count >= 0; count--) { 179 Entry entry = _entries[hash]; 180 181 if (entry == null) { 182 return _cl.getField(env, this, key); 183 } 184 else if (key.equals(entry.getKey())) { 185 return entry.getValue(); 186 } 187 188 hash = (hash + 1) & hashMask; 189 } 190 191 return _cl.getField(env, this, key); 192 } 193 194 197 public Var getFieldRef(Env env, String index) 198 { 199 Entry entry = createEntry(index); 200 201 Value value = entry._value; 202 203 if (value instanceof Var) 204 return (Var) value; 205 206 Var var = new Var(value); 207 208 entry.setValue(var); 209 210 return var; 211 } 212 213 216 public Value getFieldArg(Env env, String index) 217 { 218 Entry entry = getEntry(index); 219 220 if (entry != null) 221 return entry.toArg(); 222 else 223 return new ArgGetFieldValue(env, this, index); 224 } 225 226 229 public Value getFieldArgRef(Env env, String index) 230 { 231 Entry entry = getEntry(index); 232 233 if (entry != null) 234 return entry.toArg(); 235 else 236 return new ArgGetFieldValue(env, this, index); 237 } 238 239 242 private Entry getEntry(String key) 243 { 244 int capacity = _entries.length; 245 246 int hash = key.hashCode() & _hashMask; 247 248 int count = capacity; 249 for (; count >= 0; count--) { 250 Entry entry = _entries[hash]; 251 252 if (entry == null) 253 return null; 254 else if (key.equals(entry.getKey())) 255 return entry; 256 257 hash = (hash + 1) & _hashMask; 258 } 259 260 return null; 261 } 262 263 266 public Value get(Value key) 267 { 268 return getField(null, key.toString()); 270 } 271 272 public Value put(Value index, Value value) 273 { 274 throw new QuercusException(L.l("Object of type '{0}' cannot be used as an array", 275 getClassName())); 276 } 277 278 public Value put(Value value) 279 { 280 throw new QuercusException(L.l("Object of type '{0}' cannot be used as an array", 281 getClassName())); 282 } 283 284 287 public Value putFieldInit(Env env, String key, Value value) 288 { 289 createEntry(key); 290 291 return putField(env, key, value); 292 } 293 294 297 @Override 298 public Value putField(Env env, String key, Value value) 299 { 300 Entry entry = null; 301 302 AbstractFunction setField = _cl.getSetField(); 303 if (setField != null) { 304 entry = getEntry(key); 305 306 if (entry == null) 307 return setField.callMethod(env, this, new StringValueImpl(key), value); 308 } 309 else 310 entry = createEntry(key); 311 312 Value oldValue = entry._value; 313 314 if (value instanceof Var) { 315 Var var = (Var) value; 316 var.setReference(); 317 318 entry._value = var; 319 } 320 else if (oldValue instanceof Var) { 321 oldValue.set(value); 322 } 323 else { 324 entry._value = value; 325 } 326 327 return value; 328 } 329 330 333 public Value putField(String key, String value) 334 { 335 return putField(null, key, new StringValueImpl(value)); 336 } 337 338 341 public Value putField(String key, long value) 342 { 343 return putField(null, key, LongValue.create(value)); 344 } 345 346 349 public Value putField(String key, double value) 350 { 351 return putField(null, key, DoubleValue.create(value)); 352 } 353 354 357 public void removeField(String key) 358 { 359 int capacity = _entries.length; 360 361 int hash = key.hashCode() & _hashMask; 362 363 int count = capacity; 364 for (; count >= 0; count--) { 365 Entry entry = _entries[hash]; 366 367 if (entry == null) 368 return; 369 else if (key.equals(entry.getKey())) { 370 _size--; 371 372 _entries[hash] = null; 373 shiftEntries(hash + 1); 374 375 return; 376 } 377 378 hash = (hash + 1) & _hashMask; 379 } 380 } 381 382 385 private void shiftEntries(int index) 386 { 387 int capacity = _entries.length; 388 389 for (; index < capacity; index++) { 390 Entry entry = _entries[index]; 391 392 if (entry == null) 393 return; 394 395 _entries[index] = null; 396 397 addEntry(entry); 398 } 399 } 400 401 404 private Entry createEntry(String key) 405 { 406 int capacity = _entries.length; 407 408 int hashMask = _hashMask; 409 410 int hash = key.hashCode() & hashMask; 411 412 int count = capacity; 413 for (; count >= 0; count--) { 414 Entry entry = _entries[hash]; 415 416 if (entry == null) 417 break; 418 else if (key.equals(entry.getKey())) 419 return entry; 420 421 hash = (hash + 1) & hashMask; 422 } 423 424 _size++; 425 426 Entry newEntry = new Entry(key); 427 _entries[hash] = newEntry; 428 429 if (_entries.length <= 2 * _size) 430 expand(); 431 432 return newEntry; 433 } 434 435 private void expand() 436 { 437 Entry []entries = _entries; 438 439 _entries = new Entry[2 * entries.length]; 440 _hashMask = _entries.length - 1; 441 442 for (int i = entries.length - 1; i >= 0; i--) { 443 Entry entry = entries[i]; 444 445 if (entry != null) 446 addEntry(entry); 447 } 448 } 449 450 private void addEntry(Entry entry) 451 { 452 int capacity = _entries.length; 453 454 int hash = entry.getKey().hashCode() & _hashMask; 455 456 for (int i = capacity; i >= 0; i--) { 457 if (_entries[hash] == null) { 458 _entries[hash] = entry; 459 return; 460 } 461 462 hash = (hash + 1) & _hashMask; 463 } 464 } 465 466 469 public Value []getKeyArray() 470 { 471 Value []keys = new Value[getSize()]; 472 473 int k = 0; 474 for (int i = 0; i < _entries.length; i++) { 475 Entry entry = _entries[i]; 476 477 if (entry != null) 478 keys[k++] = new StringValueImpl(entry.getKey()); 479 } 480 481 return keys; 482 } 483 484 487 public Value []getValueArray(Env env) 488 { 489 Value []values = new Value[getSize()]; 490 491 int k = 0; 492 for (int i = 0; i < _entries.length; i++) { 493 Entry entry = _entries[i]; 494 495 if (entry != null) 496 values[k++] = entry.getValue().toValue(); 497 } 498 499 return values; 500 } 501 502 505 public Collection<Value> getIndices() 506 { 507 ArrayList<Value> indices = new ArrayList<Value>(); 508 509 for (int i = 0; i < _entries.length; i++) { 510 Entry entry = _entries[i]; 511 512 if (entry != null) 513 indices.add(new StringValueImpl(entry.getKey())); 514 } 515 516 return indices; 517 } 518 519 522 public AbstractFunction findFunction(String methodName) 523 { 524 return _cl.findFunction(methodName); 525 } 526 527 530 public Value callMethod(Env env, String methodName, Expr []args) 531 { 532 AbstractFunction fun = _cl.findFunction(methodName); 533 534 if (fun != null) 535 return fun.callMethod(env, this, args); 536 else if (_cl.getCall() != null) { 537 Expr []newArgs = new Expr[args.length + 1]; 538 newArgs[0] = new StringLiteralExpr(methodName); 539 System.arraycopy(args, 0, newArgs, 1, args.length); 540 541 return _cl.getCall().callMethod(env, this, newArgs); 542 } 543 else 544 return env.error(L.l("Call to undefined method {0}::{1}", 545 _cl.getName(), methodName)); 546 } 547 548 551 public Value callMethod(Env env, String methodName, Value []args) 552 { 553 AbstractFunction fun = _cl.findFunction(methodName); 554 555 if (fun != null) 556 return fun.callMethod(env, this, args); 557 else if (_cl.getCall() != null) { 558 StringValueImpl name = new StringValueImpl(methodName); 559 ArrayValue newArgs = new ArrayValueImpl(); 560 561 for (int i = 0; i < args.length; i++) 562 newArgs.append(args[i]); 563 564 return _cl.getCall().callMethod(env, this, name, newArgs); 565 } 566 else 567 return env.error(L.l("Call to undefined method {0}::{1}()", 568 _cl.getName(), methodName)); 569 } 570 571 574 public Value callMethod(Env env, String methodName) 575 { 576 AbstractFunction fun = _cl.findFunction(methodName); 577 578 if (fun != null) 579 return fun.callMethod(env, this); 580 else if (_cl.getCall() != null) { 581 return _cl.getCall().callMethod(env, 582 this, 583 new StringValueImpl(methodName), 584 new ArrayValueImpl()); 585 } 586 else 587 return env.error(L.l("Call to undefined method {0}::{1}()", 588 _cl.getName(), methodName)); 589 } 590 591 594 public Value callMethod(Env env, String methodName, Value a0) 595 { 596 AbstractFunction fun = _cl.findFunction(methodName); 597 598 if (fun != null) 599 return fun.callMethod(env, this, a0); 600 else if (_cl.getCall() != null) { 601 return _cl.getCall().callMethod(env, 602 this, 603 new StringValueImpl(methodName), 604 new ArrayValueImpl() 605 .append(a0)); 606 } 607 else 608 return env.error(L.l("Call to undefined method {0}::{1}()", 609 _cl.getName(), methodName)); 610 } 611 612 615 public Value callMethod(Env env, String methodName, 616 Value a0, Value a1) 617 { 618 AbstractFunction fun = _cl.findFunction(methodName); 619 620 if (fun != null) 621 return fun.callMethod(env, this, a0, a1); 622 else if (_cl.getCall() != null) { 623 return _cl.getCall().callMethod(env, 624 this, 625 new StringValueImpl(methodName), 626 new ArrayValueImpl() 627 .append(a0) 628 .append(a1)); 629 } 630 else 631 return env.error(L.l("Call to undefined method {0}::{1}()", 632 _cl.getName(), methodName)); 633 } 634 635 638 public Value callMethod(Env env, String methodName, 639 Value a0, Value a1, Value a2) 640 { 641 AbstractFunction fun = _cl.findFunction(methodName); 642 643 if (fun != null) 644 return fun.callMethod(env, this, a0, a1, a2); 645 else if (_cl.getCall() != null) { 646 return _cl.getCall().callMethod(env, 647 this, 648 new StringValueImpl(methodName), 649 new ArrayValueImpl().append(a0) 650 .append(a1) 651 .append(a2)); 652 } 653 else 654 return env.error(L.l("Call to undefined method {0}::{1}()", 655 _cl.getName(), methodName)); 656 } 657 658 661 public Value callMethod(Env env, String methodName, 662 Value a0, Value a1, Value a2, Value a3) 663 { 664 AbstractFunction fun = _cl.findFunction(methodName); 665 666 if (fun != null) 667 return fun.callMethod(env, this, a0, a1, a2, a3); 668 else if (_cl.getCall() != null) { 669 return _cl.getCall().callMethod(env, 670 this, 671 new StringValueImpl(methodName), 672 new ArrayValueImpl() 673 .append(a0) 674 .append(a1) 675 .append(a2) 676 .append(a3)); 677 } 678 else 679 return env.error(L.l("Call to undefined method {0}::{1}()", 680 _cl.getName(), methodName)); 681 } 682 683 686 public Value callMethod(Env env, String methodName, 687 Value a0, Value a1, Value a2, Value a3, Value a4) 688 { 689 AbstractFunction fun = _cl.findFunction(methodName); 690 691 if (fun != null) 692 return fun.callMethod(env, this, a0, a1, a2, a3, a4); 693 else if (_cl.getCall() != null) { 694 return _cl.getCall().callMethod(env, 695 this, 696 new StringValueImpl(methodName), 697 new ArrayValueImpl() 698 .append(a0) 699 .append(a1) 700 .append(a2) 701 .append(a3) 702 .append(a4)); 703 } 704 else 705 return env.error(L.l("Call to undefined method {0}::{1}()", 706 _cl.getName(), methodName)); 707 } 708 709 712 public Value callMethodRef(Env env, String methodName, Expr []args) 713 { 714 return _cl.getFunction(methodName).callMethodRef(env, this, args); 715 } 716 717 720 public Value callMethodRef(Env env, String methodName, Value []args) 721 { 722 AbstractFunction fun = _cl.findFunction(methodName); 723 724 if (fun != null) 725 return fun.callMethodRef(env, this, args); 726 else if (_cl.getCall() != null) { 727 StringValueImpl name = new StringValueImpl(methodName); 728 ArrayValue newArgs = new ArrayValueImpl(); 729 730 for (int i = 0; i < args.length; i++) 731 newArgs.append(args[i]); 732 733 return _cl.getCall().callMethodRef(env, this, name, newArgs); 734 } 735 else 736 return env.error(L.l("Call to undefined method {0}::{1}()", 737 _cl.getName(), methodName)); 738 } 739 740 743 public Value callMethodRef(Env env, String methodName) 744 { 745 AbstractFunction fun = _cl.findFunction(methodName); 746 747 if (fun != null) 748 return fun.callMethodRef(env, this); 749 else if (_cl.getCall() != null) { 750 return _cl.getCall().callMethodRef(env, 751 this, 752 new StringValueImpl(methodName), 753 new ArrayValueImpl()); 754 } 755 else 756 return env.error(L.l("Call to undefined method {0}::{1}()", 757 _cl.getName(), methodName)); 758 } 759 760 763 public Value callMethodRef(Env env, String methodName, Value a0) 764 { 765 AbstractFunction fun = _cl.findFunction(methodName); 766 767 if (fun != null) 768 return fun.callMethodRef(env, this, a0); 769 else if (_cl.getCall() != null) { 770 return _cl.getCall().callMethodRef(env, 771 this, 772 new StringValueImpl(methodName), 773 new ArrayValueImpl() 774 .append(a0)); 775 } 776 else 777 return env.error(L.l("Call to undefined method {0}::{1}()", 778 _cl.getName(), methodName)); 779 } 780 781 784 public Value callMethodRef(Env env, String methodName, 785 Value a0, Value a1) 786 { 787 AbstractFunction fun = _cl.findFunction(methodName); 788 789 if (fun != null) 790 return fun.callMethodRef(env, this, a0, a1); 791 else if (_cl.getCall() != null) { 792 return _cl.getCall().callMethodRef(env, 793 this, 794 new StringValueImpl(methodName), 795 new ArrayValueImpl() 796 .append(a0) 797 .append(a1)); 798 } 799 else 800 return env.error(L.l("Call to undefined method {0}::{1}()", 801 _cl.getName(), methodName)); 802 } 803 804 807 public Value callMethodRef(Env env, String methodName, 808 Value a0, Value a1, Value a2) 809 { 810 AbstractFunction fun = _cl.findFunction(methodName); 811 812 if (fun != null) 813 return fun.callMethodRef(env, this, a0, a1, a2); 814 else if (_cl.getCall() != null) { 815 return _cl.getCall().callMethodRef(env, 816 this, 817 new StringValueImpl(methodName), 818 new ArrayValueImpl() 819 .append(a0) 820 .append(a1) 821 .append(a2)); 822 } 823 else 824 return env.error(L.l("Call to undefined method {0}::{1}()", 825 _cl.getName(), methodName)); 826 } 827 828 831 public Value callMethodRef(Env env, String methodName, 832 Value a0, Value a1, Value a2, Value a3) 833 { 834 AbstractFunction fun = _cl.findFunction(methodName); 835 836 if (fun != null) 837 return fun.callMethodRef(env, this, a0, a1, a2, a3); 838 else if (_cl.getCall() != null) { 839 return _cl.getCall().callMethodRef(env, 840 this, 841 new StringValueImpl(methodName), 842 new ArrayValueImpl() 843 .append(a0) 844 .append(a1) 845 .append(a2) 846 .append(a3)); 847 } 848 else 849 return env.error(L.l("Call to undefined method {0}::{1}()", 850 _cl.getName(), methodName)); 851 } 852 853 856 public Value callMethodRef(Env env, String methodName, 857 Value a0, Value a1, Value a2, Value a3, Value a4) 858 { 859 AbstractFunction fun = _cl.findFunction(methodName); 860 861 if (fun != null) 862 return fun.callMethodRef(env, this, a0, a1, a2, a3, a4); 863 else if (_cl.getCall() != null) { 864 return _cl.getCall().callMethodRef(env, 865 this, 866 new StringValueImpl(methodName), 867 new ArrayValueImpl() 868 .append(a0) 869 .append(a1) 870 .append(a2) 871 .append(a3) 872 .append(a4)); 873 } 874 else 875 return env.error(L.l("Call to undefined method {0}::{1}()", 876 _cl.getName(), methodName)); 877 } 878 879 882 public Value callClassMethod(Env env, AbstractFunction fun, Value []args) 883 { 884 return fun.callMethod(env, this, args); 885 } 886 887 891 public Value getObject(Env env) 892 { 893 return this; 894 } 895 896 899 public Value copy() 900 { 901 return this; 902 } 903 904 907 public Value copy(Env env, IdentityHashMap<Value,Value> map) 908 { 909 Value oldValue = map.get(this); 910 911 if (oldValue != null) 912 return oldValue; 913 914 917 return this; 918 } 919 920 923 public Value clone() 924 { 925 ObjectExtValue newObject = new ObjectExtValue(_cl); 926 927 for (Map.Entry<String ,Value> entry : entrySet()) 928 newObject.putField(null, entry.getKey(), entry.getValue()); 929 930 return newObject; 931 } 932 933 935 938 public void serialize(StringBuilder sb) 939 { 940 sb.append("O:"); 941 sb.append(_cl.getName().length()); 942 sb.append(":\""); 943 sb.append(_cl.getName()); 944 sb.append("\":"); 945 sb.append(getSize()); 946 sb.append(":{"); 947 948 for (Map.Entry<String ,Value> entry : entrySet()) { 949 String key = entry.getKey(); 950 951 sb.append("s:"); 952 sb.append(key.length()); 953 sb.append(":\""); 954 sb.append(key); 955 sb.append("\";"); 956 957 entry.getValue().serialize(sb); 958 } 959 960 sb.append("}"); 961 } 962 963 967 public StringValue toString(Env env) 968 { 969 AbstractFunction fun = _cl.findFunction("__toString"); 970 971 if (fun != null) 972 return fun.callMethod(env, this, new Expr[0]).toStringValue(); 973 else 974 return new StringValueImpl(_cl.getName() + "[]"); 975 } 976 977 981 public void print(Env env) 982 { 983 env.print(toString(env)); 984 } 985 986 989 public Value toArray() 990 { 991 ArrayValue array = new ArrayValueImpl(); 992 993 for (Map.Entry<String ,Value> entry : entrySet()) { 994 array.put(new StringValueImpl(entry.getKey()), entry.getValue()); 995 } 996 997 return array; 998 } 999 1000 1003 public Value toObject(Env env) 1004 { 1005 return this; 1006 } 1007 1008 1011 public Object toJavaObject() 1012 { 1013 return this; 1014 } 1015 1016 public Set<Map.Entry<String ,Value>> entrySet() 1017 { 1018 return new EntrySet(); 1019 } 1020 1021 1024 public Set<Map.Entry<String ,Value>> sortedEntrySet() 1025 { 1026 return new TreeSet<Map.Entry<String , Value>>(entrySet()); 1027 } 1028 1029 public String toString() 1030 { 1031 return "ObjectExtValue@" + System.identityHashCode(this) + "[" + _cl.getName() + "]"; 1032 } 1033 1034 public void varDumpImpl(Env env, 1035 WriteStream out, 1036 int depth, 1037 IdentityHashMap<Value, String > valueSet) 1038 throws IOException 1039 { 1040 out.println("object(" + getName() + ") (" + getSize() + ") {"); 1041 1042 for (Map.Entry<String ,Value> mapEntry : sortedEntrySet()) { 1043 ObjectExtValue.Entry entry = (ObjectExtValue.Entry) mapEntry; 1044 1045 entry.varDumpImpl(env, out, depth + 1, valueSet); 1046 } 1047 1048 printDepth(out, 2 * depth); 1049 1050 out.print("}"); 1051 } 1052 1053 protected void printRImpl(Env env, 1054 WriteStream out, 1055 int depth, 1056 IdentityHashMap<Value, String > valueSet) 1057 throws IOException 1058 { 1059 out.print(_cl.getName()); 1060 out.print(' '); 1061 out.println("Object"); 1062 printDepth(out, 4 * depth); 1063 out.println("("); 1064 1065 for (Map.Entry<String ,Value> mapEntry : sortedEntrySet()) { 1066 ObjectExtValue.Entry entry = (ObjectExtValue.Entry) mapEntry; 1067 1068 entry.printRImpl(env, out, depth + 1, valueSet); 1069 } 1070 1071 printDepth(out, 4 * depth); 1072 out.println(")"); 1073 } 1074 1075 1079 private void writeObject(ObjectOutputStream out) 1080 throws IOException 1081 { 1082 out.writeObject(_cl.getName()); 1083 1084 out.writeInt(_size); 1085 1086 for (Map.Entry<String ,Value> entry : entrySet()) { 1087 out.writeObject(entry.getKey()); 1088 out.writeObject(entry.getValue()); 1089 } 1090 } 1091 1092 private void readObject(ObjectInputStream in) 1093 throws ClassNotFoundException , IOException 1094 { 1095 Env env = Env.getInstance(); 1096 String name = (String ) in.readObject(); 1097 1098 _cl = env.findClass(name); 1099 1100 init(); 1101 1102 if (_cl != null) { 1103 } 1104 else { 1105 _cl = env.getQuercus().getStdClass(); 1106 1107 putField(env, 1108 "__Quercus_Class_Definition_Not_Found", 1109 new StringValueImpl(name)); 1110 } 1111 1112 int size = in.readInt(); 1113 1114 for (int i = 0; i < size; i++) { 1115 putField(env, (String ) in.readObject(), (Value) in.readObject()); 1116 } 1117 } 1118 1119 public class EntrySet extends AbstractSet<Map.Entry<String ,Value>> { 1120 EntrySet() 1121 { 1122 } 1123 1124 public int size() 1125 { 1126 return ObjectExtValue.this.getSize(); 1127 } 1128 1129 public Iterator<Map.Entry<String ,Value>> iterator() 1130 { 1131 return new EntryIterator(ObjectExtValue.this._entries); 1132 } 1133 } 1134 1135 public static class EntryIterator 1136 implements Iterator<Map.Entry<String ,Value>> { 1137 private final Entry []_list; 1138 private int _index; 1139 1140 EntryIterator(Entry []list) 1141 { 1142 _list = list; 1143 } 1144 1145 public boolean hasNext() 1146 { 1147 for (; _index < _list.length && _list[_index] == null; _index++) { 1148 } 1149 1150 return _index < _list.length; 1151 } 1152 1153 public Map.Entry<String ,Value> next() 1154 { 1155 for (; _index < _list.length && _list[_index] == null; _index++) { 1156 } 1157 1158 if (_list.length <= _index) 1159 return null; 1160 1161 return _list[_index++]; 1162 } 1163 1164 public void remove() 1165 { 1166 throw new UnsupportedOperationException (); 1167 } 1168 } 1169 1170 public final static class Entry 1171 implements Map.Entry<String ,Value>, 1172 Comparable <Map.Entry<String , Value>> 1173 { 1174 private final String _key; 1175 private Value _value; 1176 1177 public Entry(String key) 1178 { 1179 _key = key; 1180 _value = NullValue.NULL; 1181 } 1182 1183 public Entry(String key, Value value) 1184 { 1185 _key = key; 1186 _value = value; 1187 } 1188 1189 public Value getValue() 1190 { 1191 return _value.toValue(); 1192 } 1193 1194 public String getKey() 1195 { 1196 return _key; 1197 } 1198 1199 public Value toValue() 1200 { 1201 return _value.toValue(); 1204 } 1205 1206 1209 public Var toRefVar() 1210 { 1211 Value val = _value; 1212 1213 if (val instanceof Var) 1214 return (Var) val; 1215 else { 1216 Var var = new Var(val); 1217 1218 _value = var; 1219 1220 return var; 1221 } 1222 } 1223 1224 1227 public Value toArgValue() 1228 { 1229 return _value.toValue(); 1230 } 1231 1232 public Value setValue(Value value) 1233 { 1234 Value oldValue = toValue(); 1235 1236 _value = value; 1237 1238 return oldValue; 1239 } 1240 1241 1244 public Value toRef() 1245 { 1246 Value value = _value; 1247 1248 if (value instanceof Var) 1249 return new RefVar((Var) value); 1250 else { 1251 Var var = new Var(_value); 1252 1253 _value = var; 1254 1255 return new RefVar(var); 1256 } 1257 } 1258 1259 1262 public Value toArgRef() 1263 { 1264 Value value = _value; 1265 1266 if (value instanceof Var) 1267 return new RefVar((Var) value); 1268 else { 1269 Var var = new Var(_value); 1270 1271 _value = var; 1272 1273 return new RefVar(var); 1274 } 1275 } 1276 1277 public Value toArg() 1278 { 1279 Value value = _value; 1280 1281 if (value instanceof Var) 1282 return value; 1283 else { 1284 Var var = new Var(_value); 1285 1286 _value = var; 1287 1288 return var; 1289 } 1290 } 1291 1292 public int compareTo(Map.Entry<String , Value> other) 1293 { 1294 if (other == null) 1295 return 1; 1296 1297 String thisKey = getKey(); 1298 String otherKey = other.getKey(); 1299 1300 if (thisKey == null) 1301 return otherKey == null ? 0 : -1; 1302 1303 if (otherKey == null) 1304 return 1; 1305 1306 return thisKey.compareTo(otherKey); 1307 } 1308 1309 public void varDumpImpl(Env env, 1310 WriteStream out, 1311 int depth, 1312 IdentityHashMap<Value, String > valueSet) 1313 throws IOException 1314 { 1315 printDepth(out, 2 * depth); 1316 out.println("[\"" + getKey() + "\"]=>"); 1317 1318 printDepth(out, 2 * depth); 1319 1320 _value.varDump(env, out, depth, valueSet); 1321 1322 out.println(); 1323 } 1324 1325 protected void printRImpl(Env env, 1326 WriteStream out, 1327 int depth, 1328 IdentityHashMap<Value, String > valueSet) 1329 throws IOException 1330 { 1331 printDepth(out, 4 * depth); 1332 out.print("[" + getKey() + "] => "); 1333 1334 _value.printR(env, out, depth + 1, valueSet); 1335 1336 out.println(); 1337 } 1338 1339 private void printDepth(WriteStream out, int depth) 1340 throws java.io.IOException 1341 { 1342 for (int i = 0; i < depth; i++) 1343 out.print(' '); 1344 } 1345 1346 public String toString() 1347 { 1348 return "ObjectExtValue.Entry[" + getKey() + "]"; 1349 } 1350 } 1351} 1352 1353 | Popular Tags |