mirror of
https://github.com/valitydev/thrift.git
synced 2024-11-08 03:08:53 +00:00
9c76258564
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1157426 13f79535-47bb-0310-9956-ffa450edef68
796 lines
21 KiB
JavaScript
796 lines
21 KiB
JavaScript
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
var Thrift = {
|
|
Version: '0.8.0-dev',
|
|
/*
|
|
Description: 'JavaScript bindings for the Apache Thrift RPC system',
|
|
License: 'http://www.apache.org/licenses/LICENSE-2.0',
|
|
Homepage: 'http://thrift.apache.org',
|
|
BugReports: 'https://issues.apache.org/jira/browse/THRIFT',
|
|
Maintainer: 'dev@thrift.apache.org',
|
|
*/
|
|
|
|
Type: {
|
|
'STOP' : 0,
|
|
'VOID' : 1,
|
|
'BOOL' : 2,
|
|
'BYTE' : 3,
|
|
'I08' : 3,
|
|
'DOUBLE' : 4,
|
|
'I16' : 6,
|
|
'I32' : 8,
|
|
'I64' : 10,
|
|
'STRING' : 11,
|
|
'UTF7' : 11,
|
|
'STRUCT' : 12,
|
|
'MAP' : 13,
|
|
'SET' : 14,
|
|
'LIST' : 15,
|
|
'UTF8' : 16,
|
|
'UTF16' : 17
|
|
},
|
|
|
|
MessageType: {
|
|
'CALL' : 1,
|
|
'REPLY' : 2,
|
|
'EXCEPTION' : 3
|
|
},
|
|
|
|
objectLength: function(obj) {
|
|
var length = 0;
|
|
for (var k in obj) {
|
|
if (obj.hasOwnProperty(k)) {
|
|
length++;
|
|
}
|
|
}
|
|
|
|
return length;
|
|
},
|
|
|
|
inherits: function(constructor, superConstructor) {
|
|
//Prototypal Inheritance http://javascript.crockford.com/prototypal.html
|
|
function F() {}
|
|
F.prototype = superConstructor.prototype;
|
|
constructor.prototype = new F();
|
|
}
|
|
};
|
|
|
|
|
|
|
|
Thrift.TException = function(message) {
|
|
this.message = message;
|
|
};
|
|
Thrift.inherits(Thrift.TException, Error);
|
|
Thrift.TException.prototype.name = 'TException';
|
|
|
|
Thrift.TApplicationExceptionType = {
|
|
'UNKNOWN' : 0,
|
|
'UNKNOWN_METHOD' : 1,
|
|
'INVALID_MESSAGE_TYPE' : 2,
|
|
'WRONG_METHOD_NAME' : 3,
|
|
'BAD_SEQUENCE_ID' : 4,
|
|
'MISSING_RESULT' : 5,
|
|
'INTERNAL_ERROR' : 6,
|
|
'PROTOCOL_ERROR' : 7
|
|
};
|
|
|
|
Thrift.TApplicationException = function(message, code) {
|
|
this.message = message;
|
|
this.code = (code === null) ? 0 : code;
|
|
};
|
|
Thrift.inherits(Thrift.TApplicationException, Thrift.TException);
|
|
Thrift.TApplicationException.prototype.name = 'TApplicationException';
|
|
|
|
Thrift.TApplicationException.prototype.read = function(input) {
|
|
while (1) {
|
|
var ret = input.readFieldBegin();
|
|
|
|
if (ret.ftype == Thrift.Type.STOP) {
|
|
break;
|
|
}
|
|
|
|
var fid = ret.fid;
|
|
|
|
switch (fid) {
|
|
case 1:
|
|
if (ret.ftype == Thrift.Type.STRING) {
|
|
ret = input.readString();
|
|
this.message = ret.value;
|
|
} else {
|
|
ret = input.skip(ret.ftype);
|
|
}
|
|
break;
|
|
case 2:
|
|
if (ret.ftype == Thrift.Type.I32) {
|
|
ret = input.readI32();
|
|
this.code = ret.value;
|
|
} else {
|
|
ret = input.skip(ret.ftype);
|
|
}
|
|
break;
|
|
default:
|
|
ret = input.skip(ret.ftype);
|
|
break;
|
|
}
|
|
|
|
input.readFieldEnd();
|
|
}
|
|
|
|
input.readStructEnd();
|
|
};
|
|
|
|
Thrift.TApplicationException.prototype.write = function(output) {
|
|
var xfer = 0;
|
|
|
|
output.writeStructBegin('TApplicationException');
|
|
|
|
if (this.message) {
|
|
output.writeFieldBegin('message', Thrift.Type.STRING, 1);
|
|
output.writeString(this.getMessage());
|
|
output.writeFieldEnd();
|
|
}
|
|
|
|
if (this.code) {
|
|
output.writeFieldBegin('type', Thrift.Type.I32, 2);
|
|
output.writeI32(this.code);
|
|
output.writeFieldEnd();
|
|
}
|
|
|
|
output.writeFieldStop();
|
|
output.writeStructEnd();
|
|
};
|
|
|
|
Thrift.TApplicationException.prototype.getCode = function() {
|
|
return this.code;
|
|
};
|
|
|
|
Thrift.TApplicationException.prototype.getMessage = function() {
|
|
return this.message;
|
|
};
|
|
|
|
/**
|
|
*If you do not specify a url then you must handle ajax on your own.
|
|
*This is how to use js bindings in a async fashion.
|
|
*/
|
|
Thrift.Transport = function(url) {
|
|
this.url = url;
|
|
this.wpos = 0;
|
|
this.rpos = 0;
|
|
|
|
this.send_buf = '';
|
|
this.recv_buf = '';
|
|
};
|
|
|
|
Thrift.Transport.prototype = {
|
|
|
|
//Gets the browser specific XmlHttpRequest Object
|
|
getXmlHttpRequestObject: function() {
|
|
try { return new XMLHttpRequest(); } catch (e1) { }
|
|
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { }
|
|
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { }
|
|
|
|
throw "Your browser doesn't support the XmlHttpRequest object.";
|
|
},
|
|
|
|
flush: function(async) {
|
|
//async mode
|
|
if (async || this.url === undefined || this.url === '') {
|
|
return this.send_buf;
|
|
}
|
|
|
|
var xreq = this.getXmlHttpRequestObject();
|
|
|
|
if (xreq.overrideMimeType) {
|
|
xreq.overrideMimeType('application/json');
|
|
}
|
|
|
|
xreq.open('POST', this.url, false);
|
|
xreq.send(this.send_buf);
|
|
|
|
if (xreq.readyState != 4) {
|
|
throw 'encountered an unknown ajax ready state: ' + xreq.readyState;
|
|
}
|
|
|
|
if (xreq.status != 200) {
|
|
throw 'encountered a unknown request status: ' + xreq.status;
|
|
}
|
|
|
|
this.recv_buf = xreq.responseText;
|
|
this.recv_buf_sz = this.recv_buf.length;
|
|
this.wpos = this.recv_buf.length;
|
|
this.rpos = 0;
|
|
},
|
|
|
|
jqRequest: function(client, postData, args, recv_method) {
|
|
if (typeof jQuery === 'undefined' ||
|
|
typeof jQuery.Deferred === 'undefined') {
|
|
throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests';
|
|
}
|
|
|
|
// Deferreds
|
|
var deferred = jQuery.Deferred();
|
|
var completeDfd = jQuery._Deferred();
|
|
var dfd = deferred.promise();
|
|
dfd.success = dfd.done;
|
|
dfd.error = dfd.fail;
|
|
dfd.complete = completeDfd.done;
|
|
|
|
var jqXHR = jQuery.ajax({
|
|
url: this.url,
|
|
data: postData,
|
|
type: 'POST',
|
|
cache: false,
|
|
dataType: 'text',
|
|
context: this,
|
|
success: this.jqResponse,
|
|
error: function(xhr, status, e) {
|
|
deferred.rejectWith(client, jQuery.merge([e], xhr.tArgs));
|
|
},
|
|
complete: function(xhr, status) {
|
|
completeDfd.resolveWith(client, [xhr, status]);
|
|
}
|
|
});
|
|
|
|
deferred.done(jQuery.makeArray(args).pop()); //pop callback from args
|
|
jqXHR.tArgs = args;
|
|
jqXHR.tClient = client;
|
|
jqXHR.tRecvFn = recv_method;
|
|
jqXHR.tDfd = deferred;
|
|
return dfd;
|
|
},
|
|
|
|
jqResponse: function(responseData, textStatus, jqXHR) {
|
|
this.setRecvBuffer(responseData);
|
|
try {
|
|
var value = jqXHR.tRecvFn.call(jqXHR.tClient);
|
|
jqXHR.tDfd.resolveWith(jqXHR, jQuery.merge([value], jqXHR.tArgs));
|
|
} catch (ex) {
|
|
jqXHR.tDfd.rejectWith(jqXHR, jQuery.merge([ex], jqXHR.tArgs));
|
|
}
|
|
},
|
|
|
|
setRecvBuffer: function(buf) {
|
|
this.recv_buf = buf;
|
|
this.recv_buf_sz = this.recv_buf.length;
|
|
this.wpos = this.recv_buf.length;
|
|
this.rpos = 0;
|
|
},
|
|
|
|
isOpen: function() {
|
|
return true;
|
|
},
|
|
|
|
open: function() {},
|
|
|
|
close: function() {},
|
|
|
|
read: function(len) {
|
|
var avail = this.wpos - this.rpos;
|
|
|
|
if (avail === 0) {
|
|
return '';
|
|
}
|
|
|
|
var give = len;
|
|
|
|
if (avail < len) {
|
|
give = avail;
|
|
}
|
|
|
|
var ret = this.read_buf.substr(this.rpos, give);
|
|
this.rpos += give;
|
|
|
|
//clear buf when complete?
|
|
return ret;
|
|
},
|
|
|
|
readAll: function() {
|
|
return this.recv_buf;
|
|
},
|
|
|
|
write: function(buf) {
|
|
this.send_buf = buf;
|
|
},
|
|
|
|
getSendBuffer: function() {
|
|
return this.send_buf;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Thrift.Protocol = function(transport) {
|
|
this.transport = transport;
|
|
};
|
|
|
|
Thrift.Protocol.Type = {};
|
|
Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"';
|
|
Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"';
|
|
Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"';
|
|
Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"';
|
|
Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"';
|
|
Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"';
|
|
Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"';
|
|
Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"';
|
|
Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"';
|
|
Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"';
|
|
Thrift.Protocol.Type[Thrift.Type.SET] = '"set"';
|
|
|
|
|
|
Thrift.Protocol.RType = {};
|
|
Thrift.Protocol.RType.tf = Thrift.Type.BOOL;
|
|
Thrift.Protocol.RType.i8 = Thrift.Type.BYTE;
|
|
Thrift.Protocol.RType.i16 = Thrift.Type.I16;
|
|
Thrift.Protocol.RType.i32 = Thrift.Type.I32;
|
|
Thrift.Protocol.RType.i64 = Thrift.Type.I64;
|
|
Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE;
|
|
Thrift.Protocol.RType.rec = Thrift.Type.STRUCT;
|
|
Thrift.Protocol.RType.str = Thrift.Type.STRING;
|
|
Thrift.Protocol.RType.map = Thrift.Type.MAP;
|
|
Thrift.Protocol.RType.lst = Thrift.Type.LIST;
|
|
Thrift.Protocol.RType.set = Thrift.Type.SET;
|
|
|
|
Thrift.Protocol.Version = 1;
|
|
|
|
Thrift.Protocol.prototype = {
|
|
|
|
getTransport: function() {
|
|
return this.transport;
|
|
},
|
|
|
|
//Write functions
|
|
writeMessageBegin: function(name, messageType, seqid) {
|
|
this.tstack = [];
|
|
this.tpos = [];
|
|
|
|
this.tstack.push([Thrift.Protocol.Version, '"' +
|
|
name + '"', messageType, seqid]);
|
|
},
|
|
|
|
writeMessageEnd: function() {
|
|
var obj = this.tstack.pop();
|
|
|
|
this.wobj = this.tstack.pop();
|
|
this.wobj.push(obj);
|
|
|
|
this.wbuf = '[' + this.wobj.join(',') + ']';
|
|
|
|
this.transport.write(this.wbuf);
|
|
},
|
|
|
|
|
|
writeStructBegin: function(name) {
|
|
this.tpos.push(this.tstack.length);
|
|
this.tstack.push({});
|
|
},
|
|
|
|
writeStructEnd: function() {
|
|
|
|
var p = this.tpos.pop();
|
|
var struct = this.tstack[p];
|
|
var str = '{';
|
|
var first = true;
|
|
for (var key in struct) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
str += ',';
|
|
}
|
|
|
|
str += key + ':' + struct[key];
|
|
}
|
|
|
|
str += '}';
|
|
this.tstack[p] = str;
|
|
},
|
|
|
|
writeFieldBegin: function(name, fieldType, fieldId) {
|
|
this.tpos.push(this.tstack.length);
|
|
this.tstack.push({ 'fieldId': '"' +
|
|
fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType]
|
|
});
|
|
|
|
},
|
|
|
|
writeFieldEnd: function() {
|
|
var value = this.tstack.pop();
|
|
var fieldInfo = this.tstack.pop();
|
|
|
|
this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' +
|
|
fieldInfo.fieldType + ':' + value + '}';
|
|
this.tpos.pop();
|
|
},
|
|
|
|
writeFieldStop: function() {
|
|
//na
|
|
},
|
|
|
|
writeMapBegin: function(keyType, valType, size) {
|
|
//size is invalid, we'll set it on end.
|
|
this.tpos.push(this.tstack.length);
|
|
this.tstack.push([Thrift.Protocol.Type[keyType],
|
|
Thrift.Protocol.Type[valType], 0]);
|
|
},
|
|
|
|
writeMapEnd: function() {
|
|
var p = this.tpos.pop();
|
|
|
|
if (p == this.tstack.length) {
|
|
return;
|
|
}
|
|
|
|
if ((this.tstack.length - p - 1) % 2 !== 0) {
|
|
this.tstack.push('');
|
|
}
|
|
|
|
var size = (this.tstack.length - p - 1) / 2;
|
|
|
|
this.tstack[p][this.tstack[p].length - 1] = size;
|
|
|
|
var map = '}';
|
|
var first = true;
|
|
while (this.tstack.length > p + 1) {
|
|
var v = this.tstack.pop();
|
|
var k = this.tstack.pop();
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
map = ',' + map;
|
|
}
|
|
|
|
if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings
|
|
map = k + ':' + v + map;
|
|
}
|
|
map = '{' + map;
|
|
|
|
this.tstack[p].push(map);
|
|
this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
|
|
},
|
|
|
|
writeListBegin: function(elemType, size) {
|
|
this.tpos.push(this.tstack.length);
|
|
this.tstack.push([Thrift.Protocol.Type[elemType], size]);
|
|
},
|
|
|
|
writeListEnd: function() {
|
|
var p = this.tpos.pop();
|
|
|
|
while (this.tstack.length > p + 1) {
|
|
var tmpVal = this.tstack[p + 1];
|
|
this.tstack.splice(p + 1, 1);
|
|
this.tstack[p].push(tmpVal);
|
|
}
|
|
|
|
this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
|
|
},
|
|
|
|
writeSetBegin: function(elemType, size) {
|
|
this.tpos.push(this.tstack.length);
|
|
this.tstack.push([Thrift.Protocol.Type[elemType], size]);
|
|
},
|
|
|
|
writeSetEnd: function() {
|
|
var p = this.tpos.pop();
|
|
|
|
while (this.tstack.length > p + 1) {
|
|
var tmpVal = this.tstack[p + 1];
|
|
this.tstack.splice(p + 1, 1);
|
|
this.tstack[p].push(tmpVal);
|
|
}
|
|
|
|
this.tstack[p] = '[' + this.tstack[p].join(',') + ']';
|
|
},
|
|
|
|
writeBool: function(value) {
|
|
this.tstack.push(value ? 1 : 0);
|
|
},
|
|
|
|
writeByte: function(i8) {
|
|
this.tstack.push(i8);
|
|
},
|
|
|
|
writeI16: function(i16) {
|
|
this.tstack.push(i16);
|
|
},
|
|
|
|
writeI32: function(i32) {
|
|
this.tstack.push(i32);
|
|
},
|
|
|
|
writeI64: function(i64) {
|
|
this.tstack.push(i64);
|
|
},
|
|
|
|
writeDouble: function(dbl) {
|
|
this.tstack.push(dbl);
|
|
},
|
|
|
|
writeString: function(str) {
|
|
// We do not encode uri components for wire transfer:
|
|
if (str === null) {
|
|
this.tstack.push(null);
|
|
} else {
|
|
// concat may be slower than building a byte buffer
|
|
var escapedString = '';
|
|
for (var i = 0; i < str.length; i++) {
|
|
var ch = str.charAt(i); // a single double quote: "
|
|
if (ch === '\"') {
|
|
escapedString += '\\\"'; // write out as: \"
|
|
} else if (ch === '\\') { // a single backslash: \
|
|
escapedString += '\\\\'; // write out as: \\
|
|
/* Currently escaped forward slashes break TJSONProtocol.
|
|
* As it stands, we can simply pass forward slashes into
|
|
* our strings across the wire without being escaped.
|
|
* I think this is the protocol's bug, not thrift.js
|
|
* } else if(ch === '/') { // a single forward slash: /
|
|
* escapedString += '\\/'; // write out as \/
|
|
* }
|
|
*/
|
|
} else if (ch === '\b') { // a single backspace: invisible
|
|
escapedString += '\\b'; // write out as: \b"
|
|
} else if (ch === '\f') { // a single formfeed: invisible
|
|
escapedString += '\\f'; // write out as: \f"
|
|
} else if (ch === '\n') { // a single newline: invisible
|
|
escapedString += '\\n'; // write out as: \n"
|
|
} else if (ch === '\r') { // a single return: invisible
|
|
escapedString += '\\r'; // write out as: \r"
|
|
} else if (ch === '\t') { // a single tab: invisible
|
|
escapedString += '\\t'; // write out as: \t"
|
|
} else {
|
|
escapedString += ch; // Else it need not be escaped
|
|
}
|
|
}
|
|
this.tstack.push('"' + escapedString + '"');
|
|
}
|
|
},
|
|
|
|
writeBinary: function(str) {
|
|
this.writeString(str);
|
|
},
|
|
|
|
|
|
|
|
// Reading functions
|
|
readMessageBegin: function(name, messageType, seqid) {
|
|
this.rstack = [];
|
|
this.rpos = [];
|
|
|
|
if (typeof jQuery !== 'undefined') {
|
|
this.robj = jQuery.parseJSON(this.transport.readAll());
|
|
} else {
|
|
this.robj = eval(this.transport.readAll());
|
|
}
|
|
|
|
var r = {};
|
|
var version = this.robj.shift();
|
|
|
|
if (version != Thrift.Protocol.Version) {
|
|
throw 'Wrong thrift protocol version: ' + version;
|
|
}
|
|
|
|
r.fname = this.robj.shift();
|
|
r.mtype = this.robj.shift();
|
|
r.rseqid = this.robj.shift();
|
|
|
|
|
|
//get to the main obj
|
|
this.rstack.push(this.robj.shift());
|
|
|
|
return r;
|
|
},
|
|
|
|
readMessageEnd: function() {
|
|
},
|
|
|
|
readStructBegin: function(name) {
|
|
var r = {};
|
|
r.fname = '';
|
|
|
|
//incase this is an array of structs
|
|
if (this.rstack[this.rstack.length - 1] instanceof Array) {
|
|
this.rstack.push(this.rstack[this.rstack.length - 1].shift());
|
|
}
|
|
|
|
return r;
|
|
},
|
|
|
|
readStructEnd: function() {
|
|
if (this.rstack[this.rstack.length - 2] instanceof Array) {
|
|
this.rstack.pop();
|
|
}
|
|
},
|
|
|
|
readFieldBegin: function() {
|
|
var r = {};
|
|
|
|
var fid = -1;
|
|
var ftype = Thrift.Type.STOP;
|
|
|
|
//get a fieldId
|
|
for (var f in (this.rstack[this.rstack.length - 1])) {
|
|
if (f === null) {
|
|
continue;
|
|
}
|
|
|
|
fid = parseInt(f, 10);
|
|
this.rpos.push(this.rstack.length);
|
|
|
|
var field = this.rstack[this.rstack.length - 1][fid];
|
|
|
|
//remove so we don't see it again
|
|
delete this.rstack[this.rstack.length - 1][fid];
|
|
|
|
this.rstack.push(field);
|
|
|
|
break;
|
|
}
|
|
|
|
if (fid != -1) {
|
|
|
|
//should only be 1 of these but this is the only
|
|
//way to match a key
|
|
for (var i in (this.rstack[this.rstack.length - 1])) {
|
|
if (Thrift.Protocol.RType[i] === null) {
|
|
continue;
|
|
}
|
|
|
|
ftype = Thrift.Protocol.RType[i];
|
|
this.rstack[this.rstack.length - 1] =
|
|
this.rstack[this.rstack.length - 1][i];
|
|
}
|
|
}
|
|
|
|
r.fname = '';
|
|
r.ftype = ftype;
|
|
r.fid = fid;
|
|
|
|
return r;
|
|
},
|
|
|
|
readFieldEnd: function() {
|
|
var pos = this.rpos.pop();
|
|
|
|
//get back to the right place in the stack
|
|
while (this.rstack.length > pos) {
|
|
this.rstack.pop();
|
|
}
|
|
|
|
},
|
|
|
|
readMapBegin: function(keyType, valType, size) {
|
|
var map = this.rstack.pop();
|
|
|
|
var r = {};
|
|
r.ktype = Thrift.Protocol.RType[map.shift()];
|
|
r.vtype = Thrift.Protocol.RType[map.shift()];
|
|
r.size = map.shift();
|
|
|
|
|
|
this.rpos.push(this.rstack.length);
|
|
this.rstack.push(map.shift());
|
|
|
|
return r;
|
|
},
|
|
|
|
readMapEnd: function() {
|
|
this.readFieldEnd();
|
|
},
|
|
|
|
readListBegin: function(elemType, size) {
|
|
var list = this.rstack[this.rstack.length - 1];
|
|
|
|
var r = {};
|
|
r.etype = Thrift.Protocol.RType[list.shift()];
|
|
r.size = list.shift();
|
|
|
|
this.rpos.push(this.rstack.length);
|
|
this.rstack.push(list);
|
|
|
|
return r;
|
|
},
|
|
|
|
readListEnd: function() {
|
|
this.readFieldEnd();
|
|
},
|
|
|
|
readSetBegin: function(elemType, size) {
|
|
return this.readListBegin(elemType, size);
|
|
},
|
|
|
|
readSetEnd: function() {
|
|
return this.readListEnd();
|
|
},
|
|
|
|
readBool: function() {
|
|
var r = this.readI32();
|
|
|
|
if (r !== null && r.value == '1') {
|
|
r.value = true;
|
|
} else {
|
|
r.value = false;
|
|
}
|
|
|
|
return r;
|
|
},
|
|
|
|
readByte: function() {
|
|
return this.readI32();
|
|
},
|
|
|
|
readI16: function() {
|
|
return this.readI32();
|
|
},
|
|
|
|
readI32: function(f) {
|
|
if (f === undefined) {
|
|
f = this.rstack[this.rstack.length - 1];
|
|
}
|
|
|
|
var r = {};
|
|
|
|
if (f instanceof Array) {
|
|
if (f.length === 0) {
|
|
r.value = undefined;
|
|
} else {
|
|
r.value = f.shift();
|
|
}
|
|
} else if (f instanceof Object) {
|
|
for (var i in f) {
|
|
if (i === null) {
|
|
continue;
|
|
}
|
|
this.rstack.push(f[i]);
|
|
delete f[i];
|
|
|
|
r.value = i;
|
|
break;
|
|
}
|
|
} else {
|
|
r.value = f;
|
|
this.rstack.pop();
|
|
}
|
|
|
|
return r;
|
|
},
|
|
|
|
readI64: function() {
|
|
return this.readI32();
|
|
},
|
|
|
|
readDouble: function() {
|
|
return this.readI32();
|
|
},
|
|
|
|
readString: function() {
|
|
var r = this.readI32();
|
|
return r;
|
|
},
|
|
|
|
readBinary: function() {
|
|
return this.readString();
|
|
},
|
|
|
|
|
|
//Method to arbitrarily skip over data.
|
|
skip: function(type) {
|
|
throw 'skip not supported yet';
|
|
}
|
|
};
|