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