comparison src/luan/LuanTable.java @ 72:cd9dbd7477ca

prevent stack overflow when printing table with circular references git-svn-id: https://luan-java.googlecode.com/svn/trunk@73 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Tue, 12 Feb 2013 05:44:15 +0000
parents f7e17cfb35f9
children 4bf3d0c0b6b9
comparison
equal deleted inserted replaced
71:5a93129995e1 72:cd9dbd7477ca
8 import java.util.ArrayList; 8 import java.util.ArrayList;
9 import java.util.Collections; 9 import java.util.Collections;
10 import java.util.Comparator; 10 import java.util.Comparator;
11 import java.util.Set; 11 import java.util.Set;
12 import java.util.HashSet; 12 import java.util.HashSet;
13 import java.util.IdentityHashMap;
13 14
14 15
15 public class LuanTable { 16 public class LuanTable {
16 private Map<Object,Object> map = null; 17 private Map<Object,Object> map = null;
17 private List<Object> list = null; 18 private List<Object> list = null;
78 } 79 }
79 return rtn; 80 return rtn;
80 } 81 }
81 82
82 @Override public String toString() { 83 @Override public String toString() {
84 return toString( Collections.newSetFromMap(new IdentityHashMap<LuanTable,Boolean>()) );
85 }
86
87 private String toString(Set<LuanTable> set) {
83 // return "table: " + Integer.toHexString(hashCode()); 88 // return "table: " + Integer.toHexString(hashCode());
89 if( !set.add(this) ) {
90 return "...";
91 }
84 StringBuilder sb = new StringBuilder(); 92 StringBuilder sb = new StringBuilder();
85 sb.append('{'); 93 sb.append('{');
86 boolean isFirst = true; 94 boolean isFirst = true;
87 if( list != null ) { 95 if( list != null ) {
88 boolean gotNull = false; 96 boolean gotNull = false;
96 } else { 104 } else {
97 sb.append(", "); 105 sb.append(", ");
98 } 106 }
99 if( gotNull ) 107 if( gotNull )
100 sb.append(i+1).append('='); 108 sb.append(i+1).append('=');
101 sb.append(Luan.toString(obj)); 109 sb.append(toString(set,obj));
102 } 110 }
103 } 111 }
104 } 112 }
105 if( map != null ) { 113 if( map != null ) {
106 for( Map.Entry<Object,Object> entry : map.entrySet() ) { 114 for( Map.Entry<Object,Object> entry : map.entrySet() ) {
107 if( isFirst ) { 115 if( isFirst ) {
108 isFirst = false; 116 isFirst = false;
109 } else { 117 } else {
110 sb.append(", "); 118 sb.append(", ");
111 } 119 }
112 sb.append(Luan.toString(entry.getKey())).append('=').append(Luan.toString(entry.getValue())); 120 sb.append(toString(set,entry.getKey())).append('=').append(toString(set,entry.getValue()));
113 } 121 }
114 } 122 }
115 sb.append('}'); 123 sb.append('}');
116 return sb.toString(); 124 return sb.toString();
125 }
126
127 private static String toString(Set<LuanTable> set,Object obj) {
128 if( obj instanceof LuanTable ) {
129 LuanTable t = (LuanTable)obj;
130 return t.toString(set);
131 } else {
132 return Luan.toString(obj);
133 }
117 } 134 }
118 135
119 public Object get(Object key) { 136 public Object get(Object key) {
120 if( list != null ) { 137 if( list != null ) {
121 Integer iT = Luan.asInteger(key); 138 Integer iT = Luan.asInteger(key);