Current section
Files
Jump to
Current section
Files
lib/snappywrap/helper.ex
defmodule Snappywrap.Helper do
import Bitwise
@moduledoc false
@doc """
Maximum allowed size of input data in bytes.
"""
@spec input_max_bytes() :: non_neg_integer()
def input_max_bytes(), do: Integer.pow(2, 32) - 1
@doc """
Calculates CRC-32C checksum for a Snappy chunk.
In Snappy, checksums are not stored directly, but masked, as checksumming data and
then its own checksum can be problematic. The masking is the same as used
in Apache Hadoop: Rotate the checksum by 15 bits, then add the constant
0xa282ead8 (using wraparound as normal for unsigned integers).
This is equivalent to the following C code:
`
uint32_t mask_checksum(uint32_t x) {
return ((x >> 15) | (x << 17)) + 0xa282ead8;
}
`
Note that the masking is reversible.
"""
def crc(data) do
data
|> Excrc32c.crc32c()
|> mask_checksum()
end
defp mask_checksum(x) do
(x >>> 15 ||| (x <<< 17 &&& 0xFFFFFFFF)) + 0xA282EAD8 &&& 0xFFFFFFFF
end
@doc """
Creates chunks of specified size from a binary
"""
def chunk_binary(binary, chunk_size), do: do_chunk_binary(binary, chunk_size, [])
defp do_chunk_binary(<<>>, _chunk_size, acc), do: Enum.reverse(acc)
defp do_chunk_binary(binary, chunk_size, acc) do
{chunk, rest} = :erlang.split_binary(binary, min(byte_size(binary), chunk_size))
do_chunk_binary(rest, chunk_size, [chunk | acc])
end
end