Consolidating code, work on read_records!
This commit is contained in:
-76
@@ -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
|
|
||||||
+18
-1
@@ -1,6 +1,6 @@
|
|||||||
module bytes
|
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
|
read_data_size(size::Vector{UInt8})::Real
|
||||||
@@ -37,3 +37,20 @@ end
|
|||||||
|
|
||||||
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
|
||||||
+56
-4
@@ -2,7 +2,6 @@ module file
|
|||||||
|
|
||||||
export FITFile, read_file
|
export FITFile, read_file
|
||||||
|
|
||||||
include("body.jl"); using .body
|
|
||||||
include("bytes.jl"); using .bytes
|
include("bytes.jl"); using .bytes
|
||||||
|
|
||||||
|
|
||||||
@@ -17,16 +16,22 @@ struct FITHeader
|
|||||||
crc::AbstractVector{<:Real}
|
crc::AbstractVector{<:Real}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mutable struct DataRecord
|
||||||
|
definition::Bool
|
||||||
|
data::Bool
|
||||||
|
end
|
||||||
|
|
||||||
mutable struct FITFileReader
|
mutable struct FITFileReader
|
||||||
filepath::AbstractString
|
filepath::AbstractString
|
||||||
fp::Union{IO, Nothing}
|
fp::Union{IO, Nothing}
|
||||||
bytes_read::Int64
|
bytes_read::Int64
|
||||||
header::Union{FITHeader, Nothing}
|
header::Union{FITHeader, Nothing}
|
||||||
body::Union{DefinitionHeader, Nothing}
|
body::Union{Vector{DataRecord}, Nothing}
|
||||||
end
|
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)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
open_fit_file!(f::FITFileReader)
|
open_fit_file!(f::FITFileReader)
|
||||||
@@ -47,6 +52,16 @@ function close_fit_file!(f::FITFileReader)
|
|||||||
f.fp = nothing
|
f.fp = nothing
|
||||||
end
|
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)
|
read_header(fit_file::IOStream)
|
||||||
@@ -54,7 +69,7 @@ end
|
|||||||
Read the header of the given fit file, and return a FITHeader struct
|
Read the header of the given fit file, and return a FITHeader struct
|
||||||
"""
|
"""
|
||||||
function read_header!(f::FITFileReader)
|
function read_header!(f::FITFileReader)
|
||||||
header = read(f.fp, HEADER_SZ; all=false)
|
header = read_bytes!(f, HEADER_SZ)
|
||||||
f.header = FITHeader(
|
f.header = FITHeader(
|
||||||
header[1],
|
header[1],
|
||||||
header[2],
|
header[2],
|
||||||
@@ -63,7 +78,42 @@ function read_header!(f::FITFileReader)
|
|||||||
byte_vec_to_string(header[9:12]),
|
byte_vec_to_string(header[9:12]),
|
||||||
header[13:14]
|
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
|
end
|
||||||
|
|
||||||
function read_file(filepath::AbstractString)::FITFileReader
|
function read_file(filepath::AbstractString)::FITFileReader
|
||||||
@@ -72,6 +122,8 @@ function read_file(filepath::AbstractString)::FITFileReader
|
|||||||
open_fit_file!(f)
|
open_fit_file!(f)
|
||||||
try
|
try
|
||||||
read_header!(f)
|
read_header!(f)
|
||||||
|
read_records!(f)
|
||||||
|
# read_rows!(f)
|
||||||
catch e
|
catch e
|
||||||
rethrow(e)
|
rethrow(e)
|
||||||
finally
|
finally
|
||||||
|
|||||||
Reference in New Issue
Block a user