Skip to content

Commit c876923

Browse files
committed
Improve recovered basket parsing
1 parent 310d987 commit c876923

File tree

2 files changed

+35
-21
lines changed

2 files changed

+35
-21
lines changed

src/bootstrap.jl

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,43 @@ function unpack(io, tkey::TKey, refs::Dict{Int32, Any}, T::Type{RecoveredTBasket
2828
# one-byte terminator
2929
skip(io, 1)
3030

31-
# then if you have offsets data, read them in
32-
if fNevBufSize > 8
33-
byteoffsets = read(io, fNevBuf * 4 + 8)
34-
skip(io, -4)
35-
else
36-
byteoffsets = Int32[]
37-
end
31+
# If this ``TBasket`` is embedded within its ``TBranch`` (i.e. must be
32+
# deserialized as part of the ``TBranch``), then ``is_embedded`` is True.
33+
#
34+
# If this ``TBasket`` is a free-standing object, then ``is_embedded`` is
35+
# False.
36+
#
37+
is_embedded = fNbytes <= fKeylen
38+
39+
border = fLast - fKeylen
40+
41+
if is_embedded
42+
# https://github.com/root-project/root/blob/0e6282a641b65bdf5ad832882e547ca990e8f1a5/tree/tree/inc/TBasket.h#L62-L65
43+
maybe_entry_size = fNevBufSize
44+
num_entries = fNevBuf
45+
key_length = fKeylen
46+
# Embedded TBaskets are always uncompressed
47+
if maybe_entry_size * num_entries + key_length != fLast
48+
skip(io, 4) # skip the first Int32, which is the fNevBuf
49+
byteoffsets = [readtype(io, Int32) - fKeylen for _ in 0:num_entries]
50+
byteoffsets[end] = border
51+
skip(io, -4)
52+
else
53+
byteoffsets = Int32[]
54+
end
3855

39-
# there's a second TKey here, but it doesn't contain any new information (in fact, less)
40-
skip(io, fKeylen)
56+
# there's a second TKey here, but it doesn't contain any new information (in fact, less)
57+
skip(io, fKeylen)
4158

42-
# the data (not including offsets)
43-
size = fLast - fKeylen
44-
contents = read(io, size)
59+
contents = read(io, border)
4560

46-
# put the offsets back in, in the way that we expect it
47-
if fNevBufSize > 8
48-
contents = vcat(contents, byteoffsets)
49-
size += length(byteoffsets)
61+
@debug "Found $(length(contents)) bytes of basket data (not yet supported) in a TTree."
62+
return RecoveredTBasket(contents, byteoffsets)
63+
else
64+
# TODO: figure out how to handle this (see uproot5 uproot/models/TBasket.py when is_embedded is False
65+
error("Handling of recovered baskets which are not embedded is not implemented yet.")
5066
end
51-
fObjlen = size
52-
fNbytes = fObjlen + fKeylen
53-
@debug "Found $(length(contents)) bytes of basket data (not yet supported) in a TTree."
54-
RecoveredTBasket(contents, byteoffsets)
67+
5568
end
5669

5770
abstract type TNamed <: ROOTStreamedObject end

src/streamers.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ function unpack(io, tkey::TKey, refs::Dict{Int32, Any}, T::Union{Type{TList},Typ
306306
objects = []
307307
for i 1:size
308308
push!(objects, readobjany!(io, tkey, refs))
309-
skip(io, readtype(io, UInt8))
309+
skip_n = readtype(io, UInt8)
310+
skip(io, skip_n)
310311
end
311312

312313
endcheck(io, preamble)

0 commit comments

Comments
 (0)