1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2012-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(asn1rtt_per).
21
22-export([skipextensions/3,complete/1]).
23
24skipextensions(Bytes0, Nr, ExtensionBitstr) when is_bitstring(ExtensionBitstr) ->
25    Prev = Nr - 1,
26    case ExtensionBitstr of
27	<<_:Prev,1:1,_/bitstring>> ->
28	    {Len,Bytes1} = decode_length(Bytes0),
29	    <<_:Len/binary,Bytes2/bitstring>> = Bytes1,
30	    skipextensions(Bytes2, Nr+1, ExtensionBitstr);
31	<<_:Prev,0:1,_/bitstring>> ->
32	    skipextensions(Bytes0, Nr+1, ExtensionBitstr);
33	_ ->
34	    Bytes0
35    end.
36
37align(Bin) when is_binary(Bin) ->
38    Bin;
39align(BitStr) when is_bitstring(BitStr) ->
40    AlignBits = bit_size(BitStr) rem 8,
41    <<_:AlignBits,Rest/binary>> = BitStr,
42    Rest.
43
44decode_length(Buffer)  -> % un-constrained
45    case align(Buffer) of
46	<<0:1,Oct:7,Rest/binary>> ->
47	    {Oct,Rest};
48	<<2:2,Val:14,Rest/binary>> ->
49	    {Val,Rest};
50	<<3:2,_Val:14,_Rest/binary>> ->
51	    %% this case should be fixed
52	    exit({error,{asn1,{decode_length,{nyi,above_16k}}}})
53    end.
54
55%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56%% complete(InList) -> ByteList
57%% Takes a coded list with bits and bytes and converts it to a list of bytes
58%% Should be applied as the last step at encode of a complete ASN.1 type
59%%
60
61complete(L0) ->
62    L = complete(L0, []),
63    case list_to_bitstring(L) of
64	<<>> -> <<0>>;
65	Bin -> Bin
66    end.
67
68complete([], []) ->
69    [];
70complete([], [H|More]) ->
71    complete(H, More);
72complete([align|T], More) ->
73    complete(T, More);
74complete([[]|T], More) ->
75    complete(T, More);
76complete([[_|_]=H], More) ->
77    complete(H, More);
78complete([[_|_]=H|T], More) ->
79    complete(H, [T|More]);
80complete([H|T], More) when is_integer(H); is_binary(H) ->
81    [H|complete(T, More)];
82complete([H|T], More) ->
83    [H|complete(T, bit_size(H), More)];
84complete(Bin, More) when is_binary(Bin) ->
85    [Bin|complete([], More)];
86complete(Bin, More) ->
87    [Bin|complete([], bit_size(Bin), More)].
88
89complete([], Bits, []) ->
90    case Bits band 7 of
91	0 -> [];
92	N -> [<<0:(8-N)>>]
93    end;
94complete([], Bits, [H|More]) ->
95    complete(H, Bits, More);
96complete([align|T], Bits, More) ->
97    case Bits band 7 of
98	0 -> complete(T, More);
99	1 -> [<<0:7>>|complete(T, More)];
100	2 -> [<<0:6>>|complete(T, More)];
101	3 -> [<<0:5>>|complete(T, More)];
102	4 -> [<<0:4>>|complete(T, More)];
103	5 -> [<<0:3>>|complete(T, More)];
104	6 -> [<<0:2>>|complete(T, More)];
105	7 -> [<<0:1>>|complete(T, More)]
106    end;
107complete([[]|T], Bits, More) ->
108    complete(T, Bits, More);
109complete([[_|_]=H], Bits, More) ->
110    complete(H, Bits, More);
111complete([[_|_]=H|T], Bits, More) ->
112    complete(H, Bits, [T|More]);
113complete([H|T], Bits, More) when is_integer(H);
114				 is_binary(H) ->
115    [H|complete(T, Bits, More)];
116complete([H|T], Bits, More) ->
117    [H|complete(T, Bits+bit_size(H), More)];
118complete(Bin, Bits, More) when is_binary(Bin) ->
119    [Bin|complete([], Bits, More)];
120complete(Bin, Bits, More) ->
121    [Bin|complete([], Bits+bit_size(Bin), More)].
122