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Ø8‘X.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ØT‘R].$ - 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. + + +

Description

Pretty printer for Erlang binaries. + +

Data Types

+ +

opts()

+

abstract datatype: opts()

+ + +

Function Index

+ + + + + + + +
compare/2Pretty print byte-to-byte comparsion of two binaries to stdout.
convert/1Convert binary to hex string.
convert/2Convert binary to hex string or binary (base-2) string.
from_str/1Construct binary from hex string.
pprint/1Pretty print a binary to stdout using io:format/2 + Note: io:format/2 is a blocking call.
pprint/2Print a binary using custom function or return the formatted result.
pprint/3Pretty print a slice of binary.
+ +

Function Details

+ +

compare/2

+
+

compare(Bin1::binary() | bitstring(), Bin2::binary() | bitstring()) -> ok

+

Pretty print byte-to-byte comparsion of two binaries to stdout.

+ +

convert/1

+
+

convert(Bin::binary() | bitstring()) -> {ok, list()}

+

Convert binary to hex string.

+ +

convert/2

+
+

convert(Bin::binary() | bitstring(), X2::hex | bin) -> {ok, list()}

+

Convert binary to hex string or binary (base-2) string.

+ +

from_str/1

+
+

from_str(Str::string()) -> binary()

+

Construct binary from hex string. + Hex string octets can be optionally separated with spaces. + Valid hex strings: +

+ +

pprint/1

+
+

pprint(Bin::binary() | bitstring()) -> ok

+

Pretty print a binary to stdout using io:format/2 + Note: io:format/2 is a blocking call.

+ +

pprint/2

+
+

pprint(Bin::binary() | bitstring(), Opts::opts()) -> ok | any()

+

Print a binary using custom function or return the formatted result. + Valid options are: +

+ + Custom functions should be of arity 1, accepting the prettified result as + an iolist() input. Returned value can be any().

+ +

pprint/3

+
+

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 + + + + + + +<h2>This page uses frames</h2> +<p>Your browser does not accept frames. +<br>You should go to the <a href="overview-summary.html">non-frame version</a> instead. +</p> + + + \ 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

+ +
binpp
+ + \ 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: + + +

Installation

+ +
    + +
  1. 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 +
  2. + +
  3. +Download the sources from binpp Github repository.

    + + +
  4. +
+ + + +

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Ø8‘X.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ØT‘R].$
+    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: -%% -%% -%% 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: -%% --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.