~fnux/telegram-tl-elixir

ref: 7730ebb4949b119a88957ba27b1f81a408e71b19 telegram-tl-elixir/lib/tl/binary.ex -rw-r--r-- 1.5 KiB
7730ebb4 — Timothée Floure Add TL.Binary.reverse_endianness/1 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
defmodule TL.Binary do
  @moduledoc """
    Helpers to work with binaries.
  """

  @doc """
    Converts a (signed) integer to its binary representation.
  """
  def encode_signed(int) do
    size = (:math.log2(abs(int))) / 8.0 |> Float.ceil |> round
    <<int::signed-size(size)-unit(8)>>
  end

  @doc """
    Converts the binary representation (of a signed integer) to its decimal
    representation.
  """
  def decode_signed(binary) do
    binary_length = byte_size binary
    <<int::signed-size(binary_length)-unit(8)>> = binary
    int
  end

  @doc """
    Split a binary at the given index.
  """
  def binary_split(binary, index) do
    left = :binary.part binary, 0, index
    right = :binary.part binary, index, byte_size(binary) - index
    {left, right}
  end

  def build_integer_from_bits_list(list, value \\ 0)
  @doc false
  def build_integer_from_bits_list([], value), do: value
  @doc """
  Build an integer from a list of bit positions.

  Example:
  ```
  iex> build_integer_from_bits_list([0,1,3,10])
  1035
  ```
  """
  def build_integer_from_bits_list([bit_index|tail], value) do
    bit_value = :math.pow(2, bit_index) |> round()
    build_integer_from_bits_list(tail, value + bit_value)
  end

  @doc """
  Reverse the endianness of a binary.

  Example:
  ```
  iex> reverse_endianness(<<1,2,3>>)
  <<3,2,1>>
  ```
  """
  def reverse_endianness(bytes) do
    bytes |> :binary.bin_to_list
          |> Enum.reverse
          |> :binary.list_to_bin
  end
end