blob: 39b0a5cc939e337c0f9896ca6bc1524dd1b227e2 [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 Farrell6fcecd42012-10-11 20:34:25 +000020 Version: '1.0.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,
Roger Meier01931492012-12-22 21:31:03 +010090 'PROTOCOL_ERROR' : 7,
91 'INVALID_TRANSFORM' : 8,
92 'INVALID_PROTOCOL' : 9,
93 'UNSUPPORTED_CLIENT_TYPE' : 10
Roger Meierb4bcbe32011-03-07 19:37:46 +000094};
T Jake Luciani322caa22010-02-15 03:24:55 +000095
Roger Meierb4bcbe32011-03-07 19:37:46 +000096Thrift.TApplicationException = function(message, code) {
97 this.message = message;
Roger Meierda6e6ae2011-03-15 09:55:33 +000098 this.code = (code === null) ? 0 : code;
Roger Meierb4bcbe32011-03-07 19:37:46 +000099};
Roger Meier6b0d4562011-07-08 12:44:29 +0000100Thrift.inherits(Thrift.TApplicationException, Thrift.TException);
101Thrift.TApplicationException.prototype.name = 'TApplicationException';
T Jake Luciani322caa22010-02-15 03:24:55 +0000102
Roger Meier6b0d4562011-07-08 12:44:29 +0000103Thrift.TApplicationException.prototype.read = function(input) {
104 while (1) {
105 var ret = input.readFieldBegin();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000106
Roger Meier6b0d4562011-07-08 12:44:29 +0000107 if (ret.ftype == Thrift.Type.STOP) {
108 break;
109 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000110
Roger Meier6b0d4562011-07-08 12:44:29 +0000111 var fid = ret.fid;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000112
Roger Meier6b0d4562011-07-08 12:44:29 +0000113 switch (fid) {
114 case 1:
115 if (ret.ftype == Thrift.Type.STRING) {
116 ret = input.readString();
117 this.message = ret.value;
118 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000119 ret = input.skip(ret.ftype);
Roger Meier6b0d4562011-07-08 12:44:29 +0000120 }
121 break;
122 case 2:
123 if (ret.ftype == Thrift.Type.I32) {
124 ret = input.readI32();
125 this.code = ret.value;
126 } else {
127 ret = input.skip(ret.ftype);
128 }
129 break;
130 default:
131 ret = input.skip(ret.ftype);
132 break;
T Jake Luciani322caa22010-02-15 03:24:55 +0000133 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000134
Roger Meier6b0d4562011-07-08 12:44:29 +0000135 input.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000136 }
Roger Meier6b0d4562011-07-08 12:44:29 +0000137
138 input.readStructEnd();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000139};
T Jake Luciani322caa22010-02-15 03:24:55 +0000140
Roger Meier6b0d4562011-07-08 12:44:29 +0000141Thrift.TApplicationException.prototype.write = function(output) {
142 var xfer = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000143
Roger Meier6b0d4562011-07-08 12:44:29 +0000144 output.writeStructBegin('TApplicationException');
145
146 if (this.message) {
147 output.writeFieldBegin('message', Thrift.Type.STRING, 1);
148 output.writeString(this.getMessage());
149 output.writeFieldEnd();
150 }
151
152 if (this.code) {
153 output.writeFieldBegin('type', Thrift.Type.I32, 2);
154 output.writeI32(this.code);
155 output.writeFieldEnd();
156 }
157
158 output.writeFieldStop();
159 output.writeStructEnd();
160};
161
162Thrift.TApplicationException.prototype.getCode = function() {
163 return this.code;
164};
165
166Thrift.TApplicationException.prototype.getMessage = function() {
167 return this.message;
168};
T Jake Luciani322caa22010-02-15 03:24:55 +0000169
170/**
171 *If you do not specify a url then you must handle ajax on your own.
172 *This is how to use js bindings in a async fashion.
173 */
Roger Meierb4bcbe32011-03-07 19:37:46 +0000174Thrift.Transport = function(url) {
175 this.url = url;
176 this.wpos = 0;
177 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000178
Roger Meierb4bcbe32011-03-07 19:37:46 +0000179 this.send_buf = '';
180 this.recv_buf = '';
181};
T Jake Luciani322caa22010-02-15 03:24:55 +0000182
183Thrift.Transport.prototype = {
184
185 //Gets the browser specific XmlHttpRequest Object
Roger Meierb4bcbe32011-03-07 19:37:46 +0000186 getXmlHttpRequestObject: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000187 try { return new XMLHttpRequest(); } catch (e1) { }
188 try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { }
189 try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000190
191 throw "Your browser doesn't support the XmlHttpRequest object.";
T Jake Luciani322caa22010-02-15 03:24:55 +0000192 },
193
Roger Meier08b30992011-04-06 21:30:53 +0000194 flush: function(async) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000195 //async mode
Roger Meier08b30992011-04-06 21:30:53 +0000196 if (async || this.url === undefined || this.url === '') {
T Jake Luciani322caa22010-02-15 03:24:55 +0000197 return this.send_buf;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000198 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000199
Roger Meierb4bcbe32011-03-07 19:37:46 +0000200 var xreq = this.getXmlHttpRequestObject();
201
Roger Meierda6e6ae2011-03-15 09:55:33 +0000202 if (xreq.overrideMimeType) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000203 xreq.overrideMimeType('application/json');
Roger Meierda6e6ae2011-03-15 09:55:33 +0000204 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000205
206 xreq.open('POST', this.url, false);
207 xreq.send(this.send_buf);
208
Roger Meierda6e6ae2011-03-15 09:55:33 +0000209 if (xreq.readyState != 4) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000210 throw 'encountered an unknown ajax ready state: ' + xreq.readyState;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000211 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000212
Roger Meierda6e6ae2011-03-15 09:55:33 +0000213 if (xreq.status != 200) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000214 throw 'encountered a unknown request status: ' + xreq.status;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000215 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000216
Roger Meierb4bcbe32011-03-07 19:37:46 +0000217 this.recv_buf = xreq.responseText;
218 this.recv_buf_sz = this.recv_buf.length;
219 this.wpos = this.recv_buf.length;
220 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000221 },
222
Roger Meier08b30992011-04-06 21:30:53 +0000223 jqRequest: function(client, postData, args, recv_method) {
224 if (typeof jQuery === 'undefined' ||
225 typeof jQuery.Deferred === 'undefined') {
226 throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests';
227 }
228
Roger Meierf666d072012-05-01 11:20:12 +0000229 var thriftTransport = this;
Roger Meier08b30992011-04-06 21:30:53 +0000230
231 var jqXHR = jQuery.ajax({
232 url: this.url,
233 data: postData,
234 type: 'POST',
235 cache: false,
Roger Meier741e7152012-12-11 21:21:00 +0100236 contentType: 'application/json',
Roger Meierf666d072012-05-01 11:20:12 +0000237 dataType: 'text thrift',
238 converters: {
239 'text thrift' : function(responseData) {
240 thriftTransport.setRecvBuffer(responseData);
241 var value = recv_method.call(client);
242 return value;
243 }
Roger Meier08b30992011-04-06 21:30:53 +0000244 },
Roger Meierf666d072012-05-01 11:20:12 +0000245 context: client,
246 success: jQuery.makeArray(args).pop()
Roger Meier08b30992011-04-06 21:30:53 +0000247 });
248
Roger Meierf666d072012-05-01 11:20:12 +0000249 return jqXHR;
Roger Meier08b30992011-04-06 21:30:53 +0000250 },
251
Roger Meierb4bcbe32011-03-07 19:37:46 +0000252 setRecvBuffer: function(buf) {
253 this.recv_buf = buf;
254 this.recv_buf_sz = this.recv_buf.length;
255 this.wpos = this.recv_buf.length;
256 this.rpos = 0;
T Jake Luciani322caa22010-02-15 03:24:55 +0000257 },
258
Roger Meierb4bcbe32011-03-07 19:37:46 +0000259 isOpen: function() {
260 return true;
T Jake Luciani322caa22010-02-15 03:24:55 +0000261 },
262
Roger Meierb4bcbe32011-03-07 19:37:46 +0000263 open: function() {},
T Jake Luciani322caa22010-02-15 03:24:55 +0000264
265 close: function() {},
266
Roger Meierb4bcbe32011-03-07 19:37:46 +0000267 read: function(len) {
268 var avail = this.wpos - this.rpos;
T Jake Luciani322caa22010-02-15 03:24:55 +0000269
Roger Meierda6e6ae2011-03-15 09:55:33 +0000270 if (avail === 0) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000271 return '';
Roger Meierda6e6ae2011-03-15 09:55:33 +0000272 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000273
Roger Meierb4bcbe32011-03-07 19:37:46 +0000274 var give = len;
T Jake Luciani322caa22010-02-15 03:24:55 +0000275
Roger Meierda6e6ae2011-03-15 09:55:33 +0000276 if (avail < len) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000277 give = avail;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000278 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000279
280 var ret = this.read_buf.substr(this.rpos, give);
281 this.rpos += give;
T Jake Luciani322caa22010-02-15 03:24:55 +0000282
283 //clear buf when complete?
Roger Meierb4bcbe32011-03-07 19:37:46 +0000284 return ret;
T Jake Luciani322caa22010-02-15 03:24:55 +0000285 },
286
Roger Meierb4bcbe32011-03-07 19:37:46 +0000287 readAll: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000288 return this.recv_buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000289 },
290
Roger Meierb4bcbe32011-03-07 19:37:46 +0000291 write: function(buf) {
292 this.send_buf = buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000293 },
294
Roger Meierb4bcbe32011-03-07 19:37:46 +0000295 getSendBuffer: function() {
296 return this.send_buf;
T Jake Luciani322caa22010-02-15 03:24:55 +0000297 }
298
Roger Meierb4bcbe32011-03-07 19:37:46 +0000299};
T Jake Luciani322caa22010-02-15 03:24:55 +0000300
301
302
Roger Meierb4bcbe32011-03-07 19:37:46 +0000303Thrift.Protocol = function(transport) {
304 this.transport = transport;
305};
T Jake Luciani322caa22010-02-15 03:24:55 +0000306
Roger Meierb4bcbe32011-03-07 19:37:46 +0000307Thrift.Protocol.Type = {};
308Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"';
309Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"';
310Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"';
311Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"';
312Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"';
313Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"';
314Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"';
315Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"';
316Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"';
317Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"';
318Thrift.Protocol.Type[Thrift.Type.SET] = '"set"';
T Jake Luciani322caa22010-02-15 03:24:55 +0000319
320
Roger Meierb4bcbe32011-03-07 19:37:46 +0000321Thrift.Protocol.RType = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000322Thrift.Protocol.RType.tf = Thrift.Type.BOOL;
323Thrift.Protocol.RType.i8 = Thrift.Type.BYTE;
324Thrift.Protocol.RType.i16 = Thrift.Type.I16;
325Thrift.Protocol.RType.i32 = Thrift.Type.I32;
326Thrift.Protocol.RType.i64 = Thrift.Type.I64;
327Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE;
328Thrift.Protocol.RType.rec = Thrift.Type.STRUCT;
329Thrift.Protocol.RType.str = Thrift.Type.STRING;
330Thrift.Protocol.RType.map = Thrift.Type.MAP;
331Thrift.Protocol.RType.lst = Thrift.Type.LIST;
332Thrift.Protocol.RType.set = Thrift.Type.SET;
T Jake Luciani322caa22010-02-15 03:24:55 +0000333
Roger Meierb4bcbe32011-03-07 19:37:46 +0000334Thrift.Protocol.Version = 1;
T Jake Luciani322caa22010-02-15 03:24:55 +0000335
336Thrift.Protocol.prototype = {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000337
338 getTransport: function() {
339 return this.transport;
T Jake Luciani322caa22010-02-15 03:24:55 +0000340 },
341
342 //Write functions
Roger Meierb4bcbe32011-03-07 19:37:46 +0000343 writeMessageBegin: function(name, messageType, seqid) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000344 this.tstack = [];
345 this.tpos = [];
346
347 this.tstack.push([Thrift.Protocol.Version, '"' +
Roger Meierb4bcbe32011-03-07 19:37:46 +0000348 name + '"', messageType, seqid]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000349 },
350
Roger Meierb4bcbe32011-03-07 19:37:46 +0000351 writeMessageEnd: function() {
352 var obj = this.tstack.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000353
Roger Meierb4bcbe32011-03-07 19:37:46 +0000354 this.wobj = this.tstack.pop();
355 this.wobj.push(obj);
356
357 this.wbuf = '[' + this.wobj.join(',') + ']';
358
359 this.transport.write(this.wbuf);
T Jake Luciani322caa22010-02-15 03:24:55 +0000360 },
361
362
Roger Meierb4bcbe32011-03-07 19:37:46 +0000363 writeStructBegin: function(name) {
364 this.tpos.push(this.tstack.length);
365 this.tstack.push({});
T Jake Luciani322caa22010-02-15 03:24:55 +0000366 },
367
Roger Meierb4bcbe32011-03-07 19:37:46 +0000368 writeStructEnd: function() {
369
370 var p = this.tpos.pop();
371 var struct = this.tstack[p];
372 var str = '{';
373 var first = true;
374 for (var key in struct) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000375 if (first) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000376 first = false;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000377 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000378 str += ',';
Roger Meierda6e6ae2011-03-15 09:55:33 +0000379 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000380
Roger Meierb4bcbe32011-03-07 19:37:46 +0000381 str += key + ':' + struct[key];
382 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000383
Roger Meierb4bcbe32011-03-07 19:37:46 +0000384 str += '}';
T Jake Luciani322caa22010-02-15 03:24:55 +0000385 this.tstack[p] = str;
386 },
387
Roger Meierb4bcbe32011-03-07 19:37:46 +0000388 writeFieldBegin: function(name, fieldType, fieldId) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000389 this.tpos.push(this.tstack.length);
390 this.tstack.push({ 'fieldId': '"' +
391 fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType]
Roger Meierb4bcbe32011-03-07 19:37:46 +0000392 });
393
T Jake Luciani322caa22010-02-15 03:24:55 +0000394 },
395
Roger Meierb4bcbe32011-03-07 19:37:46 +0000396 writeFieldEnd: function() {
397 var value = this.tstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000398 var fieldInfo = this.tstack.pop();
399
400 this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' +
Roger Meierb4bcbe32011-03-07 19:37:46 +0000401 fieldInfo.fieldType + ':' + value + '}';
402 this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000403 },
404
Roger Meierb4bcbe32011-03-07 19:37:46 +0000405 writeFieldStop: function() {
T Jake Luciani322caa22010-02-15 03:24:55 +0000406 //na
407 },
408
Roger Meierb4bcbe32011-03-07 19:37:46 +0000409 writeMapBegin: function(keyType, valType, size) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000410 //size is invalid, we'll set it on end.
Roger Meierda6e6ae2011-03-15 09:55:33 +0000411 this.tpos.push(this.tstack.length);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000412 this.tstack.push([Thrift.Protocol.Type[keyType],
413 Thrift.Protocol.Type[valType], 0]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000414 },
415
Roger Meierb4bcbe32011-03-07 19:37:46 +0000416 writeMapEnd: function() {
417 var p = this.tpos.pop();
418
Roger Meierda6e6ae2011-03-15 09:55:33 +0000419 if (p == this.tstack.length) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000420 return;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000421 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000422
Roger Meierda6e6ae2011-03-15 09:55:33 +0000423 if ((this.tstack.length - p - 1) % 2 !== 0) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000424 this.tstack.push('');
Roger Meierda6e6ae2011-03-15 09:55:33 +0000425 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000426
Roger Meierb4bcbe32011-03-07 19:37:46 +0000427 var size = (this.tstack.length - p - 1) / 2;
428
429 this.tstack[p][this.tstack[p].length - 1] = size;
430
431 var map = '}';
432 var first = true;
433 while (this.tstack.length > p + 1) {
434 var v = this.tstack.pop();
435 var k = this.tstack.pop();
436 if (first) {
437 first = false;
Roger Meierda6e6ae2011-03-15 09:55:33 +0000438 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000439 map = ',' + map;
T Jake Luciani322caa22010-02-15 03:24:55 +0000440 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000441
Roger Meier2079bfe2011-06-21 14:09:13 +0000442 if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings
Roger Meier9d8e8f82011-06-14 19:38:27 +0000443 map = k + ':' + v + map;
T Jake Luciani322caa22010-02-15 03:24:55 +0000444 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000445 map = '{' + map;
446
447 this.tstack[p].push(map);
448 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000449 },
450
Roger Meierb4bcbe32011-03-07 19:37:46 +0000451 writeListBegin: function(elemType, size) {
452 this.tpos.push(this.tstack.length);
453 this.tstack.push([Thrift.Protocol.Type[elemType], size]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000454 },
455
Roger Meierb4bcbe32011-03-07 19:37:46 +0000456 writeListEnd: function() {
457 var p = this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000458
Roger Meierb4bcbe32011-03-07 19:37:46 +0000459 while (this.tstack.length > p + 1) {
460 var tmpVal = this.tstack[p + 1];
461 this.tstack.splice(p + 1, 1);
462 this.tstack[p].push(tmpVal);
T Jake Luciani322caa22010-02-15 03:24:55 +0000463 }
464
Roger Meierb4bcbe32011-03-07 19:37:46 +0000465 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000466 },
467
Roger Meierb4bcbe32011-03-07 19:37:46 +0000468 writeSetBegin: function(elemType, size) {
469 this.tpos.push(this.tstack.length);
470 this.tstack.push([Thrift.Protocol.Type[elemType], size]);
T Jake Luciani322caa22010-02-15 03:24:55 +0000471 },
472
Roger Meierb4bcbe32011-03-07 19:37:46 +0000473 writeSetEnd: function() {
474 var p = this.tpos.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000475
Roger Meierb4bcbe32011-03-07 19:37:46 +0000476 while (this.tstack.length > p + 1) {
477 var tmpVal = this.tstack[p + 1];
478 this.tstack.splice(p + 1, 1);
479 this.tstack[p].push(tmpVal);
T Jake Luciani322caa22010-02-15 03:24:55 +0000480 }
481
Roger Meierb4bcbe32011-03-07 19:37:46 +0000482 this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
T Jake Luciani322caa22010-02-15 03:24:55 +0000483 },
484
Roger Meierb4bcbe32011-03-07 19:37:46 +0000485 writeBool: function(value) {
486 this.tstack.push(value ? 1 : 0);
T Jake Luciani322caa22010-02-15 03:24:55 +0000487 },
488
Roger Meierb4bcbe32011-03-07 19:37:46 +0000489 writeByte: function(i8) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000490 this.tstack.push(i8);
491 },
492
Roger Meierb4bcbe32011-03-07 19:37:46 +0000493 writeI16: function(i16) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000494 this.tstack.push(i16);
495 },
496
Roger Meierb4bcbe32011-03-07 19:37:46 +0000497 writeI32: function(i32) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000498 this.tstack.push(i32);
499 },
500
Roger Meierb4bcbe32011-03-07 19:37:46 +0000501 writeI64: function(i64) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000502 this.tstack.push(i64);
503 },
504
Roger Meierb4bcbe32011-03-07 19:37:46 +0000505 writeDouble: function(dbl) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000506 this.tstack.push(dbl);
507 },
508
Roger Meierb4bcbe32011-03-07 19:37:46 +0000509 writeString: function(str) {
510 // We do not encode uri components for wire transfer:
511 if (str === null) {
T Jake Luciani416eea92010-09-17 23:38:25 +0000512 this.tstack.push(null);
513 } else {
514 // concat may be slower than building a byte buffer
Roger Meierb4bcbe32011-03-07 19:37:46 +0000515 var escapedString = '';
516 for (var i = 0; i < str.length; i++) {
517 var ch = str.charAt(i); // a single double quote: "
518 if (ch === '\"') {
519 escapedString += '\\\"'; // write out as: \"
520 } else if (ch === '\\') { // a single backslash: \
521 escapedString += '\\\\'; // write out as: \\
T Jake Luciani416eea92010-09-17 23:38:25 +0000522 /* Currently escaped forward slashes break TJSONProtocol.
Roger Meierb4bcbe32011-03-07 19:37:46 +0000523 * As it stands, we can simply pass forward slashes into
524 * our strings across the wire without being escaped.
T Jake Luciani416eea92010-09-17 23:38:25 +0000525 * I think this is the protocol's bug, not thrift.js
Roger Meierb4bcbe32011-03-07 19:37:46 +0000526 * } else if(ch === '/') { // a single forward slash: /
527 * escapedString += '\\/'; // write out as \/
528 * }
T Jake Luciani416eea92010-09-17 23:38:25 +0000529 */
Roger Meierb4bcbe32011-03-07 19:37:46 +0000530 } else if (ch === '\b') { // a single backspace: invisible
531 escapedString += '\\b'; // write out as: \b"
532 } else if (ch === '\f') { // a single formfeed: invisible
533 escapedString += '\\f'; // write out as: \f"
534 } else if (ch === '\n') { // a single newline: invisible
535 escapedString += '\\n'; // write out as: \n"
536 } else if (ch === '\r') { // a single return: invisible
537 escapedString += '\\r'; // write out as: \r"
538 } else if (ch === '\t') { // a single tab: invisible
539 escapedString += '\\t'; // write out as: \t"
T Jake Luciani416eea92010-09-17 23:38:25 +0000540 } else {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000541 escapedString += ch; // Else it need not be escaped
T Jake Luciani416eea92010-09-17 23:38:25 +0000542 }
543 }
544 this.tstack.push('"' + escapedString + '"');
545 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000546 },
547
Roger Meierb4bcbe32011-03-07 19:37:46 +0000548 writeBinary: function(str) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000549 this.writeString(str);
550 },
551
552
Roger Meierb4bcbe32011-03-07 19:37:46 +0000553
T Jake Luciani322caa22010-02-15 03:24:55 +0000554 // Reading functions
Roger Meierb4bcbe32011-03-07 19:37:46 +0000555 readMessageBegin: function(name, messageType, seqid) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000556 this.rstack = [];
557 this.rpos = [];
T Jake Luciani322caa22010-02-15 03:24:55 +0000558
Roger Meier08b30992011-04-06 21:30:53 +0000559 if (typeof jQuery !== 'undefined') {
560 this.robj = jQuery.parseJSON(this.transport.readAll());
561 } else {
562 this.robj = eval(this.transport.readAll());
563 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000564
T Jake Luciani322caa22010-02-15 03:24:55 +0000565 var r = {};
Roger Meierb4bcbe32011-03-07 19:37:46 +0000566 var version = this.robj.shift();
567
568 if (version != Thrift.Protocol.Version) {
569 throw 'Wrong thrift protocol version: ' + version;
T Jake Luciani322caa22010-02-15 03:24:55 +0000570 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000571
Roger Meierda6e6ae2011-03-15 09:55:33 +0000572 r.fname = this.robj.shift();
573 r.mtype = this.robj.shift();
574 r.rseqid = this.robj.shift();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000575
576
577 //get to the main obj
578 this.rstack.push(this.robj.shift());
579
580 return r;
581 },
582
Roger Meierb4bcbe32011-03-07 19:37:46 +0000583 readMessageEnd: function() {
584 },
585
586 readStructBegin: function(name) {
587 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000588 r.fname = '';
Roger Meierb4bcbe32011-03-07 19:37:46 +0000589
590 //incase this is an array of structs
Roger Meierda6e6ae2011-03-15 09:55:33 +0000591 if (this.rstack[this.rstack.length - 1] instanceof Array) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000592 this.rstack.push(this.rstack[this.rstack.length - 1].shift());
Roger Meierda6e6ae2011-03-15 09:55:33 +0000593 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000594
595 return r;
596 },
597
598 readStructEnd: function() {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000599 if (this.rstack[this.rstack.length - 2] instanceof Array) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000600 this.rstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000601 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000602 },
603
604 readFieldBegin: function() {
605 var r = {};
606
607 var fid = -1;
608 var ftype = Thrift.Type.STOP;
609
610 //get a fieldId
611 for (var f in (this.rstack[this.rstack.length - 1])) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000612 if (f === null) {
613 continue;
614 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000615
Roger Meierda6e6ae2011-03-15 09:55:33 +0000616 fid = parseInt(f, 10);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000617 this.rpos.push(this.rstack.length);
618
Roger Meierda6e6ae2011-03-15 09:55:33 +0000619 var field = this.rstack[this.rstack.length - 1][fid];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000620
621 //remove so we don't see it again
622 delete this.rstack[this.rstack.length - 1][fid];
623
624 this.rstack.push(field);
625
626 break;
627 }
628
629 if (fid != -1) {
630
T Jake Luciani322caa22010-02-15 03:24:55 +0000631 //should only be 1 of these but this is the only
632 //way to match a key
Roger Meierda6e6ae2011-03-15 09:55:33 +0000633 for (var i in (this.rstack[this.rstack.length - 1])) {
634 if (Thrift.Protocol.RType[i] === null) {
635 continue;
636 }
T Jake Luciani322caa22010-02-15 03:24:55 +0000637
Roger Meierda6e6ae2011-03-15 09:55:33 +0000638 ftype = Thrift.Protocol.RType[i];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000639 this.rstack[this.rstack.length - 1] =
Roger Meierda6e6ae2011-03-15 09:55:33 +0000640 this.rstack[this.rstack.length - 1][i];
Roger Meierb4bcbe32011-03-07 19:37:46 +0000641 }
642 }
643
Roger Meierda6e6ae2011-03-15 09:55:33 +0000644 r.fname = '';
645 r.ftype = ftype;
646 r.fid = fid;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000647
Roger Meierb4bcbe32011-03-07 19:37:46 +0000648 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000649 },
650
Roger Meierb4bcbe32011-03-07 19:37:46 +0000651 readFieldEnd: function() {
652 var pos = this.rpos.pop();
653
T Jake Luciani322caa22010-02-15 03:24:55 +0000654 //get back to the right place in the stack
Roger Meierda6e6ae2011-03-15 09:55:33 +0000655 while (this.rstack.length > pos) {
T Jake Luciani322caa22010-02-15 03:24:55 +0000656 this.rstack.pop();
Roger Meierda6e6ae2011-03-15 09:55:33 +0000657 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000658
T Jake Luciani322caa22010-02-15 03:24:55 +0000659 },
660
Roger Meierb4bcbe32011-03-07 19:37:46 +0000661 readMapBegin: function(keyType, valType, size) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000662 var map = this.rstack.pop();
663
T Jake Luciani322caa22010-02-15 03:24:55 +0000664 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000665 r.ktype = Thrift.Protocol.RType[map.shift()];
666 r.vtype = Thrift.Protocol.RType[map.shift()];
667 r.size = map.shift();
T Jake Luciani322caa22010-02-15 03:24:55 +0000668
T Jake Luciani322caa22010-02-15 03:24:55 +0000669
T Jake Luciani322caa22010-02-15 03:24:55 +0000670 this.rpos.push(this.rstack.length);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000671 this.rstack.push(map.shift());
672
T Jake Luciani322caa22010-02-15 03:24:55 +0000673 return r;
674 },
675
Roger Meierb4bcbe32011-03-07 19:37:46 +0000676 readMapEnd: function() {
677 this.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000678 },
679
Roger Meierb4bcbe32011-03-07 19:37:46 +0000680 readListBegin: function(elemType, size) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000681 var list = this.rstack[this.rstack.length - 1];
682
683 var r = {};
Roger Meierda6e6ae2011-03-15 09:55:33 +0000684 r.etype = Thrift.Protocol.RType[list.shift()];
685 r.size = list.shift();
Roger Meierb4bcbe32011-03-07 19:37:46 +0000686
Roger Meierb4bcbe32011-03-07 19:37:46 +0000687 this.rpos.push(this.rstack.length);
688 this.rstack.push(list);
689
690 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000691 },
692
Roger Meierb4bcbe32011-03-07 19:37:46 +0000693 readListEnd: function() {
694 this.readFieldEnd();
T Jake Luciani322caa22010-02-15 03:24:55 +0000695 },
696
Roger Meierb4bcbe32011-03-07 19:37:46 +0000697 readSetBegin: function(elemType, size) {
698 return this.readListBegin(elemType, size);
699 },
700
701 readSetEnd: function() {
702 return this.readListEnd();
703 },
704
705 readBool: function() {
706 var r = this.readI32();
707
Roger Meierda6e6ae2011-03-15 09:55:33 +0000708 if (r !== null && r.value == '1') {
709 r.value = true;
710 } else {
711 r.value = false;
T Jake Luciani322caa22010-02-15 03:24:55 +0000712 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000713
714 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000715 },
716
Roger Meierb4bcbe32011-03-07 19:37:46 +0000717 readByte: function() {
718 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000719 },
720
Roger Meierb4bcbe32011-03-07 19:37:46 +0000721 readI16: function() {
722 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000723 },
T Jake Luciani322caa22010-02-15 03:24:55 +0000724
Roger Meierb4bcbe32011-03-07 19:37:46 +0000725 readI32: function(f) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000726 if (f === undefined) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000727 f = this.rstack[this.rstack.length - 1];
Roger Meierda6e6ae2011-03-15 09:55:33 +0000728 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000729
730 var r = {};
731
732 if (f instanceof Array) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000733 if (f.length === 0) {
734 r.value = undefined;
735 } else {
736 r.value = f.shift();
737 }
738 } else if (f instanceof Object) {
Roger Meierb4bcbe32011-03-07 19:37:46 +0000739 for (var i in f) {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000740 if (i === null) {
741 continue;
742 }
743 this.rstack.push(f[i]);
Roger Meierb4bcbe32011-03-07 19:37:46 +0000744 delete f[i];
745
Roger Meierda6e6ae2011-03-15 09:55:33 +0000746 r.value = i;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000747 break;
T Jake Luciani322caa22010-02-15 03:24:55 +0000748 }
749 } else {
Roger Meierda6e6ae2011-03-15 09:55:33 +0000750 r.value = f;
Roger Meierb4bcbe32011-03-07 19:37:46 +0000751 this.rstack.pop();
T Jake Luciani322caa22010-02-15 03:24:55 +0000752 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000753
754 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000755 },
756
Roger Meierb4bcbe32011-03-07 19:37:46 +0000757 readI64: function() {
758 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000759 },
760
Roger Meierb4bcbe32011-03-07 19:37:46 +0000761 readDouble: function() {
762 return this.readI32();
T Jake Luciani322caa22010-02-15 03:24:55 +0000763 },
764
Roger Meierb4bcbe32011-03-07 19:37:46 +0000765 readString: function() {
766 var r = this.readI32();
767 return r;
T Jake Luciani322caa22010-02-15 03:24:55 +0000768 },
769
Roger Meierb4bcbe32011-03-07 19:37:46 +0000770 readBinary: function() {
771 return this.readString();
T Jake Luciani322caa22010-02-15 03:24:55 +0000772 },
773
Roger Meierb4bcbe32011-03-07 19:37:46 +0000774
T Jake Luciani322caa22010-02-15 03:24:55 +0000775 //Method to arbitrarily skip over data.
Roger Meierb4bcbe32011-03-07 19:37:46 +0000776 skip: function(type) {
777 throw 'skip not supported yet';
T Jake Luciani322caa22010-02-15 03:24:55 +0000778 }
Roger Meierb4bcbe32011-03-07 19:37:46 +0000779};