1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 1999-2011. 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: -module(bs_match_bin_SUITE). 21: 22: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 23: init_per_group/2,end_per_group/2, 24: byte_split_binary/1,bit_split_binary/1,match_huge_bin/1]). 25: 26: -include_lib("test_server/include/test_server.hrl"). 27: 28: suite() -> [{ct_hooks,[ts_install_cth]}]. 29: 30: all() -> 31: [byte_split_binary, bit_split_binary, match_huge_bin]. 32: 33: groups() -> 34: []. 35: 36: init_per_suite(Config) -> 37: Config. 38: 39: end_per_suite(_Config) -> 40: ok. 41: 42: init_per_group(_GroupName, Config) -> 43: Config. 44: 45: end_per_group(_GroupName, Config) -> 46: Config. 47: 48: 49: byte_split_binary(doc) -> "Tries to split a binary at all byte-aligned positions."; 50: byte_split_binary(Config) when is_list(Config) -> 51: ?line L = lists:seq(0, 57), 52: ?line B = mkbin(L), 53: ?line byte_split(L, B, size(B)), 54: ?line Unaligned = make_unaligned_sub_binary(B), 55: ?line byte_split(L, Unaligned, size(Unaligned)). 56: 57: byte_split(L, B, Pos) when Pos >= 0 -> 58: ?line Sz1 = Pos, 59: ?line Sz2 = size(B) - Pos, 60: ?line <<B1:Sz1/binary,B2:Sz2/binary>> = B, 61: ?line B1 = list_to_binary(lists:sublist(L, 1, Pos)), 62: ?line B2 = list_to_binary(lists:nthtail(Pos, L)), 63: ?line byte_split(L, B, Pos-1); 64: byte_split(_, _, _) -> ok. 65: 66: bit_split_binary(doc) -> "Tries to split a binary at all positions."; 67: bit_split_binary(Config) when is_list(Config) -> 68: Fun = fun(Bin, List, SkipBef, N) -> 69: ?line SkipAft = 8*size(Bin) - N - SkipBef, 70: %%io:format("~p, ~p, ~p", [SkipBef,N,SkipAft]), 71: ?line <<_:SkipBef,OutBin:N/binary-unit:1,_:SkipAft>> = Bin, 72: ?line OutBin = make_bin_from_list(List, N) 73: end, 74: ?line bit_split_binary1(Fun, erlang:md5(<<1,2,3>>)), 75: ?line bit_split_binary1(Fun, 76: make_unaligned_sub_binary(erlang:md5(<<1,2,3>>))), 77: ok. 78: 79: bit_split_binary1(Action, Bin) -> 80: BitList = bits_to_list(binary_to_list(Bin), 16#80), 81: bit_split_binary2(Action, Bin, BitList, 0). 82: 83: bit_split_binary2(Action, Bin, [_|T]=List, Bef) -> 84: bit_split_binary3(Action, Bin, List, Bef, size(Bin)*8), 85: bit_split_binary2(Action, Bin, T, Bef+1); 86: bit_split_binary2(_, _, [], _) -> ok. 87: 88: bit_split_binary3(Action, Bin, List, Bef, Aft) when Bef =< Aft -> 89: Action(Bin, List, Bef, (Aft-Bef) div 8 * 8), 90: bit_split_binary3(Action, Bin, List, Bef, Aft-8); 91: bit_split_binary3(_, _, _, _, _) -> ok. 92: 93: make_bin_from_list(_, 0) -> mkbin([]); 94: make_bin_from_list(List, N) -> 95: list_to_binary([make_int(List, 8, 0), 96: make_bin_from_list(lists:nthtail(8, List), N-8)]). 97: 98: 99: make_int(_, 0, Acc) -> Acc; 100: make_int([H|T], N, Acc) -> make_int(T, N-1, Acc bsl 1 bor H). 101: 102: bits_to_list([_|T], 0) -> bits_to_list(T, 16#80); 103: bits_to_list([H|_]=List, Mask) -> 104: [case H band Mask of 105: 0 -> 0; 106: _ -> 1 107: end|bits_to_list(List, Mask bsr 1)]; 108: bits_to_list([], _) -> []. 109: 110: mkbin(L) when is_list(L) -> list_to_binary(L). 111: 112: make_unaligned_sub_binary(Bin0) -> 113: Bin1 = <<0:3,Bin0/binary,31:5>>, 114: Sz = size(Bin0), 115: <<0:3,Bin:Sz/binary,31:5>> = id(Bin1), 116: Bin. 117: 118: id(I) -> I. 119: 120: match_huge_bin(Config) when is_list(Config) -> 121: ?line Bin = <<0:(1 bsl 27),13:8>>, 122: ?line skip_huge_bin_1(1 bsl 27, Bin), 123: ?line 16777216 = match_huge_bin_1(1 bsl 27, Bin), 124: 125: %% Test overflowing the size of a binary field. 126: ?line nomatch = overflow_huge_bin_skip_32(Bin), 127: ?line nomatch = overflow_huge_bin_32(Bin), 128: ?line nomatch = overflow_huge_bin_skip_64(Bin), 129: ?line nomatch = overflow_huge_bin_64(Bin), 130: 131: %% Size in variable 132: ?line ok = overflow_huge_bin(Bin, lists:seq(25, 32)++lists:seq(50, 64)), 133: ?line ok = overflow_huge_bin_unit128(Bin, lists:seq(25, 32)++lists:seq(50, 64)), 134: 135: ok. 136: 137: overflow_huge_bin(Bin, [Sz0|Sizes]) -> 138: Sz = id(1 bsl Sz0), 139: case Bin of 140: <<_:Sz/binary-unit:8,0,_/binary>> -> 141: {error,Sz}; 142: _ -> 143: case Bin of 144: <<NewBin:Sz/binary-unit:8,0,_/binary>> -> 145: {error,Sz,size(NewBin)}; 146: _ -> 147: overflow_huge_bin(Bin, Sizes) 148: end 149: end; 150: overflow_huge_bin(_, []) -> ok. 151: 152: overflow_huge_bin_unit128(Bin, [Sz0|Sizes]) -> 153: Sz = id(1 bsl Sz0), 154: case Bin of 155: <<_:Sz/binary-unit:128,0,_/binary>> -> 156: {error,Sz}; 157: _ -> 158: case Bin of 159: <<NewBin:Sz/binary-unit:128,0,_/binary>> -> 160: {error,Sz,size(NewBin)}; 161: _ -> 162: overflow_huge_bin_unit128(Bin, Sizes) 163: end 164: end; 165: overflow_huge_bin_unit128(_, []) -> ok. 166: 167: skip_huge_bin_1(I, Bin) -> 168: <<_:I/binary-unit:1,13>> = Bin, 169: ok. 170: 171: match_huge_bin_1(I, Bin) -> 172: case Bin of 173: <<Val:I/binary-unit:1,13>> -> size(Val); 174: _ -> nomatch 175: end. 176: 177: overflow_huge_bin_skip_32(<<_:4294967296/binary,0,_/binary>>) -> 1; % 1 bsl 32 178: overflow_huge_bin_skip_32(<<_:33554432/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 25 179: overflow_huge_bin_skip_32(<<_:67108864/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 26 180: overflow_huge_bin_skip_32(<<_:134217728/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 27 181: overflow_huge_bin_skip_32(<<_:268435456/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 28 182: overflow_huge_bin_skip_32(<<_:536870912/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 29 183: overflow_huge_bin_skip_32(<<_:1073741824/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 30 184: overflow_huge_bin_skip_32(<<_:2147483648/binary-unit:8,0,_/binary>>) -> 8; % 1 bsl 31 185: overflow_huge_bin_skip_32(_) -> nomatch. 186: 187: overflow_huge_bin_32(<<Bin:4294967296/binary,_/binary>>) -> {1,Bin}; % 1 bsl 32 188: overflow_huge_bin_32(<<Bin:33554432/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 25 189: overflow_huge_bin_32(<<Bin:67108864/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 26 190: overflow_huge_bin_32(<<Bin:134217728/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 27 191: overflow_huge_bin_32(<<Bin:268435456/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 28 192: overflow_huge_bin_32(<<Bin:536870912/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 29 193: overflow_huge_bin_32(<<Bin:1073741824/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 30 194: overflow_huge_bin_32(<<Bin:2147483648/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 31 195: overflow_huge_bin_32(_) -> nomatch. 196: 197: overflow_huge_bin_skip_64(<<_:18446744073709551616/binary,0,_/binary>>) -> 1; % 1 bsl 64 198: overflow_huge_bin_skip_64(<<_:144115188075855872/binary-unit:128,0,_/binary>>) -> 2; % 1 bsl 57 199: overflow_huge_bin_skip_64(<<_:288230376151711744/binary-unit:64,0,_/binary>>) -> 3; % 1 bsl 58 200: overflow_huge_bin_skip_64(<<_:576460752303423488/binary-unit:32,0,_/binary>>) -> 4; % 1 bsl 59 201: overflow_huge_bin_skip_64(<<_:1152921504606846976/binary-unit:16,0,_/binary>>) -> 5; % 1 bsl 60 202: overflow_huge_bin_skip_64(<<_:2305843009213693952/binary-unit:8,0,_/binary>>) -> 6; % 1 bsl 61 203: overflow_huge_bin_skip_64(<<_:4611686018427387904/binary-unit:8,0,_/binary>>) -> 7; % 1 bsl 62 204: overflow_huge_bin_skip_64(<<_:9223372036854775808/binary-unit:8,_/binary>>) -> 8; % 1 bsl 63 205: overflow_huge_bin_skip_64(_) -> nomatch. 206: 207: overflow_huge_bin_64(<<Bin:18446744073709551616/binary,_/binary>>) -> {1,Bin}; % 1 bsl 64 208: overflow_huge_bin_64(<<Bin:144115188075855872/binary-unit:128,0,_/binary>>) -> {2,Bin}; % 1 bsl 57 209: overflow_huge_bin_64(<<Bin:288230376151711744/binary-unit:128,0,_/binary>>) -> {3,Bin}; % 1 bsl 58 210: overflow_huge_bin_64(<<Bin:576460752303423488/binary-unit:128,0,_/binary>>) -> {4,Bin}; % 1 bsl 59 211: overflow_huge_bin_64(<<Bin:1152921504606846976/binary-unit:128,0,_/binary>>) -> {5,Bin}; % 1 bsl 60 212: overflow_huge_bin_64(<<Bin:2305843009213693952/binary-unit:128,0,_/binary>>) -> {6,Bin}; % 1 bsl 61 213: overflow_huge_bin_64(<<Bin:4611686018427387904/binary-unit:128,0,_/binary>>) -> {7,Bin}; % 1 bsl 62 214: overflow_huge_bin_64(<<Bin:9223372036854775808/binary-unit:128,0,_/binary>>) -> {8,Bin}; % 1 bsl 63 215: overflow_huge_bin_64(_) -> nomatch.