1package com.android.test.hierarchyviewer;
2
3import java.nio.ByteBuffer;
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Locale;
8import java.util.Map;
9
10public class ViewDumpParser {
11    private Map<String, Short> mIds;
12    private List<Map<Short,Object>> mViews;
13
14    public void parse(byte[] data) {
15        Decoder d = new Decoder(ByteBuffer.wrap(data));
16
17        mViews = new ArrayList<>(100);
18        while (d.hasRemaining()) {
19            Object o = d.readObject();
20            if (o instanceof Map) {
21                //noinspection unchecked
22                mViews.add((Map<Short, Object>) o);
23            }
24        }
25
26        if (mViews.isEmpty()) {
27            return;
28        }
29
30        // the last one is the property map
31        Map<Short,Object> idMap = mViews.remove(mViews.size() - 1);
32        mIds = reverse(idMap);
33    }
34
35    public String getFirstView() {
36        if (mViews.isEmpty()) {
37            return null;
38        }
39
40        Map<Short, Object> props = mViews.get(0);
41        Object name = getProperty(props, "__name__");
42        Object hash = getProperty(props, "__hash__");
43
44        if (name instanceof String && hash instanceof Integer) {
45            return String.format(Locale.US, "%s@%x", name, hash);
46        } else {
47            return null;
48        }
49    }
50
51    private Object getProperty(Map<Short, Object> props, String key) {
52        return props.get(mIds.get(key));
53    }
54
55    private static Map<String, Short> reverse(Map<Short, Object> m) {
56        Map<String, Short> r = new HashMap<String, Short>(m.size());
57
58        for (Map.Entry<Short, Object> e : m.entrySet()) {
59            r.put((String)e.getValue(), e.getKey());
60        }
61
62        return r;
63    }
64
65    public List<Map<Short, Object>> getViews() {
66        return mViews;
67    }
68
69    public Map<String, Short> getIds() {
70        return mIds;
71    }
72
73}
74