%% Generated by prepare_templates. DO NOT EDIT THIS FILE.
%%
%% Input file: asn1ct_eval_uper.funcs

-module(asn1ct_eval_uper).
-export([encode_constrained_number/2,
encode_small_number/1]).

eint_bin_positive(Val) when Val < 256 ->
    <<Val>>;
eint_bin_positive(Val) when Val < 65536 ->
    <<Val:16>>;
eint_bin_positive(Val) when Val < 16777216 ->
    <<Val:24>>;
eint_bin_positive(Val) when Val < 4294967296 ->
    <<Val:32>>;
eint_bin_positive(Val) ->
    list_to_binary([eint_bin_positive2(Val bsr 32),<<Val:32>>]).

eint_bin_positive2(Val) when Val < 256 ->
    <<Val>>;
eint_bin_positive2(Val) when Val < 65536 ->
    <<Val:16>>;
eint_bin_positive2(Val) when Val < 16777216 ->
    <<Val:24>>;
eint_bin_positive2(Val) when Val < 4294967296 ->
    <<Val:32>>;
eint_bin_positive2(Val) ->
    [eint_bin_positive2(Val bsr 32),<<Val:32>>].

encode_constrained_number({Lb,Ub}, Val) when Val >= Lb, Ub >= Val ->
    Range = Ub - Lb + 1,
    Val2 = Val - Lb,
    NumBits = num_bits(Range),
    <<Val2:NumBits>>;
encode_constrained_number(Range, Val) ->
    exit({error,{asn1,{integer_range,Range,value,Val}}}).

encode_length(Len) ->
    if
        Len < 128 ->
            <<Len>>;
        Len < 16384 ->
            <<2:2,Len:14>>;
        true ->
            error({error,{asn1,{encode_length,{nyi,above_16k}}}})
    end.

encode_semi_constrained_number(Lb, Val) ->
    Val2 = Val - Lb,
    Bin = eint_bin_positive(Val2),
    Size = byte_size(Bin),
    if
        Size < 128 ->
            [<<Size>>,Bin];
        Size < 16384 ->
            [<<2:2,Size:14>>,Bin];
        true ->
            [encode_length(Size),Bin]
    end.

encode_small_number(Val) when Val < 64 ->
    <<Val:7>>;
encode_small_number(Val) ->
    [<<1:1>>|encode_semi_constrained_number(0, Val)].

num_bits(N) ->
    num_bits(N, 1, 0).

num_bits(N, T, B) when N =< T ->
    B;
num_bits(N, T, B) ->
    num_bits(N, T bsl 1, B + 1).
