1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2006-2012. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: %% Originally based on Per Gustafsson's test suite. 21: %% 22: 23: -module(bs_bit_binaries_SUITE). 24: 25: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 26: init_per_group/2,end_per_group/2, 27: misc/1,horrid_match/1,test_bitstr/1,test_bit_size/1,asymmetric_tests/1, 28: big_asymmetric_tests/1,binary_to_and_from_list/1, 29: big_binary_to_and_from_list/1,send_and_receive/1, 30: send_and_receive_alot/1,append/1]). 31: 32: -include_lib("test_server/include/test_server.hrl"). 33: 34: suite() -> [{ct_hooks,[ts_install_cth]}]. 35: 36: all() -> 37: [misc, horrid_match, test_bitstr, test_bit_size, 38: asymmetric_tests, big_asymmetric_tests, 39: binary_to_and_from_list, big_binary_to_and_from_list, 40: send_and_receive, send_and_receive_alot, append]. 41: 42: groups() -> 43: []. 44: 45: init_per_suite(Config) -> 46: Config. 47: 48: end_per_suite(_Config) -> 49: ok. 50: 51: init_per_group(_GroupName, Config) -> 52: Config. 53: 54: end_per_group(_GroupName, Config) -> 55: Config. 56: 57: 58: misc(Config) when is_list(Config) -> 59: ?line <<1:100>> = id(<<1:100>>), 60: ?line {ok,ok} = {match(7),match(9)}, 61: ?line {ok,ok} = {match1(15),match1(31)}, 62: ok. 63: 64: 65: match(N) -> 66: %% Move N to a Y register to cover another instruction. 67: <<0:N>> = id(<<0:N>>), 68: <<0:N,0:1>> = id(<<0:N,0:1>>), 69: ok. 70: 71: match1(N) -> 72: %% Putting the binary inside a list will force another 73: %% instruction to be used. 74: [<<42:N/little>>] = id([<<42:N/little>>]), 75: ok. 76: 77: test_bit_size(Config) when is_list(Config) -> 78: ?line 101 = bit_size(<<1:101>>), 79: ?line 1001 = bit_size(<<1:1001>>), 80: ?line 80 = bit_size(<<1:80>>), 81: ?line 800 = bit_size(<<1:800>>), 82: ?line Bin = <<0:16#1000000>>, 83: ?line BigBin = list_to_bitstring([Bin||_ <- lists:seq(1,16#10)]++[<<1:1>>]), 84: ?line 16#10000001 = erlang:bit_size(BigBin), 85: %% Only run these on computers with lots of memory 86: %% HugeBin = list_to_bitstring([BigBin||_ <- lists:seq(1,16#10)]++[<<1:1>>]), 87: %% 16#100000011 = bit_size(HugeBin), 88: ?line 0 = bit_size(<<>>), 89: ok. 90: 91: horrid_match(Config) when is_list(Config) -> 92: ?line <<1:4,B:24/bitstring>> = <<1:4,42:24/little>>, 93: ?line <<42:24/little>> = B, 94: ok. 95: 96: test_bitstr(Config) when is_list(Config) -> 97: ?line <<1:7,B/bitstring>> = <<1:7,<<1:1,6>>/bitstring>>, 98: ?line <<1:1,6>> = B, 99: ?line B = <<1:1,6>>, 100: ok. 101: 102: asymmetric_tests(Config) when is_list(Config) -> 103: ?line <<1:12>> = <<0,1:4>>, 104: ?line <<0,1:4>> = <<1:12>>, 105: ?line <<1:1,X/bitstring>> = <<128,255,0,0:2>>, 106: ?line <<1,254,0,0:1>> = X, 107: ?line X = <<1,254,0,0:1>>, 108: ?line <<1:1,X1:25/bitstring>> = <<128,255,0,0:2>>, 109: ?line <<1,254,0,0:1>> = X1, 110: ?line X1 = <<1,254,0,0:1>>, 111: ok. 112: 113: big_asymmetric_tests(Config) when is_list(Config) -> 114: ?line <<1:875,1:12>> = <<1:875,0,1:4>>, 115: ?line <<1:875,0,1:4>> = <<1:875,1:12>>, 116: ?line <<1:1,X/bitstring>> = <<128,255,0,0:2,1:875>>, 117: ?line <<1,254,0,0:1,1:875>> = X, 118: ?line X = <<1,254,0,0:1,1:875>>, 119: ?line <<1:1,X1:900/bitstring>> = <<128,255,0,0:2,1:875>>, 120: ?line <<1,254,0,0:1,1:875>> = X1, 121: ?line X1 = <<1,254,0,0:1,1:875>>, 122: ok. 123: 124: binary_to_and_from_list(Config) when is_list(Config) -> 125: ?line <<1,2,3,4,1:1>> = list_to_bitstring(bitstring_to_list(<<1,2,3,4,1:1>>)), 126: ?line [1,2,3,4,<<1:1>>] = bitstring_to_list(<<1,2,3,4,1:1>>), 127: ?line <<1:1,1,2,3,4>> = list_to_bitstring([<<1:1>>,1,2,3,4]), 128: ?line [128,129,1,130,<<0:1>>] = bitstring_to_list(<<1:1,1,2,3,4>>), 129: ok. 130: 131: big_binary_to_and_from_list(Config) when is_list(Config) -> 132: ?line <<1:800,2,3,4,1:1>> = list_to_bitstring(bitstring_to_list(<<1:800,2,3,4,1:1>>)), 133: ?line [1,2,3,4|_Rest1] = bitstring_to_list(<<1,2,3,4,1:800,1:1>>), 134: ?line <<1:801,1,2,3,4>> = list_to_bitstring([<<1:801>>,1,2,3,4]), 135: ok. 136: 137: send_and_receive(Config) when is_list(Config) -> 138: ?line Bin = <<1,2:7>>, 139: Pid = spawn_link(fun() -> receiver(Bin) end), 140: ?line Pid ! {self(),<<1:7,8:5,Bin/bitstring>>}, 141: ?line receive 142: ok -> 143: ok 144: end. 145: 146: receiver(Bin) -> 147: receive 148: {Pid,<<1:7,8:5,Bin/bitstring>>} -> 149: Pid ! ok 150: end. 151: 152: send_and_receive_alot(Config) when is_list(Config) -> 153: Bin = <<1:1000001>>, 154: Pid = spawn_link(fun() -> receiver_alot(Bin) end), 155: spamalot(100,Bin,Pid). 156: 157: spamalot(N,Bin,Pid) when N > 0 -> 158: Pid ! {self(),<<1:7,8:5,Bin/bitstring>>}, 159: receive 160: ok -> 161: ok 162: end, 163: spamalot(N-1,Bin,Pid); 164: spamalot(0,_Bin,Pid) -> 165: Pid ! no_more, 166: ok. 167: 168: receiver_alot(Bin) -> 169: receive 170: {Pid,<<1:7,8:5,Bin/bitstring>>} -> 171: Pid ! ok; 172: no_more -> ok 173: end, 174: receiver_alot(Bin). 175: 176: append(Config) when is_list(Config) -> 177: cs_init(), 178: ?line <<(-1):256/signed-unit:8>> = cs(do_append(id(<<>>), 256*8)), 179: ?line <<(-1):256/signed-unit:8>> = cs(do_append2(id(<<>>), 256*4)), 180: <<(-1):256/signed-unit:8>> = cs(do_append3(id(<<>>), 256*8)), 181: cs_end(). 182: 183: do_append(Bin, N) when N > 0 -> do_append(<<Bin/bits,1:1>>, N-1); 184: do_append(Bin, 0) -> Bin. 185: 186: do_append2(Bin, N) when N > 0 -> do_append2(<<Bin/binary-unit:2,3:2>>, N-1); 187: do_append2(Bin, 0) -> Bin. 188: 189: do_append3(Bin, N) when N > 0 -> 190: Bits = bit_size(Bin), 191: if 192: Bits rem 2 =:= 0 -> 193: do_append3(<<Bin/binary-unit:2,1:1>>, N-1); 194: Bits rem 3 =:= 0 -> 195: do_append3(<<Bin/binary-unit:3,1:1>>, N-1); 196: Bits rem 4 =:= 0 -> 197: do_append3(<<Bin/binary-unit:4,1:1>>, N-1); 198: Bits rem 5 =:= 0 -> 199: do_append3(<<Bin/binary-unit:5,1:1>>, N-1); 200: Bits rem 6 =:= 0 -> 201: do_append3(<<Bin/binary-unit:6,1:1>>, N-1); 202: Bits rem 7 =:= 0 -> 203: do_append3(<<Bin/binary-unit:7,1:1>>, N-1); 204: Bits rem 8 =:= 0 -> 205: do_append3(<<Bin/binary-unit:8,1:1>>, N-1); 206: Bits rem 9 =:= 0 -> 207: do_append3(<<Bin/binary-unit:9,1:1>>, N-1); 208: Bits rem 10 =:= 0 -> 209: do_append3(<<Bin/binary-unit:10,1:1>>, N-1); 210: Bits rem 11 =:= 0 -> 211: do_append3(<<Bin/binary-unit:11,1:1>>, N-1); 212: Bits rem 12 =:= 0 -> 213: do_append3(<<Bin/binary-unit:12,1:1>>, N-1); 214: Bits rem 13 =:= 0 -> 215: do_append3(<<Bin/binary-unit:13,1:1>>, N-1); 216: Bits rem 14 =:= 0 -> 217: do_append3(<<Bin/binary-unit:14,1:1>>, N-1); 218: Bits rem 15 =:= 0 -> 219: do_append3(<<Bin/binary-unit:15,1:1>>, N-1); 220: Bits rem 16 =:= 0 -> 221: do_append3(<<Bin/binary-unit:16,1:1>>, N-1); 222: Bits rem 17 =:= 0 -> 223: do_append3(<<Bin/binary-unit:17,1:1>>, N-1); 224: true -> 225: do_append3(<<Bin/binary-unit:1,1:1>>, N-1) 226: end; 227: do_append3(Bin, 0) -> Bin. 228: 229: cs_init() -> 230: erts_debug:set_internal_state(available_internal_state, true), 231: ok. 232: 233: cs_end() -> 234: erts_debug:set_internal_state(available_internal_state, false), 235: ok. 236: 237: %% Verify that the allocated size is exact (rounded up to the nearest byte). 238: cs(Bin) -> 239: ByteSize = byte_size(Bin), 240: {refc_binary,ByteSize,{binary,ByteSize},_} = 241: erts_debug:get_internal_state({binary_info,Bin}), 242: Bin. 243: 244: id(I) -> I.