Packages

Read DBASE files in Elixir. At the moment it only supports read.

Current section

Files

Jump to
dbf_ex lib dbf field.ex
Raw

lib/dbf/field.ex

defmodule DBF.Field do
alias DBF.Database
defstruct [
:name,
:type,
:length,
:decimal
]
@type t :: %DBF.Field{
name: binary,
type: binary,
length: integer,
decimal: integer
}
@moduledoc false
def parse_fields(%Database{version: 0x02}=db) do
{:ok, raw_fields} = :file.pread(db.device, 8, db.header_bytes-32)
fields = parse_fields_string_foxbase(raw_fields, [])
{:ok, %Database{db | fields: fields} }
end
def parse_fields(db) do
{:ok, raw_fields} = :file.pread(db.device, 32, db.header_bytes-32)
fields = parse_fields_string(raw_fields, [])
{:ok, %Database{db | fields: fields} }
end
defp parse_fields_string_foxbase(<<"\r",_::binary>>, acc) do
Enum.reverse(acc)
end
defp parse_fields_string_foxbase(<<
name::binary-size(11),
type::binary-size(1),
length::unsigned-integer-8,
_junk::binary-size(3),
rest::binary
>>, acc) do
field = %__MODULE__{
name: String.trim(name, <<0>>),
type: type,
length: length,
decimal: 0
}
parse_fields_string_foxbase(rest, [field | acc])
end
defp parse_fields_string_foxbase(_bang, acc) do
Enum.reverse(acc)
end
defp parse_fields_string(<<"\r",_::binary>>, acc) do
Enum.reverse(acc)
end
defp parse_fields_string(<<
name::binary-size(11),
type::binary-size(1),
_address::unsigned-integer-32,
length::unsigned-integer-8,
decimal::unsigned-integer-8,
_reserved::binary-size(2),
_work_area::binary-size(1),
_reserved2::binary-size(2),
_set_fields_flag::binary-size(1),
_reserved3::binary-size(8),
rest::binary
>>, acc) do
field = %__MODULE__{
name: String.trim(name, <<0>>),
type: type,
length: length,
decimal: decimal
}
parse_fields_string(rest, [field | acc])
end
defp parse_fields_string(_bang, acc) do
Enum.reverse(acc)
end
end