Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

314
LINES

< > BotCompany Repo | #1005374 // structure function (v7, using one buffer, outdated)

JavaX fragment (include)

1  
sbool structure_showTiming;
2  
3  
static String structure(Object o) {
4  
  new HashSet refd;
5  
  new StringBuilder out;
6  
  structure_1(out, o, new structure_Data(refd));
7  
  long time = now();
8  
  S s = str(out);
9  
  out = null;
10  
  s = structure_2(s, refd);
11  
  if (structure_showTiming) done_always("structure_2", time);
12  
  ret s;
13  
}
14  
15  
// leave to false, unless unstructure() breaks
16  
static boolean structure_allowShortening = false;
17  
18  
static int structure_shareStringsLongerThan = 20;
19  
20  
static class structure_Data {
21  
  int stringSizeLimit;
22  
  new IdentityHashMap<O, Integer> seen;
23  
  HashSet<Integer> refd;
24  
  new HashMap<S, Int> strings;
25  
  new HashSet<S> concepts;
26  
  Class conceptClass = findClass("Concept");
27  
  
28  
  *(HashSet<Int> *refd) {}
29  
}
30  
31  
static void structure_1(StringBuilder out, Object o, structure_Data d) {
32  
  if (o == null) { out.append("null"); ret; }
33  
  
34  
  // these are never back-referenced (for readability)
35  
  
36  
  if (o instanceof BigInteger) {
37  
    out.append("bigint(").append(o).append(")"); ret;
38  
  }
39  
  
40  
  if (o instanceof Double) {
41  
    out.append("d(").append(quote(str(o))).append(")"); ret;
42  
  }
43  
    
44  
  if (o instanceof Float) {
45  
    out.append("fl ").append(quote(str(o))); ret;
46  
  }
47  
    
48  
  if (o instanceof Long) {
49  
    out.append(o).append("L"); ret;
50  
  }
51  
  
52  
  if (o instanceof Integer) {
53  
    out.append(str(o)); ret;
54  
  }
55  
    
56  
  if (o instanceof Boolean) {
57  
    out.append(((Boolean) o).booleanValue() ? "t" : "f"); ret;
58  
  }
59  
    
60  
  if (o instanceof Character) {
61  
    out.append(quoteCharacter((Character) o)); ret;
62  
  }
63  
    
64  
  if (o instanceof File) {
65  
    out.append("File ").append(quote(((File) o).getPath())); ret;
66  
  }
67  
    
68  
  // referencable objects follow
69  
  
70  
  Integer ref = null;
71  
  if (!(o instanceof S)) {
72  
    ref = d.seen.get(o);
73  
    if (ref != null) {
74  
      d.refd.add(ref);
75  
      out.append("r").append(ref); ret;
76  
    }
77  
  }
78  
  
79  
  if (o instanceof S && (ref = d.strings.get((S) o)) != null) {
80  
    d.refd.add(ref);
81  
    out.append("r").append(ref); ret;
82  
  }
83  
  
84  
  ref = d.seen.size()+1;
85  
  d.seen.put(o, ref);
86  
  out.append("m").append(ref).append(" "); // marker
87  
88  
  if (o instanceof S) {
89  
    S s = d.stringSizeLimit != 0 ? shorten((S) o, d.stringSizeLimit) : (S) o;
90  
    if (l(s) >= structure_shareStringsLongerThan)
91  
      d.strings.put(s, ref);
92  
    out.append(quote(s)); ret;
93  
  }
94  
    
95  
  if (o instanceof HashSet) {
96  
    out.append("hashset ");
97  
    structure_1(out, new ArrayList((Set) o), d);
98  
    ret;
99  
  }
100  
101  
  if (o instanceof TreeSet) {
102  
    out.append("treeset ");
103  
    structure_1(out, new ArrayList((Set) o), d);
104  
    ret;
105  
  }
106  
  
107  
  Class c = o.getClass();
108  
  String name = c.getName();
109  
  
110  
  if (o instanceof Collection && neq(name, "main$Concept$RefL")) {
111  
    out.append("[");
112  
    int l = out.length();
113  
    for (Object x : (Collection) o) {
114  
      if (out.length() != l) out.append(", ");
115  
      structure_1(out, x, d);
116  
    }
117  
    out.append("]");
118  
    ret;
119  
  }
120  
  
121  
  if (o instanceof Map) {
122  
    if (o instanceof HashMap) out.append("hm");
123  
    out.append("{");
124  
    int l = out.length();
125  
    for (Object e : ((Map) o).entrySet()) {
126  
      if (out.length() != l) out.append(", ");
127  
      structure_1(out, ((Map.Entry) e).getKey(), d);
128  
      out.append("=");
129  
      structure_1(out, ((Map.Entry) e).getValue(), d);
130  
    }
131  
    out.append("}");
132  
    ret;
133  
  }
134  
  
135  
  if (c.isArray()) {
136  
    if (o instanceof byte[]) {
137  
      out.append("ba ").append(quote(bytesToHex((byte[]) o))); ret;
138  
    }
139  
140  
    int n = Array.getLength(o);
141  
142  
    if (o instanceof bool[]) {
143  
      S hex = boolArrayToHex((bool[]) o);
144  
      int i = l(hex);
145  
      while (i > 0 && hex.charAt(i-1) == '0' && hex.charAt(i-2) == '0') i -= 2;
146  
      out.append("boolarray ").append(n).append(" ").append(quote(substring(hex, 0, i))); ret;
147  
    }
148  
    
149  
    S atype = "array", sep = ", ";
150  
151  
    if (o instanceof int[]) {
152  
      //ret "intarray " + quote(intArrayToHex((int[]) o));
153  
      atype = "intarray";
154  
      sep = " ";
155  
    }
156  
    
157  
    out.append(atype).append("{");
158  
    for (int i = 0; i < n; i++) {
159  
      if (i != 0) out.append(sep);
160  
      structure_1(out, Array.get(o, i), d);
161  
    }
162  
    out.append("}"); ret;
163  
  }
164  
165  
  if (o instanceof Class) {
166  
    out.append("class(").append(quote(((Class) o).getName())).append(")"); ret;
167  
  }
168  
    
169  
  if (o instanceof Throwable) {
170  
    out.append("exception(").append(quote(((Throwable) o).getMessage())).append(")"); ret;
171  
  }
172  
    
173  
  if (o instanceof BitSet) {
174  
    BitSet bs = (BitSet) o;
175  
    out.append("bitset{");
176  
    int l = out.length();
177  
    for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
178  
      if (out.length() != l) out.append(", ");
179  
      out.append(i);
180  
    }
181  
    out.append("}"); ret;
182  
  }
