annotate src/main/java/org/msgpack/unpacker/MessagePackUnpacker.java @ 6:8d782f988d92

refactor
author sugi
date Fri, 09 Jan 2015 15:14:00 +0900
parents efe621b1dba9
children e7e55c455e39
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
cb825acd883a first commit
sugi
parents:
diff changeset
1 //
cb825acd883a first commit
sugi
parents:
diff changeset
2 // MessagePack for Java
cb825acd883a first commit
sugi
parents:
diff changeset
3 //
cb825acd883a first commit
sugi
parents:
diff changeset
4 // Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
cb825acd883a first commit
sugi
parents:
diff changeset
5 //
cb825acd883a first commit
sugi
parents:
diff changeset
6 // Licensed under the Apache License, Version 2.0 (the "License");
cb825acd883a first commit
sugi
parents:
diff changeset
7 // you may not use this file except in compliance with the License.
cb825acd883a first commit
sugi
parents:
diff changeset
8 // You may obtain a copy of the License at
cb825acd883a first commit
sugi
parents:
diff changeset
9 //
cb825acd883a first commit
sugi
parents:
diff changeset
10 // http://www.apache.org/licenses/LICENSE-2.0
cb825acd883a first commit
sugi
parents:
diff changeset
11 //
cb825acd883a first commit
sugi
parents:
diff changeset
12 // Unless required by applicable law or agreed to in writing, software
cb825acd883a first commit
sugi
parents:
diff changeset
13 // distributed under the License is distributed on an "AS IS" BASIS,
cb825acd883a first commit
sugi
parents:
diff changeset
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
cb825acd883a first commit
sugi
parents:
diff changeset
15 // See the License for the specific language governing permissions and
cb825acd883a first commit
sugi
parents:
diff changeset
16 // limitations under the License.
cb825acd883a first commit
sugi
parents:
diff changeset
17 //
cb825acd883a first commit
sugi
parents:
diff changeset
18 package org.msgpack.unpacker;
cb825acd883a first commit
sugi
parents:
diff changeset
19
cb825acd883a first commit
sugi
parents:
diff changeset
20 import java.io.IOException;
cb825acd883a first commit
sugi
parents:
diff changeset
21 import java.io.EOFException;
cb825acd883a first commit
sugi
parents:
diff changeset
22 import java.io.InputStream;
cb825acd883a first commit
sugi
parents:
diff changeset
23 import java.math.BigInteger;
cb825acd883a first commit
sugi
parents:
diff changeset
24 import org.msgpack.io.Input;
cb825acd883a first commit
sugi
parents:
diff changeset
25 import org.msgpack.io.StreamInput;
cb825acd883a first commit
sugi
parents:
diff changeset
26 import org.msgpack.io.BufferReferer;
cb825acd883a first commit
sugi
parents:
diff changeset
27 import org.msgpack.MessagePack;
cb825acd883a first commit
sugi
parents:
diff changeset
28 import org.msgpack.MessageTypeException;
cb825acd883a first commit
sugi
parents:
diff changeset
29 import org.msgpack.packer.Unconverter;
cb825acd883a first commit
sugi
parents:
diff changeset
30 import org.msgpack.type.ValueType;
cb825acd883a first commit
sugi
parents:
diff changeset
31
cb825acd883a first commit
sugi
parents:
diff changeset
32 public class MessagePackUnpacker extends AbstractUnpacker {
cb825acd883a first commit
sugi
parents:
diff changeset
33 private static final byte REQUIRE_TO_READ_HEAD = (byte) 0xc1;
cb825acd883a first commit
sugi
parents:
diff changeset
34
cb825acd883a first commit
sugi
parents:
diff changeset
35 protected final Input in;
cb825acd883a first commit
sugi
parents:
diff changeset
36 private final UnpackerStack stack = new UnpackerStack();
cb825acd883a first commit
sugi
parents:
diff changeset
37
cb825acd883a first commit
sugi
parents:
diff changeset
38 private byte headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
39
cb825acd883a first commit
sugi
parents:
diff changeset
40 private byte[] raw;
cb825acd883a first commit
sugi
parents:
diff changeset
41 private int rawFilled;
cb825acd883a first commit
sugi
parents:
diff changeset
42
cb825acd883a first commit
sugi
parents:
diff changeset
43 private final IntAccept intAccept = new IntAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
44 private final LongAccept longAccept = new LongAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
45 private final BigIntegerAccept bigIntegerAccept = new BigIntegerAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
46 private final DoubleAccept doubleAccept = new DoubleAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
47 private final ByteArrayAccept byteArrayAccept = new ByteArrayAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
48 private final StringAccept stringAccept = new StringAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
49 private final ArrayAccept arrayAccept = new ArrayAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
50 private final MapAccept mapAccept = new MapAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
51 private final ValueAccept valueAccept = new ValueAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
52 private final SkipAccept skipAccept = new SkipAccept();
cb825acd883a first commit
sugi
parents:
diff changeset
53
cb825acd883a first commit
sugi
parents:
diff changeset
54 public MessagePackUnpacker(MessagePack msgpack, InputStream stream) {
cb825acd883a first commit
sugi
parents:
diff changeset
55 this(msgpack, new StreamInput(stream));
cb825acd883a first commit
sugi
parents:
diff changeset
56 }
cb825acd883a first commit
sugi
parents:
diff changeset
57
cb825acd883a first commit
sugi
parents:
diff changeset
58 protected MessagePackUnpacker(MessagePack msgpack, Input in) {
cb825acd883a first commit
sugi
parents:
diff changeset
59 super(msgpack);
cb825acd883a first commit
sugi
parents:
diff changeset
60 this.in = in;
cb825acd883a first commit
sugi
parents:
diff changeset
61 }
cb825acd883a first commit
sugi
parents:
diff changeset
62
cb825acd883a first commit
sugi
parents:
diff changeset
63 private byte getHeadByte() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
64 byte b = headByte;
cb825acd883a first commit
sugi
parents:
diff changeset
65 if (b == REQUIRE_TO_READ_HEAD) {
cb825acd883a first commit
sugi
parents:
diff changeset
66 b = headByte = in.readByte();
cb825acd883a first commit
sugi
parents:
diff changeset
67 }
cb825acd883a first commit
sugi
parents:
diff changeset
68 return b;
cb825acd883a first commit
sugi
parents:
diff changeset
69 }
cb825acd883a first commit
sugi
parents:
diff changeset
70
cb825acd883a first commit
sugi
parents:
diff changeset
71 final void readOne(Accept a) throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
72 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
73 if (readOneWithoutStack(a)) {
cb825acd883a first commit
sugi
parents:
diff changeset
74 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
75 }
cb825acd883a first commit
sugi
parents:
diff changeset
76 }
cb825acd883a first commit
sugi
parents:
diff changeset
77
cb825acd883a first commit
sugi
parents:
diff changeset
78 final boolean readOneWithoutStack(Accept a) throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
79 if (raw != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
80 readRawBodyCont();
cb825acd883a first commit
sugi
parents:
diff changeset
81 a.acceptRaw(raw);
cb825acd883a first commit
sugi
parents:
diff changeset
82 raw = null;
cb825acd883a first commit
sugi
parents:
diff changeset
83 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
84 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
85 }
cb825acd883a first commit
sugi
parents:
diff changeset
86
cb825acd883a first commit
sugi
parents:
diff changeset
87 final int b = (int) getHeadByte();
cb825acd883a first commit
sugi
parents:
diff changeset
88
cb825acd883a first commit
sugi
parents:
diff changeset
89 if ((b & 0x80) == 0) { // Positive Fixnum
cb825acd883a first commit
sugi
parents:
diff changeset
90 // System.out.println("positive fixnum "+b);
cb825acd883a first commit
sugi
parents:
diff changeset
91 a.acceptInteger(b);
cb825acd883a first commit
sugi
parents:
diff changeset
92 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
93 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
94 }
cb825acd883a first commit
sugi
parents:
diff changeset
95
cb825acd883a first commit
sugi
parents:
diff changeset
96 if ((b & 0xe0) == 0xe0) { // Negative Fixnum
cb825acd883a first commit
sugi
parents:
diff changeset
97 // System.out.println("negative fixnum "+b);
cb825acd883a first commit
sugi
parents:
diff changeset
98 a.acceptInteger(b);
cb825acd883a first commit
sugi
parents:
diff changeset
99 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
100 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
101 }
cb825acd883a first commit
sugi
parents:
diff changeset
102
cb825acd883a first commit
sugi
parents:
diff changeset
103 if ((b & 0xe0) == 0xa0) { // FixRaw
cb825acd883a first commit
sugi
parents:
diff changeset
104 int count = b & 0x1f;
cb825acd883a first commit
sugi
parents:
diff changeset
105 if (count == 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
106 a.acceptEmptyRaw();
cb825acd883a first commit
sugi
parents:
diff changeset
107 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
108 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
109 }
cb825acd883a first commit
sugi
parents:
diff changeset
110 if (!tryReferRawBody(a, count)) {
cb825acd883a first commit
sugi
parents:
diff changeset
111 readRawBody(count);
cb825acd883a first commit
sugi
parents:
diff changeset
112 a.acceptRaw(raw);
cb825acd883a first commit
sugi
parents:
diff changeset
113 raw = null;
cb825acd883a first commit
sugi
parents:
diff changeset
114 }
cb825acd883a first commit
sugi
parents:
diff changeset
115 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
116 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
117 }
cb825acd883a first commit
sugi
parents:
diff changeset
118
cb825acd883a first commit
sugi
parents:
diff changeset
119 if ((b & 0xf0) == 0x90) { // FixArray
cb825acd883a first commit
sugi
parents:
diff changeset
120 int count = b & 0x0f;
cb825acd883a first commit
sugi
parents:
diff changeset
121 // System.out.println("fixarray count:"+count);
cb825acd883a first commit
sugi
parents:
diff changeset
122 a.acceptArray(count);
cb825acd883a first commit
sugi
parents:
diff changeset
123 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
124 stack.pushArray(count);
cb825acd883a first commit
sugi
parents:
diff changeset
125 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
126 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
127 }
cb825acd883a first commit
sugi
parents:
diff changeset
128
cb825acd883a first commit
sugi
parents:
diff changeset
129 if ((b & 0xf0) == 0x80) { // FixMap
cb825acd883a first commit
sugi
parents:
diff changeset
130 int count = b & 0x0f;
cb825acd883a first commit
sugi
parents:
diff changeset
131 // System.out.println("fixmap count:"+count/2);
cb825acd883a first commit
sugi
parents:
diff changeset
132 a.acceptMap(count);
cb825acd883a first commit
sugi
parents:
diff changeset
133 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
134 stack.pushMap(count);
cb825acd883a first commit
sugi
parents:
diff changeset
135 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
136 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
137 }
cb825acd883a first commit
sugi
parents:
diff changeset
138
cb825acd883a first commit
sugi
parents:
diff changeset
139 return readOneWithoutStackLarge(a, b);
cb825acd883a first commit
sugi
parents:
diff changeset
140 }
cb825acd883a first commit
sugi
parents:
diff changeset
141
cb825acd883a first commit
sugi
parents:
diff changeset
142 private boolean readOneWithoutStackLarge(Accept a, final int b)
cb825acd883a first commit
sugi
parents:
diff changeset
143 throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
144 switch (b & 0xff) {
cb825acd883a first commit
sugi
parents:
diff changeset
145 case 0xc0: // nil
cb825acd883a first commit
sugi
parents:
diff changeset
146 a.acceptNil();
cb825acd883a first commit
sugi
parents:
diff changeset
147 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
148 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
149 case 0xc2: // false
cb825acd883a first commit
sugi
parents:
diff changeset
150 a.acceptBoolean(false);
cb825acd883a first commit
sugi
parents:
diff changeset
151 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
152 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
153 case 0xc3: // true
cb825acd883a first commit
sugi
parents:
diff changeset
154 a.acceptBoolean(true);
cb825acd883a first commit
sugi
parents:
diff changeset
155 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
156 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
157 //case 0xc4: // bin 8 -> see 0xd9
cb825acd883a first commit
sugi
parents:
diff changeset
158 //case 0xc5: // bin 16 -> see 0xda
cb825acd883a first commit
sugi
parents:
diff changeset
159 //case 0xc6: // bin 32 -> see 0xdb
cb825acd883a first commit
sugi
parents:
diff changeset
160 case 0xca: // float
cb825acd883a first commit
sugi
parents:
diff changeset
161 a.acceptFloat(in.getFloat());
cb825acd883a first commit
sugi
parents:
diff changeset
162 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
163 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
164 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
165 case 0xcb: // double
cb825acd883a first commit
sugi
parents:
diff changeset
166 a.acceptDouble(in.getDouble());
cb825acd883a first commit
sugi
parents:
diff changeset
167 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
168 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
169 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
170 case 0xcc: // unsigned int 8
cb825acd883a first commit
sugi
parents:
diff changeset
171 a.acceptUnsignedInteger(in.getByte());
cb825acd883a first commit
sugi
parents:
diff changeset
172 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
173 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
174 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
175 case 0xcd: // unsigned int 16
cb825acd883a first commit
sugi
parents:
diff changeset
176 a.acceptUnsignedInteger(in.getShort());
cb825acd883a first commit
sugi
parents:
diff changeset
177 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
178 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
179 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
180 case 0xce: // unsigned int 32
cb825acd883a first commit
sugi
parents:
diff changeset
181 a.acceptUnsignedInteger(in.getInt());
cb825acd883a first commit
sugi
parents:
diff changeset
182 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
183 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
184 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
185 case 0xcf: // unsigned int 64
cb825acd883a first commit
sugi
parents:
diff changeset
186 a.acceptUnsignedInteger(in.getLong());
cb825acd883a first commit
sugi
parents:
diff changeset
187 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
188 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
189 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
190 case 0xd0: // signed int 8
cb825acd883a first commit
sugi
parents:
diff changeset
191 a.acceptInteger(in.getByte());
cb825acd883a first commit
sugi
parents:
diff changeset
192 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
193 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
194 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
195 case 0xd1: // signed int 16
cb825acd883a first commit
sugi
parents:
diff changeset
196 a.acceptInteger(in.getShort());
cb825acd883a first commit
sugi
parents:
diff changeset
197 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
198 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
199 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
200 case 0xd2: // signed int 32
cb825acd883a first commit
sugi
parents:
diff changeset
201 a.acceptInteger(in.getInt());
cb825acd883a first commit
sugi
parents:
diff changeset
202 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
203 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
204 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
205 case 0xd3: // signed int 64
cb825acd883a first commit
sugi
parents:
diff changeset
206 a.acceptInteger(in.getLong());
cb825acd883a first commit
sugi
parents:
diff changeset
207 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
208 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
209 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
210 case 0xc4: // bin 8
cb825acd883a first commit
sugi
parents:
diff changeset
211 case 0xd9: // str 8
cb825acd883a first commit
sugi
parents:
diff changeset
212 {
cb825acd883a first commit
sugi
parents:
diff changeset
213 int count = in.getByte() & 0xff;
cb825acd883a first commit
sugi
parents:
diff changeset
214 if (count == 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
215 a.acceptEmptyRaw();
cb825acd883a first commit
sugi
parents:
diff changeset
216 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
217 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
218 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
219 }
cb825acd883a first commit
sugi
parents:
diff changeset
220 if (count >= rawSizeLimit) {
cb825acd883a first commit
sugi
parents:
diff changeset
221 String reason = String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
222 "Size of raw (%d) over limit at %d",
cb825acd883a first commit
sugi
parents:
diff changeset
223 new Object[] { count, rawSizeLimit });
cb825acd883a first commit
sugi
parents:
diff changeset
224 throw new SizeLimitException(reason);
cb825acd883a first commit
sugi
parents:
diff changeset
225 }
cb825acd883a first commit
sugi
parents:
diff changeset
226 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
227 if (!tryReferRawBody(a, count)) {
cb825acd883a first commit
sugi
parents:
diff changeset
228 readRawBody(count);
cb825acd883a first commit
sugi
parents:
diff changeset
229 a.acceptRaw(raw);
cb825acd883a first commit
sugi
parents:
diff changeset
230 raw = null;
cb825acd883a first commit
sugi
parents:
diff changeset
231 }
cb825acd883a first commit
sugi
parents:
diff changeset
232 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
233 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
234 }
cb825acd883a first commit
sugi
parents:
diff changeset
235 case 0xc5: // bin 16
cb825acd883a first commit
sugi
parents:
diff changeset
236 case 0xda: // raw 16
cb825acd883a first commit
sugi
parents:
diff changeset
237 {
cb825acd883a first commit
sugi
parents:
diff changeset
238 int count = in.getShort() & 0xffff;
cb825acd883a first commit
sugi
parents:
diff changeset
239 if (count == 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
240 a.acceptEmptyRaw();
cb825acd883a first commit
sugi
parents:
diff changeset
241 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
242 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
243 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
244 }
cb825acd883a first commit
sugi
parents:
diff changeset
245 if (count >= rawSizeLimit) {
cb825acd883a first commit
sugi
parents:
diff changeset
246 String reason = String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
247 "Size of raw (%d) over limit at %d",
cb825acd883a first commit
sugi
parents:
diff changeset
248 new Object[] { count, rawSizeLimit });
cb825acd883a first commit
sugi
parents:
diff changeset
249 throw new SizeLimitException(reason);
cb825acd883a first commit
sugi
parents:
diff changeset
250 }
cb825acd883a first commit
sugi
parents:
diff changeset
251 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
252 if (!tryReferRawBody(a, count)) {
cb825acd883a first commit
sugi
parents:
diff changeset
253 readRawBody(count);
cb825acd883a first commit
sugi
parents:
diff changeset
254 a.acceptRaw(raw);
cb825acd883a first commit
sugi
parents:
diff changeset
255 raw = null;
cb825acd883a first commit
sugi
parents:
diff changeset
256 }
cb825acd883a first commit
sugi
parents:
diff changeset
257 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
258 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
259 }
cb825acd883a first commit
sugi
parents:
diff changeset
260 case 0xc6: // bin 32
cb825acd883a first commit
sugi
parents:
diff changeset
261 case 0xdb: // raw 32
cb825acd883a first commit
sugi
parents:
diff changeset
262 {
cb825acd883a first commit
sugi
parents:
diff changeset
263 int count = in.getInt();
cb825acd883a first commit
sugi
parents:
diff changeset
264 if (count == 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
265 a.acceptEmptyRaw();
cb825acd883a first commit
sugi
parents:
diff changeset
266 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
267 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
268 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
269 }
cb825acd883a first commit
sugi
parents:
diff changeset
270 if (count < 0 || count >= rawSizeLimit) {
cb825acd883a first commit
sugi
parents:
diff changeset
271 String reason = String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
272 "Size of raw (%d) over limit at %d",
cb825acd883a first commit
sugi
parents:
diff changeset
273 new Object[] { count, rawSizeLimit });
cb825acd883a first commit
sugi
parents:
diff changeset
274 throw new SizeLimitException(reason);
cb825acd883a first commit
sugi
parents:
diff changeset
275 }
cb825acd883a first commit
sugi
parents:
diff changeset
276 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
277 if (!tryReferRawBody(a, count)) {
cb825acd883a first commit
sugi
parents:
diff changeset
278 readRawBody(count);
cb825acd883a first commit
sugi
parents:
diff changeset
279 a.acceptRaw(raw);
cb825acd883a first commit
sugi
parents:
diff changeset
280 raw = null;
cb825acd883a first commit
sugi
parents:
diff changeset
281 }
cb825acd883a first commit
sugi
parents:
diff changeset
282 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
283 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
284 }
cb825acd883a first commit
sugi
parents:
diff changeset
285 case 0xdc: // array 16
cb825acd883a first commit
sugi
parents:
diff changeset
286 {
cb825acd883a first commit
sugi
parents:
diff changeset
287 int count = in.getShort() & 0xffff;
cb825acd883a first commit
sugi
parents:
diff changeset
288 if (count >= arraySizeLimit) {
cb825acd883a first commit
sugi
parents:
diff changeset
289 String reason = String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
290 "Size of array (%d) over limit at %d",
cb825acd883a first commit
sugi
parents:
diff changeset
291 new Object[] { count, arraySizeLimit });
cb825acd883a first commit
sugi
parents:
diff changeset
292 throw new SizeLimitException(reason);
cb825acd883a first commit
sugi
parents:
diff changeset
293 }
cb825acd883a first commit
sugi
parents:
diff changeset
294 a.acceptArray(count);
cb825acd883a first commit
sugi
parents:
diff changeset
295 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
296 stack.pushArray(count);
cb825acd883a first commit
sugi
parents:
diff changeset
297 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
298 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
299 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
300 }
cb825acd883a first commit
sugi
parents:
diff changeset
301 case 0xdd: // array 32
cb825acd883a first commit
sugi
parents:
diff changeset
302 {
cb825acd883a first commit
sugi
parents:
diff changeset
303 int count = in.getInt();
cb825acd883a first commit
sugi
parents:
diff changeset
304 if (count < 0 || count >= arraySizeLimit) {
cb825acd883a first commit
sugi
parents:
diff changeset
305 String reason = String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
306 "Size of array (%d) over limit at %d",
cb825acd883a first commit
sugi
parents:
diff changeset
307 new Object[] { count, arraySizeLimit });
cb825acd883a first commit
sugi
parents:
diff changeset
308 throw new SizeLimitException(reason);
cb825acd883a first commit
sugi
parents:
diff changeset
309 }
cb825acd883a first commit
sugi
parents:
diff changeset
310 a.acceptArray(count);
cb825acd883a first commit
sugi
parents:
diff changeset
311 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
312 stack.pushArray(count);
cb825acd883a first commit
sugi
parents:
diff changeset
313 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
314 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
315 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
316 }
cb825acd883a first commit
sugi
parents:
diff changeset
317 case 0xde: // map 16
cb825acd883a first commit
sugi
parents:
diff changeset
318 {
cb825acd883a first commit
sugi
parents:
diff changeset
319 int count = in.getShort() & 0xffff;
cb825acd883a first commit
sugi
parents:
diff changeset
320 if (count >= mapSizeLimit) {
cb825acd883a first commit
sugi
parents:
diff changeset
321 String reason = String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
322 "Size of map (%d) over limit at %d",
cb825acd883a first commit
sugi
parents:
diff changeset
323 new Object[] { count, mapSizeLimit });
cb825acd883a first commit
sugi
parents:
diff changeset
324 throw new SizeLimitException(reason);
cb825acd883a first commit
sugi
parents:
diff changeset
325 }
cb825acd883a first commit
sugi
parents:
diff changeset
326 a.acceptMap(count);
cb825acd883a first commit
sugi
parents:
diff changeset
327 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
328 stack.pushMap(count);
cb825acd883a first commit
sugi
parents:
diff changeset
329 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
330 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
331 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
332 }
cb825acd883a first commit
sugi
parents:
diff changeset
333 case 0xdf: // map 32
cb825acd883a first commit
sugi
parents:
diff changeset
334 {
cb825acd883a first commit
sugi
parents:
diff changeset
335 int count = in.getInt();
cb825acd883a first commit
sugi
parents:
diff changeset
336 if (count < 0 || count >= mapSizeLimit) {
cb825acd883a first commit
sugi
parents:
diff changeset
337 String reason = String.format(
cb825acd883a first commit
sugi
parents:
diff changeset
338 "Size of map (%d) over limit at %d",
cb825acd883a first commit
sugi
parents:
diff changeset
339 new Object[] { count, mapSizeLimit });
cb825acd883a first commit
sugi
parents:
diff changeset
340 throw new SizeLimitException(reason);
cb825acd883a first commit
sugi
parents:
diff changeset
341 }
cb825acd883a first commit
sugi
parents:
diff changeset
342 a.acceptMap(count);
cb825acd883a first commit
sugi
parents:
diff changeset
343 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
344 stack.pushMap(count);
cb825acd883a first commit
sugi
parents:
diff changeset
345 in.advance();
cb825acd883a first commit
sugi
parents:
diff changeset
346 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
347 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
348 }
cb825acd883a first commit
sugi
parents:
diff changeset
349 default:
cb825acd883a first commit
sugi
parents:
diff changeset
350 // System.out.println("unknown b "+(b&0xff));
cb825acd883a first commit
sugi
parents:
diff changeset
351 // headByte = CS_INVALID
cb825acd883a first commit
sugi
parents:
diff changeset
352 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
353 throw new IOException("Invalid byte: " + b); // TODO error FormatException
cb825acd883a first commit
sugi
parents:
diff changeset
354 }
cb825acd883a first commit
sugi
parents:
diff changeset
355 }
cb825acd883a first commit
sugi
parents:
diff changeset
356
cb825acd883a first commit
sugi
parents:
diff changeset
357 private boolean tryReferRawBody(BufferReferer referer, int size) throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
358 return in.tryRefer(referer, size);
cb825acd883a first commit
sugi
parents:
diff changeset
359 }
cb825acd883a first commit
sugi
parents:
diff changeset
360
cb825acd883a first commit
sugi
parents:
diff changeset
361 private void readRawBody(int size) throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
362 raw = new byte[size];
cb825acd883a first commit
sugi
parents:
diff changeset
363 rawFilled = 0;
cb825acd883a first commit
sugi
parents:
diff changeset
364 readRawBodyCont();
cb825acd883a first commit
sugi
parents:
diff changeset
365 }
cb825acd883a first commit
sugi
parents:
diff changeset
366
cb825acd883a first commit
sugi
parents:
diff changeset
367 private void readRawBodyCont() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
368 int len = in.read(raw, rawFilled, raw.length - rawFilled);
cb825acd883a first commit
sugi
parents:
diff changeset
369 rawFilled += len;
cb825acd883a first commit
sugi
parents:
diff changeset
370 if (rawFilled < raw.length) {
cb825acd883a first commit
sugi
parents:
diff changeset
371 throw new EOFException();
cb825acd883a first commit
sugi
parents:
diff changeset
372 }
cb825acd883a first commit
sugi
parents:
diff changeset
373 }
cb825acd883a first commit
sugi
parents:
diff changeset
374
cb825acd883a first commit
sugi
parents:
diff changeset
375 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
376 protected boolean tryReadNil() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
377 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
378 int b = getHeadByte() & 0xff;
cb825acd883a first commit
sugi
parents:
diff changeset
379 if (b == 0xc0) {
cb825acd883a first commit
sugi
parents:
diff changeset
380 // nil is read
cb825acd883a first commit
sugi
parents:
diff changeset
381 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
382 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
383 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
384 }
cb825acd883a first commit
sugi
parents:
diff changeset
385 // not nil
cb825acd883a first commit
sugi
parents:
diff changeset
386 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
387 }
cb825acd883a first commit
sugi
parents:
diff changeset
388
cb825acd883a first commit
sugi
parents:
diff changeset
389 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
390 public boolean trySkipNil() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
391 if (stack.getDepth() > 0 && stack.getTopCount() <= 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
392 // end of array or map
cb825acd883a first commit
sugi
parents:
diff changeset
393 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
394 }
cb825acd883a first commit
sugi
parents:
diff changeset
395
cb825acd883a first commit
sugi
parents:
diff changeset
396 int b = getHeadByte() & 0xff;
cb825acd883a first commit
sugi
parents:
diff changeset
397 if (b == 0xc0) {
cb825acd883a first commit
sugi
parents:
diff changeset
398 // nil is skipped
cb825acd883a first commit
sugi
parents:
diff changeset
399 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
400 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
401 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
402 }
cb825acd883a first commit
sugi
parents:
diff changeset
403 // not nil
cb825acd883a first commit
sugi
parents:
diff changeset
404 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
405 }
cb825acd883a first commit
sugi
parents:
diff changeset
406
cb825acd883a first commit
sugi
parents:
diff changeset
407 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
408 public void readNil() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
409 // optimized not to allocate nilAccept
cb825acd883a first commit
sugi
parents:
diff changeset
410 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
411 int b = getHeadByte() & 0xff;
cb825acd883a first commit
sugi
parents:
diff changeset
412 if (b == 0xc0) {
cb825acd883a first commit
sugi
parents:
diff changeset
413 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
414 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
415 return;
cb825acd883a first commit
sugi
parents:
diff changeset
416 }
cb825acd883a first commit
sugi
parents:
diff changeset
417 throw new MessageTypeException("Expected nil but got not nil value");
cb825acd883a first commit
sugi
parents:
diff changeset
418 }
cb825acd883a first commit
sugi
parents:
diff changeset
419
cb825acd883a first commit
sugi
parents:
diff changeset
420 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
421 public boolean readBoolean() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
422 // optimized not to allocate booleanAccept
cb825acd883a first commit
sugi
parents:
diff changeset
423 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
424 int b = getHeadByte() & 0xff;
cb825acd883a first commit
sugi
parents:
diff changeset
425 if (b == 0xc2) {
cb825acd883a first commit
sugi
parents:
diff changeset
426 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
427 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
428 return false;
cb825acd883a first commit
sugi
parents:
diff changeset
429 } else if (b == 0xc3) {
cb825acd883a first commit
sugi
parents:
diff changeset
430 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
431 headByte = REQUIRE_TO_READ_HEAD;
cb825acd883a first commit
sugi
parents:
diff changeset
432 return true;
cb825acd883a first commit
sugi
parents:
diff changeset
433 }
cb825acd883a first commit
sugi
parents:
diff changeset
434 throw new MessageTypeException(
cb825acd883a first commit
sugi
parents:
diff changeset
435 "Expected Boolean but got not boolean value");
cb825acd883a first commit
sugi
parents:
diff changeset
436 }
cb825acd883a first commit
sugi
parents:
diff changeset
437
cb825acd883a first commit
sugi
parents:
diff changeset
438 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
439 public byte readByte() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
440 // optimized not to allocate byteAccept
cb825acd883a first commit
sugi
parents:
diff changeset
441 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
442 readOneWithoutStack(intAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
443 int value = intAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
444 if (value < (int) Byte.MIN_VALUE || value > (int) Byte.MAX_VALUE) {
cb825acd883a first commit
sugi
parents:
diff changeset
445 throw new MessageTypeException(); // TODO message
cb825acd883a first commit
sugi
parents:
diff changeset
446 }
cb825acd883a first commit
sugi
parents:
diff changeset
447 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
448 return (byte) value;
cb825acd883a first commit
sugi
parents:
diff changeset
449 }
cb825acd883a first commit
sugi
parents:
diff changeset
450
cb825acd883a first commit
sugi
parents:
diff changeset
451 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
452 public short readShort() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
453 // optimized not to allocate shortAccept
cb825acd883a first commit
sugi
parents:
diff changeset
454 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
455 readOneWithoutStack(intAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
456 int value = intAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
457 if (value < (int) Short.MIN_VALUE || value > (int) Short.MAX_VALUE) {
cb825acd883a first commit
sugi
parents:
diff changeset
458 throw new MessageTypeException(); // TODO message
cb825acd883a first commit
sugi
parents:
diff changeset
459 }
cb825acd883a first commit
sugi
parents:
diff changeset
460 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
461 return (short) value;
cb825acd883a first commit
sugi
parents:
diff changeset
462 }
cb825acd883a first commit
sugi
parents:
diff changeset
463
cb825acd883a first commit
sugi
parents:
diff changeset
464 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
465 public int readInt() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
466 readOne(intAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
467 return intAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
468 }
cb825acd883a first commit
sugi
parents:
diff changeset
469
cb825acd883a first commit
sugi
parents:
diff changeset
470 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
471 public long readLong() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
472 readOne(longAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
473 return longAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
474 }
cb825acd883a first commit
sugi
parents:
diff changeset
475
cb825acd883a first commit
sugi
parents:
diff changeset
476 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
477 public BigInteger readBigInteger() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
478 readOne(bigIntegerAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
479 return bigIntegerAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
480 }
cb825acd883a first commit
sugi
parents:
diff changeset
481
cb825acd883a first commit
sugi
parents:
diff changeset
482 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
483 public float readFloat() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
484 readOne(doubleAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
485 return (float) doubleAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
486 }
cb825acd883a first commit
sugi
parents:
diff changeset
487
cb825acd883a first commit
sugi
parents:
diff changeset
488 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
489 public double readDouble() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
490 readOne(doubleAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
491 return doubleAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
492 }
cb825acd883a first commit
sugi
parents:
diff changeset
493
cb825acd883a first commit
sugi
parents:
diff changeset
494 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
495 public byte[] readByteArray() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
496 readOne(byteArrayAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
497 return byteArrayAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
498 }
cb825acd883a first commit
sugi
parents:
diff changeset
499
cb825acd883a first commit
sugi
parents:
diff changeset
500 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
501 public String readString() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
502 readOne(stringAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
503 return stringAccept.value;
cb825acd883a first commit
sugi
parents:
diff changeset
504 }
cb825acd883a first commit
sugi
parents:
diff changeset
505
cb825acd883a first commit
sugi
parents:
diff changeset
506 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
507 public int readArrayBegin() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
508 readOne(arrayAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
509 return arrayAccept.size;
cb825acd883a first commit
sugi
parents:
diff changeset
510 }
cb825acd883a first commit
sugi
parents:
diff changeset
511
cb825acd883a first commit
sugi
parents:
diff changeset
512 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
513 public void readArrayEnd(boolean check) throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
514 if (!stack.topIsArray()) {
cb825acd883a first commit
sugi
parents:
diff changeset
515 throw new MessageTypeException(
cb825acd883a first commit
sugi
parents:
diff changeset
516 "readArrayEnd() is called but readArrayBegin() is not called");
cb825acd883a first commit
sugi
parents:
diff changeset
517 }
cb825acd883a first commit
sugi
parents:
diff changeset
518
cb825acd883a first commit
sugi
parents:
diff changeset
519 int remain = stack.getTopCount();
cb825acd883a first commit
sugi
parents:
diff changeset
520 if (remain > 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
521 if (check) {
cb825acd883a first commit
sugi
parents:
diff changeset
522 throw new MessageTypeException(
cb825acd883a first commit
sugi
parents:
diff changeset
523 "readArrayEnd(check=true) is called but the array is not end");
cb825acd883a first commit
sugi
parents:
diff changeset
524 }
cb825acd883a first commit
sugi
parents:
diff changeset
525 for (int i = 0; i < remain; i++) {
cb825acd883a first commit
sugi
parents:
diff changeset
526 skip();
cb825acd883a first commit
sugi
parents:
diff changeset
527 }
cb825acd883a first commit
sugi
parents:
diff changeset
528 }
cb825acd883a first commit
sugi
parents:
diff changeset
529 stack.pop();
cb825acd883a first commit
sugi
parents:
diff changeset
530 }
cb825acd883a first commit
sugi
parents:
diff changeset
531
cb825acd883a first commit
sugi
parents:
diff changeset
532 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
533 public int readMapBegin() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
534 readOne(mapAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
535 return mapAccept.size;
cb825acd883a first commit
sugi
parents:
diff changeset
536 }
cb825acd883a first commit
sugi
parents:
diff changeset
537
cb825acd883a first commit
sugi
parents:
diff changeset
538 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
539 public void readMapEnd(boolean check) throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
540 if (!stack.topIsMap()) {
cb825acd883a first commit
sugi
parents:
diff changeset
541 throw new MessageTypeException(
cb825acd883a first commit
sugi
parents:
diff changeset
542 "readMapEnd() is called but readMapBegin() is not called");
cb825acd883a first commit
sugi
parents:
diff changeset
543 }
cb825acd883a first commit
sugi
parents:
diff changeset
544
cb825acd883a first commit
sugi
parents:
diff changeset
545 int remain = stack.getTopCount();
cb825acd883a first commit
sugi
parents:
diff changeset
546 if (remain > 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
547 if (check) {
cb825acd883a first commit
sugi
parents:
diff changeset
548 throw new MessageTypeException(
cb825acd883a first commit
sugi
parents:
diff changeset
549 "readMapEnd(check=true) is called but the map is not end");
cb825acd883a first commit
sugi
parents:
diff changeset
550 }
cb825acd883a first commit
sugi
parents:
diff changeset
551 for (int i = 0; i < remain; i++) {
cb825acd883a first commit
sugi
parents:
diff changeset
552 skip();
cb825acd883a first commit
sugi
parents:
diff changeset
553 }
cb825acd883a first commit
sugi
parents:
diff changeset
554 }
cb825acd883a first commit
sugi
parents:
diff changeset
555 stack.pop();
cb825acd883a first commit
sugi
parents:
diff changeset
556 }
cb825acd883a first commit
sugi
parents:
diff changeset
557
cb825acd883a first commit
sugi
parents:
diff changeset
558 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
559 protected void readValue(Unconverter uc) throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
560 if (uc.getResult() != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
561 uc.resetResult();
cb825acd883a first commit
sugi
parents:
diff changeset
562 }
cb825acd883a first commit
sugi
parents:
diff changeset
563 valueAccept.setUnconverter(uc);
cb825acd883a first commit
sugi
parents:
diff changeset
564
cb825acd883a first commit
sugi
parents:
diff changeset
565 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
566 if (readOneWithoutStack(valueAccept)) {
cb825acd883a first commit
sugi
parents:
diff changeset
567 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
568 if (uc.getResult() != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
569 return;
cb825acd883a first commit
sugi
parents:
diff changeset
570 }
cb825acd883a first commit
sugi
parents:
diff changeset
571 }
cb825acd883a first commit
sugi
parents:
diff changeset
572 while (true) {
cb825acd883a first commit
sugi
parents:
diff changeset
573 while (stack.getTopCount() == 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
574 if (stack.topIsArray()) {
cb825acd883a first commit
sugi
parents:
diff changeset
575 uc.writeArrayEnd(true);
cb825acd883a first commit
sugi
parents:
diff changeset
576 stack.pop();
cb825acd883a first commit
sugi
parents:
diff changeset
577 // stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
578 } else if (stack.topIsMap()) {
cb825acd883a first commit
sugi
parents:
diff changeset
579 uc.writeMapEnd(true);
cb825acd883a first commit
sugi
parents:
diff changeset
580 stack.pop();
cb825acd883a first commit
sugi
parents:
diff changeset
581 // stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
582 } else {
cb825acd883a first commit
sugi
parents:
diff changeset
583 throw new RuntimeException("invalid stack"); // FIXME error?
cb825acd883a first commit
sugi
parents:
diff changeset
584 }
cb825acd883a first commit
sugi
parents:
diff changeset
585 if (uc.getResult() != null) {
cb825acd883a first commit
sugi
parents:
diff changeset
586 return;
cb825acd883a first commit
sugi
parents:
diff changeset
587 }
cb825acd883a first commit
sugi
parents:
diff changeset
588 }
cb825acd883a first commit
sugi
parents:
diff changeset
589 readOne(valueAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
590 }
cb825acd883a first commit
sugi
parents:
diff changeset
591 }
cb825acd883a first commit
sugi
parents:
diff changeset
592
cb825acd883a first commit
sugi
parents:
diff changeset
593 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
594 public void skip() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
595 stack.checkCount();
cb825acd883a first commit
sugi
parents:
diff changeset
596 if (readOneWithoutStack(skipAccept)) {
cb825acd883a first commit
sugi
parents:
diff changeset
597 stack.reduceCount();
cb825acd883a first commit
sugi
parents:
diff changeset
598 return;
cb825acd883a first commit
sugi
parents:
diff changeset
599 }
cb825acd883a first commit
sugi
parents:
diff changeset
600 int targetDepth = stack.getDepth() - 1;
cb825acd883a first commit
sugi
parents:
diff changeset
601 while (true) {
cb825acd883a first commit
sugi
parents:
diff changeset
602 while (stack.getTopCount() == 0) {
cb825acd883a first commit
sugi
parents:
diff changeset
603 stack.pop();
cb825acd883a first commit
sugi
parents:
diff changeset
604 if (stack.getDepth() <= targetDepth) {
cb825acd883a first commit
sugi
parents:
diff changeset
605 return;
cb825acd883a first commit
sugi
parents:
diff changeset
606 }
cb825acd883a first commit
sugi
parents:
diff changeset
607 }
cb825acd883a first commit
sugi
parents:
diff changeset
608 readOne(skipAccept);
cb825acd883a first commit
sugi
parents:
diff changeset
609 }
cb825acd883a first commit
sugi
parents:
diff changeset
610 }
cb825acd883a first commit
sugi
parents:
diff changeset
611
cb825acd883a first commit
sugi
parents:
diff changeset
612 public ValueType getNextType() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
613 final int b = (int) getHeadByte();
cb825acd883a first commit
sugi
parents:
diff changeset
614 if ((b & 0x80) == 0) { // Positive Fixnum
cb825acd883a first commit
sugi
parents:
diff changeset
615 return ValueType.INTEGER;
cb825acd883a first commit
sugi
parents:
diff changeset
616 }
cb825acd883a first commit
sugi
parents:
diff changeset
617 if ((b & 0xe0) == 0xe0) { // Negative Fixnum
cb825acd883a first commit
sugi
parents:
diff changeset
618 return ValueType.INTEGER;
cb825acd883a first commit
sugi
parents:
diff changeset
619 }
cb825acd883a first commit
sugi
parents:
diff changeset
620 if ((b & 0xe0) == 0xa0) { // FixRaw
cb825acd883a first commit
sugi
parents:
diff changeset
621 return ValueType.RAW;
cb825acd883a first commit
sugi
parents:
diff changeset
622 }
cb825acd883a first commit
sugi
parents:
diff changeset
623 if ((b & 0xf0) == 0x90) { // FixArray
cb825acd883a first commit
sugi
parents:
diff changeset
624 return ValueType.ARRAY;
cb825acd883a first commit
sugi
parents:
diff changeset
625 }
cb825acd883a first commit
sugi
parents:
diff changeset
626 if ((b & 0xf0) == 0x80) { // FixMap
cb825acd883a first commit
sugi
parents:
diff changeset
627 return ValueType.MAP;
cb825acd883a first commit
sugi
parents:
diff changeset
628 }
cb825acd883a first commit
sugi
parents:
diff changeset
629 switch (b & 0xff) {
cb825acd883a first commit
sugi
parents:
diff changeset
630 case 0xc0: // nil
cb825acd883a first commit
sugi
parents:
diff changeset
631 return ValueType.NIL;
cb825acd883a first commit
sugi
parents:
diff changeset
632 case 0xc2: // false
cb825acd883a first commit
sugi
parents:
diff changeset
633 case 0xc3: // true
cb825acd883a first commit
sugi
parents:
diff changeset
634 return ValueType.BOOLEAN;
cb825acd883a first commit
sugi
parents:
diff changeset
635 case 0xca: // float
cb825acd883a first commit
sugi
parents:
diff changeset
636 case 0xcb: // double
cb825acd883a first commit
sugi
parents:
diff changeset
637 return ValueType.FLOAT;
cb825acd883a first commit
sugi
parents:
diff changeset
638 case 0xcc: // unsigned int 8
cb825acd883a first commit
sugi
parents:
diff changeset
639 case 0xcd: // unsigned int 16
cb825acd883a first commit
sugi
parents:
diff changeset
640 case 0xce: // unsigned int 32
cb825acd883a first commit
sugi
parents:
diff changeset
641 case 0xcf: // unsigned int 64
cb825acd883a first commit
sugi
parents:
diff changeset
642 case 0xd0: // signed int 8
cb825acd883a first commit
sugi
parents:
diff changeset
643 case 0xd1: // signed int 16
cb825acd883a first commit
sugi
parents:
diff changeset
644 case 0xd2: // signed int 32
cb825acd883a first commit
sugi
parents:
diff changeset
645 case 0xd3: // signed int 64
cb825acd883a first commit
sugi
parents:
diff changeset
646 return ValueType.INTEGER;
cb825acd883a first commit
sugi
parents:
diff changeset
647 // The definition based on a minor upgrade guide.
cb825acd883a first commit
sugi
parents:
diff changeset
648 // https://github.com/msgpack/msgpack/blob/master/spec.md#impl-upgrade
cb825acd883a first commit
sugi
parents:
diff changeset
649 case 0xc4: // bin 8
cb825acd883a first commit
sugi
parents:
diff changeset
650 case 0xc5: // bin 16
cb825acd883a first commit
sugi
parents:
diff changeset
651 case 0xc6: // bin 32
cb825acd883a first commit
sugi
parents:
diff changeset
652 case 0xd9: // str8
cb825acd883a first commit
sugi
parents:
diff changeset
653 case 0xda: // raw 16
cb825acd883a first commit
sugi
parents:
diff changeset
654 case 0xdb: // raw 32
cb825acd883a first commit
sugi
parents:
diff changeset
655 return ValueType.RAW;
cb825acd883a first commit
sugi
parents:
diff changeset
656 case 0xdc: // array 16
cb825acd883a first commit
sugi
parents:
diff changeset
657 case 0xdd: // array 32
cb825acd883a first commit
sugi
parents:
diff changeset
658 return ValueType.ARRAY;
cb825acd883a first commit
sugi
parents:
diff changeset
659 case 0xde: // map 16
cb825acd883a first commit
sugi
parents:
diff changeset
660 case 0xdf: // map 32
cb825acd883a first commit
sugi
parents:
diff changeset
661 return ValueType.MAP;
cb825acd883a first commit
sugi
parents:
diff changeset
662 default:
cb825acd883a first commit
sugi
parents:
diff changeset
663 throw new IOException("Invalid byte: " + b); // TODO error FormatException
cb825acd883a first commit
sugi
parents:
diff changeset
664 }
cb825acd883a first commit
sugi
parents:
diff changeset
665 }
cb825acd883a first commit
sugi
parents:
diff changeset
666
cb825acd883a first commit
sugi
parents:
diff changeset
667 public void reset() {
cb825acd883a first commit
sugi
parents:
diff changeset
668 raw = null;
cb825acd883a first commit
sugi
parents:
diff changeset
669 stack.clear();
cb825acd883a first commit
sugi
parents:
diff changeset
670 }
cb825acd883a first commit
sugi
parents:
diff changeset
671
cb825acd883a first commit
sugi
parents:
diff changeset
672 public void close() throws IOException {
cb825acd883a first commit
sugi
parents:
diff changeset
673 in.close();
cb825acd883a first commit
sugi
parents:
diff changeset
674 }
cb825acd883a first commit
sugi
parents:
diff changeset
675
cb825acd883a first commit
sugi
parents:
diff changeset
676 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
677 public int getReadByteCount() {
cb825acd883a first commit
sugi
parents:
diff changeset
678 return in.getReadByteCount();
cb825acd883a first commit
sugi
parents:
diff changeset
679 }
cb825acd883a first commit
sugi
parents:
diff changeset
680
cb825acd883a first commit
sugi
parents:
diff changeset
681 @Override
cb825acd883a first commit
sugi
parents:
diff changeset
682 public void resetReadByteCount() {
cb825acd883a first commit
sugi
parents:
diff changeset
683 in.resetReadByteCount();
cb825acd883a first commit
sugi
parents:
diff changeset
684 }
4
d5cc3aef5b74 add getSerializedByteArray Method
sugi
parents: 1
diff changeset
685
1
769ba8da0840 add get serialized ByteArray method
one
parents: 0
diff changeset
686 public byte[] getSerializedByteArray(int len) throws IOException {
6
8d782f988d92 refactor
sugi
parents: 5
diff changeset
687 byte[] b = new byte[len];
8d782f988d92 refactor
sugi
parents: 5
diff changeset
688 in.read(b, 0, b.length);
8d782f988d92 refactor
sugi
parents: 5
diff changeset
689 return b;
1
769ba8da0840 add get serialized ByteArray method
one
parents: 0
diff changeset
690 }
0
cb825acd883a first commit
sugi
parents:
diff changeset
691 }