gondola_core/io/caraspace/
writer.rs1use crate::prelude::*;
5
6#[cfg_attr(feature="pybindings", pyclass)]
12pub struct CRWriter {
13
14 pub file : File,
15 pub file_path : String,
17 pub pkts_per_file : usize,
22 pub mbytes_per_file : usize,
26 pub file_name : String,
28 pub run_id : u32,
29 file_id : usize,
30 n_packets : usize,
33 file_nbytes_wr : usize,
36 pub file_timestamp : Option<String>,
40 pub first_gcu_timestamp : Option<u64>,
43 pub file_len_gcu_sec : Option<u32>,
45}
46
47impl CRWriter {
48
49 pub fn new(mut file_path : String, run_id : u32,
64 subrun_id : Option<u64>, timestamp : Option<String>, file_len_gcu_sec : Option<u32>) -> Self {
65 if file_len_gcu_sec.is_some() {
66 if timestamp.is_none() {
67 panic!("If the writer should operate in the mode where it writes a new file every x seconds depending on the delta of gcu times in the packets, it needs the first timestamp given. This needs to be the first timestamp of the packets to be written");
68 }
69 }
70 let file : File;
71 let file_name : String;
72 if !file_path.ends_with("/") {
73 file_path += "/";
74 }
75 let filename : String;
76 let first_timestamp = timestamp.clone();
77 if let Some(subrun) = subrun_id {
78 filename = format!("{}{}", file_path, get_runfilename(run_id, subrun, None, timestamp, false));
79 } else {
80 filename = format!("{}{}", file_path, get_runfilename(run_id, 0, None, timestamp, false));
81 }
82 let path = Path::new(&filename);
83 file = OpenOptions::new().create(true).append(true).open(path).expect("Unable to open file {filename}");
85 file_name = filename;
86 let mut first_gcu_timestamp = None;
87 if first_timestamp.is_some() {
88 first_gcu_timestamp = get_unix_timestamp(&first_timestamp.unwrap(), None);
89 }
90 Self {
91 file,
92 file_path : file_path,
93 pkts_per_file : 0,
94 mbytes_per_file : 420,
95 run_id : run_id,
96 file_nbytes_wr : 0,
97 file_id : 1,
98 n_packets : 0,
99 file_name : file_name,
100 file_timestamp : None,
101 first_gcu_timestamp : first_gcu_timestamp,
102 file_len_gcu_sec : file_len_gcu_sec,
103 }
104 }
105
106 pub fn get_file(&self, timestamp : Option<String>) -> File {
107 let file : File;
108 let filename = format!("{}{}", self.file_path, get_runfilename(self.run_id, self.file_id as u64, None, timestamp, false));
109 let path = Path::new(&filename);
111 info!("Writing to file {filename}");
112 file = OpenOptions::new().create(true).append(true).open(path).expect("Unable to open file {filename}");
113 file
114 }
115
116 pub fn add_frame(&mut self, frame : &CRFrame) {
120 let buffer = frame.to_bytestream();
121 self.file_nbytes_wr += buffer.len();
122 match self.file.write_all(buffer.as_slice()) {
123 Err(err) => error!("Writing to file to path {} failed! {}", self.file_path, err),
124 Ok(_) => ()
125 }
126 self.n_packets += 1;
127 let mut newfile = false;
128 if self.pkts_per_file != 0 {
129 if self.n_packets == self.pkts_per_file {
130 newfile = true;
131 self.n_packets = 0;
132 }
133 } else if self.mbytes_per_file != 0 {
134 if self.file_nbytes_wr >= self.mbytes_per_file * 1_048_576 {
136 newfile = true;
137 self.file_nbytes_wr = 0;
138 }
139 } else if self.file_len_gcu_sec.is_some() {
140 if frame.timestamp.clone().unwrap() - self.first_gcu_timestamp.unwrap() as f64 > self.file_len_gcu_sec.unwrap() as f64 {
141 newfile = true;
142 self.file_timestamp = get_utc_timestamp_from_unix(frame.timestamp.clone().unwrap());
143 self.first_gcu_timestamp = Some(frame.timestamp.unwrap() as u64);
145 }
146 }
147 if newfile {
148 match self.file.sync_all() {
150 Err(err) => {
151 error!("Unable to sync file to disc! {err}");
152 },
153 Ok(_) => ()
154 }
155 self.file = self.get_file(self.file_timestamp.clone());
156 self.file_id += 1;
157 }
163 debug!("CRFrame written!");
164 }
165}
166
167impl Default for CRWriter {
168 fn default() -> Self {
169 CRWriter::new(String::from(""),0,None, None, None)
170 }
171}
172
173impl fmt::Display for CRWriter {
174 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
175 let mut repr = String::from("<CRWriter:");
176 repr += &(format!("\n path: {}", self.file_path));
177 repr += ">";
178 write!(f, "{}", repr)
179 }
180}
181
182#[cfg(feature="pybindings")]
183#[pymethods]
184impl CRWriter {
185
186 #[new]
187 #[pyo3(signature = (filename, run_id, subrun_id = None, timestamp = None, file_len_gcu_sec = None))]
188 fn new_py(filename : String, run_id : u32, subrun_id : Option<u64>, timestamp : Option<String>, file_len_gcu_sec : Option<u32>) -> Self {
189 Self::new(filename, run_id, subrun_id, timestamp, file_len_gcu_sec)
190 }
191
192 #[getter]
193 #[pyo3(name="current_filename")]
194 fn get_current_filename_py(&self) -> String {
195 self.file_name.clone()
196 }
197
198 fn set_mbytes_per_file(&mut self, fsize : usize) {
199 self.mbytes_per_file = fsize;
200 }
201
202 fn set_file_timestamp(&mut self, timestamp : String) {
203 self.file_timestamp = Some(timestamp);
204 }
205
206 #[pyo3(name="add_frame")]
207 fn add_frame_py(&mut self, frame : CRFrame) {
208 self.add_frame(&frame);
209 }
210}
211
212#[cfg(feature="pybindings")]
213pythonize_display!(CRWriter);
214