Added: incubator/thrift/trunk/lib/js/thrift.js URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/lib/js/thrift.js?rev=910158&view=auto ============================================================================== --- incubator/thrift/trunk/lib/js/thrift.js (added) +++ incubator/thrift/trunk/lib/js/thrift.js Mon Feb 15 03:24:55 2010 @@ -0,0 +1,671 @@ +/* + * 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.TApplicationException = { + "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 ){ + this.tstack[p].push(this.tstack.pop()) + } + + 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 ){ + this.tstack[p].push(this.tstack.pop()) + } + + 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){ + this.tstack.push('"'+encodeURIComponent(str)+'"'); + }, + + 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"] = ''; + + return r; + }, + + readStructEnd : function(){ + }, + + 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[this.rstack.length-1] + + 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.shift()) + + + 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(){ + var f = this.rstack[this.rstack.length-1] + var r = {} + + if(f instanceof Array){ + r["value"] = f.pop() + + }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() + r["value"] = decodeURIComponent(r["value"]) + + return r + }, + + readBinary : function(){ + return this.readString() + }, + + + //Method to arbitrarily skip over data. + skip : function(type){ + throw "skip not supported yet" + } + +} + + +
Modified: incubator/thrift/trunk/test/ThriftTest.thrift URL: http://svn.apache.org/viewvc/incubator/thrift/trunk/test/ThriftTest.thrift?rev=910158&r1=910157&r2=910158&view=diff ============================================================================== --- incubator/thrift/trunk/test/ThriftTest.thrift (original) +++ incubator/thrift/trunk/test/ThriftTest.thrift Mon Feb 15 03:24:55 2010 @@ -26,6 +26,7 @@ namespace rb Thrift.Test namespace perl ThriftTest namespace csharp Thrift.Test +namespace js ThriftTest /** * Docstring!
