blob: 87cd1bcfec08d9cc399bfb89081beadb29a70872 [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.*;
Stuart McCullochd602fe12012-07-20 16:50:39 +00007import java.util.zip.*;
Stuart McCullochbb014372012-06-07 21:57:32 +00008
Stuart McCulloch2286f232012-06-15 13:27:53 +00009import aQute.lib.converter.*;
10
Stuart McCullochbb014372012-06-07 21:57:32 +000011public class Decoder implements Closeable {
12 final JSONCodec codec;
13 Reader reader;
14 int current;
15 MessageDigest digest;
Stuart McCulloch2286f232012-06-15 13:27:53 +000016 Map<String,Object> extra;
17 String encoding = "UTF-8";
18
19 boolean strict;
Stuart McCullochd602fe12012-07-20 16:50:39 +000020 boolean inflate;
Stuart McCullochbb014372012-06-07 21:57:32 +000021
22 Decoder(JSONCodec codec) {
23 this.codec = codec;
24 }
25
26 public Decoder from(File file) throws Exception {
27 return from(new FileInputStream(file));
28 }
29
30 public Decoder from(InputStream in) throws Exception {
Stuart McCullochd602fe12012-07-20 16:50:39 +000031
32 if ( inflate)
33 in = new InflaterInputStream(in);
34
Stuart McCullochbb014372012-06-07 21:57:32 +000035 return from(new InputStreamReader(in, encoding));
36 }
Stuart McCulloch2286f232012-06-15 13:27:53 +000037
Stuart McCullochbb014372012-06-07 21:57:32 +000038 public Decoder charset(String encoding) {
39 this.encoding = encoding;
40 return this;
41 }
Stuart McCulloch2286f232012-06-15 13:27:53 +000042
Stuart McCullochbb014372012-06-07 21:57:32 +000043 public Decoder strict() {
44 this.strict = true;
45 return this;
46 }
47
48 public Decoder from(Reader in) throws Exception {
49 reader = in;
50 read();
51 return this;
52 }
53
54 public Decoder faq(String in) throws Exception {
55 return from(in.replace('\'', '"'));
56 }
57
58 public Decoder from(String in) throws Exception {
59 return from(new StringReader(in));
60 }
61
62 public Decoder mark() throws NoSuchAlgorithmException {
63 if (digest == null)
64 digest = MessageDigest.getInstance("SHA1");
65 digest.reset();
66 return this;
67 }
68
69 public byte[] digest() {
70 if (digest == null)
71 return null;
72
73 return digest.digest();
74 }
75
Stuart McCulloch2286f232012-06-15 13:27:53 +000076 public <T> T get(Class<T> clazz) throws Exception {
Stuart McCullochbb014372012-06-07 21:57:32 +000077 return (T) codec.decode(clazz, this);
78 }
79
80 public Object get(Type type) throws Exception {
81 return codec.decode(type, this);
82 }
83
84 public Object get() throws Exception {
85 return codec.decode(null, this);
86 }
87
Stuart McCulloch2286f232012-06-15 13:27:53 +000088 public <T> T get(TypeReference<T> ref) throws Exception {
89 return (T) codec.decode(ref.getType(), this);
90 }
91
Stuart McCullochbb014372012-06-07 21:57:32 +000092 int read() throws Exception {
93 current = reader.read();
94 if (digest != null) {
95 digest.update((byte) (current / 256));
96 digest.update((byte) (current % 256));
97 }
98 return current;
99 }
100
101 int current() {
102 return current;
103 }
104
105 /**
106 * Skip any whitespace.
107 *
108 * @return
109 * @throws Exception
110 */
111 int skipWs() throws Exception {
112 while (Character.isWhitespace(current()))
113 read();
114 return current();
115 }
116
117 /**
118 * Skip any whitespace.
119 *
120 * @return
121 * @throws Exception
122 */
123 int next() throws Exception {
124 read();
125 return skipWs();
126 }
127
128 void expect(String s) throws Exception {
129 for (int i = 0; i < s.length(); i++)
130 if (!(s.charAt(i) == read()))
131 throw new IllegalArgumentException("Expected " + s + " but got something different");
132 read();
133 }
134
135 public boolean isEof() throws Exception {
136 int c = skipWs();
137 return c < 0;
138 }
139
140 public void close() throws IOException {
141 reader.close();
142 }
143
Stuart McCulloch2286f232012-06-15 13:27:53 +0000144 public Map<String,Object> getExtra() {
Stuart McCullochbb014372012-06-07 21:57:32 +0000145 if (extra == null)
Stuart McCulloch2286f232012-06-15 13:27:53 +0000146 extra = new HashMap<String,Object>();
Stuart McCullochbb014372012-06-07 21:57:32 +0000147 return extra;
148 }
Stuart McCullochd602fe12012-07-20 16:50:39 +0000149
150 public Decoder inflate() {
151 if ( reader != null)
152 throw new IllegalStateException("Reader already set, inflate must come before from()");
153 inflate = true;
154 return this;
155 }
Stuart McCullochbb014372012-06-07 21:57:32 +0000156}