|  | /* | 
|  | * 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 = { | 
|  |  | 
|  | 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 | 
|  | } | 
|  | } | 
|  |  | 
|  | Thrift.TException = {} | 
|  | Thrift.TException.prototype = { | 
|  | initialize: function( message, code ) { | 
|  | this.message = message; | 
|  | this.code    = (code == null) ? 0 : code; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | Thrift.TApplicationExceptionType = { | 
|  | "UNKNOWN"              : 0, | 
|  | "UNKNOWN_METHOD"       : 1, | 
|  | "INVALID_MESSAGE_TYPE" : 2, | 
|  | "WRONG_METHOD_NAME"    : 3, | 
|  | "BAD_SEQUENCE_ID"      : 4, | 
|  | "MISSING_RESULT"       : 5 | 
|  | } | 
|  |  | 
|  | Thrift.TApplicationException = function(message, code){ | 
|  | this.message = message | 
|  | this.code    = (code == null) ? 0 : code | 
|  | } | 
|  |  | 
|  | Thrift.TApplicationException.prototype = { | 
|  |  | 
|  | read : function(input){ | 
|  |  | 
|  | var ftype | 
|  | var fid | 
|  | var ret = input.readStructBegin(fname) | 
|  |  | 
|  | this.fname = ret.fname | 
|  |  | 
|  | while(1){ | 
|  |  | 
|  | ret = input.readFieldBegin() | 
|  |  | 
|  | if(ret.ftype == TType.STOP) | 
|  | break | 
|  |  | 
|  | var fid = ret.fid | 
|  |  | 
|  | switch(fid){ | 
|  | case 1: | 
|  | if( ret.ftype == Type.STRING ){ | 
|  | ret = input.readString() | 
|  | this.message = ret.value | 
|  | } else { | 
|  | ret = input.skip(ret.ftype) | 
|  | } | 
|  |  | 
|  | break | 
|  | case 2: | 
|  | if( ret.ftype == 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() | 
|  |  | 
|  | }, | 
|  |  | 
|  | write: function(output){ | 
|  | var xfer   = 0; | 
|  |  | 
|  | output.writeStructBegin('TApplicationException'); | 
|  |  | 
|  | if (this.message) { | 
|  | output.writeFieldBegin('message', Type.STRING, 1) | 
|  | output.writeString(this.getMessage()) | 
|  | output.writeFieldEnd() | 
|  | } | 
|  |  | 
|  | if (this.code) { | 
|  | output.writeFieldBegin('type', Type.I32, 2) | 
|  | output.writeI32(this.code) | 
|  | output.writeFieldEnd() | 
|  | } | 
|  |  | 
|  | output.writeFieldStop() | 
|  | output.writeStructEnd() | 
|  |  | 
|  | }, | 
|  |  | 
|  | getCode : function() { | 
|  | return this.code | 
|  | }, | 
|  |  | 
|  | 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(e) {} | 
|  | try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {} | 
|  | try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {} | 
|  |  | 
|  | throw "Your browser doesn't support the XmlHttpRequest object.  Try upgrading to Firefox." | 
|  |  | 
|  | }, | 
|  |  | 
|  | flush : function(){ | 
|  |  | 
|  | //async mode | 
|  | if(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 | 
|  | }, | 
|  |  | 
|  | 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 = new Array() | 
|  | this.tpos   = new Array(); | 
|  |  | 
|  | 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  += '"'+k+'":'+v | 
|  | } | 
|  | 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 = new Array() | 
|  | this.rpos   = new Array() | 
|  |  | 
|  | 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) | 
|  | 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 f in (this.rstack[this.rstack.length-1])){ | 
|  | if(Thrift.Protocol.RType[f] == null ) continue | 
|  |  | 
|  | ftype = Thrift.Protocol.RType[f] | 
|  | this.rstack[this.rstack.length-1] = this.rstack[this.rstack.length-1][f] | 
|  | } | 
|  | } | 
|  |  | 
|  | 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 | 
|  | } | 
|  |  | 
|  | 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" | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  |  |