183  
    
184  
  // Need more cases? This should cover all library classes...
185  
  if (name.startsWith("java.") || name.startsWith("javax.")) {
186  
    out.append(str(o)); ret;
187  
  }
188  
    
189  
  if (name.equals("main$Lisp")) {
190  
    out.append("l(");
191  
    structure_1(out, getOpt(o, "head"), d);
192  
    L args = cast getOpt(o, "args");
193  
    if (nempty(args))
194  
      for (int i = 0; i < l(args); i++) {
195  
        out.append(", ");
196  
        O arg = args.get(i);
197  
        
198  
        // sweet shortening
199  
        if (arg != null && eq(arg.getClass().getName(), "main$Lisp") && isTrue(call(arg, "isEmpty")))
200  
          arg = get(arg, "head");
201  
          
202  
        structure_1(out, arg, d);
203  
      }
204  
    out.append(")"); ret;
205  
  }
206  
  
207  
  bool concept = d.conceptClass != null && d.conceptClass.isInstance(o);
208  
  S dynName = shortDynamicClassName(o);
209  
  if (concept && !d.concepts.contains(dynName)) {
210  
    d.concepts.add(dynName);
211  
    out.append("c ");
212  
  }
213  
  
214  
  // serialize an object with fields.
215  
  // first, collect all fields and values in fv.
