Working on reading the body

main
Jacob Windle 2023-04-21 08:07:56 -04:00
parent 977b9bf507
commit 348f9633c3
3 changed files with 66 additions and 21 deletions

View File

@ -1,27 +1,29 @@
"""
read the body of the FIT file.
"""
module body
# TODO: Why do this?
import Base.show
export RecordHeader, read_row
export DefinitionHeader, DataRecord, read_row
include("bytes.jl"); using.bytes
include("mesg_num.jl"); using .mesg_num
struct DefinitionMessage end
struct DataMessage end
"""
RecordHeader
struct DefinitionHeader
endianness::AbstractString
number::Int64
fields::UInt8
end
The byte that corresponds to the type of message that this record holds.
"""
struct RecordHeader
definition_message::Bool
timestamp_message::Bool
# 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
@ -31,17 +33,44 @@ end
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)
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
RecordHeader(
bit_at(header_byte, 2),
bit_at(header_byte, 1))
# 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 show(io::IO, header::RecordHeader)
println(io, header.definition_message ? "DefinitionMessage" : "DataMessage")
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

View File

@ -10,7 +10,7 @@ using .body
struct FITFile
header::FITHeader
body::RecordHeader
body::DefinitionHeader
end
function read_file(filepath::AbstractString)::FITFile

View File

@ -2,6 +2,8 @@
module mesg_num
export get_mesg_num_string, get_field_definition_string
FILE_ID = 0
CAPABILITIES = 1
DEVICE_SETTINGS = 2
@ -202,7 +204,7 @@ MESG_NUM_MAP = Dict(
Given the number from our data record, get a string label. Nothing if not found.
"""
function get_mesg_num_string(mesg_num::Integer)::Union{AbstractString,Nothing}
function get_mesg_num_string(mesg_num::Real)::Union{AbstractString,Nothing}
try
MESG_NUM_MAP[mesg_num]
catch e
@ -214,4 +216,18 @@ function get_mesg_num_string(mesg_num::Integer)::Union{AbstractString,Nothing}
end
end
FIELD_DEFINITION_MAP = Dict(
0xFF => "Invalid",
254 => "MessageIndex",
253 => "Timestamp",
250 => "PartNumber"
)
function get_field_definition_string(num::Real)::Union{AbstractString,Nothing}
try
FIELD_DEFINITION_MAP[num]
catch e
nothing
end
end
end