aboutsummaryrefslogblamecommitdiffstats
path: root/lib/hipe/test/bs_SUITE_data/bs_match.erl
blob: b241ea8d35cca3bc5420748723e0137d7224ecf7 (plain) (tree)
1
2
3
4
5


                                                                      

                                                                               








                                                                      
                                                            
                                                              































































































































































                                                                              
 


                                                                     









                                          


































































































                                                                                                   
%%% -*- erlang-indent-level: 2 -*-
%%%-------------------------------------------------------------------
%%% File    : bs_match.erl
%%% Authors : Per Gustafsson <[email protected]>, Kostis Sagonas <[email protected]>
%%% Purpose : Tests matching and construction of binaries
%%%    TODO : Add binary and float tests
%%% Created : 20 Feb 2004
%%%-------------------------------------------------------------------
-module(bs_match).

-export([test/0]).

test() ->
  Funs = [fun test_aligned/0, fun test_unaligned/0,
	  fun test_zero_tail/0, fun test_integer_matching/0,
	  fun test_writable_bin/0, fun test_match_huge_bin/0],
  lists:foreach(fun (F) -> ok = F() end, Funs).

%%-------------------------------------------------------------------
%% Test aligned accesses

test_aligned() ->
  10 = aligned_skip_bits_all(1, <<10,11,12>>),
  ok = aligned().

aligned_skip_bits_all(N, Bin) ->
  <<X:N/integer-unit:8, _/binary>> = Bin,
  X.

aligned() ->
  Tail1 = mkbin([]),
  {258, Tail1} = al_get_tail_used(mkbin([1,2])),
  Tail2 = mkbin(lists:seq(1, 127)),
  {35091, Tail2} = al_get_tail_used(mkbin([137,19|Tail2])),
  64896 = al_get_tail_unused(mkbin([253,128])),
  64895 = al_get_tail_unused(mkbin([253,127|lists:seq(42, 255)])),
  Tail3 = mkbin(lists:seq(0, 19)),
  {0, Tail1} = get_dyn_tail_used(Tail1, 0),
  {0, Tail3} = get_dyn_tail_used(mkbin([Tail3]), 0),
  {73, Tail3} = get_dyn_tail_used(mkbin([73|Tail3]), 8),
  0 = get_dyn_tail_unused(mkbin([]), 0),
  233 = get_dyn_tail_unused(mkbin([233]), 8),
  23 = get_dyn_tail_unused(mkbin([23,22,2]), 8),
  ok.

mkbin(L) when is_list(L) -> list_to_binary(L).

al_get_tail_used(<<A:16,T/binary>>) -> {A, T}.

al_get_tail_unused(<<A:16,_/binary>>) -> A.

%%-------------------------------------------------------------------
%% Test unaligned accesses

test_unaligned() ->
  10 = unaligned_skip_bits_all(8, <<10,11,12>>),
  ok = unaligned().

unaligned_skip_bits_all(N, Bin) ->
  <<X:N, _/binary>> = Bin,
  X.

unaligned() ->
  {'EXIT', {function_clause,_}} = (catch get_tail_used(mkbin([42]))),
  {'EXIT', {{badmatch,_},_}} = (catch get_dyn_tail_used(mkbin([137]), 3)),
  {'EXIT', {function_clause,_}} = (catch get_tail_unused(mkbin([42,33]))),
  {'EXIT', {{badmatch,_},_}} = (catch get_dyn_tail_unused(mkbin([44]), 7)),
  ok.

get_tail_used(<<A:1, T/binary>>) -> {A, T}.

get_tail_unused(<<A:15, _/binary>>) -> A.

get_dyn_tail_used(Bin, Sz) ->
  <<A:Sz, T/binary>> = Bin,
  {A,T}.

get_dyn_tail_unused(Bin, Sz) ->
  <<A:Sz, _T/binary>> = Bin,
  A.

%%-------------------------------------------------------------------
%% Test zero tail

test_zero_tail() ->
  42 = zt8(mkbin([42])),
  {'EXIT', {function_clause, _}} = (catch zt8(mkbin([1,2]))),
  {'EXIT', {function_clause, _}} = (catch zt44(mkbin([1,2]))),
  ok.

zt8(<<A:8>>) -> A.

zt44(<<_:4,_:4>>) -> ok.

%%-------------------------------------------------------------------
%% Test integer matching