216  
  
217  
  String shortName = dropPrefix("main$", name);
218  
  
219  
  new TreeMap<S, O> fv;
220  
  while (c != Object.class) {
221  
    for (Field field : getDeclaredFields_cached(c)) {
222  
      if ((field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0)
223  
        continue;
224  
      S fieldName = field.getName();
225  
      
226  
      Object value;
227  
      try {
228  
        value = field.get(o);
229  
      } catch (Exception e) {
230  
        value = "?";
231  
      }
232  
      
233  
      // omit field "className" if equal to class's name
234  
      if (concept && eq(fieldName, "className")
235  
        && eq(value, shortName)) value = null;
236  
      
237  
      // put special cases here...
238  
      
239  
      if (value != null)
240  
        fv.put(fieldName, value);
241  
    }
242  
    c = c.getSuperclass();
243  
  }
244  
  
245  
  // Now we have fields & values. Process fieldValues if it's a DynamicObject.
246  
  
247  
  if (o instanceof DynamicObject) {
248  
    fv.putAll((Map) fv.get("fieldValues"));
249  
    fv.remove("fieldValues");
250  
    shortName = dynName;
251  
    fv.remove("className");
252  
  }
253  
  
254  
  S singleField = fv.size() == 1 ? first(fv.keySet()) : null;
255  
  
256  
  // Render this$1 first because unstructure needs it for constructor call.
257  
  
258  
  out.append(shortName).append("(");
259  
  int l = out.length();
260  
  
261  
  if (fv.containsKey("this$1")) {
262  
    out.append("this$1=");
263  
    structure_1(out, fv.get("this$1"), d);
264  
    fv.remove("this$1");
265  
  }
266  
  
267  
  // Render the other fields.
268  
269  
  for (S fieldName : fv.keySet()) {
270  
    if (out.length() != l) out.append(", ");
271  
    out.append(fieldName).append("=");
272  
    structure_1(out, fv.get(fieldName), d);
273  
  }
274  
275  
  /*if (structure_allowShortening && singleField != null)
276  
    b = b.replaceAll("^" + singleField + "=", ""); // drop field name if only one*/
277  
    
278  
  if (out.length() == l) out.setLength(l-1); // drop "("
279  
  else out.append(")");
280  
}
281  
282  
// drop unused markers
283  
static S structure_2(final S s, final HashSet<Integer> refd) {
284  
  final new StringBuilder out;
285  
  
286  
  javaTok_streaming(s, new JavaTok_Stream {
287  
    int n = -1;
288  
    bool drop;
289  
    
290  
    void add(int i, int j) {
291  
      ++n;
292  
      if ((n & 1) != 0 && s.charAt(i) == 'm') {
293  
        S t;
294  
        try {
295  
          t = s.substring(i+1, j);
296  
        } catch e {
297  
          print("i=" + i + ", j=" + j);
298  
          ret;
299  
        }
300  
        if (isInteger(t)
301  
          && !refd.contains(parseInt(t))) {
302  
          drop = true;
303  
          ret;
304  
        }
305  
      }
306  
      if (drop)
307  
        drop = false;
308  
      else
309  
        out.append(s, i, j);
310  
    }
311  
  });
312  
  
313  
  ret str(out);
314  
}

Author comment

Began life as a copy of #1003037

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1005374
Snippet name: structure function (v7, using one buffer, outdated)
Eternal ID of this version: #1005374/1
Text MD5: 6c72c3a2ea31a17cc76cc2f09b78bc0a
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-11-28 20:47:16
Source code size: 8306 bytes / 314 lines
Pitched / IR pitched: No / No
Views / Downloads: 597 / 612
Referenced in: [show references]