Consolidating code, work on read_records!
parent
08964fdb53
commit
8665fd5bb4
76
src/body.jl
76
src/body.jl
|
@ -1,76 +0,0 @@
|
|||
module body
|
||||
|
||||
# TODO: Why do this?
|
||||
import Base.show
|
||||
|
||||
export DefinitionHeader, DataRecord, read_row
|
||||
|
||||
include("bytes.jl"); using.bytes
|
||||
include("mesg_num.jl"); using .mesg_num
|
||||
|
||||
|
||||
struct DefinitionHeader
|
||||
endianness::AbstractString
|
||||
number::Int64
|
||||
fields::UInt8
|
||||
end
|
||||
|
||||
# TODO: field_number has a string value, type has a Julia type.
|
||||
struct DefinitionField
|
||||
field_number::AbstractString
|
||||
size::UInt8
|
||||
type::UInt8
|
||||
end
|
||||
|
||||
struct DataRecord
|
||||
hdr::DefinitionHeader
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
read_row(f::io)
|
||||
|
||||
Read a row of the file at a time. Parse the row into a data or def message.
|
||||
TODO: Endianness matters here. Need to resolve endianness with the architecture bit.
|
||||
"""
|
||||
function read_row(f::IO)::DefinitionHeader
|
||||
header_byte = read(f, 1; all=false)[1]
|
||||
|
||||
definition_message = Bool(bit_at(header_byte, 2))
|
||||
# The message byte is 7
|
||||
# hdr = RecordHeader(
|
||||
# Bool(bit_at(header_byte, 2)),
|
||||
# Bool(bit_at(header_byte, 1)))
|
||||
# TODO: hdr if compressed timestamp needs to be handled in special way.
|
||||
|
||||
if definition_message
|
||||
fixed_bytes = read(f, 5; all=false)
|
||||
hdr = DefinitionHeader(
|
||||
endianness(fixed_bytes[2]), byte_vec_to_int(fixed_bytes[3:4]), fixed_bytes[end]
|
||||
)
|
||||
end
|
||||
hdr_fields = [hdr_field(read(f, 3; all=false)) for i ∈ 1:hdr.fields + 1]
|
||||
println(hdr_fields)
|
||||
hdr
|
||||
end
|
||||
|
||||
function hdr_field(vec::Vector{UInt8})::DefinitionField
|
||||
println(vec)
|
||||
DefinitionField(
|
||||
get_mesg_num_string(vec[1]), vec[2], vec[3]
|
||||
)
|
||||
end
|
||||
|
||||
function endianness(b::UInt8)::AbstractString
|
||||
Bool(b) ? "BigEndian" : "LittleEndian"
|
||||
end
|
||||
|
||||
function show(io::IO, header::DefinitionHeader)
|
||||
print(io, "DefinitionHeader($(header.endianness), $(header.number), $(header.fields) messages)")
|
||||
end
|
||||
|
||||
function show(io::IO, field::DefinitionField)
|
||||
print(io, "DefinitionField($(field.field_number), $(field.size), $(field.type))")
|
||||
end
|
||||
|
||||
end
|
21
src/bytes.jl
21
src/bytes.jl
|
@ -1,6 +1,6 @@
|
|||
module bytes
|
||||
|
||||
export byte_vec_to_int, byte_vec_to_string, bit_at
|
||||
export byte_vec_to_int, byte_vec_to_string, bit_at, bit_vector
|
||||
|
||||
"""
|
||||
read_data_size(size::Vector{UInt8})::Real
|
||||
|
@ -36,4 +36,21 @@ function bit_at(byte::UInt8, idx::Int64; t::Type=Int64)::Int64
|
|||
end
|
||||
|
||||
end
|
||||
# byte_vec_to_string(UInt8.(collect("ABC")))
|
||||
# byte_vec_to_string(UInt8.(collect("ABC")))
|
||||
|
||||
function bit_vector(byte::UInt8; little_endian=false)::Vector{UInt8}
|
||||
range = if little_endian
|
||||
8:-1:1
|
||||
else
|
||||
1:1:8
|
||||
end
|
||||
|
||||
s = bitstring(byte)
|
||||
[parse(UInt8, s[b]) for b in range]
|
||||
end
|
||||
|
||||
|
||||
function bit_vector(byte_vector::Vector{UInt8}; little_endian=false)::Vector{UInt8}
|
||||
vecs = [bit_vector(byte; little_endian=little_endian) for byte ∈ byte_vector]
|
||||
reduce(vcat, vecs)
|
||||
end
|
62
src/file.jl
62
src/file.jl
|
@ -2,7 +2,6 @@ module file
|
|||
|
||||
export FITFile, read_file
|
||||
|
||||
include("body.jl"); using .body
|
||||
include("bytes.jl"); using .bytes
|
||||
|
||||
|
||||
|
@ -17,16 +16,22 @@ struct FITHeader
|
|||
crc::AbstractVector{<:Real}
|
||||
end
|
||||
|
||||
mutable struct DataRecord
|
||||
definition::Bool
|
||||
data::Bool
|
||||
end
|
||||
|
||||
mutable struct FITFileReader
|
||||
filepath::AbstractString
|
||||
fp::Union{IO, Nothing}
|
||||
bytes_read::Int64
|
||||
header::Union{FITHeader, Nothing}
|
||||
body::Union{DefinitionHeader, Nothing}
|
||||
body::Union{Vector{DataRecord}, Nothing}
|
||||
end
|
||||
|
||||
|
||||
blank_file(fp::AbstractString) = FITFileReader(fp, nothing, 0, nothing, nothing)
|
||||
blank_row() = DataRecord(false, false)
|
||||
|
||||
"""
|
||||
open_fit_file!(f::FITFileReader)
|
||||
|
@ -47,6 +52,16 @@ function close_fit_file!(f::FITFileReader)
|
|||
f.fp = nothing
|
||||
end
|
||||
|
||||
"""
|
||||
read_bytes!(f::FITFileReader, nb::Integer)::Vector{UInt8}
|
||||
|
||||
Read nb bytes from f, update f.bytes_read, return bytes
|
||||
"""
|
||||
function read_bytes!(f::FITFileReader, nb::Integer)::Vector{UInt8}
|
||||
bytes = read(f.fp, nb; all=false)
|
||||
f.bytes_read += max(length(bytes), nb)
|
||||
bytes
|
||||
end
|
||||
|
||||
"""
|
||||
read_header(fit_file::IOStream)
|
||||
|
@ -54,7 +69,7 @@ end
|
|||
Read the header of the given fit file, and return a FITHeader struct
|
||||
"""
|
||||
function read_header!(f::FITFileReader)
|
||||
header = read(f.fp, HEADER_SZ; all=false)
|
||||
header = read_bytes!(f, HEADER_SZ)
|
||||
f.header = FITHeader(
|
||||
header[1],
|
||||
header[2],
|
||||
|
@ -63,7 +78,42 @@ function read_header!(f::FITFileReader)
|
|||
byte_vec_to_string(header[9:12]),
|
||||
header[13:14]
|
||||
)
|
||||
f.bytes_read += HEADER_SZ
|
||||
end
|
||||
|
||||
"""
|
||||
decode_header(v::Vector{UInt8})
|
||||
|
||||
Decode the header byte, determine if the record is a definition, data, or timestamp.
|
||||
"""
|
||||
function decode_header(v::Vector{UInt8})::DataRecord
|
||||
record = blank_row()
|
||||
|
||||
record.definition = v[7] === 0x01
|
||||
record.data = !record.definition
|
||||
end
|
||||
|
||||
"""
|
||||
read_records!(f::FITFileReader)
|
||||
|
||||
Read all the data record messages.
|
||||
"""
|
||||
function read_records!(f::FITFileReader)
|
||||
if f.bytes_read < 12 || f.bytes_read > 14
|
||||
throw("invalid header read, not within header size")
|
||||
end
|
||||
|
||||
# Read header byte - decode
|
||||
header_bits = bit_vector(read_bytes!(f, 1); little_endian=true)
|
||||
record = decode_header(header_bits)
|
||||
|
||||
# Push record to the body.
|
||||
if isnothing(f.body)
|
||||
f.body = [record]
|
||||
else
|
||||
push!(f.body, record)
|
||||
end
|
||||
|
||||
record
|
||||
end
|
||||
|
||||
function read_file(filepath::AbstractString)::FITFileReader
|
||||
|
@ -71,7 +121,9 @@ function read_file(filepath::AbstractString)::FITFileReader
|
|||
|
||||
open_fit_file!(f)
|
||||
try
|
||||
read_header!(f)
|
||||
read_header!(f)
|
||||
read_records!(f)
|
||||
# read_rows!(f)
|
||||
catch e
|
||||
rethrow(e)
|
||||
finally
|
||||
|
|
Loading…
Reference in New Issue