From a1b6862ce9b4b0c8aea7320e7a53102c05fe3103 Mon Sep 17 00:00:00 2001
From: Tamas Gal <himself@tamasgal.com>
Date: Fri, 28 Feb 2025 10:13:56 +0100
Subject: [PATCH] Add I/O helper functions

---
 docs/src/api.md      |  2 ++
 src/daq.jl           |  6 ++++++
 src/exports.jl       |  4 ++++
 src/tools/general.jl | 39 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 51 insertions(+)

diff --git a/docs/src/api.md b/docs/src/api.md
index 63319831..442f880c 100644
--- a/docs/src/api.md
+++ b/docs/src/api.md
@@ -150,6 +150,8 @@ getevent
 categorize
 nthbitset
 most_frequent
+packedsize
+writestruct
 ```
 
 ### DAQ
diff --git a/src/daq.jl b/src/daq.jl
index d2f9981f..de1802a1 100644
--- a/src/daq.jl
+++ b/src/daq.jl
@@ -52,3 +52,9 @@ function Base.read(s::IO, ::Type{T}; legacy=false) where T<:DAQEvent
 
     T(header, snapshot_hits, triggered_hits)
 end
+
+function Base.write(io::IO, s::Summaryslice)
+    # write(io, Int32(size?))
+    # write(io, Int32(DAQDATATYPES.DAQSUMMARYSLICE))
+    writestruct(io, s.header)
+end
diff --git a/src/exports.jl b/src/exports.jl
index d531fdf6..31b22e09 100644
--- a/src/exports.jl
+++ b/src/exports.jl
@@ -130,6 +130,10 @@ MCEventMatcher,
 SummarysliceIntervalIterator,
 getevent,
 
+# I/O
+packedsize,
+writestruct,
+
 # Utils
 categorize,
 is3dmuon,
diff --git a/src/tools/general.jl b/src/tools/general.jl
index 06ada871..e6465791 100644
--- a/src/tools/general.jl
+++ b/src/tools/general.jl
@@ -109,3 +109,42 @@ function tonumifpossible(v::AbstractString)
     end
     v
 end
+
+
+"""
+Calculates the packed size in bytes of an immutable struct containing only
+primitives and other isbitstypes.
+"""
+function packedsize(dt::DataType)
+    isbitstype(dt) || error("Only isbits types are supported")
+    n = 0
+    for ftype in fieldtypes(dt)
+        if isprimitivetype(ftype)
+            n += sizeof(ftype)
+        else
+            n += packedsize(ftype)
+        end
+    end
+    n
+end
+packedsize(::T) where T = packedsize(T)
+
+
+"""
+Serialises an immutable struct containing only primitives and
+other isbitstypes. Returns the number of bytes written.
+"""
+function writestruct(io::IO, s::T) where T
+    isbitstype(T) || error("Only isbits types are supported")
+    n = 0
+    for fname in fieldnames(T)
+        v = getfield(s, fname)
+        if isprimitivetype(fieldtype(T, fname))
+            write(io, v)
+            n += sizeof(v)
+        else
+            n += writestruct(io, v)
+        end
+    end
+    n
+end
-- 
GitLab