Current section
Files
Jump to
Current section
Files
src/brot.erl
-module(brot).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/brot.gleam").
-export([encode/1, decode/1, encode_with/2, new_encoder/0, new_encoder_with/1, append_encoder/2, is_encoder_finished/1, finish_encoder/1, finish_encoder_with/2, new_decoder/0, stream_decoder/2, is_decoder_finished/1]).
-export_type([mode/0, options/0, encoder/0, decoder/0, stream_outcome/0]).
-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(
" Brotli is a general-purpose compression algorithm developed by Google that\n"
" offers compression ratios comparable to the best currently available \n"
" methods. It's particularly effective for web content and is supported \n"
" natively by all modern browsers.\n"
" \n"
" Brotli compression is most effective for data larger than ~1KB. For very \n"
" small data, the compression overhead may result in larger output.\n"
" \n"
" ### Examples\n"
" \n"
" Simple decompression:\n"
" ```gleam\n"
" simplifile.read_bits(\"payload.br\")\n"
" |> result.replace_error(Nil)\n"
" |> result.try(brot.decode)\n"
" ```\n"
" \n"
" Encoding with custom options:\n"
" ```gleam\n"
" brot.Options(..brot.default_options, quality: 3, window: 10)\n"
" |> brot.encode_with(payload, _)\n"
" |> result.map(simplifile.write_bits(\"payload.br\", _))\n"
" ```\n"
" \n"
" Working with streaming data:\n"
" ```gleam\n"
" let encoder = brot.new_encoder()\n"
" list.map(chunks, brot.append_encoder(encoder, _))\n"
" brot.finish_encoder(encoder)\n"
" ```\n"
" \n"
" <script>\n"
" const docs = [\n"
" {\n"
" header: \"Options\",\n"
" functions: [\"default_options\"]\n"
" },\n"
" {\n"
" header: \"Simple\",\n"
" functions: [\"encode\", \"decode\", \"encode_with\"]\n"
" },\n"
" {\n"
" header: \"Encoder\",\n"
" functions: [\n"
" \"new_encoder\", \n"
" \"new_encoder_with\", \n"
" \"append_encoder\", \n"
" \"is_encoder_finished\", \n"
" \"finish_encoder\", \n"
" \"finish_encoder_with\"\n"
" ]\n"
" },\n"
" {\n"
" header: \"Decoder\",\n"
" functions: [\"new_decoder\", \"stream_decoder\", \"is_decoder_finished\"]\n"
" }\n"
" ]\n"
"\n"
" const callback = () => {\n"
" const list = document.querySelector(\".sidebar > ul:last-of-type\")\n"
" const sortedLists = document.createDocumentFragment()\n"
" const sortedMembers = document.createDocumentFragment()\n"
"\n"
" for (const section of docs) {\n"
" sortedLists.append((() => {\n"
" const node = document.createElement(\"h3\")\n"
" node.append(section.header)\n"
" return node\n"
" })())\n"
" sortedMembers.append((() => {\n"
" const node = document.createElement(\"h2\")\n"
" node.append(section.header)\n"
" return node\n"
" })())\n"
"\n"
" const sortedList = document.createElement(\"ul\")\n"
" sortedLists.append(sortedList)\n"
"\n"
" const sortedFunctions = [...section.functions].sort()\n"
"\n"
" for (const funcName of sortedFunctions) {\n"
" const href = `#${funcName}`\n"
" const member = document.querySelector(\n"
" `.member:has(h2 > a[href=\"${href}\"])`\n"
" )\n"
" const sidebar = list.querySelector(`li:has(a[href=\"${href}\"])`)\n"
" sortedList.append(sidebar)\n"
" sortedMembers.append(member)\n"
" }\n"
" }\n"
"\n"
" document.querySelector(\".sidebar\").insertBefore(sortedLists, list)\n"
" document\n"
" .querySelector(\".module-members:has(#module-values)\")\n"
" .insertBefore(\n"
" sortedMembers,\n"
" document.querySelector(\"#module-values\").nextSibling\n"
" )\n"
" }\n"
"\n"
" document.readyState !== \"loading\"\n"
" ? callback()\n"
" : document.addEventListener(\n"
" \"DOMContentLoaded\",\n"
" callback,\n"
" { once: true }\n"
" )\n"
" </script>\n"
).
-type mode() :: generic | text | font.
-type options() :: {options,
mode(),
integer(),
integer(),
integer(),
boolean(),
integer(),
boolean(),
integer(),
integer(),
integer()}.
-type encoder() :: any().
-type decoder() :: any().
-type stream_outcome() :: {done, bitstring()} | {more, bitstring()}.
-file("src/brot.gleam", 114).
?DOC(
" Compresses data using Brotli with default settings. For custom compression \n"
" settings, use `encode_with`. Returns the compressed data or an error if \n"
" compression fails.\n"
).
-spec encode(bitstring()) -> {ok, bitstring()} | {error, nil}.
encode(Data) ->
brot_ffi:encode(Data).
-file("src/brot.gleam", 119).
?DOC(
" Decompresses Brotli-compressed data. Returns the decompressed original data\n"
" or an error if decompression fails.\n"
).
-spec decode(bitstring()) -> {ok, bitstring()} | {error, nil}.
decode(Data) ->
brot_ffi:decode(Data).
-file("src/brot.gleam", 194).
?DOC(
" Compresses data using Brotli with custom options. This allows fine-tuned \n"
" control over compression parameters. Returns the compressed data, or an \n"
" error if compression fails.\n"
).
-spec encode_with(bitstring(), options()) -> {ok, bitstring()} | {error, nil}.
encode_with(Data, Options) ->
brot_ffi:encode_with(Data, Options).
-file("src/brot.gleam", 203).
?DOC(" Creates a new streaming encoder with default settings.\n").
-spec new_encoder() -> encoder().
new_encoder() ->
brotli_encoder:new().
-file("src/brot.gleam", 207).
?DOC(" Creates a new streaming encoder with custom options.\n").
-spec new_encoder_with(options()) -> encoder().
new_encoder_with(Options) ->
brot_ffi:new_encoder_with(Options).
-file("src/brot.gleam", 214).
?DOC(
" Appends data to a streaming encoder and returns any available compressed \n"
" output. The encoder may buffer data internally, so compressed output might \n"
" not be available immediately for small inputs. Returns an error if encoding\n"
" fails.\n"
).
-spec append_encoder(encoder(), bitstring()) -> {ok, bitstring()} | {error, nil}.
append_encoder(Encoder, Data) ->
brot_ffi:append_encoder(Encoder, Data).
-file("src/brot.gleam", 220).
?DOC(
" Checks if the encoder has finished processing and flushed all output. \n"
" Returns `True` if encoding is complete and all output has been flushed, \n"
" `False` otherwise.\n"
).
-spec is_encoder_finished(encoder()) -> boolean().
is_encoder_finished(Encoder) ->
brotli_encoder:is_finished(Encoder).
-file("src/brot.gleam", 227).
?DOC(
" Finalizes the encoder and returns any remaining compressed output. This \n"
" flushes all internal buffers and completes the compression stream. After \n"
" calling this, the encoder is finished and should not be used further. \n"
" Returns an error if finishing fails.\n"
).
-spec finish_encoder(encoder()) -> {ok, bitstring()} | {error, nil}.
finish_encoder(Encoder) ->
brot_ffi:finish_encoder(Encoder).
-file("src/brot.gleam", 234).
?DOC(
" Appends final data to the encoder and immediately finishes compression. This \n"
" is a convenience function that combines `append_encoder` and \n"
" `finish_encoder`. Returns all remaining compressed output, or an error if \n"
" encoding or finishing fails.\n"
).
-spec finish_encoder_with(encoder(), bitstring()) -> {ok, bitstring()} |
{error, nil}.
finish_encoder_with(Encoder, Data) ->
brot_ffi:finish_encoder_with(Encoder, Data).
-file("src/brot.gleam", 246).
?DOC(" Creates a new streaming decoder.\n").
-spec new_decoder() -> decoder().
new_decoder() ->
brotli_decoder:new().
-file("src/brot.gleam", 262).
?DOC(
" Feeds compressed data to a streaming decoder and returns decompressed output.\n"
" The decoder processes data incrementally and indicates whether more input is \n"
" needed. Returns an error if decompression fails.\n"
).
-spec stream_decoder(decoder(), bitstring()) -> {ok, stream_outcome()} |
{error, nil}.
stream_decoder(Decoder, Data) ->
brot_ffi:stream_decoder(Decoder, Data).
-file("src/brot.gleam", 270).
?DOC(
" Checks if the decoder has finished decompressing all data. Returns `True` if \n"
" decompression is complete, `False` if more data is expected.\n"
).
-spec is_decoder_finished(decoder()) -> boolean().
is_decoder_finished(Decoder) ->
brotli_decoder:is_finished(Decoder).