From 49ef6587b4cb830cbe35a8e14ac4ad5a2c457923 Mon Sep 17 00:00:00 2001 From: Roger Meier Date: Wed, 11 Apr 2012 22:28:26 +0000 Subject: [PATCH] THRIFT-1079 Support i64 in AS3 Patch: Ethan Urie git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1325048 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/generate/t_as3_generator.cc | 28 ++++--- lib/as3/build.xml | 4 + .../src/org/apache/thrift/TDeserializer.as | 48 +++++++++++ lib/as3/src/org/apache/thrift/TSerializer.as | 47 +++++++++++ .../apache/thrift/protocol/TBinaryProtocol.as | 44 +++++------ .../org/apache/thrift/protocol/TProtocol.as | 8 +- .../apache/thrift/transport/TMemoryBuffer.as | 79 +++++++++++++++++++ 7 files changed, 220 insertions(+), 38 deletions(-) create mode 100644 lib/as3/src/org/apache/thrift/TDeserializer.as create mode 100644 lib/as3/src/org/apache/thrift/TSerializer.as create mode 100644 lib/as3/src/org/apache/thrift/transport/TMemoryBuffer.as diff --git a/compiler/cpp/src/generate/t_as3_generator.cc b/compiler/cpp/src/generate/t_as3_generator.cc index 05514f15..29ac98ac 100644 --- a/compiler/cpp/src/generate/t_as3_generator.cc +++ b/compiler/cpp/src/generate/t_as3_generator.cc @@ -193,7 +193,8 @@ class t_as3_generator : public t_oop_generator { ttype->is_container() || ttype->is_struct() || ttype->is_xception() || - ttype->is_string(); + ttype->is_string() || + (ttype->is_base_type() && ((t_base_type*)ttype)->get_base() == t_base_type::TYPE_I64);//for using the new BigInteger library } std::string constant_name(std::string name); @@ -261,7 +262,8 @@ string t_as3_generator::as3_type_imports() { string() + "import org.apache.thrift.Set;\n" + "import flash.utils.ByteArray;\n" + - "import flash.utils.Dictionary;\n\n"; + "import flash.utils.Dictionary;\n" + + "import com.hurlant.math.BigInteger;\n\n"; } /** @@ -484,7 +486,13 @@ void t_as3_generator::print_const_value(std::ofstream& out, string name, t_type* vector::const_iterator f_iter; const map& val = value->get_map(); map::const_iterator v_iter; - out << name << ":" << type_name(type) << " = new " << type_name(type, false, true) << "();" << endl; + + out << name; + if(!defval){ + out << ":" << type_name(type); + } + out << " = new " << type_name(type, false, true) << "();" << endl; + if (!in_static) { indent(out) << "{" << endl; indent_up(); @@ -591,20 +599,20 @@ string t_as3_generator::render_const_value(ofstream& out, string name, t_type* t render << ((value->get_integer() > 0) ? "true" : "false"); break; case t_base_type::TYPE_BYTE: - render << "(byte)" << value->get_integer(); + render << "int(" << value->get_integer() << ")"; break; case t_base_type::TYPE_I16: - render << "(short)" << value->get_integer(); + render << "int(" << value->get_integer() << ")"; break; case t_base_type::TYPE_I32: render << value->get_integer(); break; case t_base_type::TYPE_I64: - render << value->get_integer() << "L"; + render << "new BigInteger(\"" << hex << value->get_integer() << dec << "\")"; break; case t_base_type::TYPE_DOUBLE: if (value->get_type() == t_const_value::CV_INTEGER) { - render << "(double)" << value->get_integer(); + render << "Number(" << value->get_integer() << ")"; } else { render << value->get_double(); } @@ -2465,7 +2473,7 @@ string t_as3_generator::base_type_name(t_base_type* type, case t_base_type::TYPE_I32: return "int"; case t_base_type::TYPE_I64: - throw "i64 is not yet supported in as3"; + return "BigInteger"; case t_base_type::TYPE_DOUBLE: return "Number"; default: @@ -2500,8 +2508,10 @@ string t_as3_generator::declare_field(t_field* tfield, bool init) { case t_base_type::TYPE_BYTE: case t_base_type::TYPE_I16: case t_base_type::TYPE_I32: + result += " = 0"; //leaving this here even though it doesn't work with BigInteger because it's never called by the generator. + break; case t_base_type::TYPE_I64: - result += " = 0"; + result += " = new BigInteger(\"0x0\")"; break; case t_base_type::TYPE_DOUBLE: result += " = (double)0"; diff --git a/lib/as3/build.xml b/lib/as3/build.xml index aa523f02..98c654a0 100644 --- a/lib/as3/build.xml +++ b/lib/as3/build.xml @@ -41,6 +41,7 @@ + @@ -81,6 +82,9 @@ + + + diff --git a/lib/as3/src/org/apache/thrift/TDeserializer.as b/lib/as3/src/org/apache/thrift/TDeserializer.as new file mode 100644 index 00000000..a31aa0b7 --- /dev/null +++ b/lib/as3/src/org/apache/thrift/TDeserializer.as @@ -0,0 +1,48 @@ +/* + * 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. + */ + +package org.apache.thrift { + import flash.utils.ByteArray; + + import org.apache.thrift.protocol.TBinaryProtocol; + import org.apache.thrift.protocol.TProtocol; + import org.apache.thrift.transport.TMemoryBuffer; + + public class TDeserializer { + private var _protocol:TProtocol; + private var _transport:TMemoryBuffer; + + public function TDeserializer() { + _transport = new TMemoryBuffer(); + _protocol = new TBinaryProtocol(_transport); + } + + /** + * Take the bytes from the ByteArray bytes and populate base with it. + */ + public function deserialize(base:TBase, bytes:ByteArray):void { + bytes.position = 0; //make sure we're at the beginning. It's a very good place to start + _transport.reset(); + _transport.write(bytes, 0, bytes.bytesAvailable); //write the ByteArray into the transport object + _transport.reset(); + base.read(_protocol); // Read the data from the transport into the TBase object via the protocol + } + + } +} diff --git a/lib/as3/src/org/apache/thrift/TSerializer.as b/lib/as3/src/org/apache/thrift/TSerializer.as new file mode 100644 index 00000000..c243d0bb --- /dev/null +++ b/lib/as3/src/org/apache/thrift/TSerializer.as @@ -0,0 +1,47 @@ +/* + * 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. + */ + +package org.apache.thrift { + import flash.utils.ByteArray; + + import org.apache.thrift.protocol.TBinaryProtocol; + import org.apache.thrift.protocol.TProtocol; + import org.apache.thrift.transport.TMemoryBuffer; + import org.apache.thrift.transport.TTransport; + + public class TSerializer { + private var _protocol:TProtocol; + private var _transport:TTransport; + + public function TSerializer() { + _transport = new TMemoryBuffer(); + _protocol = new TBinaryProtocol( _transport ); + } + + public function serialize( message:TBase ):ByteArray { + ( _transport as TMemoryBuffer ).reset(); + message.write( _protocol ); + return ( _transport as TMemoryBuffer ).getArray(); + } + + public function toString( message:TBase ):String { + return serialize( message ).toString(); + } + } +} diff --git a/lib/as3/src/org/apache/thrift/protocol/TBinaryProtocol.as b/lib/as3/src/org/apache/thrift/protocol/TBinaryProtocol.as index 44124797..f6acdb76 100644 --- a/lib/as3/src/org/apache/thrift/protocol/TBinaryProtocol.as +++ b/lib/as3/src/org/apache/thrift/protocol/TBinaryProtocol.as @@ -21,6 +21,7 @@ package org.apache.thrift.protocol { import flash.utils.ByteArray; + import com.hurlant.math.BigInteger; import org.apache.thrift.TError; import org.apache.thrift.transport.THttpClient; import org.apache.thrift.transport.TTransport; @@ -154,18 +155,20 @@ package org.apache.thrift.protocol { trans_.write(out, 0, 4); } - //private byte[] i64out = new byte[8]; - //public function writeI64(i64:Number):void { - //i64out[0] = (byte)(0xff & (i64 >> 56)); - //i64out[1] = (byte)(0xff & (i64 >> 48)); - //i64out[2] = (byte)(0xff & (i64 >> 40)); - //i64out[3] = (byte)(0xff & (i64 >> 32)); - //i64out[4] = (byte)(0xff & (i64 >> 24)); - //i64out[5] = (byte)(0xff & (i64 >> 16)); - //i64out[6] = (byte)(0xff & (i64 >> 8)); - //i64out[7] = (byte)(0xff & (i64)); - //trans_.write(i64out, 0, 8); - //} + public function writeI64(i64:BigInteger):void { + reset(out); + var ba:ByteArray = i64.toByteArray(); + ba.position = 0; + + // pad the output to make sure this 64-bit number takes + // all 64-bits, and no more since BigInteger can handle more + var difference:int = 8 - Math.min(8, ba.length); + for( ; difference > 0; difference-- ){ + out.writeByte(0); + } + out.writeBytes(ba, 0, Math.min(8, ba.bytesAvailable)); + trans_.write(out, 0, 8); + } public function writeDouble(dub:Number):void { reset(out); @@ -264,21 +267,10 @@ package org.apache.thrift.protocol { return bytes.readInt(); } - //private byte[] i64rd = new byte[8]; - /* - public function readI64() throws TException { - readAll(i64rd, 0, 8); - return - ((long)(i64rd[0] & 0xff) << 56) | - ((long)(i64rd[1] & 0xff) << 48) | - ((long)(i64rd[2] & 0xff) << 40) | - ((long)(i64rd[3] & 0xff) << 32) | - ((long)(i64rd[4] & 0xff) << 24) | - ((long)(i64rd[5] & 0xff) << 16) | - ((long)(i64rd[6] & 0xff) << 8) | - ((long)(i64rd[7] & 0xff)); + public function readI64():BigInteger { + readAll(8); + return new BigInteger(bytes); } - */ public function readDouble():Number { readAll(8); diff --git a/lib/as3/src/org/apache/thrift/protocol/TProtocol.as b/lib/as3/src/org/apache/thrift/protocol/TProtocol.as index bb9d7447..53499dc0 100644 --- a/lib/as3/src/org/apache/thrift/protocol/TProtocol.as +++ b/lib/as3/src/org/apache/thrift/protocol/TProtocol.as @@ -22,6 +22,8 @@ package org.apache.thrift.protocol { import org.apache.thrift.TError; import org.apache.thrift.transport.TTransport; + import com.hurlant.math.BigInteger; + import flash.utils.ByteArray; /** @@ -70,7 +72,7 @@ package org.apache.thrift.protocol { function writeI32(i32:int):void; - //function writeI64(i64:Number):void; + function writeI64(i64:BigInteger):void; function writeDouble(dub:Number):void; @@ -113,7 +115,7 @@ package org.apache.thrift.protocol { function readI32():int; - //function readI64():Number; + function readI64():BigInteger; function readDouble():Number; @@ -121,4 +123,4 @@ package org.apache.thrift.protocol { function readBinary():ByteArray; } -} \ No newline at end of file +} diff --git a/lib/as3/src/org/apache/thrift/transport/TMemoryBuffer.as b/lib/as3/src/org/apache/thrift/transport/TMemoryBuffer.as new file mode 100644 index 00000000..8338e134 --- /dev/null +++ b/lib/as3/src/org/apache/thrift/transport/TMemoryBuffer.as @@ -0,0 +1,79 @@ +/* + * 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. + */ + +package org.apache.thrift.transport { + import flash.utils.ByteArray; + + public class TMemoryBuffer extends TTransport { + private var _barray:ByteArray; + + public function TMemoryBuffer() { + super(); + _barray = new ByteArray(); + } + + /** + * @param buf the ByteArray to read into + * @param buf the off to start writing + * @param len the number of bytes to write into buf + */ + override public function read(buf:ByteArray, off:int, len:int):int { + buf.position = 0; + + var amtToRead:int = Math.min(len, _barray.bytesAvailable); + + if (amtToRead > 0) { + // offset, in writeBytes refers to the position of the array to read from + buf.writeBytes( _barray, _barray.position, amtToRead ); + _barray.position += amtToRead; //we need to remember where we are in order to read the next thing + } + return amtToRead; + } + + /** + * @param buf the ByteArray to read from + * @param off the position to start reading from + * @param len the number of bytes to read + */ + override public function write(buf:ByteArray, off:int, len:int):void { + buf.position = off; + // offset in readBytes() refers to where to start _writing_ in the ByteArray you pass in. + buf.readBytes(_barray, _barray.length, len); + _barray.position = _barray.length; //put the position at the end of the used bytes in order to allow appending + } + + override public function flush(callback:Function=null):void { + if ( callback != null ){ + callback( null ); + } + reset(); + } + + public function getArray():ByteArray { + var ret:ByteArray = new ByteArray(); + ret.writeBytes(_barray); //copy _barray + ret.position = 0; + return ret; + } + + public function reset():void { + _barray.position = 0; + } + } +} -- 2.17.1