-module(gleamlz_string). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([decompress_from_uint8/1, decompress_from_base64/1, decompress_from_encoded_uri/1, compress_to_uint8/1, compress_to_base64/1, compress_to_encoded_uri/1]). -export_type([decompress_error/0, decode_type/0]). -type decompress_error() :: e_invalid_input. -type decode_type() :: {char, {bitstring(), bitstring(), gleam@dict:dict(integer(), bitstring())}} | {index, {integer(), bitstring()}} | eof. -spec decode_base64( list(binary()), gleam@dict:dict(binary(), integer()), bitstring() ) -> {ok, bitstring()} | {error, decompress_error()}. decode_base64(String_list, Key_dict, Bitstring) -> case String_list of [Char | Rest] -> case gleam@dict:get(Key_dict, Char) of {ok, Num} -> decode_base64( Rest, Key_dict, <>/bitstring>> ); _ -> {error, e_invalid_input} end; [] -> {ok, Bitstring} end. -spec to_utf16(bitstring(), binary()) -> {ok, binary()} | {error, decompress_error()}. to_utf16(Bitstring, String) -> case Bitstring of <<>> -> {ok, String}; <> -> case Bytes of Surrogate when (Surrogate >= 16#D800) andalso (Surrogate =< 16#DFFF) -> case Surrogate of High when (High >= 16#D800) andalso (High =< 16#DBFF) -> case Rest of <> -> Codepoint = (((High - 16#D800) * 16#400) + (Low - 16#DC00)) + 16#10000, _assert_subject = gleam@string:utf_codepoint( Codepoint ), {ok, Codepoint@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"gleamlz_string"/utf8>>, function => <<"to_utf16"/utf8>>, line => 326} ) end, to_utf16( Rest@1, <> ); _ -> {error, e_invalid_input} end; _ -> {error, e_invalid_input} end; Other -> _assert_subject@2 = case Other of 65534 -> gleam@bit_array:to_string(<<239, 191, 190>>); 65535 -> gleam@bit_array:to_string(<<239, 191, 191>>); Any -> _assert_subject@1 = gleam@string:utf_codepoint(Any), {ok, Codepoint@2} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"gleamlz_string"/utf8>>, function => <<"to_utf16"/utf8>>, line => 347}) end, {ok, gleam_stdlib:utf_codepoint_list_to_string( [Codepoint@2] )} end, {ok, Str} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"gleamlz_string"/utf8>>, function => <<"to_utf16"/utf8>>, line => 339}) end, to_utf16(Rest, <>) end; _ -> {error, e_invalid_input} end. -spec find_bits(integer()) -> integer(). find_bits(Num) -> _pipe = Num, _pipe@1 = gleam@int:to_base2(_pipe), gleam@string:length(_pipe@1). -spec reverse(bitstring()) -> bitstring(). reverse(Bitstring) -> case Bitstring of <<>> -> <<>>; _ -> <> = case Bitstring of <<_:1/bitstring, _/bitstring>> -> Bitstring; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"gleamlz_string"/utf8>>, function => <<"reverse"/utf8>>, line => 374}) end, gleam@bit_array:append(reverse(Rest), Value) end. -spec w_output( binary(), gleam@dict:dict(binary(), {integer(), boolean()}), boolean() ) -> {gleam@dict:dict(binary(), {integer(), boolean()}), bitstring()}. w_output(W, Dict, Char_just_added) -> _assert_subject = gleam@dict:get(Dict, W), {ok, Var} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"gleamlz_string"/utf8>>, function => <<"w_output"/utf8>>, line => 174}) end, case Var of {Index, true} -> Dict@1 = gleam@dict:insert(Dict, W, {Index, false}), Marker_size = find_bits(Index), _assert_subject@1 = <>, <> = case _assert_subject@1 of <<_/utf8, _/bitstring>> -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"gleamlz_string"/utf8>>, function => <<"w_output"/utf8>>, line => 180}) end, Char_val = gleam@string:utf_codepoint_to_int(Char_codepoint), {Size_marker, Char_size} = (case find_bits(Char_val) of Index@1 when Index@1 =< 8 -> {0, 8}; _ -> {1, 16} end), Size_marker_bits = reverse( <> ), Char_bits = reverse(<>), {Dict@1, <>}; {Index@2, false} -> Map_size = maps:size(Dict) + 2, Map_size@1 = case Char_just_added of true -> Map_size - 1; false -> Map_size end, Size = find_bits(Map_size@1), {Dict, reverse(<>)} end. -spec compress_string( binary(), list(integer()), gleam@dict:dict(binary(), {integer(), boolean()}), bitstring() ) -> bitstring(). compress_string(W, Str, Dict, Final_str) -> case Str of [] -> Size = find_bits(maps:size(Dict) + 2), {_, Output} = w_output(W, Dict, false), <>))/bitstring>>; [C | Rest] -> Char_just_added = not gleam@dict:has_key( Dict, gleam_stdlib:utf_codepoint_list_to_string([C]) ), Dict@1 = case Char_just_added of true -> gleam@dict:insert( Dict, gleam_stdlib:utf_codepoint_list_to_string([C]), {maps:size(Dict) + 3, true} ); false -> Dict end, Wc = <>, case gleam@dict:has_key(Dict@1, Wc) of true -> compress_string(Wc, Rest, Dict@1, Final_str); false -> {Dict@2, Output@1} = w_output(W, Dict@1, Char_just_added), Dict@3 = gleam@dict:insert( Dict@2, Wc, {maps:size(Dict@2) + 3, false} ), compress_string( gleam_stdlib:utf_codepoint_list_to_string([C]), Rest, Dict@3, <> ) end end. -spec decode_next_segment(bitstring(), gleam@dict:dict(integer(), bitstring())) -> {ok, decode_type()} | {error, decompress_error()}. decode_next_segment(Bitstring, Dict) -> Size = begin _pipe = (maps:size(Dict) + 3), find_bits(_pipe) end, case Bitstring of <> -> _assert_subject = reverse(<>), <> = case _assert_subject of <<_:Size>> -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"gleamlz_string"/utf8>>, function => <<"decode_next_segment"/utf8>>, line => 273}) end, case Dict_entry@1 of 0 -> case Rest of <> -> _assert_subject@1 = reverse(<>), <> = case _assert_subject@1 of <<_:8>> -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"gleamlz_string"/utf8>>, function => <<"decode_next_segment"/utf8>>, line => 278}) end, _assert_subject@2 = gleam@string:utf_codepoint(C@1), {ok, Codepoint} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"gleamlz_string"/utf8>>, function => <<"decode_next_segment"/utf8>>, line => 279}) end, Char = <>, Dict@1 = gleam@dict:insert( Dict, maps:size(Dict) + 3, Char ), {ok, {char, {Char, Rest@1, Dict@1}}}; _ -> {error, e_invalid_input} end; 1 -> case Rest of <> -> _assert_subject@3 = reverse(<>), <> = case _assert_subject@3 of <<_:16>> -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"gleamlz_string"/utf8>>, function => <<"decode_next_segment"/utf8>>, line => 290}) end, Char@1 = <>, Dict@2 = gleam@dict:insert( Dict, maps:size(Dict) + 3, Char@1 ), {ok, {char, {Char@1, Rest@2, Dict@2}}}; _ -> {error, e_invalid_input} end; 2 -> {ok, eof}; Index -> {ok, {index, {Index, Rest}}} end; _ -> {error, e_invalid_input} end. -spec decompress_string( bitstring(), bitstring(), gleam@dict:dict(integer(), bitstring()), bitstring() ) -> {ok, bitstring()} | {error, decompress_error()}. decompress_string(W, Str, Dict, Final_str) -> gleam@result:'try'( decode_next_segment(Str, Dict), fun(Return) -> case Return of {char, Char} -> Dict@1 = gleam@dict:insert( erlang:element(3, Char), maps:size(erlang:element(3, Char)) + 3, gleam@bit_array:append(W, erlang:element(1, Char)) ), decompress_string( erlang:element(1, Char), erlang:element(2, Char), Dict@1, <> ); {index, Seq} -> C = case gleam@dict:get(Dict, erlang:element(1, Seq)) of {ok, Value} -> {ok, Value}; {error, nil} -> case (maps:size(Dict) + 3) =:= erlang:element( 1, Seq ) of true -> {ok, gleam@bit_array:append( W, <> )}; false -> {error, e_invalid_input} end end, gleam@result:'try'( C, fun(C@1) -> Dict@2 = gleam@dict:insert( Dict, maps:size(Dict) + 3, gleam@bit_array:append(W, <>) ), decompress_string( C@1, erlang:element(2, Seq), Dict@2, <> ) end ); eof -> {ok, <>} end end ). -spec decompress(bitstring()) -> {ok, binary()} | {error, decompress_error()}. decompress(Bstring) -> case Bstring of <<>> -> {ok, <<""/utf8>>}; _ -> gleam@result:'try'( decode_next_segment(Bstring, gleam@dict:new()), fun(Return) -> case Return of {char, Char} -> gleam@result:'try'( decompress_string( erlang:element(1, Char), erlang:element(2, Char), erlang:element(3, Char), <<>> ), fun(String) -> to_utf16(String, <<""/utf8>>) end ); _ -> {error, e_invalid_input} end end ) end. -spec decompress_from_uint8(bitstring()) -> {ok, binary()} | {error, decompress_error()}. decompress_from_uint8(Bits) -> decompress(Bits). -spec decompress_from_base64(binary()) -> {ok, binary()} | {error, decompress_error()}. decompress_from_base64(Base64_string) -> _pipe = <<"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="/utf8>>, _pipe@1 = gleam@string:to_graphemes(_pipe), _pipe@2 = gleam@list:index_map(_pipe@1, fun(X, I) -> {X, I} end), _pipe@3 = maps:from_list(_pipe@2), _pipe@4 = decode_base64( gleam@string:to_graphemes(Base64_string), _pipe@3, <<>> ), gleam@result:'try'(_pipe@4, fun decompress/1). -spec decompress_from_encoded_uri(binary()) -> {ok, binary()} | {error, decompress_error()}. decompress_from_encoded_uri(Uri_string) -> _pipe = Uri_string, _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"/"/utf8>>), _pipe@2 = gleam@string:replace(_pipe@1, <<"$"/utf8>>, <<"="/utf8>>), decompress_from_base64(_pipe@2). -spec bit_size(bitstring(), integer()) -> integer(). bit_size(Bits, Size) -> case Bits of <<_:1/bitstring, Rest/bitstring>> -> bit_size(Rest, Size + 1); _ -> Size end. -spec compress(binary()) -> bitstring(). compress(String) -> case String of <<""/utf8>> -> <<""/utf8>>; _ -> Bitstring = begin _pipe = gleam@string:to_utf_codepoints(String), compress_string(<<""/utf8>>, _pipe, gleam@dict:new(), <<>>) end, Padding_bits = 16 - (begin _pipe@1 = Bitstring, bit_size(_pipe@1, 0) end rem 16), <> end. -spec compress_to_uint8(binary()) -> bitstring(). compress_to_uint8(String) -> compress(String). -spec compress_to_base64(binary()) -> binary(). compress_to_base64(String) -> _pipe = String, _pipe@1 = compress(_pipe), gleam_stdlib:bit_array_base64_encode(_pipe@1, true). -spec compress_to_encoded_uri(binary()) -> binary(). compress_to_encoded_uri(String) -> _pipe = String, _pipe@1 = compress_to_base64(_pipe), _pipe@2 = gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"-"/utf8>>), gleam@string:replace(_pipe@2, <<"="/utf8>>, <<"$"/utf8>>).