Reading definition headers
This commit is contained in:
+12
-1
@@ -1,6 +1,6 @@
|
|||||||
module bytes
|
module bytes
|
||||||
|
|
||||||
export byte_vec_to_int, byte_vec_to_string, bit_at, bit_vector
|
export byte_vec_to_int, byte_vec_to_string, bit_at, bit_vector, sum_bits
|
||||||
|
|
||||||
"""
|
"""
|
||||||
read_data_size(size::Vector{UInt8})::Real
|
read_data_size(size::Vector{UInt8})::Real
|
||||||
@@ -53,5 +53,16 @@ function bit_vector(byte_vector::Vector{UInt8}; little_endian=false)::Vector{UIn
|
|||||||
reduce(vcat, vecs)
|
reduce(vcat, vecs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
sum_bits(bit_vector::Vector{UInt8})::Int64
|
||||||
|
|
||||||
|
Sum the bits found in bit_vector, return a value in Int64, Calculate the value of
|
||||||
|
each bit along the way.
|
||||||
|
"""
|
||||||
|
function sum_bits(bit_vector::Vector{UInt8})::Int64
|
||||||
|
rev = reverse(bit_vector)
|
||||||
|
sum([rev[i] * (2 ^ (i - 1)) for i ∈ eachindex(rev)])
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
# byte_vec_to_string(UInt8.(collect("ABC")))
|
# byte_vec_to_string(UInt8.(collect("ABC")))
|
||||||
|
|||||||
+81
-8
@@ -1,8 +1,11 @@
|
|||||||
module file
|
module file
|
||||||
|
|
||||||
export FITFile, read_file
|
import Base.show
|
||||||
|
|
||||||
|
export FITFile, read_file, DataRecord
|
||||||
|
|
||||||
include("bytes.jl"); using .bytes
|
include("bytes.jl"); using .bytes
|
||||||
|
include("mesg_num.jl"); using .mesg_num
|
||||||
|
|
||||||
|
|
||||||
HEADER_SZ = 14
|
HEADER_SZ = 14
|
||||||
@@ -16,9 +19,34 @@ struct FITHeader
|
|||||||
crc::AbstractVector{<:Real}
|
crc::AbstractVector{<:Real}
|
||||||
end
|
end
|
||||||
|
|
||||||
mutable struct DataRecord
|
"""
|
||||||
|
RecordHeader
|
||||||
|
|
||||||
|
Contains the header byte for a record row
|
||||||
|
"""
|
||||||
|
mutable struct RecordHeader
|
||||||
definition::Bool
|
definition::Bool
|
||||||
data::Bool
|
data::Bool
|
||||||
|
local_mesg_type::Int64
|
||||||
|
end
|
||||||
|
|
||||||
|
mutable struct DefinitionBody
|
||||||
|
architecture::AbstractString
|
||||||
|
global_mesg_type::AbstractString # Read from mesg_num.jl using the bytes in this field.
|
||||||
|
num_fields::UInt8
|
||||||
|
end
|
||||||
|
|
||||||
|
mutable struct DataBody
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
DataRecord
|
||||||
|
|
||||||
|
Represents a DataRecord within the Garmin file.
|
||||||
|
"""
|
||||||
|
mutable struct DataRecord
|
||||||
|
hdr::Union{RecordHeader, Nothing}
|
||||||
|
body::Union{DefinitionBody, DataBody}
|
||||||
end
|
end
|
||||||
|
|
||||||
mutable struct FITFileReader
|
mutable struct FITFileReader
|
||||||
@@ -31,7 +59,8 @@ end
|
|||||||
|
|
||||||
|
|
||||||
blank_file(fp::AbstractString) = FITFileReader(fp, nothing, 0, nothing, nothing)
|
blank_file(fp::AbstractString) = FITFileReader(fp, nothing, 0, nothing, nothing)
|
||||||
blank_row() = DataRecord(false, false)
|
blank_row() = DataRecord(nothing)
|
||||||
|
blank_header_byte() = RecordHeader(false, false, 0)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
open_fit_file!(f::FITFileReader)
|
open_fit_file!(f::FITFileReader)
|
||||||
@@ -81,15 +110,42 @@ function read_header!(f::FITFileReader)
|
|||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
decode_header(v::Vector{UInt8})
|
decode_header(v::Vector{UInt8})::RecordHeader
|
||||||
|
|
||||||
Decode the header byte, determine if the record is a definition, data, or timestamp.
|
Decode the header byte, determine if the record is a definition, data, or timestamp.
|
||||||
"""
|
"""
|
||||||
function decode_header(v::Vector{UInt8})::DataRecord
|
function decode_header(v::Vector{UInt8})::RecordHeader
|
||||||
record = blank_row()
|
record = blank_header_byte()
|
||||||
|
|
||||||
record.definition = v[7] === 0x01
|
record.definition = v[7] === 0x01
|
||||||
record.data = !record.definition
|
record.data = !record.definition
|
||||||
|
record.local_mesg_type = sum_bits(v[end-3:end])
|
||||||
|
record
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
read_record_content!(f::FITFileReader, hdr::RecordHeader)::Union{DefinitionBody, DataBody}
|
||||||
|
|
||||||
|
Using f, read the appropriate message body given the hdr (which tells us if this is def or data)
|
||||||
|
"""
|
||||||
|
function read_record_content!(f::FITFileReader, hdr::RecordHeader)::Union{DefinitionBody, DataBody}
|
||||||
|
# Read the definition record, return the body
|
||||||
|
if hdr.definition
|
||||||
|
# Read the fixed 5 bytes first.
|
||||||
|
def_header_bytes = read_bytes!(f, 5)
|
||||||
|
def_header_fields = read_bytes!(f, def_header_bytes[end] * 3)
|
||||||
|
|
||||||
|
# See if there is developer data
|
||||||
|
def_header_developer_flag = read_bytes!(f, 1)
|
||||||
|
if def_header_developer_flag[1] > 0x00
|
||||||
|
def_header_developer_fields = read_bytes!(f, def_header_developer_flag * 3)
|
||||||
|
end
|
||||||
|
|
||||||
|
DefinitionBody(
|
||||||
|
def_header_bytes[2] == 0 ? "littleendian" : "bigendian",
|
||||||
|
get_mesg_num_string(byte_vec_to_int(def_header_bytes[3:4])),
|
||||||
|
def_header_bytes[end]
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -104,7 +160,11 @@ function read_records!(f::FITFileReader)
|
|||||||
|
|
||||||
# Read header byte - decode
|
# Read header byte - decode
|
||||||
header_bits = bit_vector(read_bytes!(f, 1); little_endian=true)
|
header_bits = bit_vector(read_bytes!(f, 1); little_endian=true)
|
||||||
record = decode_header(header_bits)
|
header = decode_header(header_bits)
|
||||||
|
|
||||||
|
# Read the record content
|
||||||
|
|
||||||
|
record = DataRecord(header, read_record_content!(f, header))
|
||||||
|
|
||||||
# Push record to the body.
|
# Push record to the body.
|
||||||
if isnothing(f.body)
|
if isnothing(f.body)
|
||||||
@@ -132,4 +192,17 @@ function read_file(filepath::AbstractString)::FITFileReader
|
|||||||
f
|
f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function show(io::IO, hdr::RecordHeader)
|
||||||
|
type = hdr.definition ? "Definition" : "Data"
|
||||||
|
println(io, "Header($(type), local_message_type=$(hdr.local_mesg_type))")
|
||||||
|
end
|
||||||
|
|
||||||
|
function show(io::IO, ffr::FITFileReader)
|
||||||
|
println(io, "FITFileReader($(ffr.filepath), bytes_read=$(ffr.bytes_read), header=$(ffr.header), body=$(ffr.body))")
|
||||||
|
end
|
||||||
|
|
||||||
|
function show(io::IO, defbody::DefinitionBody)
|
||||||
|
println(io, "DefinitionBody(arch=$(defbody.architecture), global_type=$(defbody.global_mesg_type), num_fields=$(defbody.num_fields))")
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user