[thrift] preliminary Erlang support (initial import)
Summary:
* missing {list,map,set}s, inheritance is spotty
* loose source code, plus everything is one process (application / gen_server behavior is forthcoming)
* codegen is a mess, need t_fp_generator
Test Plan:
* codegen invoked without -erl generates identical code for test/
* calculatorHandler plus 'thrift -erl -r tutorial.thrift' more or less works
Revert Plan: ok
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665146 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/erl/src-loose/protocol/tBinaryProtocol.erl b/lib/erl/src-loose/protocol/tBinaryProtocol.erl
new file mode 100644
index 0000000..b82af73
--- /dev/null
+++ b/lib/erl/src-loose/protocol/tBinaryProtocol.erl
@@ -0,0 +1,232 @@
+-module(tBinaryProtocol).
+
+-include("thrift/thrift.hrl").
+-include("thrift/protocol/tBinaryProtocol.hrl").
+-include("thrift/protocol/tProtocolException.hrl").
+
+-export([
+ new/1,
+ trans/1,
+ skip/2,
+
+ writeMessageBegin/4, writeMessageEnd/1,
+ writeStructBegin/2, writeStructEnd/1,
+ writeFieldBegin/4, writeFieldEnd/1, writeFieldStop/1,
+ writeMapBegin/4, writeMapEnd/1,
+ writeListBegin/3, writeListEnd/1,
+ writeSetBegin/3, writeSetEnd/1,
+
+ writeBool/2, writeByte/2, writeI16/2, writeI32/2,
+ writeI64/2, writeDouble/2, writeString/2,
+
+ readMessageBegin/1, readMessageEnd/1,
+ readStructBegin/1, readStructEnd/1,
+ readFieldBegin/1, readFieldEnd/1,
+ readMapBegin/1, readMapEnd/1,
+ readListBegin/1, readListEnd/1,
+ readSetBegin/1, readSetEnd/1,
+
+ readBool/1, readByte/1, readI16/1, readI32/1,
+ readI64/1, readDouble/1, readString/1
+]).
+
+new(Trans) ->
+ #tBinaryProtocol{trans=Trans}.
+
+trans(This) -> % accessor
+ ?ATTR(trans).
+
+skip(This, Type) ->
+ tProtocol:skip(This, Type).
+
+writeMessageBegin(This, Name, Type, Seqid) ->
+ writeI32(This, ?VERSION_1 bor Type),
+ writeString(This, Name),
+ writeI32(This, Seqid).
+
+writeMessageEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+writeStructBegin(This, Name) ->
+ This, Name, % suppress unused warnings
+ ok.
+
+writeStructEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+writeFieldBegin(This, Name, Type, Id) ->
+ Name,
+ writeByte(This, Type),
+ writeI16(This, Id).
+
+writeFieldEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+writeFieldStop(This) ->
+ writeByte(This, ?tType_STOP).
+
+writeMapBegin(This, Ktype, Vtype, Size) ->
+ writeByte(This, Ktype),
+ writeByte(This, Vtype),
+ writeI32(This, Size).
+
+writeMapEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+writeListBegin(This, Etype, Size) ->
+ writeByte(This, Etype),
+ writeI32(This, Size).
+
+writeListEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+writeSetBegin(This, Etype, Size) ->
+ writeByte(This, Etype),
+ writeI32(This, Size).
+
+writeSetEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+%
+
+writeBool(This, Bool) ->
+ if Bool -> % true
+ writeByte(This, 1);
+ true -> % false
+ writeByte(This, 0)
+ end.
+
+writeByte(This, Byte) ->
+ Trans = This#tBinaryProtocol.trans,
+ ?M1(Trans, write, binary_to_list(<<Byte:8/big>>)).
+
+writeI16(This, I16) ->
+ Trans = This#tBinaryProtocol.trans,
+ ?M1(Trans, write, binary_to_list(<<I16:16/big>>)).
+
+writeI32(This, I32) ->
+ Trans = This#tBinaryProtocol.trans,
+ ?M1(Trans, write, binary_to_list(<<I32:32/big>>)).
+
+writeI64(This, I64) ->
+ Trans = This#tBinaryProtocol.trans,
+ ?M1(Trans, write, binary_to_list(<<I64:64/big>>)).
+
+writeDouble(This, Double) ->
+ Trans = This#tBinaryProtocol.trans,
+ ?M1(Trans, write, binary_to_list(<<Double:64/big>>)).
+
+writeString(This, Str) ->
+ Trans = This#tBinaryProtocol.trans,
+ writeI32(This, length(Str)),
+ ?M1(Trans, write, Str).
+
+%
+
+readMessageBegin(This) ->
+ Version = readI32(This),
+ if
+ (Version band ?VERSION_MASK) /= ?VERSION_1 ->
+ throw(tProtocolException:new(?tProtocolException_BAD_VERSION,
+ "Missing version identifier"));
+ true -> ok
+ end,
+ Type = Version band 16#000000ff,
+ Name = readString(This),
+ Seqid = readI32(This),
+ { Name, Type, Seqid }.
+
+readMessageEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+readStructBegin(This) ->
+ This, % suppress unused warnings
+ ok.
+
+readStructEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+readFieldBegin(This) ->
+ Type = readByte(This),
+ if Type == ?tType_STOP ->
+ { nil, Type, 0 }; % WATCH
+ true ->
+ Id = readI16(This),
+ { nil, Type, Id }
+ end.
+
+readFieldEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+readMapBegin(This) ->
+ Ktype = readByte(This),
+ Vtype = readByte(This),
+ Size = readI32(This),
+ { Ktype, Vtype, Size }.
+
+readMapEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+readListBegin(This) ->
+ Etype = readByte(This),
+ Size = readI32(This),
+ { Etype, Size }.
+
+readListEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+readSetBegin(This) ->
+ Etype = readByte(This),
+ Size = readI32(This),
+ { Etype, Size }.
+
+readSetEnd(This) ->
+ This, % suppress unused warnings
+ ok.
+
+% WATCH everything ... who knows what of this will work
+
+readBool(This) ->
+ Byte = readByte(This),
+ (Byte /= 0).
+
+readByte(This) ->
+ Trans = This#tBinaryProtocol.trans,
+ <<Val:8/integer-signed-big, _/binary>> = ?M1(Trans, readAll, 1),
+ Val.
+
+readI16(This) ->
+ Trans = This#tBinaryProtocol.trans,
+ <<Val:16/integer-signed-big, _/binary>> = ?M1(Trans, readAll, 2),
+ Val.
+
+readI32(This) ->
+ Trans = This#tBinaryProtocol.trans,
+ <<Val:32/integer-signed-big, _/binary>> = ?M1(Trans, readAll, 4),
+ Val.
+
+readI64(This) ->
+ Trans = This#tBinaryProtocol.trans,
+ <<Val:64/integer-signed-big, _/binary>> = ?M1(Trans, readAll, 8),
+ Val.
+
+readDouble(This) ->
+ Trans = This#tBinaryProtocol.trans,
+ <<Val:64/float-signed-big, _/binary>> = ?M1(Trans, readAll, 8),
+ Val.
+
+readString(This) ->
+ Trans = This#tBinaryProtocol.trans,
+ Sz = readI32(This),
+ binary_to_list(?M1(Trans, readAll, Sz)).
diff --git a/lib/erl/src-loose/protocol/tBinaryProtocol.hrl b/lib/erl/src-loose/protocol/tBinaryProtocol.hrl
new file mode 100644
index 0000000..cfd4836
--- /dev/null
+++ b/lib/erl/src-loose/protocol/tBinaryProtocol.hrl
@@ -0,0 +1,4 @@
+-define(VERSION_MASK, 16#FFFF0000).
+-define(VERSION_1, 16#80010000).
+-record(tBinaryProtocol, {trans}).
+
diff --git a/lib/erl/src-loose/protocol/tProtocol.erl b/lib/erl/src-loose/protocol/tProtocol.erl
new file mode 100644
index 0000000..a36ca11
--- /dev/null
+++ b/lib/erl/src-loose/protocol/tProtocol.erl
@@ -0,0 +1,69 @@
+-module(tProtocol).
+
+-include("thrift/thrift.hrl").
+-include("thrift/protocol/tProtocol.hrl").
+
+-export([new/1, skip/2]).
+
+skip_struct_loop(This) ->
+ { Name, Type, Id } = ?M0(This, readFieldBegin),
+ Name, Id, % suppress unused warnings
+ if
+ Type == ?tType_STOP ->
+ ok;
+ true ->
+ skip(This, Type),
+ ?M0(This, readFieldEnd),
+
+ %% this is here in original tprotocol.rb, but i think it's a bug
+ % ?M0(This, readStructEnd),
+ skip_struct_loop(This)
+ end.
+
+skip_map_repeat(This, Ktype, Vtype, Times) ->
+ skip(This, Ktype),
+ skip(This, Vtype),
+ skip_map_repeat(This, Ktype, Vtype, Times-1).
+
+skip_set_repeat(This, Etype, Times) ->
+ skip(This, Etype),
+ skip_set_repeat(This, Etype, Times-1).
+
+new(Trans) ->
+ #tProtocol{trans=Trans}.
+
+skip(This, Type) ->
+ case Type of
+ ?tType_STOP -> nil; % WATCH
+ ?tType_BOOL -> ?M0(This, readBool);
+ ?tType_BYTE -> ?M0(This, readByte);
+ ?tType_I16 -> ?M0(This, readI16);
+ ?tType_I32 -> ?M0(This, readI32);
+ ?tType_I64 -> ?M0(This, readI64);
+ ?tType_DOUBLE -> ?M0(This, readDouble);
+ ?tType_STRING -> ?M0(This, readString);
+
+ ?tType_STRUCT ->
+ ?M0(This, readStructBegin),
+ skip_struct_loop(This),
+
+ %% this isn't here in the original tprotocol.rb, but i think it's a bug
+ ?M0(This, readStructEnd);
+
+ ?tType_MAP ->
+ {Ktype, Vtype, Size} = ?M0(This, readMapBegin),
+ skip_map_repeat(This, Ktype, Vtype, Size),
+ ?M0(This, readMapEnd);
+
+ ?tType_SET ->
+ {Etype, Size} = ?M0(This, readSetBegin),
+ skip_set_repeat(This, Etype, Size),
+ ?M0(This, readSetEnd);
+
+ ?tType_LIST ->
+ {Etype, Size} = ?M0(This, readListBegin),
+ skip_set_repeat(This, Etype, Size), % [sic] skipping same as for SET
+ ?M0(This, readListEnd)
+ end.
+
+
diff --git a/lib/erl/src-loose/protocol/tProtocol.hrl b/lib/erl/src-loose/protocol/tProtocol.hrl
new file mode 100644
index 0000000..4385124
--- /dev/null
+++ b/lib/erl/src-loose/protocol/tProtocol.hrl
@@ -0,0 +1 @@
+-record(tProtocol, {trans}).
diff --git a/lib/erl/src-loose/protocol/tProtocolException.erl b/lib/erl/src-loose/protocol/tProtocolException.erl
new file mode 100644
index 0000000..b9aa48a
--- /dev/null
+++ b/lib/erl/src-loose/protocol/tProtocolException.erl
@@ -0,0 +1,9 @@
+-module(tProtocolException).
+-include("tProtocolException.hrl").
+-export([new/2, new/1, new/0]).
+
+new(Type, Message) ->
+ #tProtocolException{type=Type, message=Message}.
+
+new(Type) -> new(Type, nil).
+new() -> new(?tProtocolException_UNKNOWN, nil).
diff --git a/lib/erl/src-loose/protocol/tProtocolException.hrl b/lib/erl/src-loose/protocol/tProtocolException.hrl
new file mode 100644
index 0000000..96bf3ac
--- /dev/null
+++ b/lib/erl/src-loose/protocol/tProtocolException.hrl
@@ -0,0 +1,8 @@
+-record(tProtocolException, {message, type}).
+
+-define(tProtocolException_UNKNOWN, 0).
+-define(tProtocolException_INVALID_DATA, 1).
+-define(tProtocolException_NEGATIVE_SIZE, 2).
+-define(tProtocolException_SIZE_LIMIT, 3).
+-define(tProtocolException_BAD_VERSION, 4).
+