[erlang-questions] Protocol Mapping

Ulf Wiger ulf@REDACTED
Wed Dec 19 17:36:27 CET 2012


For fun, I made a version with parse_trans which generates a module:

-module(mapping).

-compile(export_all).
-include_lib("parse_trans/include/codegen.hrl").

-define(MAP, [
	{hello, 100},
	{help, 101},
	{done, 102}
]).

codegen(Mod) ->
    codegen:gen_module(
      {'$var',Mod}, [{encode,1},
                              {decode,1}],
      [{encode, [fun({'$var',X}) ->
                               {'$var', Y}
                         end || {X, Y} <- ?MAP]},
       {decode, [fun({'$var', Y}) ->
                               {'$var', X}
                         end || {X, Y} <- ?MAP]}]).


Eshell V5.9.2  (abort with ^G)
1> c(mapping).
{ok,mapping}
2> mapping:codegen(x).
[{attribute,1,module,x},
 {attribute,37,export,[{encode,1},{decode,1}]},
 {function,39,encode,1,
           [{clause,39,[{atom,39,hello}],[],[{integer,40,100}]},
            {clause,39,[{atom,39,help}],[],[{integer,40,101}]},
            {clause,39,[{atom,39,done}],[],[{integer,40,102}]}]},
 {function,42,decode,1,
           [{clause,42,[{integer,42,100}],[],[{atom,43,hello}]},
            {clause,42,[{integer,42,101}],[],[{atom,43,help}]},
            {clause,42,[{integer,42,102}],[],[{atom,43,done}]}]}]
3> compile:forms(v(2),[]).
{ok,x,
    <<70,79,82,49,0,0,2,48,66,69,65,77,65,116,111,109,0,0,0,
      71,0,0,0,9,1,120,...>>}
4> code:load_binary(x,"/tmp/x.beam",element(3,v(3))).
{module,x}
5> x:encode(hello).
100
6> x:decode(100).                                    
hello

The codegen:gen_module/3 pseudo-function is documented here:

https://github.com/esl/parse_trans/blob/master/doc/parse_trans_codegen.md#gen_module3

BR,
Ulf W

On 19 Dec 2012, at 14:05, Attila Rajmund Nohl wrote:

> Hello!
> 
> You could try to generate the code that implements the first pattern.
> 
> 2012/12/19 Steve Davis <steven.charles.davis@REDACTED>:
>> Hi,
>> 
>> I'm frequently facing situations with binary protocol
>> translations/transforms where I need to map binary codes to e.g. atoms and
>> back.
>> 
>> This is of course "easy" in Erlang, but suffers some inconveniences. I've
>> attached a code snippet distilled down to the simplest case to explain my
>> issue.
>> 
>> I'm sure the first codec pattern below is familiar, and for sure is
>> efficient.
>> However, there are multiple places where updating is required to add new
>> message types.
>> 
>> The second pattern is much less usual, but handy as one line achieves the
>> addition of a new message type.
>> It helps particularly when there is more than one pairing involved (e.g.
>> {atom, code, status_message}).
>> 
>> For sure this cannot be something nobody has seen/thought about. I'm
>> wondering if anyone has comment on this, and maybe suggestions for
>> approaches that I haven't thought of.
>> 
>> /s
>> -------
>> -module(mapping).
>> 
>> -compile(export_all).
>> 
>> %% traditional
>> 
>> -define(HELLO, 100).
>> -define(HELP, 101).
>> -define(DONE, 102).
>> 
>> encode(hello) -> ?HELLO;
>> encode(help) -> ?HELP;
>> encode(done) -> ?DONE.
>> 
>> decode(?HELLO) -> hello;
>> decode(?HELP) -> help;
>> decode(?DONE) -> done.
>> 
>> %% alternative
>> 
>> -define(MAP, [
>> {hello, 100},
>> {help, 101},
>> {done, 102}
>> ]).
>> 
>> encode0(X) ->
>> {X, Y} = lists:keyfind(X, 1, ?MAP),
>> Y.
>> 
>> decode0(X) ->
>> {Y, X} = lists:keyfind(X, 2, ?MAP),
>> Y.
>> 
>> 
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
http://feuerlabs.com






More information about the erlang-questions mailing list