blob: d1c9adf9f77baabadad75194ce8fd49ce508d9f5 [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 = {
Jake Farrell9c762582011-08-13 21:29:36 +000020 Version: '0.8.0-dev',
Roger Meier0244e932011-03-09 15:25:01 +000021/*
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,
Roger Meier345ecc72011-08-03 09:49:27 +000088 'MISSING_RESULT' : 5,
89 'INTERNAL_ERROR' : 6,
90 'PROTOCOL_ERROR' : 7
Roger Meierb4bcbe32011-03-07 19:37:46 +000091};
T Jake Luciani322caa22010-02-15 03:24:55 +000092
Roger Meierb4bcbe32011-03-07 19:37:46 +000093Thrift.TApplicationException = function(message, code) {
94 this.message = message;
Roger Meierda6e6ae2011-03-15 09:55:33 +000095 this.code = (code === null) ? 0 : code;
Roger Meierb4bcbe32011-03-07 19:37:46 +000096};
Roger Meier6b0d4562011-07-08 12:44:29 +000097Thrift.inherits(Thrift.TApplicationException, Thrift.TException);
98Thrift.TApplicationException.prototype.name = 'TApplicationException';
T Jake Luciani322caa22010-02-15 03:24:55 +000099
Roger Meier6b0d4562011-07-08 12:44:29 +0000100Thrift.TApplicationException.prototype.read = function(input) {
101 while (1) {
102 var ret = input.readFieldBegin();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000103
Roger Meier6b0d4562011-07-08 12:44:29 +0000104 if (ret.ftype == Thrift.Type.STOP) {
105 break;
106 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000107
Roger Meier6b0d4562011-07-08 12:44:29 +0000108 var fid = ret.fid;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000109
Roger Meier6b0d4562011-07-08 12:44:29 +0000110 switch (fid) {
111 case 1:
112 if (ret.ftype == Thrift.Type.STRING) {
113 ret = input.readString();
114 this.message = ret.value;
115 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000116 ret = input.skip(ret.ftype);
Roger Meier6b0d4562011-07-08 12:44:29 +0000117 }
118 break;
119 case 2:
120 if (ret.ftype == Thrift.Type.I32) {
121 ret = input.readI32();
122 this.code = ret.value;
123 } else {
124 ret = input.skip(ret.ftype);
125 }
126 break;
127 default:
128 ret = input.skip(ret.ftype);
129 break;
T Jake Luciani322caa22010-02-15 03:24:55 +0000130 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000131
Roger Meier6b0d4562011-07-08 12:44:29 +0000132 input.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000133 }
Roger Meier6b0d4562011-07-08 12:44:29 +0000134
135 input.readStructEnd();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000136};
T Jake Luciani322caa22010-02-15 03:24:55 +0000137
Roger Meier6b0d4562011-07-08 12:44:29 +0000138Thrift.TApplicationException.prototype.write = function(output) {
139 var xfer = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000140
Roger Meier6b0d4562011-07-08 12:44:29 +0000141 output.writeStructBegin('TApplicationException');
142
143 if (this.message) {
144 output.writeFieldBegin('message', Thrift.Type.STRING, 1);
145 output.writeString(this.getMessage());
146 output.writeFieldEnd();
147 }
148
149 if (this.code) {
150 output.writeFieldBegin('type', Thrift.Type.I32, 2);
151 output.writeI32(this.code);
152 output.writeFieldEnd();
153 }
154
155 output.writeFieldStop();
156 output.writeStructEnd();
157};
158
159Thrift.TApplicationException.prototype.getCode = function() {
160 return this.code;
161};
162
163Thrift.TApplicationException.prototype.getMessage = function() {
164 return this.message;
165};
T Jake Luciani322caa22010-02-15 03:24:55 +0000166
167/**
168 *If you do not specify a url then you must handle ajax on your own.
169 *This is how to use js bindings in a async fashion.
170 */
Roger Meierb4bcbe32011-03-07 19:37:46 +0000171Thrift.Transport = function(url) {
172 this.url = url;
173 this.wpos = 0;
174 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000175
Roger Meierb4bcbe32011-03-07 19:37:46 +0000176 this.send_buf = '';
177 this.recv_buf = '';
178};
T Jake Luciani322caa22010-02-15 03:24:55 +0000179
180Thrift.Transport.prototype = {
181
182 //Gets the browser specific XmlHttpRequest Object
Roger Meierb4bcbe32011-03-07 19:37:46 +0000183 getXmlHttpRequestObject: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000184 try { return new XMLHttpRequest(); } catch (e1) { }
185 try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { }
186 try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000187
188 throw "Your browser doesn't support the XmlHttpRequest object.";
T Jake Luciani322caa22010-02-15 03:24:55 +0000189 },
190
Roger Meier08b30992011-04-06 21:30:53 +0000191 flush: function(async) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000192 //async mode
Roger Meier08b30992011-04-06 21:30:53 +0000193 if (async || this.url === undefined || this.url === '') {
T Jake Luciani322caa22010-02-15 03:24:55 +0000194 return this.send_buf;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000195 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000196
Roger Meierb4bcbe32011-03-07 19:37:46 +0000197 var xreq = this.getXmlHttpRequestObject();
198
Roger Meierda6e6ae2011-03-15 09:55:33 +0000199 if (xreq.overrideMimeType) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000200 xreq.overrideMimeType('application/json');
Roger Meierda6e6ae2011-03-15 09:55:33 +0000201 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000202
203 xreq.open('POST', this.url, false);
204 xreq.send(this.send_buf);
205
Roger Meierda6e6ae2011-03-15 09:55:33 +0000206 if (xreq.readyState != 4) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000207 throw 'encountered an unknown ajax ready state: ' + xreq.readyState;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000208 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000209
Roger Meierda6e6ae2011-03-15 09:55:33 +0000210 if (xreq.status != 200) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000211 throw 'encountered a unknown request status: ' + xreq.status;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000212 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000213
Roger Meierb4bcbe32011-03-07 19:37:46 +0000214 this.recv_buf = xreq.responseText;
215 this.recv_buf_sz = this.recv_buf.length;
216 this.wpos = this.recv_buf.length;
217 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000218 },
219
Roger Meier08b30992011-04-06 21:30:53 +0000220 jqRequest: function(client, postData, args, recv_method) {
221 if (typeof jQuery === 'undefined' ||
222 typeof jQuery.Deferred === 'undefined') {
223 throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests';
224 }
225
226 // Deferreds
227 var deferred = jQuery.Deferred();
228 var completeDfd = jQuery._Deferred();
229 var dfd = deferred.promise();
230 dfd.success = dfd.done;
231 dfd.error = dfd.fail;
232 dfd.complete = completeDfd.done;
233
234 var jqXHR = jQuery.ajax({
235 url: this.url,
236 data: postData,
237 type: 'POST',
238 cache: false,
239 dataType: 'text',
240 context: this,
241 success: this.jqResponse,
242 error: function(xhr, status, e) {
243 deferred.rejectWith(client, jQuery.merge([e], xhr.tArgs));
244 },
245 complete: function(xhr, status) {
246 completeDfd.resolveWith(client, [xhr, status]);
247 }
248 });
249
250 deferred.done(jQuery.makeArray(args).pop()); //pop callback from args
251 jqXHR.tArgs = args;
252 jqXHR.tClient = client;
253 jqXHR.tRecvFn = recv_method;
254 jqXHR.tDfd = deferred;
255 return dfd;
256 },
257
258 jqResponse: function(responseData, textStatus, jqXHR) {
259 this.setRecvBuffer(responseData);
260 try {
261 var value = jqXHR.tRecvFn.call(jqXHR.tClient);
262 jqXHR.tDfd.resolveWith(jqXHR, jQuery.merge([value], jqXHR.tArgs));
263 } catch (ex) {
264 jqXHR.tDfd.rejectWith(jqXHR, jQuery.merge([ex], jqXHR.tArgs));
265 }
266 },
267
Roger Meierb4bcbe32011-03-07 19:37:46 +0000268 setRecvBuffer: function(buf) {
269 this.recv_buf = buf;
270 this.recv_buf_sz = this.recv_buf.length;
271 this.wpos = this.recv_buf.length;
272 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000273 },
274
Roger Meierb4bcbe32011-03-07 19:37:46 +0000275 isOpen: function() {
276 return true;
T Jake Luciani322caa22010-02-15 03:24:55 +0000277 },
278
Roger Meierb4bcbe32011-03-07 19:37:46 +0000279 open: function() {},
T Jake Luciani322caa22010-02-15 03:24:55 +0000280
281 close: function() {},
282
Roger Meierb4bcbe32011-03-07 19:37:46 +0000283 read: function(len) {
284 var avail = this.wpos - this.rpos;
T Jake Luciani322caa22010-02-15 03:24:55 +0000285
Roger Meierda6e6ae2011-03-15 09:55:33 +0000286 if (avail === 0) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000287 return '';
Roger Meierda6e6ae2011-03-15 09:55:33 +0000288 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000289
Roger Meierb4bcbe32011-03-07 19:37:46 +0000290 var give = len;
T Jake Luciani322caa22010-02-15 03:24:55 +0000291
Roger Meierda6e6ae2011-03-15 09:55:33 +0000292 if (avail < len) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000293 give = avail;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000294 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000295
296 var ret = this.read_buf.substr(this.rpos, give);
297 this.rpos += give;
T Jake Luciani322caa22010-02-15 03:24:55 +0000298
299 //clear buf when complete?
Roger Meierb4bcbe32011-03-07 19:37:46 +0000300 return ret;
T Jake Luciani322caa22010-02-15 03:24:55 +0000301 },
302
Roger Meierb4bcbe32011-03-07 19:37:46 +0000303 readAll: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000304 return this.recv_buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000305 },
306
Roger Meierb4bcbe32011-03-07 19:37:46 +0000307 write: function(buf) {
308 this.send_buf = buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000309 },
310
Roger Meierb4bcbe32011-03-07 19:37:46 +0000311 getSendBuffer: function() {
312 return this.send_buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000313 }
314
Roger Meierb4bcbe32011-03-07 19:37:46 +0000315};
T Jake Luciani322caa22010-02-15 03:24:55 +0000316
317
318
Roger Meierb4bcbe32011-03-07 19:37:46 +0000319Thrift.Protocol = function(transport) {
320 this.transport = transport;
321};
T Jake Luciani322caa22010-02-15 03:24:55 +0000322
Roger Meierb4bcbe32011-03-07 19:37:46 +0000323Thrift.Protocol.Type = {};
324Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"';
325Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"';
326Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"';
327Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"';
328Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"';
329Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"';
330Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"';
331Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"';
332Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"';
333Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"';
334Thrift.Protocol.Type[Thrift.Type.SET] = '"set"';
T Jake Luciani322caa22010-02-15 03:24:55 +0000335
336
Roger Meierb4bcbe32011-03-07 19:37:46 +0000337Thrift.Protocol.RType = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000338Thrift.Protocol.RType.tf = Thrift.Type.BOOL;
339Thrift.Protocol.RType.i8 = Thrift.Type.BYTE;
340Thrift.Protocol.RType.i16 = Thrift.Type.I16;
341Thrift.Protocol.RType.i32 = Thrift.Type.I32;
342Thrift.Protocol.RType.i64 = Thrift.Type.I64;
343Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE;
344Thrift.Protocol.RType.rec = Thrift.Type.STRUCT;
345Thrift.Protocol.RType.str = Thrift.Type.STRING;
346Thrift.Protocol.RType.map = Thrift.Type.MAP;
347Thrift.Protocol.RType.lst = Thrift.Type.LIST;
348Thrift.Protocol.RType.set = Thrift.Type.SET;
T Jake Luciani322caa22010-02-15 03:24:55 +0000349
Roger Meierb4bcbe32011-03-07 19:37:46 +0000350Thrift.Protocol.Version = 1;
T Jake Luciani322caa22010-02-15 03:24:55 +0000351
352Thrift.Protocol.prototype = {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000353
354 getTransport: function() {
355 return this.transport;
T Jake Luciani322caa22010-02-15 03:24:55 +0000356 },
357
358 //Write functions
Roger Meierb4bcbe32011-03-07 19:37:46 +0000359 writeMessageBegin: function(name, messageType, seqid) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000360 this.tstack = [];
361 this.tpos = [];
362
363 this.tstack.push([Thrift.Protocol.Version, '"' +
Roger Meierb4bcbe32011-03-07 19:37:46 +0000364 name + '"', messageType, seqid]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000365 },
366
Roger Meierb4bcbe32011-03-07 19:37:46 +0000367 writeMessageEnd: function() {
368 var obj = this.tstack.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000369
Roger Meierb4bcbe32011-03-07 19:37:46 +0000370 this.wobj = this.tstack.pop();
371 this.wobj.push(obj);
372
373 this.wbuf = '[' + this.wobj.join(',') + ']';
374
375 this.transport.write(this.wbuf);
T Jake Luciani322caa22010-02-15 03:24:55 +0000376 },
377
378
Roger Meierb4bcbe32011-03-07 19:37:46 +0000379 writeStructBegin: function(name) {
380 this.tpos.push(this.tstack.length);
381 this.tstack.push({});
T Jake Luciani322caa22010-02-15 03:24:55 +0000382 },
383
Roger Meierb4bcbe32011-03-07 19:37:46 +0000384 writeStructEnd: function() {
385
386 var p = this.tpos.pop();
387 var struct = this.tstack[p];
388 var str = '{';
389 var first = true;
390 for (var key in struct) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000391 if (first) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000392 first = false;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000393 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000394 str += ',';
Roger Meierda6e6ae2011-03-15 09:55:33 +0000395 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000396
Roger Meierb4bcbe32011-03-07 19:37:46 +0000397 str += key + ':' + struct[key];
398 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000399
Roger Meierb4bcbe32011-03-07 19:37:46 +0000400 str += '}';
T Jake Luciani322caa22010-02-15 03:24:55 +0000401 this.tstack[p] = str;
402 },
403
Roger Meierb4bcbe32011-03-07 19:37:46 +0000404 writeFieldBegin: function(name, fieldType, fieldId) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000405 this.tpos.push(this.tstack.length);
406 this.tstack.push({ 'fieldId': '"' +
407 fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType]
Roger Meierb4bcbe32011-03-07 19:37:46 +0000408 });
409
T Jake Luciani322caa22010-02-15 03:24:55 +0000410 },
411
Roger Meierb4bcbe32011-03-07 19:37:46 +0000412 writeFieldEnd: function() {
413 var value = this.tstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000414 var fieldInfo = this.tstack.pop();
415
416 this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' +
Roger Meierb4bcbe32011-03-07 19:37:46 +0000417 fieldInfo.fieldType + ':' + value + '}';
418 this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000419 },
420
Roger Meierb4bcbe32011-03-07 19:37:46 +0000421 writeFieldStop: function() {
T Jake Luciani322caa22010-02-15 03:24:55 +0000422 //na
423 },
424
Roger Meierb4bcbe32011-03-07 19:37:46 +0000425 writeMapBegin: function(keyType, valType, size) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000426 //size is invalid, we'll set it on end.
Roger Meierda6e6ae2011-03-15 09:55:33 +0000427 this.tpos.push(this.tstack.length);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000428 this.tstack.push([Thrift.Protocol.Type[keyType],
429 Thrift.Protocol.Type[valType], 0]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000430 },
431
Roger Meierb4bcbe32011-03-07 19:37:46 +0000432 writeMapEnd: function() {
433 var p = this.tpos.pop();
434
Roger Meierda6e6ae2011-03-15 09:55:33 +0000435 if (p == this.tstack.length) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000436 return;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000437 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000438
Roger Meierda6e6ae2011-03-15 09:55:33 +0000439 if ((this.tstack.length - p - 1) % 2 !== 0) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000440 this.tstack.push('');
Roger Meierda6e6ae2011-03-15 09:55:33 +0000441 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000442
Roger Meierb4bcbe32011-03-07 19:37:46 +0000443 var size = (this.tstack.length - p - 1) / 2;
444
445 this.tstack[p][this.tstack[p].length - 1] = size;
446
447 var map = '}';
448 var first = true;
449 while (this.tstack.length > p + 1) {
450 var v = this.tstack.pop();
451 var k = this.tstack.pop();
452 if (first) {
453 first = false;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000454 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000455 map = ',' + map;
T Jake Luciani322caa22010-02-15 03:24:55 +0000456 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000457
Roger Meier2079bfe2011-06-21 14:09:13 +0000458 if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings
Roger Meier9d8e8f82011-06-14 19:38:27 +0000459 map = k + ':' + v + map;
T Jake Luciani322caa22010-02-15 03:24:55 +0000460 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000461 map = '{' + map;
462
463 this.tstack[p].push(map);
464 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000465 },
466
Roger Meierb4bcbe32011-03-07 19:37:46 +0000467 writeListBegin: function(elemType, size) {
468 this.tpos.push(this.tstack.length);
469 this.tstack.push([Thrift.Protocol.Type[elemType], size]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000470 },
471
Roger Meierb4bcbe32011-03-07 19:37:46 +0000472 writeListEnd: function() {
473 var p = this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000474
Roger Meierb4bcbe32011-03-07 19:37:46 +0000475 while (this.tstack.length > p + 1) {
476 var tmpVal = this.tstack[p + 1];
477 this.tstack.splice(p + 1, 1);
478 this.tstack[p].push(tmpVal);
T Jake Luciani322caa22010-02-15 03:24:55 +0000479 }
480
Roger Meierb4bcbe32011-03-07 19:37:46 +0000481 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000482 },
483
Roger Meierb4bcbe32011-03-07 19:37:46 +0000484 writeSetBegin: function(elemType, size) {
485 this.tpos.push(this.tstack.length);
486 this.tstack.push([Thrift.Protocol.Type[elemType], size]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000487 },
488
Roger Meierb4bcbe32011-03-07 19:37:46 +0000489 writeSetEnd: function() {
490 var p = this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000491
Roger Meierb4bcbe32011-03-07 19:37:46 +0000492 while (this.tstack.length > p + 1) {
493 var tmpVal = this.tstack[p + 1];
494 this.tstack.splice(p + 1, 1);
495 this.tstack[p].push(tmpVal);
T Jake Luciani322caa22010-02-15 03:24:55 +0000496 }
497
Roger Meierb4bcbe32011-03-07 19:37:46 +0000498 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000499 },
500
Roger Meierb4bcbe32011-03-07 19:37:46 +0000501 writeBool: function(value) {
502 this.tstack.push(value ? 1 : 0);
T Jake Luciani322caa22010-02-15 03:24:55 +0000503 },
504
Roger Meierb4bcbe32011-03-07 19:37:46 +0000505 writeByte: function(i8) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000506 this.tstack.push(i8);
507 },
508
Roger Meierb4bcbe32011-03-07 19:37:46 +0000509 writeI16: function(i16) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000510 this.tstack.push(i16);
511 },
512
Roger Meierb4bcbe32011-03-07 19:37:46 +0000513 writeI32: function(i32) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000514 this.tstack.push(i32);
515 },
516
Roger Meierb4bcbe32011-03-07 19:37:46 +0000517 writeI64: function(i64) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000518 this.tstack.push(i64);
519 },
520
Roger Meierb4bcbe32011-03-07 19:37:46 +0000521 writeDouble: function(dbl) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000522 this.tstack.push(dbl);
523 },
524
Roger Meierb4bcbe32011-03-07 19:37:46 +0000525 writeString: function(str) {
526 // We do not encode uri components for wire transfer:
527 if (str === null) {
T Jake Luciani416eea92010-09-17 23:38:25 +0000528 this.tstack.push(null);
529 } else {
530 // concat may be slower than building a byte buffer
Roger Meierb4bcbe32011-03-07 19:37:46 +0000531 var escapedString = '';
532 for (var i = 0; i < str.length; i++) {
533 var ch = str.charAt(i); // a single double quote: "
534 if (ch === '\"') {
535 escapedString += '\\\"'; // write out as: \"
536 } else if (ch === '\\') { // a single backslash: \
537 escapedString += '\\\\'; // write out as: \\
T Jake Luciani416eea92010-09-17 23:38:25 +0000538 /* Currently escaped forward slashes break TJSONProtocol.
Roger Meierb4bcbe32011-03-07 19:37:46 +0000539 * As it stands, we can simply pass forward slashes into
540 * our strings across the wire without being escaped.
T Jake Luciani416eea92010-09-17 23:38:25 +0000541 * I think this is the protocol's bug, not thrift.js
Roger Meierb4bcbe32011-03-07 19:37:46 +0000542 * } else if(ch === '/') { // a single forward slash: /
543 * escapedString += '\\/'; // write out as \/
544 * }
T Jake Luciani416eea92010-09-17 23:38:25 +0000545 */
Roger Meierb4bcbe32011-03-07 19:37:46 +0000546 } else if (ch === '\b') { // a single backspace: invisible
547 escapedString += '\\b'; // write out as: \b"
548 } else if (ch === '\f') { // a single formfeed: invisible
549 escapedString += '\\f'; // write out as: \f"
550 } else if (ch === '\n') { // a single newline: invisible
551 escapedString += '\\n'; // write out as: \n"
552 } else if (ch === '\r') { // a single return: invisible
553 escapedString += '\\r'; // write out as: \r"
554 } else if (ch === '\t') { // a single tab: invisible
555 escapedString += '\\t'; // write out as: \t"
T Jake Luciani416eea92010-09-17 23:38:25 +0000556 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000557 escapedString += ch; // Else it need not be escaped
T Jake Luciani416eea92010-09-17 23:38:25 +0000558 }
559 }
560 this.tstack.push('"' + escapedString + '"');
561 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000562 },
563
Roger Meierb4bcbe32011-03-07 19:37:46 +0000564 writeBinary: function(str) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000565 this.writeString(str);
566 },
567
568
Roger Meierb4bcbe32011-03-07 19:37:46 +0000569
T Jake Luciani322caa22010-02-15 03:24:55 +0000570 // Reading functions
Roger Meierb4bcbe32011-03-07 19:37:46 +0000571 readMessageBegin: function(name, messageType, seqid) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000572 this.rstack = [];
573 this.rpos = [];
T Jake Luciani322caa22010-02-15 03:24:55 +0000574
Roger Meier08b30992011-04-06 21:30:53 +0000575 if (typeof jQuery !== 'undefined') {
576 this.robj = jQuery.parseJSON(this.transport.readAll());
577 } else {
578 this.robj = eval(this.transport.readAll());
579 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000580
T Jake Luciani322caa22010-02-15 03:24:55 +0000581 var r = {};
Roger Meierb4bcbe32011-03-07 19:37:46 +0000582 var version = this.robj.shift();
583
584 if (version != Thrift.Protocol.Version) {
585 throw 'Wrong thrift protocol version: ' + version;
T Jake Luciani322caa22010-02-15 03:24:55 +0000586 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000587
Roger Meierda6e6ae2011-03-15 09:55:33 +0000588 r.fname = this.robj.shift();
589 r.mtype = this.robj.shift();
590 r.rseqid = this.robj.shift();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000591
592
593 //get to the main obj
594 this.rstack.push(this.robj.shift());
595
596 return r;
597 },
598
Roger Meierb4bcbe32011-03-07 19:37:46 +0000599 readMessageEnd: function() {
600 },
601
602 readStructBegin: function(name) {
603 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000604 r.fname = '';
Roger Meierb4bcbe32011-03-07 19:37:46 +0000605
606 //incase this is an array of structs
Roger Meierda6e6ae2011-03-15 09:55:33 +0000607 if (this.rstack[this.rstack.length - 1] instanceof Array) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000608 this.rstack.push(this.rstack[this.rstack.length - 1].shift());
Roger Meierda6e6ae2011-03-15 09:55:33 +0000609 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000610
611 return r;
612 },
613
614 readStructEnd: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000615 if (this.rstack[this.rstack.length - 2] instanceof Array) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000616 this.rstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000617 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000618 },
619
620 readFieldBegin: function() {
621 var r = {};
622
623 var fid = -1;
624 var ftype = Thrift.Type.STOP;
625
626 //get a fieldId
627 for (var f in (this.rstack[this.rstack.length - 1])) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000628 if (f === null) {
629 continue;
630 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000631
Roger Meierda6e6ae2011-03-15 09:55:33 +0000632 fid = parseInt(f, 10);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000633 this.rpos.push(this.rstack.length);
634
Roger Meierda6e6ae2011-03-15 09:55:33 +0000635 var field = this.rstack[this.rstack.length - 1][fid];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000636
637 //remove so we don't see it again
638 delete this.rstack[this.rstack.length - 1][fid];
639
640 this.rstack.push(field);
641
642 break;
643 }
644
645 if (fid != -1) {
646
T Jake Luciani322caa22010-02-15 03:24:55 +0000647 //should only be 1 of these but this is the only
648 //way to match a key
Roger Meierda6e6ae2011-03-15 09:55:33 +0000649 for (var i in (this.rstack[this.rstack.length - 1])) {
650 if (Thrift.Protocol.RType[i] === null) {
651 continue;
652 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000653
Roger Meierda6e6ae2011-03-15 09:55:33 +0000654 ftype = Thrift.Protocol.RType[i];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000655 this.rstack[this.rstack.length - 1] =
Roger Meierda6e6ae2011-03-15 09:55:33 +0000656 this.rstack[this.rstack.length - 1][i];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000657 }
658 }
659
Roger Meierda6e6ae2011-03-15 09:55:33 +0000660 r.fname = '';
661 r.ftype = ftype;
662 r.fid = fid;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000663
Roger Meierb4bcbe32011-03-07 19:37:46 +0000664 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000665 },
666
Roger Meierb4bcbe32011-03-07 19:37:46 +0000667 readFieldEnd: function() {
668 var pos = this.rpos.pop();
669
T Jake Luciani322caa22010-02-15 03:24:55 +0000670 //get back to the right place in the stack
Roger Meierda6e6ae2011-03-15 09:55:33 +0000671 while (this.rstack.length > pos) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000672 this.rstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000673 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000674
T Jake Luciani322caa22010-02-15 03:24:55 +0000675 },
676
Roger Meierb4bcbe32011-03-07 19:37:46 +0000677 readMapBegin: function(keyType, valType, size) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000678 var map = this.rstack.pop();
679
T Jake Luciani322caa22010-02-15 03:24:55 +0000680 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000681 r.ktype = Thrift.Protocol.RType[map.shift()];
682 r.vtype = Thrift.Protocol.RType[map.shift()];
683 r.size = map.shift();
T Jake Luciani322caa22010-02-15 03:24:55 +0000684
T Jake Luciani322caa22010-02-15 03:24:55 +0000685
T Jake Luciani322caa22010-02-15 03:24:55 +0000686 this.rpos.push(this.rstack.length);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000687 this.rstack.push(map.shift());
688
T Jake Luciani322caa22010-02-15 03:24:55 +0000689 return r;
690 },
691
Roger Meierb4bcbe32011-03-07 19:37:46 +0000692 readMapEnd: function() {
693 this.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000694 },
695
Roger Meierb4bcbe32011-03-07 19:37:46 +0000696 readListBegin: function(elemType, size) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000697 var list = this.rstack[this.rstack.length - 1];
698
699 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000700 r.etype = Thrift.Protocol.RType[list.shift()];
701 r.size = list.shift();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000702
Roger Meierb4bcbe32011-03-07 19:37:46 +0000703 this.rpos.push(this.rstack.length);
704 this.rstack.push(list);
705
706 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000707 },
708
Roger Meierb4bcbe32011-03-07 19:37:46 +0000709 readListEnd: function() {
710 this.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000711 },
712
Roger Meierb4bcbe32011-03-07 19:37:46 +0000713 readSetBegin: function(elemType, size) {
714 return this.readListBegin(elemType, size);
715 },
716
717 readSetEnd: function() {
718 return this.readListEnd();
719 },
720
721 readBool: function() {
722 var r = this.readI32();
723
Roger Meierda6e6ae2011-03-15 09:55:33 +0000724 if (r !== null && r.value == '1') {
725 r.value = true;
726 } else {
727 r.value = false;
T Jake Luciani322caa22010-02-15 03:24:55 +0000728 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000729
730 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000731 },
732
Roger Meierb4bcbe32011-03-07 19:37:46 +0000733 readByte: function() {
734 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000735 },
736
Roger Meierb4bcbe32011-03-07 19:37:46 +0000737 readI16: function() {
738 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000739 },
T Jake Luciani322caa22010-02-15 03:24:55 +0000740
Roger Meierb4bcbe32011-03-07 19:37:46 +0000741 readI32: function(f) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000742 if (f === undefined) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000743 f = this.rstack[this.rstack.length - 1];
Roger Meierda6e6ae2011-03-15 09:55:33 +0000744 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000745
746 var r = {};
747
748 if (f instanceof Array) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000749 if (f.length === 0) {
750 r.value = undefined;
751 } else {
752 r.value = f.shift();
753 }
754 } else if (f instanceof Object) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000755 for (var i in f) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000756 if (i === null) {
757 continue;
758 }
759 this.rstack.push(f[i]);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000760 delete f[i];
761
Roger Meierda6e6ae2011-03-15 09:55:33 +0000762 r.value = i;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000763 break;
T Jake Luciani322caa22010-02-15 03:24:55 +0000764 }
765 } else {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000766 r.value = f;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000767 this.rstack.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000768 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000769
770 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000771 },
772
Roger Meierb4bcbe32011-03-07 19:37:46 +0000773 readI64: function() {
774 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000775 },
776
Roger Meierb4bcbe32011-03-07 19:37:46 +0000777 readDouble: function() {
778 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000779 },
780
Roger Meierb4bcbe32011-03-07 19:37:46 +0000781 readString: function() {
782 var r = this.readI32();
783 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000784 },
785
Roger Meierb4bcbe32011-03-07 19:37:46 +0000786 readBinary: function() {
787 return this.readString();
T Jake Luciani322caa22010-02-15 03:24:55 +0000788 },
789
Roger Meierb4bcbe32011-03-07 19:37:46 +0000790
T Jake Luciani322caa22010-02-15 03:24:55 +0000791 //Method to arbitrarily skip over data.
Roger Meierb4bcbe32011-03-07 19:37:46 +0000792 skip: function(type) {
793 throw 'skip not supported yet';
T Jake Luciani322caa22010-02-15 03:24:55 +0000794 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000795};