Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/dataset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ function CDFDataset(filename)
compression = CompressionType(compression_bytes)
RecordSizeType = is_cdf_v3(magic_bytes) ? UInt64 : UInt32
# Parse CDF header to extract version, majority, and compression
cdr = load_cdr(io, 8, RecordSizeType)
gdr = load_gdr(io, cdr.gdr_offset, RecordSizeType)
cdr = CDR(io, 8, RecordSizeType)
gdr = GDR(io, cdr.gdr_offset, RecordSizeType)
return CDFDataset{compression, RecordSizeType}(filename, cdr, gdr)
end
end
Expand Down Expand Up @@ -105,7 +105,7 @@ function Base.keys(cdf::CDFDataset)
i = 1
for current_offset in (gdr.rVDRhead, gdr.zVDRhead)
while current_offset != 0
vdr = load_vdr(io, current_offset, RecordSizeType)
vdr = VDR(io, current_offset, RecordSizeType)
varnames[i] = vdr.name
i += 1
current_offset = vdr.vdr_next
Expand Down
33 changes: 3 additions & 30 deletions src/loading/cdr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,17 @@
# Handles structured loading of the main CDF file header

"""
load_cdr(io::IO, offset::Int, is_v3::Bool) -> CDR
CDR(io::IO, RecordSizeType) -> CDR

Load a CDF Descriptor Record from the IO stream at the specified offset.
This follows the CDF specification for CDR record structure.

# Arguments
- `io`: IO stream to read from
- `offset`: Byte offset where CDR starts (typically 8)
- `is_v3`: Whether this is a CDF v3 file (affects field sizes)

# Returns
- `CDR`: Parsed CDR structure with all fields
"""
@inline function load_cdr(io::IO, offset, RecordSizeType)
seek(io, offset)
@inline function CDR(io::IO, RecordSizeType)
# Read header
header = Header(io, RecordSizeType)
@assert header.record_type == 1 "Invalid CDR record type"
# Read remaining CDR fields in order as per CDF specification
gdr_offset = read_be(io, RecordSizeType)
fields = read_be(io, 9, Int32)
return CDR(header, gdr_offset, fields...)
end

"""
parse_cdf_header(io::IO, magic_bytes::Vector{UInt8}, compression_bytes::Vector{UInt8}) -> FileHeader

Parse the CDF file header using a structured approach.
This is the main entry point for reading CDF file metadata.

# Returns
- `FileHeader`: Parsed file header with version, majority, compression, and CDR
"""
function parse_cdf_header(io::IO, RecordSizeType, compression)
# Load CDR record starting at offset 8
cdr = load_cdr(io, 8, RecordSizeType)
# Extract file properties from CDR
version, majority = extract_file_properties(cdr)

return FileHeader(version, majority, compression, cdr)
end
end
5 changes: 2 additions & 3 deletions src/loading/gdr.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
"""
load_gdr(io::IO, offset::UInt64, is_v3::Bool) -> GDR
GDR(io::IO, RecordSizeType)
Load a Global Descriptor Record from the IO stream at the specified offset.
"""
@inline function load_gdr(io::IO, offset::UInt64, RecordSizeType)
seek(io, offset)
@inline function GDR(io::IO, RecordSizeType)
# Read header
header = Header(io, RecordSizeType)
@assert header.record_type == 2
Expand Down
11 changes: 3 additions & 8 deletions src/loading/vdr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ function readname(io::IO)
end

"""
load_vdr(io::IO, offset, RecordSizeType) -> VDR
VDR(io::IO, RecordSizeType) -> VDR

Load a Variable Descriptor Record from the IO stream at the specified offset.
"""
@inline function load_vdr(io::IO, offset, RecordSizeType)
seek(io, offset)
@inline function VDR(io::IO, RecordSizeType)
header = Header(io, RecordSizeType)
@assert header.record_type in (3, 8)

Expand All @@ -36,12 +35,8 @@ Load a Variable Descriptor Record from the IO stream at the specified offset.
)
end

function load_rVDR(io::IO, offset, RecordSizeType)
return load_vdr(io, offset, RecordSizeType)
end

function load_zVDR(io::IO, offset, RecordSizeType)
vdr = load_vdr(io, offset, RecordSizeType)
vdr = VDR(io, offset, RecordSizeType)
z_num_dims = read_uint32_be(io)

# Read dimension sizes
Expand Down
6 changes: 2 additions & 4 deletions src/loading/vxr.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
"""
VXR(io::IO, offset, RecordSizeType)
VXR(io::IO, RecordSizeType)
Load a Variable Index Record from the IO stream at the specified offset.
"""
function VXR(io::IO, offset, RecordSizeType)
seek(io, offset)

function VXR(io::IO, RecordSizeType)
# Read header
header = Header(io, RecordSizeType)
@assert header.record_type == 6 "Invalid VXR record type"
Expand Down
42 changes: 10 additions & 32 deletions src/records.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ version(cdr::CDR; verbose = true) = verbose ? (cdr.version, cdr.release, cdr.inc
Majority(cdr::CDR) = (cdr.flags & 0x01) != 0 ? Majority(0) : Majority(1) # Row=0, Column=1
is_cdf_v3(cdr::CDR) = cdr.version == 3

"""
File header containing parsed information from CDR
"""
struct FileHeader
version::Tuple{UInt32, UInt32, UInt32}
majority::Majority
compression::CompressionType
cdr::CDR # Store the parsed CDR for reference
end

"""
Global Descriptor Record (GDR) - contains global information about the CDF file
Points to variable and attribute descriptor records
Expand Down Expand Up @@ -143,6 +133,15 @@ struct VVR{T}
data::Vector{T} # Raw variable data
end

for R in (:CDR, :GDR, :VXR, :VDR)
@eval begin
@inline function $R(io::IO, offset, RecordSizeType)
seek(io, offset)
return $R(io, RecordSizeType)
end
end
end

# Utility functions to decode CDR flags
"""
decode_cdr_flags(flags::UInt32)
Expand All @@ -165,20 +164,6 @@ function decode_cdr_flags(flags)
)
end

"""
extract_file_properties(cdr::CDR)

Extract high-level file properties from parsed CDR record.
"""
function extract_file_properties(cdr)
# Extract version tuple
version = (cdr.version, cdr.release, cdr.increment)

# Extract majority from flags (bit 0: 1=row major, 0=column major)
majority = (cdr.flags & 0x01) != 0 ? Majority(0) : Majority(1) # Row=0, Column=1
return (version, majority)
end

# Pretty printing for CDR structure
function Base.show(io::IO, cdr::CDR)
flag_info = decode_cdr_flags(cdr.flags)
Expand All @@ -195,11 +180,4 @@ function Base.show(io::IO, cdr::CDR)
println(io, " - Checksum Used: $(flag_info.checksum_used)")
println(io, " - MD5 Checksum: $(flag_info.md5_checksum)")
return println(io, " Identifier: $(cdr.identifier)")
end

function Base.show(io::IO, header::FileHeader)
println(io, "CDF File Header:")
println(io, " Version: $(header.version)")
println(io, " Majority: $(header.majority)")
return println(io, " Compression: $(header.compression)")
end
end