blob: 860cb99c9fc720f17da474de1434ddd2f2f8c039 [file] [log] [blame]
T Jake Luciani322caa22010-02-15 03:24:55 +00001/*
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 */
19var Thrift = {
Roger Meier0244e932011-03-09 15:25:01 +000020 Version: '0.7.0-dev',
21/*
22 Description: 'JavaScript bindings for the Apache Thrift RPC system',
23 License: 'http://www.apache.org/licenses/LICENSE-2.0',
24 Homepage: 'http://thrift.apache.org',
25 BugReports: 'https://issues.apache.org/jira/browse/THRIFT',
26 Maintainer: 'dev@thrift.apache.org',
27*/
T Jake Luciani322caa22010-02-15 03:24:55 +000028
Roger Meierb4bcbe32011-03-07 19:37:46 +000029 Type: {
30 'STOP' : 0,
31 'VOID' : 1,
32 'BOOL' : 2,
33 'BYTE' : 3,
34 'I08' : 3,
35 'DOUBLE' : 4,
36 'I16' : 6,
37 'I32' : 8,
38 'I64' : 10,
39 'STRING' : 11,
40 'UTF7' : 11,
41 'STRUCT' : 12,
42 'MAP' : 13,
43 'SET' : 14,
44 'LIST' : 15,
45 'UTF8' : 16,
46 'UTF16' : 17
T Jake Luciani322caa22010-02-15 03:24:55 +000047 },
48
Roger Meierb4bcbe32011-03-07 19:37:46 +000049 MessageType: {
50 'CALL' : 1,
51 'REPLY' : 2,
52 'EXCEPTION' : 3
Roger Meier55ea68f2011-02-16 19:29:50 +000053 },
Roger Meierb4bcbe32011-03-07 19:37:46 +000054
55 objectLength: function(obj) {
56 var length = 0;
Roger Meierda6e6ae2011-03-15 09:55:33 +000057 for (var k in obj) {
58 if (obj.hasOwnProperty(k)) {
Roger Meier08b30992011-04-06 21:30:53 +000059 length++;
Roger Meierda6e6ae2011-03-15 09:55:33 +000060 }
61 }
62
Roger Meierb4bcbe32011-03-07 19:37:46 +000063 return length;
Roger Meier55ea68f2011-02-16 19:29:50 +000064 },
65
Roger Meierda6e6ae2011-03-15 09:55:33 +000066 inherits: function(constructor, superConstructor) {
Roger Meierb4bcbe32011-03-07 19:37:46 +000067 //Prototypal Inheritance http://javascript.crockford.com/prototypal.html
68 function F() {}
69 F.prototype = superConstructor.prototype;
70 constructor.prototype = new F();
T Jake Luciani322caa22010-02-15 03:24:55 +000071 }
Roger Meierb4bcbe32011-03-07 19:37:46 +000072};
T Jake Luciani322caa22010-02-15 03:24:55 +000073
Roger Meier55ea68f2011-02-16 19:29:50 +000074
T Jake Luciani322caa22010-02-15 03:24:55 +000075
Roger Meier6b0d4562011-07-08 12:44:29 +000076Thrift.TException = function(message) {
77 this.message = message;
78};
79Thrift.inherits(Thrift.TException, Error);
80Thrift.TException.prototype.name = 'TException';
T Jake Luciani322caa22010-02-15 03:24:55 +000081
T Jake Lucianiefabb892010-07-28 22:31:12 +000082Thrift.TApplicationExceptionType = {
Roger Meierb4bcbe32011-03-07 19:37:46 +000083 'UNKNOWN' : 0,
84 'UNKNOWN_METHOD' : 1,
85 'INVALID_MESSAGE_TYPE' : 2,
86 'WRONG_METHOD_NAME' : 3,
87 'BAD_SEQUENCE_ID' : 4,
88 'MISSING_RESULT' : 5
89};
T Jake Luciani322caa22010-02-15 03:24:55 +000090
Roger Meierb4bcbe32011-03-07 19:37:46 +000091Thrift.TApplicationException = function(message, code) {
92 this.message = message;
Roger Meierda6e6ae2011-03-15 09:55:33 +000093 this.code = (code === null) ? 0 : code;
Roger Meierb4bcbe32011-03-07 19:37:46 +000094};
Roger Meier6b0d4562011-07-08 12:44:29 +000095Thrift.inherits(Thrift.TApplicationException, Thrift.TException);
96Thrift.TApplicationException.prototype.name = 'TApplicationException';
T Jake Luciani322caa22010-02-15 03:24:55 +000097
Roger Meier6b0d4562011-07-08 12:44:29 +000098Thrift.TApplicationException.prototype.read = function(input) {
99 while (1) {
100 var ret = input.readFieldBegin();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000101
Roger Meier6b0d4562011-07-08 12:44:29 +0000102 if (ret.ftype == Thrift.Type.STOP) {
103 break;
104 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000105
Roger Meier6b0d4562011-07-08 12:44:29 +0000106 var fid = ret.fid;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000107
Roger Meier6b0d4562011-07-08 12:44:29 +0000108 switch (fid) {
109 case 1:
110 if (ret.ftype == Thrift.Type.STRING) {
111 ret = input.readString();
112 this.message = ret.value;
113 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000114 ret = input.skip(ret.ftype);
Roger Meier6b0d4562011-07-08 12:44:29 +0000115 }
116 break;
117 case 2:
118 if (ret.ftype == Thrift.Type.I32) {
119 ret = input.readI32();
120 this.code = ret.value;
121 } else {
122 ret = input.skip(ret.ftype);
123 }
124 break;
125 default:
126 ret = input.skip(ret.ftype);
127 break;
T Jake Luciani322caa22010-02-15 03:24:55 +0000128 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000129
Roger Meier6b0d4562011-07-08 12:44:29 +0000130 input.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000131 }
Roger Meier6b0d4562011-07-08 12:44:29 +0000132
133 input.readStructEnd();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000134};
T Jake Luciani322caa22010-02-15 03:24:55 +0000135
Roger Meier6b0d4562011-07-08 12:44:29 +0000136Thrift.TApplicationException.prototype.write = function(output) {
137 var xfer = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000138
Roger Meier6b0d4562011-07-08 12:44:29 +0000139 output.writeStructBegin('TApplicationException');
140
141 if (this.message) {
142 output.writeFieldBegin('message', Thrift.Type.STRING, 1);
143 output.writeString(this.getMessage());
144 output.writeFieldEnd();
145 }
146
147 if (this.code) {
148 output.writeFieldBegin('type', Thrift.Type.I32, 2);
149 output.writeI32(this.code);
150 output.writeFieldEnd();
151 }
152
153 output.writeFieldStop();
154 output.writeStructEnd();
155};
156
157Thrift.TApplicationException.prototype.getCode = function() {
158 return this.code;
159};
160
161Thrift.TApplicationException.prototype.getMessage = function() {
162 return this.message;
163};
T Jake Luciani322caa22010-02-15 03:24:55 +0000164
165/**
166 *If you do not specify a url then you must handle ajax on your own.
167 *This is how to use js bindings in a async fashion.
168 */
Roger Meierb4bcbe32011-03-07 19:37:46 +0000169Thrift.Transport = function(url) {
170 this.url = url;
171 this.wpos = 0;
172 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000173
Roger Meierb4bcbe32011-03-07 19:37:46 +0000174 this.send_buf = '';
175 this.recv_buf = '';
176};
T Jake Luciani322caa22010-02-15 03:24:55 +0000177
178Thrift.Transport.prototype = {
179
180 //Gets the browser specific XmlHttpRequest Object
Roger Meierb4bcbe32011-03-07 19:37:46 +0000181 getXmlHttpRequestObject: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000182 try { return new XMLHttpRequest(); } catch (e1) { }
183 try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { }
184 try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000185
186 throw "Your browser doesn't support the XmlHttpRequest object.";
T Jake Luciani322caa22010-02-15 03:24:55 +0000187 },
188
Roger Meier08b30992011-04-06 21:30:53 +0000189 flush: function(async) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000190 //async mode
Roger Meier08b30992011-04-06 21:30:53 +0000191 if (async || this.url === undefined || this.url === '') {
T Jake Luciani322caa22010-02-15 03:24:55 +0000192 return this.send_buf;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000193 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000194
Roger Meierb4bcbe32011-03-07 19:37:46 +0000195 var xreq = this.getXmlHttpRequestObject();
196
Roger Meierda6e6ae2011-03-15 09:55:33 +0000197 if (xreq.overrideMimeType) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000198 xreq.overrideMimeType('application/json');
Roger Meierda6e6ae2011-03-15 09:55:33 +0000199 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000200
201 xreq.open('POST', this.url, false);
202 xreq.send(this.send_buf);
203
Roger Meierda6e6ae2011-03-15 09:55:33 +0000204 if (xreq.readyState != 4) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000205 throw 'encountered an unknown ajax ready state: ' + xreq.readyState;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000206 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000207
Roger Meierda6e6ae2011-03-15 09:55:33 +0000208 if (xreq.status != 200) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000209 throw 'encountered a unknown request status: ' + xreq.status;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000210 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000211
Roger Meierb4bcbe32011-03-07 19:37:46 +0000212 this.recv_buf = xreq.responseText;
213 this.recv_buf_sz = this.recv_buf.length;
214 this.wpos = this.recv_buf.length;
215 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000216 },
217
Roger Meier08b30992011-04-06 21:30:53 +0000218 jqRequest: function(client, postData, args, recv_method) {
219 if (typeof jQuery === 'undefined' ||
220 typeof jQuery.Deferred === 'undefined') {
221 throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests';
222 }
223
224 // Deferreds
225 var deferred = jQuery.Deferred();
226 var completeDfd = jQuery._Deferred();
227 var dfd = deferred.promise();
228 dfd.success = dfd.done;
229 dfd.error = dfd.fail;
230 dfd.complete = completeDfd.done;
231
232 var jqXHR = jQuery.ajax({
233 url: this.url,
234 data: postData,
235 type: 'POST',
236 cache: false,
237 dataType: 'text',
238 context: this,
239 success: this.jqResponse,
240 error: function(xhr, status, e) {
241 deferred.rejectWith(client, jQuery.merge([e], xhr.tArgs));
242 },
243 complete: function(xhr, status) {
244 completeDfd.resolveWith(client, [xhr, status]);
245 }
246 });
247
248 deferred.done(jQuery.makeArray(args).pop()); //pop callback from args
249 jqXHR.tArgs = args;
250 jqXHR.tClient = client;
251 jqXHR.tRecvFn = recv_method;
252 jqXHR.tDfd = deferred;
253 return dfd;
254 },
255
256 jqResponse: function(responseData, textStatus, jqXHR) {
257 this.setRecvBuffer(responseData);
258 try {
259 var value = jqXHR.tRecvFn.call(jqXHR.tClient);
260 jqXHR.tDfd.resolveWith(jqXHR, jQuery.merge([value], jqXHR.tArgs));
261 } catch (ex) {
262 jqXHR.tDfd.rejectWith(jqXHR, jQuery.merge([ex], jqXHR.tArgs));
263 }
264 },
265
Roger Meierb4bcbe32011-03-07 19:37:46 +0000266 setRecvBuffer: function(buf) {
267 this.recv_buf = buf;
268 this.recv_buf_sz = this.recv_buf.length;
269 this.wpos = this.recv_buf.length;
270 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000271 },
272
Roger Meierb4bcbe32011-03-07 19:37:46 +0000273 isOpen: function() {
274 return true;
T Jake Luciani322caa22010-02-15 03:24:55 +0000275 },
276
Roger Meierb4bcbe32011-03-07 19:37:46 +0000277 open: function() {},
T Jake Luciani322caa22010-02-15 03:24:55 +0000278
279 close: function() {},
280
Roger Meierb4bcbe32011-03-07 19:37:46 +0000281 read: function(len) {
282 var avail = this.wpos - this.rpos;
T Jake Luciani322caa22010-02-15 03:24:55 +0000283
Roger Meierda6e6ae2011-03-15 09:55:33 +0000284 if (avail === 0) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000285 return '';
Roger Meierda6e6ae2011-03-15 09:55:33 +0000286 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000287
Roger Meierb4bcbe32011-03-07 19:37:46 +0000288 var give = len;
T Jake Luciani322caa22010-02-15 03:24:55 +0000289
Roger Meierda6e6ae2011-03-15 09:55:33 +0000290 if (avail < len) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000291 give = avail;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000292 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000293
294 var ret = this.read_buf.substr(this.rpos, give);
295 this.rpos += give;
T Jake Luciani322caa22010-02-15 03:24:55 +0000296
297 //clear buf when complete?
Roger Meierb4bcbe32011-03-07 19:37:46 +0000298 return ret;
T Jake Luciani322caa22010-02-15 03:24:55 +0000299 },
300
Roger Meierb4bcbe32011-03-07 19:37:46 +0000301 readAll: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000302 return this.recv_buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000303 },
304
Roger Meierb4bcbe32011-03-07 19:37:46 +0000305 write: function(buf) {
306 this.send_buf = buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000307 },
308
Roger Meierb4bcbe32011-03-07 19:37:46 +0000309 getSendBuffer: function() {
310 return this.send_buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000311 }
312
Roger Meierb4bcbe32011-03-07 19:37:46 +0000313};
T Jake Luciani322caa22010-02-15 03:24:55 +0000314
315
316
Roger Meierb4bcbe32011-03-07 19:37:46 +0000317Thrift.Protocol = function(transport) {
318 this.transport = transport;
319};
T Jake Luciani322caa22010-02-15 03:24:55 +0000320
Roger Meierb4bcbe32011-03-07 19:37:46 +0000321Thrift.Protocol.Type = {};
322Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"';
323Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"';
324Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"';
325Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"';
326Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"';
327Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"';
328Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"';
329Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"';
330Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"';
331Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"';
332Thrift.Protocol.Type[Thrift.Type.SET] = '"set"';
T Jake Luciani322caa22010-02-15 03:24:55 +0000333
334
Roger Meierb4bcbe32011-03-07 19:37:46 +0000335Thrift.Protocol.RType = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000336Thrift.Protocol.RType.tf = Thrift.Type.BOOL;
337Thrift.Protocol.RType.i8 = Thrift.Type.BYTE;
338Thrift.Protocol.RType.i16 = Thrift.Type.I16;
339Thrift.Protocol.RType.i32 = Thrift.Type.I32;
340Thrift.Protocol.RType.i64 = Thrift.Type.I64;
341Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE;
342Thrift.Protocol.RType.rec = Thrift.Type.STRUCT;
343Thrift.Protocol.RType.str = Thrift.Type.STRING;
344Thrift.Protocol.RType.map = Thrift.Type.MAP;
345Thrift.Protocol.RType.lst = Thrift.Type.LIST;
346Thrift.Protocol.RType.set = Thrift.Type.SET;
T Jake Luciani322caa22010-02-15 03:24:55 +0000347
Roger Meierb4bcbe32011-03-07 19:37:46 +0000348Thrift.Protocol.Version = 1;
T Jake Luciani322caa22010-02-15 03:24:55 +0000349
350Thrift.Protocol.prototype = {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000351
352 getTransport: function() {
353 return this.transport;
T Jake Luciani322caa22010-02-15 03:24:55 +0000354 },
355
356 //Write functions
Roger Meierb4bcbe32011-03-07 19:37:46 +0000357 writeMessageBegin: function(name, messageType, seqid) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000358 this.tstack = [];
359 this.tpos = [];
360
361 this.tstack.push([Thrift.Protocol.Version, '"' +
Roger Meierb4bcbe32011-03-07 19:37:46 +0000362 name + '"', messageType, seqid]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000363 },
364
Roger Meierb4bcbe32011-03-07 19:37:46 +0000365 writeMessageEnd: function() {
366 var obj = this.tstack.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000367
Roger Meierb4bcbe32011-03-07 19:37:46 +0000368 this.wobj = this.tstack.pop();
369 this.wobj.push(obj);
370
371 this.wbuf = '[' + this.wobj.join(',') + ']';
372
373 this.transport.write(this.wbuf);
T Jake Luciani322caa22010-02-15 03:24:55 +0000374 },
375
376
Roger Meierb4bcbe32011-03-07 19:37:46 +0000377 writeStructBegin: function(name) {
378 this.tpos.push(this.tstack.length);
379 this.tstack.push({});
T Jake Luciani322caa22010-02-15 03:24:55 +0000380 },
381
Roger Meierb4bcbe32011-03-07 19:37:46 +0000382 writeStructEnd: function() {
383
384 var p = this.tpos.pop();
385 var struct = this.tstack[p];
386 var str = '{';
387 var first = true;
388 for (var key in struct) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000389 if (first) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000390 first = false;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000391 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000392 str += ',';
Roger Meierda6e6ae2011-03-15 09:55:33 +0000393 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000394
Roger Meierb4bcbe32011-03-07 19:37:46 +0000395 str += key + ':' + struct[key];
396 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000397
Roger Meierb4bcbe32011-03-07 19:37:46 +0000398 str += '}';
T Jake Luciani322caa22010-02-15 03:24:55 +0000399 this.tstack[p] = str;
400 },
401
Roger Meierb4bcbe32011-03-07 19:37:46 +0000402 writeFieldBegin: function(name, fieldType, fieldId) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000403 this.tpos.push(this.tstack.length);
404 this.tstack.push({ 'fieldId': '"' +
405 fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType]
Roger Meierb4bcbe32011-03-07 19:37:46 +0000406 });
407
T Jake Luciani322caa22010-02-15 03:24:55 +0000408 },
409
Roger Meierb4bcbe32011-03-07 19:37:46 +0000410 writeFieldEnd: function() {
411 var value = this.tstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000412 var fieldInfo = this.tstack.pop();
413
414 this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' +
Roger Meierb4bcbe32011-03-07 19:37:46 +0000415 fieldInfo.fieldType + ':' + value + '}';
416 this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000417 },
418
Roger Meierb4bcbe32011-03-07 19:37:46 +0000419 writeFieldStop: function() {
T Jake Luciani322caa22010-02-15 03:24:55 +0000420 //na
421 },
422
Roger Meierb4bcbe32011-03-07 19:37:46 +0000423 writeMapBegin: function(keyType, valType, size) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000424 //size is invalid, we'll set it on end.
Roger Meierda6e6ae2011-03-15 09:55:33 +0000425 this.tpos.push(this.tstack.length);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000426 this.tstack.push([Thrift.Protocol.Type[keyType],
427 Thrift.Protocol.Type[valType], 0]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000428 },
429
Roger Meierb4bcbe32011-03-07 19:37:46 +0000430 writeMapEnd: function() {
431 var p = this.tpos.pop();
432
Roger Meierda6e6ae2011-03-15 09:55:33 +0000433 if (p == this.tstack.length) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000434 return;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000435 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000436
Roger Meierda6e6ae2011-03-15 09:55:33 +0000437 if ((this.tstack.length - p - 1) % 2 !== 0) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000438 this.tstack.push('');
Roger Meierda6e6ae2011-03-15 09:55:33 +0000439 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000440
Roger Meierb4bcbe32011-03-07 19:37:46 +0000441 var size = (this.tstack.length - p - 1) / 2;
442
443 this.tstack[p][this.tstack[p].length - 1] = size;
444
445 var map = '}';
446 var first = true;
447 while (this.tstack.length > p + 1) {
448 var v = this.tstack.pop();
449 var k = this.tstack.pop();
450 if (first) {
451 first = false;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000452 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000453 map = ',' + map;
T Jake Luciani322caa22010-02-15 03:24:55 +0000454 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000455
Roger Meier2079bfe2011-06-21 14:09:13 +0000456 if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings
Roger Meier9d8e8f82011-06-14 19:38:27 +0000457 map = k + ':' + v + map;
T Jake Luciani322caa22010-02-15 03:24:55 +0000458 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000459 map = '{' + map;
460
461 this.tstack[p].push(map);
462 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000463 },
464
Roger Meierb4bcbe32011-03-07 19:37:46 +0000465 writeListBegin: function(elemType, size) {
466 this.tpos.push(this.tstack.length);
467 this.tstack.push([Thrift.Protocol.Type[elemType], size]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000468 },
469
Roger Meierb4bcbe32011-03-07 19:37:46 +0000470 writeListEnd: function() {
471 var p = this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000472
Roger Meierb4bcbe32011-03-07 19:37:46 +0000473 while (this.tstack.length > p + 1) {
474 var tmpVal = this.tstack[p + 1];
475 this.tstack.splice(p + 1, 1);
476 this.tstack[p].push(tmpVal);
T Jake Luciani322caa22010-02-15 03:24:55 +0000477 }
478
Roger Meierb4bcbe32011-03-07 19:37:46 +0000479 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000480 },
481
Roger Meierb4bcbe32011-03-07 19:37:46 +0000482 writeSetBegin: function(elemType, size) {
483 this.tpos.push(this.tstack.length);
484 this.tstack.push([Thrift.Protocol.Type[elemType], size]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000485 },
486
Roger Meierb4bcbe32011-03-07 19:37:46 +0000487 writeSetEnd: function() {
488 var p = this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000489
Roger Meierb4bcbe32011-03-07 19:37:46 +0000490 while (this.tstack.length > p + 1) {
491 var tmpVal = this.tstack[p + 1];
492 this.tstack.splice(p + 1, 1);
493 this.tstack[p].push(tmpVal);
T Jake Luciani322caa22010-02-15 03:24:55 +0000494 }
495
Roger Meierb4bcbe32011-03-07 19:37:46 +0000496 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000497 },
498
Roger Meierb4bcbe32011-03-07 19:37:46 +0000499 writeBool: function(value) {
500 this.tstack.push(value ? 1 : 0);
T Jake Luciani322caa22010-02-15 03:24:55 +0000501 },
502
Roger Meierb4bcbe32011-03-07 19:37:46 +0000503 writeByte: function(i8) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000504 this.tstack.push(i8);
505 },
506
Roger Meierb4bcbe32011-03-07 19:37:46 +0000507 writeI16: function(i16) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000508 this.tstack.push(i16);
509 },
510
Roger Meierb4bcbe32011-03-07 19:37:46 +0000511 writeI32: function(i32) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000512 this.tstack.push(i32);
513 },
514
Roger Meierb4bcbe32011-03-07 19:37:46 +0000515 writeI64: function(i64) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000516 this.tstack.push(i64);
517 },
518
Roger Meierb4bcbe32011-03-07 19:37:46 +0000519 writeDouble: function(dbl) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000520 this.tstack.push(dbl);
521 },
522
Roger Meierb4bcbe32011-03-07 19:37:46 +0000523 writeString: function(str) {
524 // We do not encode uri components for wire transfer:
525 if (str === null) {
T Jake Luciani416eea92010-09-17 23:38:25 +0000526 this.tstack.push(null);
527 } else {
528 // concat may be slower than building a byte buffer
Roger Meierb4bcbe32011-03-07 19:37:46 +0000529 var escapedString = '';
530 for (var i = 0; i < str.length; i++) {
531 var ch = str.charAt(i); // a single double quote: "
532 if (ch === '\"') {
533 escapedString += '\\\"'; // write out as: \"
534 } else if (ch === '\\') { // a single backslash: \
535 escapedString += '\\\\'; // write out as: \\
T Jake Luciani416eea92010-09-17 23:38:25 +0000536 /* Currently escaped forward slashes break TJSONProtocol.
Roger Meierb4bcbe32011-03-07 19:37:46 +0000537 * As it stands, we can simply pass forward slashes into
538 * our strings across the wire without being escaped.
T Jake Luciani416eea92010-09-17 23:38:25 +0000539 * I think this is the protocol's bug, not thrift.js
Roger Meierb4bcbe32011-03-07 19:37:46 +0000540 * } else if(ch === '/') { // a single forward slash: /
541 * escapedString += '\\/'; // write out as \/
542 * }
T Jake Luciani416eea92010-09-17 23:38:25 +0000543 */
Roger Meierb4bcbe32011-03-07 19:37:46 +0000544 } else if (ch === '\b') { // a single backspace: invisible
545 escapedString += '\\b'; // write out as: \b"
546 } else if (ch === '\f') { // a single formfeed: invisible
547 escapedString += '\\f'; // write out as: \f"
548 } else if (ch === '\n') { // a single newline: invisible
549 escapedString += '\\n'; // write out as: \n"
550 } else if (ch === '\r') { // a single return: invisible
551 escapedString += '\\r'; // write out as: \r"
552 } else if (ch === '\t') { // a single tab: invisible
553 escapedString += '\\t'; // write out as: \t"
T Jake Luciani416eea92010-09-17 23:38:25 +0000554 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000555 escapedString += ch; // Else it need not be escaped
T Jake Luciani416eea92010-09-17 23:38:25 +0000556 }
557 }
558 this.tstack.push('"' + escapedString + '"');
559 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000560 },
561
Roger Meierb4bcbe32011-03-07 19:37:46 +0000562 writeBinary: function(str) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000563 this.writeString(str);
564 },
565
566
Roger Meierb4bcbe32011-03-07 19:37:46 +0000567
T Jake Luciani322caa22010-02-15 03:24:55 +0000568 // Reading functions
Roger Meierb4bcbe32011-03-07 19:37:46 +0000569 readMessageBegin: function(name, messageType, seqid) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000570 this.rstack = [];
571 this.rpos = [];
T Jake Luciani322caa22010-02-15 03:24:55 +0000572
Roger Meier08b30992011-04-06 21:30:53 +0000573 if (typeof jQuery !== 'undefined') {
574 this.robj = jQuery.parseJSON(this.transport.readAll());
575 } else {
576 this.robj = eval(this.transport.readAll());
577 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000578
T Jake Luciani322caa22010-02-15 03:24:55 +0000579 var r = {};
Roger Meierb4bcbe32011-03-07 19:37:46 +0000580 var version = this.robj.shift();
581
582 if (version != Thrift.Protocol.Version) {
583 throw 'Wrong thrift protocol version: ' + version;
T Jake Luciani322caa22010-02-15 03:24:55 +0000584 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000585
Roger Meierda6e6ae2011-03-15 09:55:33 +0000586 r.fname = this.robj.shift();
587 r.mtype = this.robj.shift();
588 r.rseqid = this.robj.shift();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000589
590
591 //get to the main obj
592 this.rstack.push(this.robj.shift());
593
594 return r;
595 },
596
Roger Meierb4bcbe32011-03-07 19:37:46 +0000597 readMessageEnd: function() {
598 },
599
600 readStructBegin: function(name) {
601 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000602 r.fname = '';
Roger Meierb4bcbe32011-03-07 19:37:46 +0000603
604 //incase this is an array of structs
Roger Meierda6e6ae2011-03-15 09:55:33 +0000605 if (this.rstack[this.rstack.length - 1] instanceof Array) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000606 this.rstack.push(this.rstack[this.rstack.length - 1].shift());
Roger Meierda6e6ae2011-03-15 09:55:33 +0000607 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000608
609 return r;
610 },
611
612 readStructEnd: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000613 if (this.rstack[this.rstack.length - 2] instanceof Array) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000614 this.rstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000615 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000616 },
617
618 readFieldBegin: function() {
619 var r = {};
620
621 var fid = -1;
622 var ftype = Thrift.Type.STOP;
623
624 //get a fieldId
625 for (var f in (this.rstack[this.rstack.length - 1])) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000626 if (f === null) {
627 continue;
628 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000629
Roger Meierda6e6ae2011-03-15 09:55:33 +0000630 fid = parseInt(f, 10);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000631 this.rpos.push(this.rstack.length);
632
Roger Meierda6e6ae2011-03-15 09:55:33 +0000633 var field = this.rstack[this.rstack.length - 1][fid];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000634
635 //remove so we don't see it again
636 delete this.rstack[this.rstack.length - 1][fid];
637
638 this.rstack.push(field);
639
640 break;
641 }
642
643 if (fid != -1) {
644
T Jake Luciani322caa22010-02-15 03:24:55 +0000645 //should only be 1 of these but this is the only
646 //way to match a key
Roger Meierda6e6ae2011-03-15 09:55:33 +0000647 for (var i in (this.rstack[this.rstack.length - 1])) {
648 if (Thrift.Protocol.RType[i] === null) {
649 continue;
650 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000651
Roger Meierda6e6ae2011-03-15 09:55:33 +0000652 ftype = Thrift.Protocol.RType[i];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000653 this.rstack[this.rstack.length - 1] =
Roger Meierda6e6ae2011-03-15 09:55:33 +0000654 this.rstack[this.rstack.length - 1][i];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000655 }
656 }
657
Roger Meierda6e6ae2011-03-15 09:55:33 +0000658 r.fname = '';
659 r.ftype = ftype;
660 r.fid = fid;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000661
Roger Meierb4bcbe32011-03-07 19:37:46 +0000662 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000663 },
664
Roger Meierb4bcbe32011-03-07 19:37:46 +0000665 readFieldEnd: function() {
666 var pos = this.rpos.pop();
667
T Jake Luciani322caa22010-02-15 03:24:55 +0000668 //get back to the right place in the stack
Roger Meierda6e6ae2011-03-15 09:55:33 +0000669 while (this.rstack.length > pos) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000670 this.rstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000671 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000672
T Jake Luciani322caa22010-02-15 03:24:55 +0000673 },
674
Roger Meierb4bcbe32011-03-07 19:37:46 +0000675 readMapBegin: function(keyType, valType, size) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000676 var map = this.rstack.pop();
677
T Jake Luciani322caa22010-02-15 03:24:55 +0000678 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000679 r.ktype = Thrift.Protocol.RType[map.shift()];
680 r.vtype = Thrift.Protocol.RType[map.shift()];
681 r.size = map.shift();
T Jake Luciani322caa22010-02-15 03:24:55 +0000682
T Jake Luciani322caa22010-02-15 03:24:55 +0000683
T Jake Luciani322caa22010-02-15 03:24:55 +0000684 this.rpos.push(this.rstack.length);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000685 this.rstack.push(map.shift());
686
T Jake Luciani322caa22010-02-15 03:24:55 +0000687 return r;
688 },
689
Roger Meierb4bcbe32011-03-07 19:37:46 +0000690 readMapEnd: function() {
691 this.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000692 },
693
Roger Meierb4bcbe32011-03-07 19:37:46 +0000694 readListBegin: function(elemType, size) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000695 var list = this.rstack[this.rstack.length - 1];
696
697 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000698 r.etype = Thrift.Protocol.RType[list.shift()];
699 r.size = list.shift();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000700
Roger Meierb4bcbe32011-03-07 19:37:46 +0000701 this.rpos.push(this.rstack.length);
702 this.rstack.push(list);
703
704 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000705 },
706
Roger Meierb4bcbe32011-03-07 19:37:46 +0000707 readListEnd: function() {
708 this.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000709 },
710
Roger Meierb4bcbe32011-03-07 19:37:46 +0000711 readSetBegin: function(elemType, size) {
712 return this.readListBegin(elemType, size);
713 },
714
715 readSetEnd: function() {
716 return this.readListEnd();
717 },
718
719 readBool: function() {
720 var r = this.readI32();
721
Roger Meierda6e6ae2011-03-15 09:55:33 +0000722 if (r !== null && r.value == '1') {
723 r.value = true;
724 } else {
725 r.value = false;
T Jake Luciani322caa22010-02-15 03:24:55 +0000726 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000727
728 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000729 },
730
Roger Meierb4bcbe32011-03-07 19:37:46 +0000731 readByte: function() {
732 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000733 },
734
Roger Meierb4bcbe32011-03-07 19:37:46 +0000735 readI16: function() {
736 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000737 },
T Jake Luciani322caa22010-02-15 03:24:55 +0000738
Roger Meierb4bcbe32011-03-07 19:37:46 +0000739 readI32: function(f) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000740 if (f === undefined) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000741 f = this.rstack[this.rstack.length - 1];
Roger Meierda6e6ae2011-03-15 09:55:33 +0000742 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000743
744 var r = {};
745
746 if (f instanceof Array) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000747 if (f.length === 0) {
748 r.value = undefined;
749 } else {
750 r.value = f.shift();
751 }
752 } else if (f instanceof Object) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000753 for (var i in f) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000754 if (i === null) {
755 continue;
756 }
757 this.rstack.push(f[i]);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000758 delete f[i];
759
Roger Meierda6e6ae2011-03-15 09:55:33 +0000760 r.value = i;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000761 break;
T Jake Luciani322caa22010-02-15 03:24:55 +0000762 }
763 } else {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000764 r.value = f;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000765 this.rstack.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000766 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000767
768 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000769 },
770
Roger Meierb4bcbe32011-03-07 19:37:46 +0000771 readI64: function() {
772 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000773 },
774
Roger Meierb4bcbe32011-03-07 19:37:46 +0000775 readDouble: function() {
776 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000777 },
778
Roger Meierb4bcbe32011-03-07 19:37:46 +0000779 readString: function() {
780 var r = this.readI32();
781 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000782 },
783
Roger Meierb4bcbe32011-03-07 19:37:46 +0000784 readBinary: function() {
785 return this.readString();
T Jake Luciani322caa22010-02-15 03:24:55 +0000786 },
787
Roger Meierb4bcbe32011-03-07 19:37:46 +0000788
T Jake Luciani322caa22010-02-15 03:24:55 +0000789 //Method to arbitrarily skip over data.
Roger Meierb4bcbe32011-03-07 19:37:46 +0000790 skip: function(type) {
791 throw 'skip not supported yet';
T Jake Luciani322caa22010-02-15 03:24:55 +0000792 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000793};