-module(section). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([parse_raw_section/2, decode_custom_section/1, decode_memory_section/1, decode_section/2, from_raw_data/2]). -export_type([raw_section/0, section/0]). -type raw_section() :: {raw_section, integer(), integer(), gleam@option:option(bitstring())}. -type section() :: {custom, integer(), binary(), gleam@option:option(bitstring())} | {type, integer()} | {import, integer()} | {function, integer()} | {table, integer()} | {memory, integer(), list(types@limits:limits())} | {global, integer()} | {export, integer()} | {start, integer()} | {element, integer()} | {code, integer()} | {data, integer()} | {data_count, integer()}. -spec parse_raw_section(integer(), bitstring()) -> {ok, raw_section()} | {error, binary()}. parse_raw_section(Position, Raw_data) -> gleam@result:'try'( case gleam_stdlib:bit_array_slice(Raw_data, Position, 1) of {ok, Section_type_id_raw_data} -> case Section_type_id_raw_data of <> -> {ok, Section_type_id_decoded}; _ -> {error, <<"section::parse_raw_section: can't decode section type id raw data into an integer"/utf8>>} end; {error, _} -> {error, <<"section::parse_raw_section: can't get section type id raw data"/utf8>>} end, fun(Section_type_id) -> gleam@result:'try'( util:decode_u32leb128(Position + 1, Raw_data), fun(_use0) -> {Section_length, Section_length_word_size} = _use0, Section_raw_content = case Section_length > 0 of true -> gleam@bool:guard( (((Position + 1) + Section_length_word_size) + Section_length) > erlang:byte_size(Raw_data), {error, <<"section::parse_raw_section: unexpected end of the section's content segment"/utf8>>}, fun() -> case gleam_stdlib:bit_array_slice( Raw_data, (Position + 1) + Section_length_word_size, Section_length ) of {ok, Content} -> {ok, {some, Content}}; {error, _} -> {error, <<"section::parse_raw_section: can't get the section's content segment"/utf8>>} end end ); false -> {ok, none} end, gleam@result:'try'(case Section_raw_content of {ok, V} -> {ok, V}; {error, Reason} -> {error, Reason} end, fun(Section_raw_content@1) -> {ok, {raw_section, Section_type_id, Section_length, Section_raw_content@1}} end) end ) end ). -spec decode_custom_section(raw_section()) -> {ok, section()} | {error, binary()}. decode_custom_section(Raw_section) -> case erlang:element(4, Raw_section) of {some, Content} -> gleam@result:'try'( types@name:from_raw_data(0, Content), fun(Custom_section_name) -> gleam@result:'try'( types@name:to_string(Custom_section_name), fun(Name_string) -> Name_length = types@name:length(Custom_section_name), Content_length = erlang:byte_size(Content), case gleam_stdlib:bit_array_slice( Content, Name_length + 1, (Content_length - Name_length) - 1 ) of {ok, Custom_data} -> {ok, {custom, erlang:element(3, Raw_section), Name_string, {some, Custom_data}}}; {error, _} -> {error, <<"section::decode_custom_section: can't get custom data"/utf8>>} end end ) end ); none -> {error, <<"section::decode_custom_section: empty section content"/utf8>>} end. -spec decode_memory_section(raw_section()) -> {ok, section()} | {error, binary()}. decode_memory_section(Raw_section) -> case erlang:element(4, Raw_section) of {some, Content} -> gleam@result:'try'( types@vector:from_raw_data(0, Content), fun(Raw_vec) -> gleam@result:'try'( types@limits:from_vector(Raw_vec), fun(Mem_vec) -> {ok, {memory, erlang:element(3, Raw_section), erlang:element(1, Mem_vec)}} end ) end ); none -> {error, <<"section::decode_memory_section: empty section content"/utf8>>} end. -spec decode_section(integer(), bitstring()) -> {ok, section()} | {error, binary()}. decode_section(Position, Raw_data) -> gleam@result:'try'( parse_raw_section(Position, Raw_data), fun(Parsed_raw_section) -> case erlang:element(2, Parsed_raw_section) of N when N =:= 16#00 -> decode_custom_section(Parsed_raw_section); N@1 when N@1 =:= 16#05 -> decode_memory_section(Parsed_raw_section); _ -> {error, <<<<"section::decode_section: unknown section type id \""/utf8, (gleam@int:to_string( erlang:element(2, Parsed_raw_section) ))/binary>>/binary, "\""/utf8>>} end end ). -spec from_raw_data(integer(), bitstring()) -> {ok, section()} | {error, binary()}. from_raw_data(Position, Raw_data) -> gleam@result:'try'( decode_section(Position, Raw_data), fun(Sec) -> {ok, Sec} end ).