test_integer_matching() ->
  ok = test_static_integer_matching_1(),
  ok = test_static_integer_matching_2(),
  ok = test_static_integer_matching_3(),
  ok = test_static_integer_matching_4(),
  DynFun = fun (N) -> ok = test_dynamic_integer_matching(N) end,
  lists:foreach(DynFun, [28, 27, 9, 17, 25, 8, 16, 24, 32]).

test_static_integer_matching_1() ->
  <<0:6, -25:28/integer-signed, 0:6>> = s11(),
  <<0:6, -25:28/integer-little-signed, 0:6>> = s12(),
  <<0:6, 25:28/integer-little, 0:6>> = s13(),
  <<0:6, 25:28, 0:6>> = s14(),
  ok.

s11() ->
  <<0:6, -25:28/integer-signed, 0:6>>.
s12() ->
  <<0:6, -25:28/integer-little-signed, 0:6>>.
s13() ->
  <<0:6, 25:28/integer-little, 0:6>>.
s14() ->
  <<0:6, 25:28, 0:6>>.

test_static_integer_matching_2() ->
  <<0:6, -25:20/integer-signed, 0:6>> = s21(),
  <<0:6, -25:20/integer-little-signed, 0:6>> = s22(),
  <<0:6, 25:20/integer-little, 0:6>> = s23(),
  <<0:6, 25:20, 0:6>> = s24(),
  ok.

s21() ->
  <<0:6, -25:20/integer-signed, 0:6>>.
s22() ->
  <<0:6, -25:20/integer-little-signed, 0:6>>.
s23() ->
  <<0:6, 25:20/integer-little, 0:6>>.
s24() ->
  <<0:6, 25:20, 0:6>>.

test_static_integer_matching_3() ->
  <<0:6, -25:12/integer-signed, 0:6>> = s31(),
  <<0:6, -25:12/integer-little-signed, 0:6>> = s32(),
  <<0:6, 25:12/integer-little, 0:6>> = s33(),
  <<0:6, 25:12, 0:6>> = s34(),
  ok.

s31() ->
  <<0:6, -25:12/integer-signed, 0:6>>.
s32() ->
  <<0:6, -25:12/integer-little-signed, 0:6>>.
s33() ->
  <<0:6, 25:12/integer-little, 0:6>>.
s34() ->
  <<0:6, 25:12, 0:6>>.

test_static_integer_matching_4() ->
  <<0:6, -3:4/integer-signed, 0:6>> = s41(),
  <<0:6, -3:4/integer-little-signed, 0:6>> = s42(),
  <<0:6, 7:4/integer-little, 0:6>> = s43(),
  <<0:6, 7:4, 0:6>> = s44(),
  ok.

s41() ->
  <<0:6, -3:4/integer-signed, 0:6>>.
s42() ->
  <<0:6, -3:4/integer-little-signed, 0:6>>.
s43() ->
  <<0:6, 7:4/integer-little, 0:6>>.
s44() ->
  <<0:6, 7:4, 0:6>>.

test_dynamic_integer_matching(N) ->
  S = 32 - N,
  <<-12:N/integer-signed, 0:S>> = <<-12:N/integer-signed, 0:S>>,
  <<-12:N/integer-little-signed, 0:S>> = <<-12:N/integer-little-signed, 0:S>>,
  <<12:N/integer, 0:S>> = <<12:N/integer, 0:S>>,
  <<12:N/integer-little, 0:S>> = <<12:N/integer-little, 0:S>>,
  ok.

%%-------------------------------------------------------------------
%% Test writable bin -- added by Sverker Eriksson

test_writable_bin() ->
  test_writable_bin(<<>>, 0),
  ok.

test_writable_bin(Bin, 128) ->
  Bin;
test_writable_bin(Bin0, N) when N < 128 ->
  Bin1 = <<Bin0/binary, N>>,
  <<_/utf8, _/binary>> = Bin1,
  test_writable_bin(Bin1, N+1).

%%-------------------------------------------------------------------
%% Test matching with a huge bin -- taken from bs_match_bin_SUITE

test_match_huge_bin() ->
  Bin = <<0:(1 bsl 27),13:8>>,
  skip_huge_bin_1(1 bsl 27, Bin),
  16777216 = match_huge_bin_1(1 bsl 27, Bin),
  %% Test overflowing the size of a binary field.
  nomatch = overflow_huge_bin_skip_32(Bin),
  nomatch = overflow_huge_bin_32(Bin),
  nomatch = overflow_huge_bin_skip_64(Bin),
  nomatch = overflow_huge_bin_64(Bin),
  %% Size in variable
  ok = overflow_huge_bin(Bin, lists:seq(25, 32)++lists:seq(50, 64)),
  ok = overflow_huge_bin_unit128(Bin, lists:seq(25, 32)++lists:seq(50, 64)),
  ok.

