itsy v0.0.2 Itsy.Binary
Link to this section Summary
Functions
Generate an encoding for the given power of 2 length character set
Get the number of characters needed for an encoding, in order to pad to a whole byte
Get the number of bits one character of an encoding will represent
Pack a list of integers, floats, or bitstrings into a bitstring
Unpack integers, floats, or bitstrings from a bitstring
Link to this section Types
decoder() :: decode_type() | (bitstring(), [encodable()] -> decode_type())
encode_options() :: [ multiple: pos_integer(), pad_chr: String.t(), pad_bit: integer() ]
packing_options() :: [ position: position(), into: bitstring(), endian: endianness(), reverse: boolean() ]
unpacking_options() :: [ position: position(), count: nil | non_neg_integer(), endian: endianness(), sign: signedness(), reverse: boolean(), decoder: decoder() ]
Link to this section Functions
encoder( [{char :: String.t(), value :: non_neg_integer()}, ...], encoder_options() ) :: Macro.t()
Generate an encoding for the given power of 2 length character set.
The encoder will generate two functions encode/3
and decode/3
. These functions will be used to encode data using your specified encoding scheme, and decode strings with that encoding. The naming of these functions can be changed by setting the :encode
and :decode
options.
By default the functions are made public (including documentation). They can be made private by setting the :private
option to true
. Optionally only the docs can be removed by setting :docs
to false
.
The generated documentation includes some doctests. To use these tests make sure the module is specified as a doctest in your test code. If you do not wish for these to be included in your tests (but still want the docs), then simply exclude (:except
option) the two functions from your ExUnit.DocTest.doctests/2
.
defmodule MyBase4 do
require Itsy.Binary
"ABCD"
|> String.graphemes
|> Enum.with_index
|> Itsy.Binary.encoder
end
MyBase4.encode("hello") |> MyBase4.decode
Get the number of characters needed for an encoding, in order to pad to a whole byte.
This value can be given to the :multiples
option when encoding, in order to obtain an encoding with the minimum amount of padding needed so it can be concatenated with other encoded data.
iex> Itsy.Binary.encoder_padding(1)
1
iex> Itsy.Binary.encoder_padding(2)
8
iex> Itsy.Binary.encoder_padding(4)
4
iex> Itsy.Binary.encoder_padding(8)
8
iex> Itsy.Binary.encoder_padding(16)
2
iex> Itsy.Binary.encoder_padding(:erlang.bsl(1, 1000))
1
Get the number of bits one character of an encoding will represent.
iex> Itsy.Binary.encoder_size(1)
0
iex> Itsy.Binary.encoder_size(2)
1
iex> Itsy.Binary.encoder_size(4)
2
iex> Itsy.Binary.encoder_size(8)
3
iex> Itsy.Binary.encoder_size(16)
4
iex> Itsy.Binary.encoder_size(:erlang.bsl(1, 1000))
1000
pack([encodable()], non_neg_integer(), packing_options()) :: bitstring()
Pack a list of integers, floats, or bitstrings into a bitstring.
The values can be packed into a pre-existing bitstring by setting the :into
option to the desired destination.
The position in the bitstring the values are packed is determined by the :position
option. A :high
position will place them in the high-order bits, while a :low
position will place them in the low-order bits. By default this is set to :low
.
The list can be inserted in the same order or optionally in reverse order, when the :reverse
option is set to true.
[position: :high, reverse: false]
- most significant bit will be based on the first number in the list.[position: :high, reverse: true]
- most significant bit will be based on the last number in the list.[position: :low, reverse: true]
- least significant bit will be based on the first number in the list.[position: :low, reverse: false]
- least significant bit will be based on the last number in the list.
The byte order defaults to big endian, this can be overriden by setting the :endian
option to a kind expected by bitstring parameters.
iex> Itsy.Binary.pack([0], 2)
<<0 :: 2>>
iex> Itsy.Binary.pack([0], 3)
<<0 :: 3>>
iex> Itsy.Binary.pack([], 2)
<<>>
iex> Itsy.Binary.pack([0, 0, 0, 0], 2)
<<0 :: 8>>
iex> Itsy.Binary.pack([1, 2, 3, 4], 2)
<<1 :: 2, 2 :: 2, 3 :: 2, 0 :: 2>>
iex> Itsy.Binary.pack([1, 2, 3, 4], 2, position: :high)
<<1 :: 2, 2 :: 2, 3 :: 2, 0 :: 2>>
iex> Itsy.Binary.pack([1, 2, 3, 4], 2, reverse: true)
<<0 :: 2, 3 :: 2, 2 :: 2, 1 :: 2>>
iex> Itsy.Binary.pack([1, 2, 3, 4], 2, position: :high, reverse: true)
<<0 :: 2, 3 :: 2, 2 :: 2, 1 :: 2>>
iex> Itsy.Binary.pack([1, 2, 3, 4000], 12, position: :high, reverse: true)
<<4000 :: 12, 3 :: 12, 2 :: 12, 1 :: 12>>
iex> Itsy.Binary.pack([1, 2, 3, 4], 3, into: "foo")
<<"foo", 1 :: 3, 2 :: 3, 3 :: 3, 4 :: 3>>
iex> Itsy.Binary.pack([1, 2, 3, 4], 3, into: "foo", reverse: true)
<<"foo", 4 :: 3, 3 :: 3, 2 :: 3, 1 :: 3>>
iex> Itsy.Binary.pack([1, 2, 3, 4], 3, into: "foo", position: :high)
<<1 :: 3, 2 :: 3, 3 :: 3, 4 :: 3, "foo">>
iex> Itsy.Binary.pack([1, 2, 3, 4], 3, into: "foo", position: :high, reverse: true)
<<4 :: 3, 3 :: 3, 2 :: 3, 1 :: 3, "foo">>
iex> Itsy.Binary.pack([1], 32, endian: :little)
<<1 :: 8, 0 :: 24>>
iex> Itsy.Binary.pack([1], 32)
<<0 :: 24, 1 :: 8>>
iex> Itsy.Binary.pack([0.5], 32)
<<63 :: 8, 0 :: 24>>
iex> Itsy.Binary.pack(["foo", "bar"], 24)
"foobar"
iex> Itsy.Binary.pack(["foo", "bar"], 8)
"fb"
iex> Itsy.Binary.pack(["foo", "bar"], 32)
<<"foo", 0 :: 8, "bar", 0 :: 8>>
unpack(bitstring(), non_neg_integer(), unpacking_options()) :: [encodable()]
Unpack integers, floats, or bitstrings from a bitstring.
The type of value to unpack is inferred by the :decoder
. By default this option is set to :integer
, but can be set to any of the other types, or a function that will return the type to be used for that value.
A certain number of values can be unpacked by setting the :count
option.
The position in the bitstring the values are packed is determined by the :position
option. A :high
position will place them in the high-order bits, while a :low
position will place them in the low-order bits. By default this is set to :low
.
The list can be inserted in the same order or optionally in reverse order, when the :reverse
option is set to true.
[position: :high, reverse: false]
- most significant bit will be used in the first number in the list.[position: :high, reverse: true]
- most significant bit will be used in the last number in the list.[position: :low, reverse: true]
- least significant bit will be used in the first number in the list.[position: :low, reverse: false]
- least significant bit will be used in the last number in the list.
The byte order defaults to big endian, this can be overriden by setting the :endian
option to a kind expected by bitstring parameters.
The signedness of the integers defaults to unsigned, this can be overriden by setting the :sign
option to a kind expected by bitstring parameters.
iex> Itsy.Binary.unpack(<<0 :: 2>>, 2)
[0]
iex> Itsy.Binary.unpack(<<0 :: 3>>, 3)
[0]
iex> Itsy.Binary.unpack(<<>>, 2)
[]
iex> Itsy.Binary.unpack(<<0 :: 8>>, 2)
[0, 0, 0, 0]
iex> Itsy.Binary.unpack(<<1 :: 2, 2 :: 2, 3 :: 2, 0 :: 2>>, 2)
[1, 2, 3, 0]
iex> Itsy.Binary.unpack(<<1 :: 2, 2 :: 2, 3 :: 2, 0 :: 2>>, 2, position: :high)
[1, 2, 3, 0]
iex> Itsy.Binary.unpack(<<0 :: 2, 3 :: 2, 2 :: 2, 1 :: 2>>, 2, reverse: true)
[1, 2, 3, 0]
iex> Itsy.Binary.unpack(<<0 :: 2, 3 :: 2, 2 :: 2, 1 :: 2>>, 2, position: :high, reverse: true)
[1, 2, 3, 0]
iex> Itsy.Binary.unpack(<<4000 :: 12, 3 :: 12, 2 :: 12, 1 :: 12>>, 12, position: :high, reverse: true)
[1, 2, 3, 4000]
iex> Itsy.Binary.unpack(<<"foo", 1 :: 3, 2 :: 3, 3 :: 3, 4 :: 3>>, 3, count: 4)
[1, 2, 3, 4]
iex> Itsy.Binary.unpack(<<"foo", 4 :: 3, 3 :: 3, 2 :: 3, 1 :: 3>>, 3, count: 4, reverse: true)
[1, 2, 3, 4]
iex> Itsy.Binary.unpack(<<1 :: 3, 2 :: 3, 3 :: 3, 4 :: 3, "foo">>, 3, count: 4, position: :high)
[1, 2, 3, 4]
iex> Itsy.Binary.unpack(<<4 :: 3, 3 :: 3, 2 :: 3, 1 :: 3, "foo">>, 3, count: 4, position: :high, reverse: true)
[1, 2, 3, 4]
iex> Itsy.Binary.unpack(<<1 :: 8, 0 :: 24>>, 32, endian: :little)
[1]
iex> Itsy.Binary.unpack(<<0 :: 24, 1 :: 8>>, 32)
[1]
iex> Itsy.Binary.unpack(<<255 :: 8>>, 8, endian: :big, sign: :signed)
[-1]
iex> Itsy.Binary.unpack(<<63 :: 8, 0 :: 24>>, 32, decoder: :float)
[0.5]
iex> Itsy.Binary.unpack("foobar", 24, decoder: :bitstring)
["foo", "bar"]
iex> Itsy.Binary.unpack(<<"test", 1 :: 32>>, 32, decoder: fn
...> _, [] -> :bitstring
...> _, _ -> :integer
...> end)
["test", 1]