blob: 3cbed4b696cb6cd2b09dc648795cb1de04bd9a4a [file] [log] [blame]
Stuart McCullochbb014372012-06-07 21:57:32 +00001package aQute.lib.json;
2
3import java.io.*;
4import java.lang.reflect.*;
5import java.security.*;
6import java.util.*;
7
8public class Decoder implements Closeable {
9 final JSONCodec codec;
10 Reader reader;
11 int current;
12 MessageDigest digest;
13 Map<String, Object> extra;
14 String encoding = "UTF-8";
15
16 boolean strict;
17
18 Decoder(JSONCodec codec) {
19 this.codec = codec;
20 }
21
22 public Decoder from(File file) throws Exception {
23 return from(new FileInputStream(file));
24 }
25
26 public Decoder from(InputStream in) throws Exception {
27 return from(new InputStreamReader(in, encoding));
28 }
29
30 public Decoder charset(String encoding) {
31 this.encoding = encoding;
32 return this;
33 }
34
35 public Decoder strict() {
36 this.strict = true;
37 return this;
38 }
39
40 public Decoder from(Reader in) throws Exception {
41 reader = in;
42 read();
43 return this;
44 }
45
46 public Decoder faq(String in) throws Exception {
47 return from(in.replace('\'', '"'));
48 }
49
50 public Decoder from(String in) throws Exception {
51 return from(new StringReader(in));
52 }
53
54 public Decoder mark() throws NoSuchAlgorithmException {
55 if (digest == null)
56 digest = MessageDigest.getInstance("SHA1");
57 digest.reset();
58 return this;
59 }
60
61 public byte[] digest() {
62 if (digest == null)
63 return null;
64
65 return digest.digest();
66 }
67
68 @SuppressWarnings("unchecked") public <T> T get(Class<T> clazz) throws Exception {
69 return (T) codec.decode(clazz, this);
70 }
71
72 public Object get(Type type) throws Exception {
73 return codec.decode(type, this);
74 }
75
76 public Object get() throws Exception {
77 return codec.decode(null, this);
78 }
79
80 int read() throws Exception {
81 current = reader.read();
82 if (digest != null) {
83 digest.update((byte) (current / 256));
84 digest.update((byte) (current % 256));
85 }
86 return current;
87 }
88
89 int current() {
90 return current;
91 }
92
93 /**
94 * Skip any whitespace.
95 *
96 * @return
97 * @throws Exception
98 */
99 int skipWs() throws Exception {
100 while (Character.isWhitespace(current()))
101 read();
102 return current();
103 }
104
105 /**
106 * Skip any whitespace.
107 *
108 * @return
109 * @throws Exception
110 */
111 int next() throws Exception {
112 read();
113 return skipWs();
114 }
115
116 void expect(String s) throws Exception {
117 for (int i = 0; i < s.length(); i++)
118 if (!(s.charAt(i) == read()))
119 throw new IllegalArgumentException("Expected " + s + " but got something different");
120 read();
121 }
122
123 public boolean isEof() throws Exception {
124 int c = skipWs();
125 return c < 0;
126 }
127
128 public void close() throws IOException {
129 reader.close();
130 }
131
132 public Map<String, Object> getExtra() {
133 if (extra == null)
134 extra = new HashMap<String, Object>();
135 return extra;
136 }
137}