overflow_huge_bin(Bin, [Sz0|Sizes]) ->
  Sz = id(1 bsl Sz0),
  case Bin of
    <<_:Sz/binary-unit:8,0,_/binary>> ->
      {error,Sz};
    _ ->
      case Bin of
	<<NewBin:Sz/binary-unit:8,0,_/binary>> ->
	  {error,Sz,size(NewBin)};
	_ ->
	  overflow_huge_bin(Bin, Sizes)
      end
  end;
overflow_huge_bin(_, []) -> ok.

overflow_huge_bin_unit128(Bin, [Sz0|Sizes]) ->
  Sz = id(1 bsl Sz0),
  case Bin of
    <<_:Sz/binary-unit:128,0,_/binary>> ->
      {error,Sz};
    _ ->
      case Bin of
	<<NewBin:Sz/binary-unit:128,0,_/binary>> ->
	  {error,Sz,size(NewBin)};
	_ ->
	  overflow_huge_bin_unit128(Bin, Sizes)
      end
  end;
overflow_huge_bin_unit128(_, []) -> ok.

skip_huge_bin_1(I, Bin) ->
  <<_:I/binary-unit:1,13>> = Bin,
  ok.

match_huge_bin_1(I, Bin) ->
  case Bin of
    <<Val:I/binary-unit:1,13>> -> size(Val);
    _ -> nomatch
  end.

overflow_huge_bin_skip_32(<<_:4294967296/binary,0,_/binary>>) -> 1; % 1 bsl 32
overflow_huge_bin_skip_32(<<_:33554432/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 25
overflow_huge_bin_skip_32(<<_:67108864/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 26
overflow_huge_bin_skip_32(<<_:134217728/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 27
overflow_huge_bin_skip_32(<<_:268435456/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 28
overflow_huge_bin_skip_32(<<_:536870912/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 29
overflow_huge_bin_skip_32(<<_:1073741824/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 30
overflow_huge_bin_skip_32(<<_:2147483648/binary-unit:8,0,_/binary>>) -> 8; % 1 bsl 31
overflow_huge_bin_skip_32(_) -> nomatch.

overflow_huge_bin_32(<<Bin:4294967296/binary,_/binary>>) -> {1,Bin}; % 1 bsl 32
overflow_huge_bin_32(<<Bin:33554432/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 25
overflow_huge_bin_32(<<Bin:67108864/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 26
overflow_huge_bin_32(<<Bin:134217728/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 27
overflow_huge_bin_32(<<Bin:268435456/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 28
overflow_huge_bin_32(<<Bin:536870912/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 29
overflow_huge_bin_32(<<Bin:1073741824/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 30
overflow_huge_bin_32(<<Bin:2147483648/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 31
overflow_huge_bin_32(_) -> nomatch.

overflow_huge_bin_skip_64(<<_:18446744073709551616/binary,0,_/binary>>) -> 1; % 1 bsl 64
overflow_huge_bin_skip_64(<<_:144115188075855872/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 57
overflow_huge_bin_skip_64(<<_:288230376151711744/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 58
overflow_huge_bin_skip_64(<<_:576460752303423488/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 59
overflow_huge_bin_skip_64(<<_:1152921504606846976/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 60
overflow_huge_bin_skip_64(<<_:2305843009213693952/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 61
overflow_huge_bin_skip_64(<<_:4611686018427387904/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 62
overflow_huge_bin_skip_64(<<_:9223372036854775808/binary-unit:8,_/binary>>) -> 8; % 1 bsl 63
overflow_huge_bin_skip_64(_) -> nomatch.

overflow_huge_bin_64(<<Bin:18446744073709551616/binary,_/binary>>) -> {1,Bin}; % 1 bsl 64
overflow_huge_bin_64(<<Bin:144115188075855872/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 57
overflow_huge_bin_64(<<Bin:288230376151711744/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 58
overflow_huge_bin_64(<<Bin:576460752303423488/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 59
overflow_huge_bin_64(<<Bin:1152921504606846976/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 60
overflow_huge_bin_64(<<Bin:2305843009213693952/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 61
overflow_huge_bin_64(<<Bin:4611686018427387904/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 62
overflow_huge_bin_64(<<Bin:9223372036854775808/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 63
overflow_huge_bin_64(_) -> nomatch.

id(I) -> I.