%%% Copyright (c) 2015, NORDUnet A/S. %%% See LICENSE for licensing information. -module(tlv). -export([encode/2, decode/1, encodelist/1, decodelist/1]). -spec encode(binary(), binary()) -> binary(). encode(Type, Value) when byte_size(Type) == 4 -> Len = byte_size(Value) + 8, <>. -spec decode(binary()) -> {binary(), binary(), binary()}. decode(Data) -> <> = Data, Length = TotalLength - 8, <> = Rest1, <> = Rest2, {Type, Value, Rest3}. %% Convenience functions -spec encodelist([{binary(), binary()}]) -> binary(). encodelist(List) -> list_to_binary([encode(Type, Value) || {Type, Value} <- List]). -spec decodelist(binary()) -> [{binary(), binary()}]. decodelist(Data) -> decodelist(Data, []). decodelist(<<>>, Acc) -> lists:reverse(Acc); decodelist(Data, Acc) -> {Type, Value, Rest} = decode(Data), decodelist(Rest, [{Type, Value} | Acc]). %%%%%%%%%%%%%%%%%%%% -include_lib("eunit/include/eunit.hrl"). -define(TESTDATA1, {<<"DATA">>, <<"some data">>}). -define(TESTDATA2, {<<"DAT2">>, <<"some other data">>}). the_test_() -> {setup, fun() -> [?TESTDATA1, ?TESTDATA2] end, fun(_) -> ok end, fun(TestVectors) -> [?_assertEqual({T, V, <<>>}, decode(encode(T, V))) || {T, V} <- TestVectors] end}. -define(LISTTESTDATA, [?TESTDATA1, ?TESTDATA2]). list_test() -> Encoded = encodelist(?LISTTESTDATA), ?assertEqual(decodelist(Encoded), ?LISTTESTDATA), {T1, V1, Rest} = decode(Encoded), ?assertEqual({T1, V1}, ?TESTDATA1), {T2, V2, <<>>} = decode(Rest), ?assertEqual({T2, V2}, ?TESTDATA2).