Skip to content

Commit a36b935

Browse files
committed
Do not neglect gap after th last field
1 parent 4cb3cd1 commit a36b935

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

src/StructIO.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ function unsafe_unpack(io, T, target, endianness, ::Type{Packed}; gaps=field_gap
266266
isempty(gaps) || skip(io, gaps[i])
267267
unsafe_unpack(io, fT, target_i, endianness, Packed)
268268
end
269+
isempty(gaps) || skip(io, gaps[fieldcount(T) + 1])
269270
end
270271

271272
# `Packed` packing strategy override for `unsafe_pack`
@@ -286,6 +287,7 @@ function unsafe_pack(
286287
isempty(gaps) || skip(io, gaps[i])
287288
unsafe_pack(io, f, endianness, Packed)
288289
end
290+
isempty(gaps) || skip(io, gaps[fieldcount(T) + 1])
289291
end
290292

291293
"""
@@ -337,7 +339,7 @@ function strip_gap_nodes!(strct_expr::Expr)
337339
!isa(f, LineNumberNode) || continue
338340
if f.head === :(::)
339341
# collect positions of gap nodes, when encountering a structure
340-
# field,
342+
# field, store the accumulated gap and reset the accumulator
341343
if f.args[1] === :_
342344
if isa(f.args[2], Integer) && f.args[2] >= 0
343345
push!(gap_locations, k)
@@ -354,6 +356,8 @@ function strip_gap_nodes!(strct_expr::Expr)
354356
end
355357
end
356358
end
359+
# do not neglect the gap after the last field
360+
push!(field_gap_values, gap_value)
357361
if all(iszero, field_gap_values)
358362
field_gap_values = UInt[]
359363
end

test/runtests.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,19 @@ end align_packed
4343
dummy_4::UInt16
4444
dummy_5::UInt64
4545
D::UInt8
46+
dummy_6::UInt8
4647
end align_packed
4748

4849
@io struct GappedStruct
4950
A::UInt32
50-
_::1
51-
_::2
51+
_::3
5252
B::UInt16
5353
_::4
5454
C::UInt128
5555
_::2
5656
_::8
5757
_D::UInt8
58+
_::1
5859
end align_packed
5960

6061

@@ -197,20 +198,22 @@ end
197198
@testset "Struct with gaps" begin
198199
A,B,C,D = 1,2,3,4
199200
gapped_struct = GappedStruct(A, B, C, D)
200-
raw_data = RawData(UInt32(A),0xBE, 0xBEEF,UInt16(B),0xDEADBEEF,UInt128(C),
201-
0xBEEF, 0xDEADBEEFDEADBEEF, UInt8(D));
202-
unpacked_raw_data = RawData(UInt32(A),0x00, 0x0000,UInt16(B),0x00000000,UInt128(C),
203-
0x0000, 0x0000000000000000, UInt8(D));
201+
raw_data = RawData(A, 0xBE, 0xBEEF, B, 0xDEADBEEF, C, 0xBEEF, 0xDEADBEEFDEADBEEF,
202+
D, 0xBE);
203+
unpacked_raw_data = RawData(A, 0, 0, B, 0, C, 0, 0, D, 0);
204204
#
205+
@test all(StructIO.field_gaps(GappedStruct) .== [0, 3, 4, 10, 1])
205206
@test packed_sizeof(RawData) == packed_sizeof(GappedStruct)
206207
for endian in [:LittleEndian, :BigEndian]
207208
buf = IOBuffer()
208209
pack(buf, raw_data, endian)
209210
seekstart(buf)
210211
@test unpack(buf, GappedStruct, endian) == gapped_struct
212+
@test eof(buf)
211213
#
212214
buf = IOBuffer(zeros(UInt8, packed_sizeof(GappedStruct)), read=true, write=true)
213215
pack(buf, gapped_struct, endian)
216+
@test eof(buf)
214217
seekstart(buf)
215218
@test unpack(buf, GappedStruct, endian) == gapped_struct
216219
seekstart(buf)

0 commit comments

Comments
 (0)