]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | package org.apache.thrift.protocol { | |
21 | ||
22 | import flash.utils.ByteArray; | |
23 | ||
24 | import org.apache.thrift.TError; | |
25 | import org.apache.thrift.transport.THttpClient; | |
26 | import org.apache.thrift.transport.TTransport; | |
27 | ||
28 | /** | |
29 | * Binary protocol implementation for thrift. | |
30 | */ | |
31 | public class TBinaryProtocol implements TProtocol { | |
32 | ||
33 | private static var ANONYMOUS_STRUCT:TStruct = new TStruct(); | |
34 | ||
35 | protected static const VERSION_MASK:int = int(0xffff0000); | |
36 | protected static const VERSION_1:int = int(0x80010000); | |
37 | ||
38 | protected var strictRead_:Boolean = false; | |
39 | protected var strictWrite_:Boolean = true; | |
40 | ||
41 | /** | |
42 | * Factory | |
43 | */ | |
44 | /* | |
45 | public static class Factory implements TProtocolFactory { | |
46 | protected boolean strictRead_ = false; | |
47 | protected boolean strictWrite_ = true; | |
48 | ||
49 | public Factory() { | |
50 | this(false, true); | |
51 | } | |
52 | ||
53 | public Factory(boolean strictRead, boolean strictWrite) { | |
54 | strictRead_ = strictRead; | |
55 | strictWrite_ = strictWrite; | |
56 | } | |
57 | ||
58 | public TProtocol getProtocol(TTransport trans) { | |
59 | return new TBinaryProtocol(trans, strictRead_, strictWrite_); | |
60 | } | |
61 | } | |
62 | */ | |
63 | ||
64 | private var trans_:TTransport; | |
65 | ||
66 | /** | |
67 | * Constructor | |
68 | */ | |
69 | public function TBinaryProtocol(trans:TTransport, strictRead:Boolean=false, strictWrite:Boolean=true) { | |
70 | trans_ = trans; | |
71 | strictRead_ = strictRead; | |
72 | strictWrite_ = strictWrite; | |
73 | } | |
74 | ||
75 | public function getTransport():TTransport { | |
76 | return trans_; | |
77 | } | |
78 | ||
79 | public function writeMessageBegin(message:TMessage):void { | |
80 | if (strictWrite_) { | |
81 | var version:int = VERSION_1 | message.type; | |
82 | writeI32(version); | |
83 | writeString(message.name); | |
84 | writeI32(message.seqid); | |
85 | } else { | |
86 | writeString(message.name); | |
87 | writeByte(message.type); | |
88 | writeI32(message.seqid); | |
89 | } | |
90 | } | |
91 | ||
92 | public function writeMessageEnd():void {} | |
93 | ||
94 | public function writeStructBegin(struct:TStruct):void {} | |
95 | ||
96 | public function writeStructEnd():void {} | |
97 | ||
98 | public function writeFieldBegin(field:TField):void { | |
99 | writeByte(field.type); | |
100 | writeI16(field.id); | |
101 | } | |
102 | ||
103 | public function writeFieldEnd():void {} | |
104 | ||
105 | public function writeFieldStop():void { | |
106 | writeByte(TType.STOP); | |
107 | } | |
108 | ||
109 | public function writeMapBegin(map:TMap):void { | |
110 | writeByte(map.keyType); | |
111 | writeByte(map.valueType); | |
112 | writeI32(map.size); | |
113 | } | |
114 | ||
115 | public function writeMapEnd():void {} | |
116 | ||
117 | public function writeListBegin(list:TList):void { | |
118 | writeByte(list.elemType); | |
119 | writeI32(list.size); | |
120 | } | |
121 | ||
122 | public function writeListEnd():void {} | |
123 | ||
124 | public function writeSetBegin(set:TSet):void { | |
125 | writeByte(set.elemType); | |
126 | writeI32(set.size); | |
127 | } | |
128 | ||
129 | public function writeSetEnd():void {} | |
130 | ||
131 | public function writeBool(b:Boolean):void { | |
132 | writeByte(b ? 1 : 0); | |
133 | } | |
134 | ||
135 | private var out:ByteArray = new ByteArray(); | |
136 | public function writeByte(b:int):void { | |
137 | reset(out); | |
138 | out.writeByte(b); | |
139 | trans_.write(out, 0, 1); | |
140 | } | |
141 | ||
142 | public function writeI16(i16:int):void { | |
143 | reset(out); | |
144 | out.writeShort(i16); | |
145 | trans_.write(out, 0, 2); | |
146 | } | |
147 | ||
148 | public function writeI32(i32:int):void { | |
149 | reset(out); | |
150 | out.writeInt(i32); | |
151 | trans_.write(out, 0, 4); | |
152 | } | |
153 | ||
154 | //private byte[] i64out = new byte[8]; | |
155 | //public function writeI64(i64:Number):void { | |
156 | //i64out[0] = (byte)(0xff & (i64 >> 56)); | |
157 | //i64out[1] = (byte)(0xff & (i64 >> 48)); | |
158 | //i64out[2] = (byte)(0xff & (i64 >> 40)); | |
159 | //i64out[3] = (byte)(0xff & (i64 >> 32)); | |
160 | //i64out[4] = (byte)(0xff & (i64 >> 24)); | |
161 | //i64out[5] = (byte)(0xff & (i64 >> 16)); | |
162 | //i64out[6] = (byte)(0xff & (i64 >> 8)); | |
163 | //i64out[7] = (byte)(0xff & (i64)); | |
164 | //trans_.write(i64out, 0, 8); | |
165 | //} | |
166 | ||
167 | public function writeDouble(dub:Number):void { | |
168 | reset(out); | |
169 | out.writeDouble(dub); | |
170 | trans_.write(out, 0, 8); | |
171 | } | |
172 | ||
173 | private var stringOut:ByteArray = new ByteArray(); | |
174 | ||
175 | public function writeString(str:String):void { | |
176 | reset(stringOut); | |
177 | stringOut.writeUTFBytes(str); | |
178 | ||
179 | writeI32(stringOut.length); | |
180 | trans_.write(stringOut, 0, stringOut.length); | |
181 | } | |
182 | ||
183 | public function writeBinary(bin:ByteArray):void { | |
184 | writeI32(bin.length); | |
185 | trans_.write(bin, 0, bin.length); | |
186 | } | |
187 | ||
188 | /** | |
189 | * Reading methods. | |
190 | */ | |
191 | ||
192 | public function readMessageBegin():TMessage { | |
193 | var size:int = readI32(); | |
194 | if (size < 0) { | |
195 | var version:int = size & VERSION_MASK; | |
196 | if (version != VERSION_1) { | |
197 | throw new TProtocolError(TProtocolError.BAD_VERSION, "Bad version in readMessageBegin"); | |
198 | } | |
199 | return new TMessage(readString(), size & 0x000000ff, readI32()); | |
200 | } | |
201 | else { | |
202 | if (strictRead_) { | |
203 | throw new TProtocolError(TProtocolError.BAD_VERSION, "Missing version in readMessageBegin, old client?"); | |
204 | } | |
205 | return new TMessage(readStringBody(size), readByte(), readI32()); | |
206 | } | |
207 | } | |
208 | ||
209 | public function readMessageEnd():void {} | |
210 | ||
211 | public function readStructBegin():TStruct { | |
212 | return ANONYMOUS_STRUCT; | |
213 | } | |
214 | ||
215 | public function readStructEnd():void {} | |
216 | ||
217 | public function readFieldBegin():TField { | |
218 | var type:int = readByte(); | |
219 | var id:int = type == TType.STOP ? 0 : readI16(); | |
220 | return new TField("", type, id); | |
221 | } | |
222 | ||
223 | public function readFieldEnd():void {} | |
224 | ||
225 | public function readMapBegin():TMap { | |
226 | return new TMap(readByte(), readByte(), readI32()); | |
227 | } | |
228 | ||
229 | public function readMapEnd():void {} | |
230 | ||
231 | public function readListBegin():TList { | |
232 | return new TList(readByte(), readI32()); | |
233 | } | |
234 | ||
235 | public function readListEnd():void {} | |
236 | ||
237 | public function readSetBegin():TSet { | |
238 | return new TSet(readByte(), readI32()); | |
239 | } | |
240 | ||
241 | public function readSetEnd():void {} | |
242 | ||
243 | public function readBool():Boolean { | |
244 | return (readByte() == 1); | |
245 | } | |
246 | ||
247 | private var bytes:ByteArray = new ByteArray(); | |
248 | ||
249 | public function readByte():int { | |
250 | readAll(1); | |
251 | return bytes.readByte(); | |
252 | } | |
253 | ||
254 | public function readI16():int { | |
255 | readAll(2); | |
256 | return bytes.readShort(); | |
257 | } | |
258 | ||
259 | public function readI32():int { | |
260 | readAll(4); | |
261 | return bytes.readInt(); | |
262 | } | |
263 | ||
264 | //private byte[] i64rd = new byte[8]; | |
265 | /* | |
266 | public function readI64() throws TException { | |
267 | readAll(i64rd, 0, 8); | |
268 | return | |
269 | ((long)(i64rd[0] & 0xff) << 56) | | |
270 | ((long)(i64rd[1] & 0xff) << 48) | | |
271 | ((long)(i64rd[2] & 0xff) << 40) | | |
272 | ((long)(i64rd[3] & 0xff) << 32) | | |
273 | ((long)(i64rd[4] & 0xff) << 24) | | |
274 | ((long)(i64rd[5] & 0xff) << 16) | | |
275 | ((long)(i64rd[6] & 0xff) << 8) | | |
276 | ((long)(i64rd[7] & 0xff)); | |
277 | } | |
278 | */ | |
279 | ||
280 | public function readDouble():Number { | |
281 | readAll(8); | |
282 | return bytes.readDouble(); | |
283 | } | |
284 | ||
285 | public function readString():String { | |
286 | var size:int = readI32(); | |
287 | readAll(size); | |
288 | return bytes.readUTFBytes(size); | |
289 | } | |
290 | ||
291 | public function readStringBody(size:int):String { | |
292 | readAll(size); | |
293 | return bytes.readUTFBytes(size); | |
294 | } | |
295 | ||
296 | public function readBinary():ByteArray { | |
297 | var size:int = readI32(); | |
298 | var buf:ByteArray = new ByteArray(); | |
299 | trans_.readAll(buf, 0, size); | |
300 | return buf; | |
301 | } | |
302 | ||
303 | private function readAll(len:int):void { | |
304 | reset(bytes); | |
305 | ||
306 | trans_.readAll(bytes, 0, len); | |
307 | ||
308 | bytes.position = 0; | |
309 | } | |
310 | ||
311 | private static function reset(arr:ByteArray):void { | |
312 | arr.length = 0; | |
313 | arr.position = 0; | |
314 | } | |
315 | } | |
316 | } |