diff --git a/Makefile b/Makefile
deleted file mode 100644
index e9cb7e1..0000000
--- a/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-REBAR=rebar
-
-all: compile
-
-compile:
- $(REBAR) compile
-
-clean:
- $(REBAR) clean
-
-test: clean compile
- $(REBAR) eunit skip_deps=true
-
-docs:
- $(REBAR) doc skip_deps=true
-
diff --git a/README.md b/README.md
deleted file mode 100644
index f4ad290..0000000
--- a/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-binpp - Erlang Binary Pretty Printer
-===================================
-
-Example usage:
-
- 1> Bin.
- <<12,242,207,49,82,69,45,130,212,69,80,88,8,81,23,36,86,7,
- 68,19,133,97,51,216,56,145,88,8,81,...>>
- 2> binpp:pprint(Bin).
- 0C F2 CF 31 52 45 2D 82 D4 45 50 58 08 51 17 24 .òÏ1RE-ÔEPX.Q.$
- 56 07 44 13 85 61 33 D8 38 91 58 08 51 17 24 56 V.D.
a3Ø8X.Q.$V
- 0A 14 20 4E 24 16 09 60 F4 0A 15 11 01 30 13 89 .. N$..`ô....0.
- 05 81 0F 09 15 C5 61 33 D8 54 91 52 5D 81 17 24 ....Åa3ØTR].$
- 11 14 60 23 D1 3D 55 80 ..`#Ñ=U
- ok
-
-Binpp will use io:format to output the formatted binary by default, however
-there are options making pprint functions return formatted data instead
-of performing direct IO write:
-
- 1> Bin2 = <<"foo bar baz">>.
- <<"foo bar baz">>
- 2> binpp:pprint(Bin2, [{return, iolist}]).
- [["66 6F 6F 20 62 61 72 20 62 61 7A ",32,
- "foo bar baz","\n"]]
- 3> binpp:pprint(Bin2, [{return, binary}]).
- <<"66 6F 6F 20 62 61 72 20 62 61 7A foo bar baz\n">>
-
-You may use a custom printer function as well:
-
- 4> binpp:pprint(Bin2, [{printer, fun(O) -> io:format("~s~n", [O]) end}]).
- 66 6F 6F 20 62 61 72 20 62 61 7A foo bar baz
-
- ok
-
-An additional API is provided for printing binary fragments:
-
- 5> binpp:pprint(Bin2, {0, 3}, []).
- 66 6F 6F foo
-
-Also, binary byte-to-byte comparsion:
-
- 6> binpp:compare(<<1,2,1024:512,3,4>>, <<1,3,1024:512,5,6>>).
- -- 02 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
- -- -- 03 04 -- -- 05 06
- ok
-
-Plus a handy little helper:
-
- 7> binpp:compare(<<1,2,255,3,1024:512>>, binpp:from_str("01 02 FF CC")).
- -- -- -- 03 00 00 00 00 00 00 00 00 00 00 00 00 -- -- -- CC ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
- 00 00 04 00 ?? ?? ?? ??
- ok
-
-That's all folks!
diff --git a/doc/binpp.html b/doc/binpp.html
new file mode 100644
index 0000000..0560a85
--- /dev/null
+++ b/doc/binpp.html
@@ -0,0 +1,92 @@
+
+
+
+
+Module binpp
+
+
+
+
+
+
+Module binpp
+Pretty printer for Erlang binaries.
+
+
+Pretty printer for Erlang binaries.
+
+
+
+
+abstract datatype : opts()
+
+
+
+compare/2 Pretty print byte-to-byte comparsion of two binaries to stdout.
+convert/1 Convert binary to hex string.
+convert/2 Convert binary to hex string or binary (base-2) string.
+from_str/1 Construct binary from hex string.
+pprint/1 Pretty print a binary to stdout using io:format/2
+ Note: io:format/2 is a blocking call.
+pprint/2 Print a binary using custom function or return the formatted result.
+pprint/3 Pretty print a slice of binary.
+
+
+
+
+
+
+
compare(Bin1::binary() | bitstring(), Bin2::binary() | bitstring()) -> ok
+
Pretty print byte-to-byte comparsion of two binaries to stdout.
+
+
+
+
convert(Bin::binary() | bitstring()) -> {ok, list()}
+
Convert binary to hex string.
+
+
+
+
convert(Bin::binary() | bitstring(), X2::hex | bin) -> {ok, list()}
+
Convert binary to hex string or binary (base-2) string.
+
+
+
+
from_str(Str::string()) -> binary()
+
Construct binary from hex string.
+ Hex string octets can be optionally separated with spaces.
+ Valid hex strings:
+
+ "AA BB FF 01"
+ "AABBFF01"
+
+
+
+
+
pprint(Bin::binary() | bitstring()) -> ok
+
Pretty print a binary to stdout using io:format/2
+ Note: io:format/2 is a blocking call.
+
+
+
+
pprint(Bin::binary() | bitstring(), Opts::opts() ) -> ok | any()
+
Print a binary using custom function or return the formatted result.
+ Valid options are:
+
+ {return, binary}
+ {return, iolist}
+ {printer, CustomFunction}
+
+
+ Custom functions should be of arity 1, accepting the prettified result as
+ an iolist() input. Returned value can be any() .
+
+
+
+
pprint(Bin::binary() | bitstring(), X2::{non_neg_integer(), non_neg_integer()}, Opts::opts() ) -> ok | any()
+
Pretty print a slice of binary.
+
+
+
+Generated by EDoc, Oct 30 2012, 14:26:44.
+
+
diff --git a/doc/edoc-info b/doc/edoc-info
new file mode 100644
index 0000000..40806c7
--- /dev/null
+++ b/doc/edoc-info
@@ -0,0 +1,3 @@
+{application,binpp}.
+{packages,[]}.
+{modules,[binpp]}.
diff --git a/doc/erlang.png b/doc/erlang.png
new file mode 100644
index 0000000..987a618
Binary files /dev/null and b/doc/erlang.png differ
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..9e425e6
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,17 @@
+
+
+
+The binpp application
+
+
+
+
+
+
+This page uses frames
+Your browser does not accept frames.
+ You should go to the non-frame version instead.
+
+
+
+
\ No newline at end of file
diff --git a/doc/modules-frame.html b/doc/modules-frame.html
new file mode 100644
index 0000000..85d8792
--- /dev/null
+++ b/doc/modules-frame.html
@@ -0,0 +1,12 @@
+
+
+
+The binpp application
+
+
+
+Modules
+
+
+
\ No newline at end of file
diff --git a/doc/overview-summary.html b/doc/overview-summary.html
new file mode 100644
index 0000000..73d378a
--- /dev/null
+++ b/doc/overview-summary.html
@@ -0,0 +1,121 @@
+
+
+
+
+binpp - Erlang Binary Pretty Printer
+
+
+
+
+binpp - Erlang Binary Pretty Printer
+Copyright 2012 (c) Adam Rutkowski <hq@mtod.org>
+Version: 1.1
+
+This lilbrary provides additional utility functions for working with Erlang
+binary() and bitstring() types.
+
+You might find it useful if you are going to:
+
+ Implement or debug arbitrary protocols
+ Log/dump binary data
+ Learn how Erlang binaries work
+
+
+Installation
+
+
+
+binpp comes with a Makefile that requires rebar build tool.
+
+If you don't have rebar installed, you may get it from Rebar Github repository
+
+
+
+Download the sources from binpp Github repository .
+
+
+ To build the library run make .
+ To run the tests run make test .
+ To generate documentation run make docs .
+
+
+
+
+
+
+Example usage
+
+ 1> Bin.
+ <<12,242,207,49,82,69,45,130,212,69,80,88,8,81,23,36,86,7,
+ 68,19,133,97,51,216,56,145,88,8,81,...>>
+ 2> binpp:pprint(Bin).
+ 0C F2 CF 31 52 45 2D 82 D4 45 50 58 08 51 17 24 .òÏ1RE-ÔEPX.Q.$
+ 56 07 44 13 85 61 33 D8 38 91 58 08 51 17 24 56 V.D.
a3Ø8X.Q.$V
+ 0A 14 20 4E 24 16 09 60 F4 0A 15 11 01 30 13 89 .. N$..`ô....0.
+ 05 81 0F 09 15 C5 61 33 D8 54 91 52 5D 81 17 24 ....Åa3ØTR].$
+ 11 14 60 23 D1 3D 55 80 ..`#Ñ=U
+ ok
+
+Binpp will use io:format to output the formatted binary by default, however
+there are options making pprint functions return formatted data instead
+of performing direct IO write:
+
+ 1> Bin2 = <<"foo bar baz">>.
+ <<"foo bar baz">>
+ 2> binpp:pprint(Bin2, [{return, iolist}]).
+ [["66 6F 6F 20 62 61 72 20 62 61 7A ",32,
+ "foo bar baz","\n"]]
+ 3> binpp:pprint(Bin2, [{return, binary}]).
+ <<"66 6F 6F 20 62 61 72 20 62 61 7A foo bar baz\n">>
+
+You may use a custom printer function as well:
+
+ 4> binpp:pprint(Bin2, [{printer, fun(O) -> io:format("~s~n", [O]) end}]).
+ 66 6F 6F 20 62 61 72 20 62 61 7A foo bar baz
+
+ ok
+
+An additional API is provided for printing binary fragments:
+
+ 5> binpp:pprint(Bin2, {0, 3}, []).
+ 66 6F 6F foo
+
+Also, binary byte-to-byte comparsion:
+
+ 6> binpp:compare(<<1,2,1024:512,3,4>>, <<1,3,1024:512,5,6>>).
+ -- 02 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 03 -- -- -- -- -- -- -- -- -- -- -- -- -- --
+ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+ -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+ -- -- 03 04 -- -- 05 06
+ ok
+
+Plus a handy little helper:
+
+ 7> binpp:compare(<<1,2,255,3,1024:512>>, binpp:from_str("01 02 FF CC")).
+ -- -- -- 03 00 00 00 00 00 00 00 00 00 00 00 00 -- -- -- CC ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
+ 00 00 04 00 ?? ?? ?? ??
+ ok
+
+That's all folks!
+
+Get involved
+
+Bug reports can be submitted to: binpp issues @ Github .
+
+Patches and feature requests are always welcome!
+
+Module index:
+
+ binpp
+ Erlang Binary Pretty Printer
+
+
+
+
+Generated by EDoc, Oct 30 2012, 14:26:44.
+
+
diff --git a/doc/packages-frame.html b/doc/packages-frame.html
new file mode 100644
index 0000000..0b3f6c2
--- /dev/null
+++ b/doc/packages-frame.html
@@ -0,0 +1,11 @@
+
+
+
+The binpp application
+
+
+
+Packages
+
+
+
\ No newline at end of file
diff --git a/doc/stylesheet.css b/doc/stylesheet.css
new file mode 100644
index 0000000..e426a90
--- /dev/null
+++ b/doc/stylesheet.css
@@ -0,0 +1,55 @@
+/* standard EDoc style sheet */
+body {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ margin-left: .25in;
+ margin-right: .2in;
+ margin-top: 0.2in;
+ margin-bottom: 0.2in;
+ color: #000000;
+ background-color: #ffffff;
+}
+h1,h2 {
+ margin-left: -0.2in;
+}
+div.navbar {
+ background-color: #add8e6;
+ padding: 0.2em;
+}
+h2.indextitle {
+ padding: 0.4em;
+ background-color: #add8e6;
+}
+h3.function,h3.typedecl {
+ background-color: #add8e6;
+ padding-left: 1em;
+}
+div.spec {
+ margin-left: 2em;
+ background-color: #eeeeee;
+}
+a.module,a.package {
+ text-decoration:none
+}
+a.module:hover,a.package:hover {
+ background-color: #eeeeee;
+}
+ul.definitions {
+ list-style-type: none;
+}
+ul.index {
+ list-style-type: none;
+ background-color: #eeeeee;
+}
+
+/*
+ * Minor style tweaks
+ */
+ul {
+ list-style-type: square;
+}
+table {
+ border-collapse: collapse;
+}
+td {
+ padding: 3
+}
diff --git a/rebar.config b/rebar.config
deleted file mode 100644
index 0428f27..0000000
--- a/rebar.config
+++ /dev/null
@@ -1,4 +0,0 @@
-{cover_enabled, true}.
-{cover_print_enabled, true}.
-{eunit_opts, [verbose,
- {report, {eunit_surefire, [{dir, "."}]}}]}.
diff --git a/src/binpp.app.src b/src/binpp.app.src
deleted file mode 100644
index d919bb3..0000000
--- a/src/binpp.app.src
+++ /dev/null
@@ -1,6 +0,0 @@
-{application, binpp, [
- {description, "Erlang Binary Pretty Printer"},
- {vsn, "1.1"},
- {registered, []},
- {applications, [kernel, stdlib]}
-]}.
diff --git a/src/binpp.erl b/src/binpp.erl
deleted file mode 100644
index 1da793d..0000000
--- a/src/binpp.erl
+++ /dev/null
@@ -1,374 +0,0 @@
-%%%
-%%% DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
-%%% Version 2, December 2004
-%%%
-%%% Copyright (C) 2011 Adam Rutkowski
-%%%
-%%% Everyone is permitted to copy and distribute verbatim or modified
-%%% copies of this license document, and changing it is allowed as long
-%%% as the name is changed.
-%%%
-%%% DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
-%%% TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-%%%
-
-%% @doc Pretty printer for Erlang binaries.
-%%
--module(binpp).
--author('Adam Rutkowski hq@mtod.org').
-
--export([pprint/1, pprint/2, pprint/3]).
--export([compare/2]).
--export([from_str/1]).
--export([convert/1, convert/2]).
-
--opaque opt() :: {return, iolist} | {return, binary} | {printer, function()}.
--opaque opts() :: list(opt()).
-
-%% Printer constants
--define(SPACE, $ ).
--define(SPECIAL, $.).
--define(FILL, $0).
-
-%% Comparison glyphs
--define(MISSING, "??").
--define(EQUAL, "--").
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% API %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%% @doc Pretty print a binary to stdout using io:format/2
-%% Note: io:format/2 is a blocking call.
--spec pprint(binary() | bitstring()) -> ok.
-pprint(Bin) ->
- pprint(Bin, []).
-
-%% @doc Print a binary using custom function or return the formatted result.
-%% Valid option is one of:
-%%
-%% {return, binary}
-%% {return, iolist}
-%% {printer, CustomFunction}
-%%
-%%
-%% Custom printers should be of arity 1, accepting the prettified result as
-%% an iolist() input. Returned value can be any() .
--spec pprint(binary() | bitstring(), opts()) -> ok | any().
-pprint(Bin, Opts) when is_list(Opts) ->
- {ok, Octets} = convert(Bin, hex),
- Buckets = buckets(16, Octets),
- apply_opts(lists:map(fun print_bucket/1, Buckets), Opts).
-
-%% @doc Pretty print a slice of binary.
--spec pprint(binary() | bitstring(), {non_neg_integer(), non_neg_integer()},
- opts()) -> ok | any().
-pprint(Bin, {Pos, Len}, Opts) when Len =< byte_size(Bin), (Pos+Len) =< byte_size(Bin) ->
- pprint(binary:part(Bin, Pos, Len), Opts);
-pprint(Bin, {Pos, _}, Opts) ->
- pprint(binary:part(Bin, Pos, byte_size(Bin)-Pos), Opts).
-
-%% @doc Pretty print byte-to-byte comparsion of two binaries to stdout.
--spec compare(binary() | bitstring(), binary() | bitstring()) -> ok.
-compare(Bin1, Bin2) when is_binary(Bin1) orelse is_bitstring(Bin1),
- is_binary(Bin2) orelse is_bitstring(Bin2) ->
- {ok, Octets1} = convert(Bin1, hex),
- {ok, Octets2} = convert(Bin2, hex),
- {ok, {D1, D2}} = diff(Octets1, Octets2),
- print_comparison(buckets(16, D1), buckets(16, D2)).
-
-%% @doc Construct binary from hex string.
-%% Hex string octets can be optionally separated with spaces.
-%% Valid hex strings:
-%%
-%% "AA BB FF 01"
-%% "AABBFF01"
-%%
--spec from_str(string()) -> binary().
-from_str(Str) when is_list(Str) ->
- Bytes = case lists:member(?SPACE, Str) of
- true ->
- string:tokens(Str, [?SPACE]);
- false when length(Str) rem 2 =:= 0 ->
- buckets(2, Str)
- end,
- list_to_binary([list_to_integer(B, 16) || B <- Bytes]).
-
-%% @doc Convert binary to hex string.
--spec convert(binary() | bitstring()) -> {ok, list()}.
-convert(Bin) when is_binary(Bin) orelse is_bitstring(Bin) ->
- convert(Bin, hex).
-
-%% @doc Convert binary to hex string or binary (base-2) string.
--spec convert(binary() | bitstring(), hex | bin) -> {ok, list()}.
-convert(Bin, hex) when is_binary(Bin) orelse is_bitstring(Bin) ->
- convert(Bin, [], fun byte_to_hexstr/1);
-convert(Bin, bin) when is_binary(Bin) orelse is_bitstring(Bin) ->
- convert(Bin, [], fun byte_to_binstr/1).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Internals %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
--spec apply_opts(iolist(), opts()) -> ok | iolist() | binary().
-apply_opts(IoList, []) ->
- io:format("~s~n", [IoList]);
-apply_opts(IoList, [{return, iolist}]) ->
- IoList;
-apply_opts(IoList, [{return, binary}]) ->
- iolist_to_binary(IoList);
-apply_opts(IoList, [{printer, Fun}]) when is_function(Fun) ->
- Fun(IoList);
-apply_opts(_, _) -> erlang:error(badarg).
-
--spec convert(binary() | bitstring(), list(), function()) -> {ok, string()}.
-convert(<<>>, Acc, _) ->
- {ok, lists:reverse(Acc)};
-convert(Bin, [], FormatFun) when is_bitstring(Bin), not is_binary(Bin) ->
- %% byte align bistring() to make a complementary binary()
- Align = (8 - (bit_size(Bin) rem 8)),
- error_logger:info_msg("Aligned bitstring with ~.10B bit(s).~n", [Align]),
- convert(<>, [], FormatFun);
-convert(<>, SoFar, FormatFun) ->
- convert(Rest, [FormatFun(Bin)|SoFar], FormatFun).
-
-print_bucket(Bucket) ->
- OctetLine = string:join(Bucket, [?SPACE]),
- OctetRepr = lists:map(
- fun(B) ->
- case list_to_integer(B, 16) of
- Code when Code >= ?SPACE -> Code;
- _ -> ?SPECIAL
- end
- end,
- Bucket),
- io_lib:format("~s ~s~n", [string:left(OctetLine, 16*2 + 16, ?SPACE), OctetRepr]).
-
--spec print_comparison(list(), list()) -> ok.
-print_comparison([], []) ->
- ok;
-print_comparison([L|LRest], [R|RRest]) ->
- Zfill = fun(Line) -> string:left(Line, 16*2 + 16, ?SPACE) end,
- DiffL = Zfill(string:join(L, [?SPACE])),
- DiffR = Zfill(string:join(R, [?SPACE])),
- io:format("~s ~s~n", [DiffL, DiffR]),
- print_comparison(LRest, RRest).
-
--spec diff(list(), list()) -> {ok, {list(), list()}}.
-diff(L1, L2) when is_list(L1), is_list(L2) ->
- diff(L1, L2, [], []).
-
--spec diff(list(), list(), list(), list()) -> {ok, {list(), list()}}.
-diff([], [], LD, RD) ->
- {ok, {lists:reverse(LD), lists:reverse(RD)}};
-diff([], [H2|R2], LD, RD) ->
- diff([], R2, [?MISSING|LD], [H2|RD]);
-diff([H1|R1], [], LD, RD) ->
- diff(R1, [], [H1|LD], [?MISSING|RD]);
-diff([H1|R1], [H1|R2], LD, RD) -> %% H1 =:= H2
- diff(R1, R2, [?EQUAL|LD], [?EQUAL|RD]);
-diff([H1|R1], [H2|R2], LD, RD) ->
- diff(R1, R2, [H1|LD], [H2|RD]).
-
--spec byte_to_hexstr(byte()) -> string().
-byte_to_hexstr(B) when B >= 0, B =< 255 ->
- to_hexstr(B, 16, 2).
-
--spec byte_to_binstr(byte()) -> string().
-byte_to_binstr(B) when B >= 0, B =< 255 ->
- to_hexstr(B, 2, 8).
-
--spec to_hexstr(byte(), non_neg_integer(), non_neg_integer()) -> string().
-to_hexstr(B, Base, Len) ->
- string:right(integer_to_list(B, Base), Len, ?FILL).
-
-%% @doc Divide list L into X lists of size N
-%% courtesy of MononcQc
--spec buckets(non_neg_integer(), list()) -> list(list()).
-buckets(N, L) ->
- buckets(1, N, length(L) div N, L, [[]]).
-buckets(_, _, 0, [], [[]|Acc]) ->
- lists:reverse(Acc);
-buckets(_, _, 0, Rest, [[]|Acc]) ->
- lists:reverse([Rest|Acc]);
-buckets(N, N, M, [H|T], [A|Acc]) ->
- buckets(1, N, M-1, T, [[], lists:reverse([H|A]) | Acc]);
-buckets(X, N, M, [H|T], [A|Acc]) ->
- buckets(X+1, N, M, T, [[H|A]|Acc]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Tests %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
--ifdef(TEST).
--include_lib("eunit/include/eunit.hrl").
-
--define(MAX_BIN_SIZE, 2048).
--define(RUNS, 100).
-
-setup_random() ->
- _ = random:seed(erlang:now()),
- ok.
-
-binpp_random_test_() ->
- {setup, fun setup_random/0, [
- {generator, fun rand_pprint/0},
- {generator, fun rand_pprint_bitstring/0},
- {generator, fun rand_compare/0},
- {generator, fun rand_pprint_opts/0},
- {generator, fun rand_pprint_slice/0},
- {generator, fun rand_from_str/0}
- ]}.
-
-buckets_test_() ->
- F = fun buckets/2,
- Tests = [
- { {1, [1,2,3,4]}, [ [1], [2], [3], [4] ] },
- { {2, [1,2,3,4]}, [ [1,2], [3,4] ] },
- { {3, [1,2,3,4]}, [ [1,2,3], [4] ] },
- { {4, [1,2,3,4]}, [ [1,2,3,4] ] },
- { {5, [1,2,3,4]}, [ [1,2,3,4] ] }
- ],
- [ { <<"Buckets">>, fun() -> ?assertEqual(R, F(I1, I2)) end }
- || { {I1, I2}, R } <- Tests ].
-
-byte_to_binstr_test_() ->
- F = fun byte_to_binstr/1,
- Tests = [
- { 0, "00000000" },
- { 1, "00000001" },
- { 255, "11111111" }
- ],
- [ { iolist_to_binary(["Convert ", integer_to_list(I)]),
- fun() -> ?assertEqual(R, F(I)) end }
- || { I, R } <- Tests ].
-
-byte_to_hexstr_test_() ->
- F = fun byte_to_hexstr/1,
- Tests = [
- { 0, "00" },
- { 1, "01" },
- { 255, "FF" }
- ],
- [ { iolist_to_binary(["Convert ", integer_to_list(I)]),
- fun() -> ?assertEqual(R, F(I)) end }
- || { I, R } <- Tests ].
-
-diff_test_() ->
- F = fun diff/2,
- Tests = [
- { { [], [] }, { [], []} },
- { { [1, 2], [1, 1] }, { [?EQUAL, 2], [?EQUAL, 1]} },
- { { [1], [1, 1] }, { [?EQUAL, ?MISSING], [?EQUAL, 1]} },
- { { [1, 2, 3], [2, 1] }, { [1, 2, 3], [2, 1, ?MISSING]} },
- { { [], [2, 1] }, { [?MISSING, ?MISSING], [2, 1]} }
- ],
- [ { <<"Diff">>, fun() -> ?assertEqual({ok, R}, F(I1, I2)) end }
- || { {I1, I2}, R } <- Tests ].
-
-print_bucket_test_() ->
- F = fun print_bucket/1,
- Tests = [
- { ["00", "FF"],
- ["00 FF ", ?SPACE, [?SPECIAL, 255], "\n"] },
-
- { ["41" || _ <- lists:seq(1, 16) ],
- ["41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ", ?SPACE, [$A || _ <- lists:seq(1, 16)], "\n"] }
- ],
- [ { iolist_to_binary(["Print ", I]), fun() -> ?assertEqual(R, F(I)) end }
- || { I, R } <- Tests ].
-
-convert_hex_test_() ->
- F = fun convert/1,
- Tests = [
- { <<1,2,3>>, ["01", "02", "03"] },
- { <<256:32>>, ["00", "00", "01", "00"] },
- { <<"AAA">>, ["41", "41", "41"] },
- { <<256:7>>, ["00"] },
- { <<256:9>>, ["80", "00"] }
- ],
- [ { <<"Convert">>, fun() -> ?assertEqual({ok, R}, F(I)) end } || { I, R } <- Tests ].
-
-convert_bin_test_() ->
- F = fun convert/2,
- Tests = [
- { <<1,2,3>>, ["00000001","00000010","00000011"] },
- { <<256:32>>, ["00000000","00000000","00000001", "00000000"] },
- { <<"AAA">>, ["01000001","01000001","01000001"] },
- { <<256:7>>, ["00000000"] },
- { <<256:9>>, ["10000000","00000000"] }
- ],
- [ { <<"Convert">>, fun() -> ?assertEqual({ok, R}, F(I, bin)) end } || { I, R } <- Tests ].
-
-rand_pprint() ->
- F = fun pprint/1,
- Tests = [ { crypto:rand_bytes(random:uniform(?MAX_BIN_SIZE)), ok } || _ <- lists:seq(1, ?RUNS) ],
- [ { <<"Random pprint">>, fun() -> ?assertEqual(R, F(I)) end }
- || { I, R } <- Tests ].
-
-rand_pprint_bitstring() ->
- F = fun pprint/1,
- Tests = [ { << (crypto:rand_bytes(random:uniform(?MAX_BIN_SIZE)))/binary, 0:(random:uniform(7))>>, ok }
- || _ <- lists:seq(1, ?RUNS) ],
- [ { <<"Random pprint (bitstring)">>, fun() -> ?assertEqual(R, F(I)) end }
- || { I, R } <- Tests ].
-
-rand_compare() ->
- F = fun compare/2,
- Rand = fun() -> crypto:rand_bytes(random:uniform(?MAX_BIN_SIZE)) end,
- Tests = [ { { Rand(), Rand() }, ok } || _ <- lists:seq(1, ?RUNS) ],
- [ { <<"Random compare">>, fun() -> ?assertEqual(R, F(I1, I2)) end }
- || { {I1, I2}, R } <- Tests ].
-
-rand_pprint_opts() ->
- F = fun pprint/2,
- CustomPrinter = fun(B) when is_list(B) -> works end,
- OptsMap = [
- %% Option %% Predicate
- { {return, binary}, fun erlang:is_binary/1 },
- { {return, iolist}, fun erlang:is_list/1 },
- { {printer, CustomPrinter}, fun(works) -> true; (_) -> false end },
- { {invalid, option}, fun({'EXIT', {badarg, _}}) -> true; (O) -> O end }
- ],
- Range = length(OptsMap),
- Rand = fun() ->
- Input = crypto:rand_bytes(random:uniform(?MAX_BIN_SIZE)),
- {Opt, Predicate} = lists:nth(random:uniform(Range), OptsMap),
- {Input, Opt, Predicate}
- end,
- Tests = [ Rand() || _ <- lists:seq(1, ?RUNS) ],
- Title = fun(Opt) ->
- iolist_to_binary([ "Random pprint w/ opt: ", io_lib:format("~p", [Opt]) ]) end,
- [ { Title(Opt), fun() -> ?assertEqual(true, Pred( catch( F(I, [Opt]) ) )) end }
- || {I, Opt, Pred} <- Tests ].
-
-rand_pprint_slice() ->
- F = fun pprint/3,
- Rand = fun() ->
- Bytes = crypto:rand_bytes(random:uniform(?MAX_BIN_SIZE)),
- Pos = random:uniform(byte_size(Bytes)),
- Len = random:uniform(byte_size(Bytes)),
- {Bytes, Pos, Len}
- end,
- Tests = [ Rand() || _ <- lists:seq(1, ?RUNS) ],
- Title = fun(Size, Slice) ->
- iolist_to_binary(io_lib:format("Random pprint w/ slice: (~p) ~p", [Size, Slice]))
- end,
- [ { Title(byte_size(Bytes), {Pos, Len}), fun() -> ?assertEqual(ok, F(Bytes, {Pos, Len}, [])) end }
- || { Bytes, Pos, Len } <- Tests ].
-
-rand_from_str() ->
- F = fun from_str/1,
- Rand = fun() ->
- Bytes = crypto:rand_bytes(random:uniform(?MAX_BIN_SIZE)),
- {ok, Converted} = convert(Bytes),
- case random:uniform(2) of
- 1 -> {lists:flatten(Converted), Bytes};
- 2 -> {string:join(Converted, " "), Bytes}
- end
- end,
- Tests = [ Rand() || _ <- lists:seq(1, ?RUNS) ],
- [ { <<"Random from_str">>, fun() -> ?assertEqual(R, F(I)) end }
- || { I, R } <- Tests ].
-
--endif.