diff --git a/erlang/OMakefile b/erlang/OMakefile
index 34c590f..89b1c63 100644
--- a/erlang/OMakefile
+++ b/erlang/OMakefile
@@ -30,13 +30,16 @@
# If so, define the subdirectory targets and uncomment this section.
#
-.DEFAULT: msgpack.beam
+.DEFAULT: msgpack.beam msgpack.html
msgpack.beam: msgpack.erl
erlc $<
+msgpack.html: msgpack.erl
+ erl -noshell -run edoc_run file $<
+
test: msgpack.beam
erl -noshell -s msgpack test -s init stop
clean:
- -rm *.beam
+ -rm -f *.beam *.html
diff --git a/erlang/msgpack.erl b/erlang/msgpack.erl
index f23ac87..aa9851d 100644
--- a/erlang/msgpack.erl
+++ b/erlang/msgpack.erl
@@ -15,26 +15,47 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
+
+%% @doc MessagePack codec for Erlang.
+%%
+%% APIs are almost compatible with C API
+%% except for buffering functions (both copying and zero-copying), which are unavailable.
+%%
+%%
+%% Equivalence between Erlang and Msgpack type :
+%% | erlang | msgpack |
+%% | integer() | pos_fixnum/neg_fixnum/uint8/uint16/uint32/uint64/int8/int16/int32/int64 |
+%% | float() | float/double |
+%% | nil | nil |
+%% | boolean() | boolean |
+%% | binary() | fix_raw/raw16/raw32 |
+%% | list() | fix_array/array16/array32 |
+%% | {proplist()} | fix_map/map16/map32 |
+%%
+%% @end
+
-module(msgpack).
-author('kuenishi+msgpack@gmail.com').
-%% tuples, atoms are not supported. lists, integers, double, and so on.
-%% see http://msgpack.sourceforge.jp/spec for supported formats.
-%% APIs are almost compatible with C API (http://msgpack.sourceforge.jp/c:doc)
-%% except buffering functions (both copying and zero-copying).
-export([pack/1, unpack/1, unpack_all/1]).
-% compile:
-% erl> c(msgpack).
-% erl> S = .
-% erl> {S, <<>>} = msgpack:unpack( msgpack:pack(S) ).
--type reason() :: {badarg,term()} | incomplete.
+% @type msgpack_term() = [msgpack_term()]
+% | {[{msgpack_term(),msgpack_term()}]}
+% | integer() | float() | binary().
+% Erlang representation of msgpack data.
-type msgpack_term() :: [msgpack_term()]
| {[{msgpack_term(),msgpack_term()}]}
| integer() | float() | binary().
-% ===== external APIs ===== %
--spec pack(Term::msgpack_term()) -> binary() | {error, reason()}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% external APIs
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% @doc Encode an erlang term into an msgpack binary.
+% Returns {error, {badarg, term()}} if the input is illegal.
+% @spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}
+-spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}.
pack(Term)->
try
pack_(Term)
@@ -43,11 +64,12 @@ pack(Term)->
{error, Exception}
end.
-% unpacking.
-% if failed in decoding and not end, get more data
-% and feed more Bin into this function.
-% TODO: error case for imcomplete format when short for any type formats.
--spec unpack( Bin::binary() )-> {msgpack_term(), binary()} | {error, reason()}.
+% @doc Decode an msgpack binary into an erlang term.
+% It only decodes the first msgpack packet contained in the binary; the rest is returned as is.
+% Returns {error, {badarg, term()}} if the input is corrupted.
+% Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again).
+% @spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}
+-spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}.
unpack(Bin) when is_binary(Bin) ->
try
unpack_(Bin)
@@ -58,7 +80,7 @@ unpack(Bin) when is_binary(Bin) ->
unpack(Other) ->
{error, {badarg, Other}}.
--spec unpack_all( binary() ) -> [msgpack_term()].
+-spec unpack_all(binary()) -> [msgpack_term()].
unpack_all(Data)->
case unpack(Data) of
{ Term, Binary } when bit_size(Binary) =:= 0 ->
@@ -68,7 +90,9 @@ unpack_all(Data)->
end.
-% ===== internal APIs ===== %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% internal APIs
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pack them all
-spec pack_(msgpack_term()) -> binary() | no_return().
@@ -95,6 +119,7 @@ pack_(Map) when is_tuple(Map), element(1,Map)=:=dict ->
pack_(Other) ->
throw({error, {badarg, Other}}).
+
-spec pack_uint_(non_neg_integer()) -> binary().
% positive fixnum
pack_uint_(N) when N < 128 ->
@@ -129,6 +154,7 @@ pack_int_(N) when N > -16#FFFFFFFF ->
pack_int_(N) ->
<< 16#D3:8, N:64/big-signed-integer-unit:1 >>.
+
-spec pack_double(float()) -> binary().
% float : erlang's float is always IEEE 754 64bit format.
% pack_float(F) when is_float(F)->
@@ -138,6 +164,7 @@ pack_int_(N) ->
pack_double(F) ->
<< 16#CB:8, F:64/big-float-unit:1 >>.
+
-spec pack_raw(binary()) -> binary().
% raw bytes
pack_raw(Bin) ->
@@ -150,6 +177,7 @@ pack_raw(Bin) ->
<< 16#DB:8, Len:32/big-unsigned-integer-unit:1, Bin/binary >>
end.
+
-spec pack_array([msgpack_term()]) -> binary() | no_return().
% list
pack_array(L) ->
@@ -173,6 +201,7 @@ unpack_array_(Bin, Len, Acc) ->
{Term, Rest} = unpack_(Bin),
unpack_array_(Rest, Len-1, [Term|Acc]).
+
-spec pack_map(M::[{msgpack_term(),msgpack_term()}]) -> binary() | no_return().
pack_map(M)->
case length(M) of
@@ -245,7 +274,10 @@ unpack_(Bin) ->
throw(incomplete)
end.
-% ===== test codes ===== %
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% unit tests
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-include_lib("eunit/include/eunit.hrl").
-ifdef(EUNIT).