zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

cow_iolists.erl (3318B)


      1 %% Copyright (c) 2017-2018, Loïc Hoguin <essen@ninenines.eu>
      2 %%
      3 %% Permission to use, copy, modify, and/or distribute this software for any
      4 %% purpose with or without fee is hereby granted, provided that the above
      5 %% copyright notice and this permission notice appear in all copies.
      6 %%
      7 %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8 %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9 %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     10 %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11 %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     12 %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     13 %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     14 
     15 -module(cow_iolists).
     16 
     17 -export([split/2]).
     18 
     19 -ifdef(TEST).
     20 -include_lib("proper/include/proper.hrl").
     21 -endif.
     22 
     23 -spec split(non_neg_integer(), iodata()) -> {iodata(), iodata()}.
     24 split(N, Iolist) ->
     25 	case split(N, Iolist, []) of
     26 		{ok, Before, After} ->
     27 			{Before, After};
     28 		{more, _, Before} ->
     29 			{lists:reverse(Before), <<>>}
     30 	end.
     31 
     32 split(0, Rest, Acc) ->
     33 	{ok, lists:reverse(Acc), Rest};
     34 split(N, [], Acc) ->
     35 	{more, N, Acc};
     36 split(N, Binary, Acc) when byte_size(Binary) =< N ->
     37 	{more, N - byte_size(Binary), [Binary|Acc]};
     38 split(N, Binary, Acc) when is_binary(Binary) ->
     39 	<< Before:N/binary, After/bits >> = Binary,
     40 	{ok, lists:reverse([Before|Acc]), After};
     41 split(N, [Binary|Tail], Acc) when byte_size(Binary) =< N ->
     42 	split(N - byte_size(Binary), Tail, [Binary|Acc]);
     43 split(N, [Binary|Tail], Acc) when is_binary(Binary) ->
     44 	<< Before:N/binary, After/bits >> = Binary,
     45 	{ok, lists:reverse([Before|Acc]), [After|Tail]};
     46 split(N, [Char|Tail], Acc) when is_integer(Char) ->
     47 	split(N - 1, Tail, [Char|Acc]);
     48 split(N, [List|Tail], Acc0) ->
     49 	case split(N, List, Acc0) of
     50 		{ok, Before, After} ->
     51 			{ok, Before, [After|Tail]};
     52 		{more, More, Acc} ->
     53 			split(More, Tail, Acc)
     54 	end.
     55 
     56 -ifdef(TEST).
     57 
     58 split_test_() ->
     59 	Tests = [
     60 		{10, "Hello world!", "Hello worl", "d!"},
     61 		{10, <<"Hello world!">>, "Hello worl", "d!"},
     62 		{10, ["He", [<<"llo">>], $\s, [["world"], <<"!">>]], "Hello worl", "d!"},
     63 		{10, ["Hello "|<<"world!">>], "Hello worl", "d!"},
     64 		{10, "Hello!", "Hello!", ""},
     65 		{10, <<"Hello!">>, "Hello!", ""},
     66 		{10, ["He", [<<"ll">>], $o, [["!"]]], "Hello!", ""},
     67 		{10, ["Hel"|<<"lo!">>], "Hello!", ""},
     68 		{10, [[<<>>|<<>>], [], <<"Hello world!">>], "Hello worl", "d!"},
     69 		{10, [[<<"He">>|<<"llo">>], [$\s], <<"world!">>], "Hello worl", "d!"},
     70 		{10, [[[]|<<"He">>], [[]|<<"llo wor">>]|<<"ld!">>], "Hello worl", "d!"}
     71 	],
     72 	[{iolist_to_binary(V), fun() ->
     73 		{B, A} = split(N, V),
     74 		true = iolist_to_binary(RB) =:= iolist_to_binary(B),
     75 		true = iolist_to_binary(RA) =:= iolist_to_binary(A)
     76 	end} || {N, V, RB, RA} <- Tests].
     77 
     78 prop_split_test() ->
     79 	?FORALL({N, Input},
     80 		{non_neg_integer(), iolist()},
     81 		begin
     82 			Size = iolist_size(Input),
     83 			{Before, After} = split(N, Input),
     84 			if
     85 				N >= Size ->
     86 					((iolist_size(After) =:= 0)
     87 						andalso iolist_to_binary(Before) =:= iolist_to_binary(Input));
     88 				true ->
     89 					<<ExpectBefore:N/binary, ExpectAfter/bits>> = iolist_to_binary(Input),
     90 					(ExpectBefore =:= iolist_to_binary(Before))
     91 						andalso (ExpectAfter =:= iolist_to_binary(After))
     92 			end
     93 		end).
     94 
     95 -endif.