-module(qrkit@internal@mode).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/qrkit/internal/mode.gleam").
-export([mode_bits/1, char_count_bits/2, utf8_byte_length/1, character_count/2, is_numeric_char/1, numeric_bits_length/1, alphanumeric_bits_length/1, data_bits_length/2, numeric_increment_cost/1, alphanumeric_increment_cost/1, is_kanji_char/1, is_alphanumeric_char/1, encode/3]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-file("src/qrkit/internal/mode.gleam", 18).
?DOC(false).
-spec mode_bits(qrkit@types:mode()) -> integer().
mode_bits(Mode) ->
case Mode of
numeric ->
2#0001;
alphanumeric ->
2#0010;
byte ->
2#0100;
kanji ->
2#1000
end.
-file("src/qrkit/internal/mode.gleam", 27).
?DOC(false).
-spec char_count_bits(qrkit@types:mode(), integer()) -> integer().
char_count_bits(Mode, Version) ->
case Version < 10 of
true ->
case Mode of
numeric ->
10;
alphanumeric ->
9;
byte ->
8;
kanji ->
8
end;
false ->
case Version < 27 of
true ->
case Mode of
numeric ->
12;
alphanumeric ->
11;
byte ->
16;
kanji ->
10
end;
false ->
case Mode of
numeric ->
14;
alphanumeric ->
13;
byte ->
16;
kanji ->
12
end
end
end.
-file("src/qrkit/internal/mode.gleam", 72).
?DOC(false).
-spec utf8_byte_length(binary()) -> integer().
utf8_byte_length(Text) ->
_pipe = Text,
_pipe@1 = gleam_stdlib:identity(_pipe),
erlang:byte_size(_pipe@1).
-file("src/qrkit/internal/mode.gleam", 56).
?DOC(false).
-spec character_count(binary(), qrkit@types:mode()) -> integer().
character_count(Data, Mode) ->
case Mode of
byte ->
utf8_byte_length(Data);
_ ->
erlang:length(qrkit@internal@util:characters(Data))
end.
-file("src/qrkit/internal/mode.gleam", 76).
?DOC(false).
-spec is_numeric_char(binary()) -> boolean().
is_numeric_char(Char) ->
case gleam_stdlib:parse_int(Char) of
{ok, Value} ->
(Value >= 0) andalso (Value =< 9);
{error, _} ->
false
end.
-file("src/qrkit/internal/mode.gleam", 104).
?DOC(false).
-spec numeric_bits_length(integer()) -> integer().
numeric_bits_length(Length) ->
(10 * (Length div 3)) + case Length rem 3 of
0 ->
0;
1 ->
4;
_ ->
7
end.
-file("src/qrkit/internal/mode.gleam", 114).
?DOC(false).
-spec alphanumeric_bits_length(integer()) -> integer().
alphanumeric_bits_length(Length) ->
(11 * (Length div 2)) + case Length rem 2 of
0 ->
0;
_ ->
6
end.
-file("src/qrkit/internal/mode.gleam", 63).
?DOC(false).
-spec data_bits_length(binary(), qrkit@types:mode()) -> integer().
data_bits_length(Data, Mode) ->
case Mode of
numeric ->
numeric_bits_length(
erlang:length(qrkit@internal@util:characters(Data))
);
alphanumeric ->
alphanumeric_bits_length(
erlang:length(qrkit@internal@util:characters(Data))
);
byte ->
utf8_byte_length(Data) * 8;
kanji ->
erlang:length(qrkit@internal@util:characters(Data)) * 13
end.
-file("src/qrkit/internal/mode.gleam", 123).
?DOC(false).
-spec numeric_increment_cost(integer()) -> integer().
numeric_increment_cost(Mod3) ->
case Mod3 of
0 ->
4;
_ ->
3
end.
-file("src/qrkit/internal/mode.gleam", 130).
?DOC(false).
-spec alphanumeric_increment_cost(integer()) -> integer().
alphanumeric_increment_cost(Mod2) ->
case Mod2 of
0 ->
6;
_ ->
5
end.
-file("src/qrkit/internal/mode.gleam", 200).
?DOC(false).
-spec encode_byte(binary()) -> bitstring().
encode_byte(Data) ->
gleam_stdlib:identity(Data).
-file("src/qrkit/internal/mode.gleam", 241).
?DOC(false).
-spec do_alphanumeric_value(list(binary()), binary(), integer()) -> {ok,
integer()} |
{error, nil}.
do_alphanumeric_value(Chars, Needle, Index) ->
case Chars of
[] ->
{error, nil};
[Char | Rest] ->
case Char =:= Needle of
true ->
{ok, Index};
false ->
do_alphanumeric_value(Rest, Needle, Index + 1)
end
end.
-file("src/qrkit/internal/mode.gleam", 256).
?DOC(false).
-spec must_parse(binary()) -> integer().
must_parse(Text) ->
case gleam_stdlib:parse_int(Text) of
{ok, Value} ->
Value;
{error, _} ->
0
end.
-file("src/qrkit/internal/mode.gleam", 142).
?DOC(false).
-spec do_encode_numeric(list(binary()), qrkit@internal@bitstream:bit_stream()) -> qrkit@internal@bitstream:bit_stream().
do_encode_numeric(Chars, Stream) ->
case Chars of
[A, B, C | Rest] ->
Value = must_parse(<<<<A/binary, B/binary>>/binary, C/binary>>),
do_encode_numeric(
Rest,
qrkit@internal@bitstream:append_bits(Stream, Value, 10)
);
[A@1, B@1] ->
Value@1 = must_parse(<<A@1/binary, B@1/binary>>),
qrkit@internal@bitstream:append_bits(Stream, Value@1, 7);
[A@2] ->
Value@2 = must_parse(A@2),
qrkit@internal@bitstream:append_bits(Stream, Value@2, 4);
[] ->
Stream
end.
-file("src/qrkit/internal/mode.gleam", 137).
?DOC(false).
-spec encode_numeric(binary()) -> bitstring().
encode_numeric(Data) ->
_pipe = do_encode_numeric(
qrkit@internal@util:characters(Data),
qrkit@internal@bitstream:new()
),
qrkit@internal@bitstream:to_bit_array(_pipe).
-file("src/qrkit/internal/mode.gleam", 263).
?DOC(false).
-spec is_ok({ok, any()} | {error, any()}) -> boolean().
is_ok(Result) ->
case Result of
{ok, _} ->
true;
{error, _} ->
false
end.
-file("src/qrkit/internal/mode.gleam", 304).
?DOC(false).
-spec katakana_sjis(integer()) -> integer().
katakana_sjis(Codepoint) ->
Offset = Codepoint - 16#30A1,
case Offset >= 63 of
true ->
(16#8340 + Offset) + 1;
false ->
16#8340 + Offset
end.
-file("src/qrkit/internal/mode.gleam", 312).
?DOC(false).
-spec punctuation_sjis(integer()) -> {ok, integer()} | {error, nil}.
punctuation_sjis(Codepoint) ->
case Codepoint of
16#3000 ->
{ok, 16#8140};
16#3001 ->
{ok, 16#8141};
16#3002 ->
{ok, 16#8142};
16#30FC ->
{ok, 16#815B};
_ ->
{error, nil}
end.
-file("src/qrkit/internal/mode.gleam", 281).
?DOC(false).
-spec codepoint_to_sjis(integer()) -> {ok, integer()} | {error, nil}.
codepoint_to_sjis(Codepoint) ->
case (Codepoint >= 16#3041) andalso (Codepoint =< 16#3093) of
true ->
{ok, (16#829F + Codepoint) - 16#3041};
false ->
case (Codepoint >= 16#30A1) andalso (Codepoint =< 16#30F6) of
true ->
{ok, katakana_sjis(Codepoint)};
false ->
case (Codepoint >= 16#FF10) andalso (Codepoint =< 16#FF19) of
true ->
{ok, (16#824F + Codepoint) - 16#FF10};
false ->
case (Codepoint >= 16#FF21) andalso (Codepoint =< 16#FF3A) of
true ->
{ok, (16#8260 + Codepoint) - 16#FF21};
false ->
case (Codepoint >= 16#FF41) andalso (Codepoint
=< 16#FF5A) of
true ->
{ok,
(16#8281 + Codepoint) - 16#FF41};
false ->
punctuation_sjis(Codepoint)
end
end
end
end
end.
-file("src/qrkit/internal/mode.gleam", 270).
?DOC(false).
-spec to_sjis(binary()) -> {ok, integer()} | {error, nil}.
to_sjis(Char) ->
case qrkit@internal@util:characters(Char) of
[First] ->
case gleam@string:to_utf_codepoints(First) of
[Codepoint] ->
codepoint_to_sjis(gleam_stdlib:identity(Codepoint));
_ ->
{error, nil}
end;
_ ->
{error, nil}
end.
-file("src/qrkit/internal/mode.gleam", 87).
?DOC(false).
-spec is_kanji_char(binary()) -> boolean().
is_kanji_char(Char) ->
_pipe = Char,
_pipe@1 = to_sjis(_pipe),
is_ok(_pipe@1).
-file("src/qrkit/internal/mode.gleam", 211).
?DOC(false).
-spec do_encode_kanji(
list(binary()),
integer(),
qrkit@internal@bitstream:bit_stream()
) -> {ok, bitstring()} | {error, qrkit@error:encode_error()}.
do_encode_kanji(Chars, Index, Stream) ->
case Chars of
[Char | Rest] ->
case to_sjis(Char) of
{ok, Sjis} ->
Adjusted = case (Sjis >= 16#8140) andalso (Sjis =< 16#9FFC) of
true ->
Sjis - 16#8140;
false ->
Sjis - 16#C140
end,
Value = ((Adjusted div 256) * 16#C0) + (Adjusted rem 256),
do_encode_kanji(
Rest,
Index + 1,
qrkit@internal@bitstream:append_bits(Stream, Value, 13)
);
{error, _} ->
{error, {unsupported_character, Index, Char}}
end;
[] ->
{ok, qrkit@internal@bitstream:to_bit_array(Stream)}
end.
-file("src/qrkit/internal/mode.gleam", 204).
?DOC(false).
-spec encode_kanji(binary(), integer()) -> {ok, bitstring()} |
{error, qrkit@error:encode_error()}.
encode_kanji(Data, Index) ->
do_encode_kanji(
qrkit@internal@util:characters(Data),
Index,
qrkit@internal@bitstream:new()
).
-file("src/qrkit/internal/mode.gleam", 237).
?DOC(false).
-spec alphanumeric_value(binary()) -> {ok, integer()} | {error, nil}.
alphanumeric_value(Char) ->
do_alphanumeric_value(
[<<"0"/utf8>>,
<<"1"/utf8>>,
<<"2"/utf8>>,
<<"3"/utf8>>,
<<"4"/utf8>>,
<<"5"/utf8>>,
<<"6"/utf8>>,
<<"7"/utf8>>,
<<"8"/utf8>>,
<<"9"/utf8>>,
<<"A"/utf8>>,
<<"B"/utf8>>,
<<"C"/utf8>>,
<<"D"/utf8>>,
<<"E"/utf8>>,
<<"F"/utf8>>,
<<"G"/utf8>>,
<<"H"/utf8>>,
<<"I"/utf8>>,
<<"J"/utf8>>,
<<"K"/utf8>>,
<<"L"/utf8>>,
<<"M"/utf8>>,
<<"N"/utf8>>,
<<"O"/utf8>>,
<<"P"/utf8>>,
<<"Q"/utf8>>,
<<"R"/utf8>>,
<<"S"/utf8>>,
<<"T"/utf8>>,
<<"U"/utf8>>,
<<"V"/utf8>>,
<<"W"/utf8>>,
<<"X"/utf8>>,
<<"Y"/utf8>>,
<<"Z"/utf8>>,
<<" "/utf8>>,
<<"$"/utf8>>,
<<"%"/utf8>>,
<<"*"/utf8>>,
<<"+"/utf8>>,
<<"-"/utf8>>,
<<"."/utf8>>,
<<"/"/utf8>>,
<<":"/utf8>>],
Char,
0
).
-file("src/qrkit/internal/mode.gleam", 83).
?DOC(false).
-spec is_alphanumeric_char(binary()) -> boolean().
is_alphanumeric_char(Char) ->
_pipe = Char,
_pipe@1 = alphanumeric_value(_pipe),
is_ok(_pipe@1).
-file("src/qrkit/internal/mode.gleam", 170).
?DOC(false).
-spec do_encode_alphanumeric(
list(binary()),
integer(),
qrkit@internal@bitstream:bit_stream()
) -> {ok, bitstring()} | {error, qrkit@error:encode_error()}.
do_encode_alphanumeric(Chars, Index, Stream) ->
case Chars of
[A, B | Rest] ->
case {alphanumeric_value(A), alphanumeric_value(B)} of
{{ok, First}, {ok, Second}} ->
do_encode_alphanumeric(
Rest,
Index + 2,
qrkit@internal@bitstream:append_bits(
Stream,
(First * 45) + Second,
11
)
);
{{error, _}, _} ->
{error, {unsupported_character, Index, A}};
{_, {error, _}} ->
{error, {unsupported_character, Index + 1, B}}
end;
[A@1] ->
case alphanumeric_value(A@1) of
{ok, Value} ->
{ok,
begin
_pipe = qrkit@internal@bitstream:append_bits(
Stream,
Value,
6
),
qrkit@internal@bitstream:to_bit_array(_pipe)
end};
{error, _} ->
{error, {unsupported_character, Index, A@1}}
end;
[] ->
{ok, qrkit@internal@bitstream:to_bit_array(Stream)}
end.
-file("src/qrkit/internal/mode.gleam", 163).
?DOC(false).
-spec encode_alphanumeric(binary(), integer()) -> {ok, bitstring()} |
{error, qrkit@error:encode_error()}.
encode_alphanumeric(Data, Index) ->
do_encode_alphanumeric(
qrkit@internal@util:characters(Data),
Index,
qrkit@internal@bitstream:new()
).
-file("src/qrkit/internal/mode.gleam", 91).
?DOC(false).
-spec encode(binary(), qrkit@types:mode(), integer()) -> {ok, bitstring()} |
{error, qrkit@error:encode_error()}.
encode(Data, Mode, Index) ->
case Mode of
numeric ->
{ok, encode_numeric(Data)};
alphanumeric ->
encode_alphanumeric(Data, Index);
byte ->
{ok, encode_byte(Data)};
kanji ->
encode_kanji(Data, Index)
end.