Skip to content

Commit 00b6528

Browse files
author
Kevin Vu te Laar
committed
Replace C with C++ casting, sample pack/unpack fix
Replace C-style casts with C++-style casts. `sample_unpack()` always unpacks source sample timespec instead of default or user-specified values. `sample_pack()` uses user-specified if provided; otherwise falls back to source sample timespec when packing from a sample, or to the system clock when packing from a list. Modified stubs to reflect changes. Signed-off-by: Kevin Vu te Laar <vu.te@rwth-aachen.de>
1 parent f0c4eb8 commit 00b6528

5 files changed

Lines changed: 102 additions & 88 deletions

File tree

python/binding/capi_python_binding.cpp

Lines changed: 95 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ class SamplesArray {
4747
delete[] smps;
4848
}
4949

50-
void *get_block(unsigned int start) { return (void *)&smps[start]; }
50+
void *get_block(unsigned int start) {
51+
return reinterpret_cast<void *>(&smps[start]);
52+
}
5153

5254
void bulk_alloc(unsigned int start_idx, unsigned int stop_idx,
5355
unsigned int smpl_len) {
@@ -125,39 +127,51 @@ struct timespec ns_to_timespec(int64_t time_ns) {
125127
PYBIND11_MODULE(python_binding, m) {
126128
m.def("memory_init", &memory_init);
127129

128-
m.def("node_check", [](void *n) -> int { return node_check((vnode *)n); });
130+
m.def("node_check", [](void *n) -> int {
131+
return node_check(reinterpret_cast<vnode *>(n));
132+
});
129133

130-
m.def("node_destroy",
131-
[](void *n) -> int { return node_destroy((vnode *)n); });
134+
m.def("node_destroy", [](void *n) -> int {
135+
return node_destroy(reinterpret_cast<vnode *>(n));
136+
});
132137

133138
m.def(
134139
"node_details",
135-
[](void *n) -> const char * { return node_details((vnode *)n); },
140+
[](void *n) -> const char * {
141+
return node_details(reinterpret_cast<vnode *>(n));
142+
},
136143
py::return_value_policy::copy);
137144

138145
m.def("node_input_signals_max_cnt", [](void *n) -> unsigned {
139-
return node_input_signals_max_cnt((vnode *)n);
146+
return node_input_signals_max_cnt(reinterpret_cast<vnode *>(n));
140147
});
141148

142-
m.def("node_is_enabled",
143-
[](void *n) -> bool { return node_is_enabled((const vnode *)n); });
149+
m.def("node_is_enabled", [](void *n) -> bool {
150+
return node_is_enabled(reinterpret_cast<const vnode *>(n));
151+
});
144152

145153
m.def("node_is_valid_name",
146154
[](const char *name) -> bool { return node_is_valid_name(name); });
147155

148156
m.def(
149157
"node_name",
150-
[](void *n) -> const char * { return node_name((vnode *)n); },
158+
[](void *n) -> const char * {
159+
return node_name(reinterpret_cast<vnode *>(n));
160+
},
151161
py::return_value_policy::copy);
152162

153163
m.def(
154164
"node_name_full",
155-
[](void *n) -> const char * { return node_name_full((vnode *)n); },
165+
[](void *n) -> const char * {
166+
return node_name_full(reinterpret_cast<vnode *>(n));
167+
},
156168
py::return_value_policy::copy);
157169

158170
m.def(
159171
"node_name_short",
160-
[](void *n) -> const char * { return node_name_short((vnode *)n); },
172+
[](void *n) -> const char * {
173+
return node_name_short(reinterpret_cast<vnode *>(n));
174+
},
161175
py::return_value_policy::copy);
162176

163177
m.def(
@@ -173,8 +187,8 @@ PYBIND11_MODULE(python_binding, m) {
173187
json_t *inner = json_object_iter_value(it);
174188

175189
if (json_is_object(inner)) { // create node with name
176-
return (vnode *)villas::node::NodeFactory::make(
177-
json_object_iter_value(it), id, json_object_iter_key(it));
190+
return reinterpret_cast<vnode *>(villas::node::NodeFactory::make(
191+
json_object_iter_value(it), id, json_object_iter_key(it)));
178192
} else { // create node without name
179193
char *capi_str = json_dumps(json, 0);
180194
auto ret = node_new(id_str, capi_str);
@@ -186,33 +200,44 @@ PYBIND11_MODULE(python_binding, m) {
186200
py::return_value_policy::take_ownership);
187201

188202
m.def("node_output_signals_max_cnt", [](void *n) -> unsigned {
189-
return node_output_signals_max_cnt((vnode *)n);
203+
return node_output_signals_max_cnt(reinterpret_cast<vnode *>(n));
190204
});
191205

192-
m.def("node_pause", [](void *n) -> int { return node_pause((vnode *)n); });
206+
m.def("node_pause", [](void *n) -> int {
207+
return node_pause(reinterpret_cast<vnode *>(n));
208+
});
193209

194-
m.def("node_prepare",
195-
[](void *n) -> int { return node_prepare((vsample *)n); });
210+
m.def("node_prepare", [](void *n) -> int {
211+
return node_prepare(reinterpret_cast<vnode *>(n));
212+
});
196213

197214
m.def("node_read", [](void *n, SamplesArray &a, unsigned cnt) -> int {
198-
return node_read((vnode *)n, a.get_smps(), cnt);
215+
return node_read(reinterpret_cast<vnode *>(n), a.get_smps(), cnt);
199216
});
200217

201218
m.def("node_read", [](void *n, void *smpls, unsigned cnt) -> int {
202-
return node_read((vnode *)n, (vsample **)smpls, cnt);
219+
return node_read(reinterpret_cast<vnode *>(n),
220+
reinterpret_cast<vsample **>(smpls), cnt);
203221
});
204222

205-
m.def("node_restart",
206-
[](void *n) -> int { return node_restart((vnode *)n); });
223+
m.def("node_restart", [](void *n) -> int {
224+
return node_restart(reinterpret_cast<vnode *>(n));
225+
});
207226

208-
m.def("node_resume", [](void *n) -> int { return node_resume((vnode *)n); });
227+
m.def("node_resume", [](void *n) -> int {
228+
return node_resume(reinterpret_cast<vnode *>(n));
229+
});
209230

210-
m.def("node_reverse",
211-
[](void *n) -> int { return node_reverse((vnode *)n); });
231+
m.def("node_reverse", [](void *n) -> int {
232+
return node_reverse(reinterpret_cast<vnode *>(n));
233+
});
212234

213-
m.def("node_start", [](void *n) -> int { return node_start((vnode *)n); });
235+
m.def("node_start", [](void *n) -> int {
236+
return node_start(reinterpret_cast<vnode *>(n));
237+
});
214238

215-
m.def("node_stop", [](void *n) -> int { return node_stop((vnode *)n); });
239+
m.def("node_stop",
240+
[](void *n) -> int { return node_stop(reinterpret_cast<vnode *>(n)); });
216241

217242
m.def("node_to_json_str", [](void *n) -> py::str {
218243
auto json = reinterpret_cast<villas::node::Node *>(n)->toJson();
@@ -226,11 +251,12 @@ PYBIND11_MODULE(python_binding, m) {
226251
});
227252

228253
m.def("node_write", [](void *n, SamplesArray &a, unsigned cnt) -> int {
229-
return node_write((vnode *)n, a.get_smps(), cnt);
254+
return node_write(reinterpret_cast<vnode *>(n), a.get_smps(), cnt);
230255
});
231256

232257
m.def("node_write", [](void *n, void *smpls, unsigned cnt) -> int {
233-
return node_write((vnode *)n, (vsample **)smpls, cnt);
258+
return node_write(reinterpret_cast<vnode *>(n),
259+
reinterpret_cast<vsample **>(smpls), cnt);
234260
});
235261

236262
m.def(
@@ -243,13 +269,13 @@ PYBIND11_MODULE(python_binding, m) {
243269

244270
// Decrease reference count and release memory if last reference was held.
245271
m.def("sample_decref", [](void *smps) -> void {
246-
auto smp = (vsample **)smps;
272+
auto smp = reinterpret_cast<vsample **>(smps);
247273
sample_decref(*smp);
248274
});
249275

250276
m.def("sample_length", [](void *smp) -> unsigned {
251277
if (smp) {
252-
return sample_length((vsample *)smp);
278+
return sample_length(reinterpret_cast<vsample *>(smp));
253279
} else {
254280
return -1;
255281
}
@@ -259,15 +285,15 @@ PYBIND11_MODULE(python_binding, m) {
259285
"sample_pack",
260286
[](void *s, std::optional<int64_t> ts_origin_ns,
261287
std::optional<int64_t> ts_received_ns) -> vsample * {
262-
struct timespec ts_origin =
263-
ts_origin_ns ? ns_to_timespec(*ts_origin_ns) : time_now();
264-
struct timespec ts_received =
265-
ts_received_ns ? ns_to_timespec(*ts_received_ns) : time_now();
266-
267-
auto smp = (villas::node::Sample *)s;
288+
auto smp = reinterpret_cast<villas::node::Sample *>(s);
268289
uint64_t *seq = &smp->sequence;
269290
unsigned len = smp->length;
270-
double *values = (double *)smp->data;
291+
double *values = reinterpret_cast<double *>(smp->data);
292+
293+
struct timespec ts_origin =
294+
ts_origin_ns ? ns_to_timespec(*ts_origin_ns) : smp->ts.origin;
295+
struct timespec ts_received =
296+
ts_received_ns ? ns_to_timespec(*ts_received_ns) : smp->ts.received;
271297

272298
return sample_pack(seq, &ts_origin, &ts_received, len, values);
273299
},
@@ -283,52 +309,56 @@ PYBIND11_MODULE(python_binding, m) {
283309
ts_received_ns ? ns_to_timespec(*ts_received_ns) : time_now();
284310

285311
unsigned values_len = values.size();
286-
double cvalues[values.size()];
312+
double cvalues[values_len];
313+
287314
for (unsigned int i = 0; i < values_len; ++i) {
288315
cvalues[i] = values[i].cast<double>();
289316
}
290317
uint64_t sequence = seq;
291318

292-
auto tmp = (void *)sample_pack(&sequence, &ts_origin, &ts_received,
293-
values_len, cvalues);
294-
return tmp;
319+
return reinterpret_cast<void *>(sample_pack(
320+
&sequence, &ts_origin, &ts_received, values_len, cvalues));
295321
},
296322
py::return_value_policy::reference);
297323

298324
m.def(
299325
"sample_unpack",
300-
[](void *ss, void *ds, std::optional<int64_t> ts_origin_ns,
301-
std::optional<int64_t> ts_received_ns) -> void {
302-
struct timespec ts_origin =
303-
ts_origin_ns ? ns_to_timespec(*ts_origin_ns) : time_now();
304-
struct timespec ts_received =
305-
ts_received_ns ? ns_to_timespec(*ts_received_ns) : time_now();
326+
[](void *ss, void *ds) -> void {
327+
auto dSmp = reinterpret_cast<villas::node::Sample **>(ds);
328+
auto srcSmp = reinterpret_cast<villas::node::Sample *>(ss);
329+
auto &destSmp = *dSmp;
306330

307-
auto srcSmp = (villas::node::Sample **)ss;
308-
auto destSmp = (villas::node::Sample **)ds;
309-
310-
if (!*srcSmp) {
331+
if (!srcSmp) {
311332
throw std::runtime_error("Tried to unpack empty sample!");
312333
}
313-
if (!*destSmp) {
314-
*destSmp = (villas::node::Sample *)sample_alloc((*srcSmp)->length);
315-
} else if ((*destSmp)->capacity < (*srcSmp)->length) {
316-
sample_decref(*(vsample **)destSmp);
317-
*destSmp = (villas::node::Sample *)sample_alloc((*srcSmp)->length);
334+
if (!destSmp) {
335+
goto alloc;
336+
}
337+
if (destSmp->capacity < srcSmp->length) {
338+
sample_decref(reinterpret_cast<vsample *>(destSmp));
339+
goto alloc;
340+
}
341+
if (0) {
342+
alloc:
343+
*dSmp = reinterpret_cast<villas::node::Sample *>(
344+
sample_alloc(srcSmp->length));
345+
destSmp = *dSmp;
318346
}
319347

320-
uint64_t *seq = &(*destSmp)->sequence;
321-
int *flags = &(*destSmp)->flags;
322-
unsigned *len = &(*destSmp)->length;
323-
double *values = (double *)(*destSmp)->data;
348+
uint64_t *seq = &destSmp->sequence;
349+
struct timespec *ts_origin = &destSmp->ts.origin;
350+
struct timespec *ts_received = &destSmp->ts.received;
351+
int *flags = &destSmp->flags;
352+
unsigned *len = &destSmp->length;
353+
double *values = reinterpret_cast<double *>(destSmp->data);
324354

325-
sample_unpack(*(vsample **)srcSmp, seq, &ts_origin, &ts_received, flags,
326-
len, values);
355+
sample_unpack(reinterpret_cast<vsample *>(srcSmp), seq, ts_origin,
356+
ts_received, flags, len, values);
327357
},
328358
py::return_value_policy::reference);
329359

330360
m.def("sample_details", [](void *s) {
331-
auto smp = (villas::node::Sample *)s;
361+
auto smp = reinterpret_cast<villas::node::Sample *>(s);
332362
if (!smp) {
333363
return py::dict();
334364
}
@@ -344,7 +374,7 @@ PYBIND11_MODULE(python_binding, m) {
344374

345375
py::list data;
346376
for (unsigned int i = 0; i < smp->length; ++i) {
347-
data.append((double)smp->data[i]);
377+
data.append(static_cast<double>(smp->data[i]));
348378
}
349379
d["data"] = data;
350380

@@ -364,7 +394,7 @@ PYBIND11_MODULE(python_binding, m) {
364394
if (a[idx]) {
365395
sample_decref(a[idx]);
366396
}
367-
a[idx] = (vsample *)smp;
397+
a[idx] = reinterpret_cast<vsample *>(smp);
368398
})
369399
.def("__len__", &SamplesArray::size)
370400
.def("bulk_alloc", &SamplesArray::bulk_alloc)

python/villas/node/binding.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,12 @@ def pack_from(
8888
def unpack_to(
8989
self,
9090
target: Capsule,
91-
ts_origin: Optional[int] = None,
92-
ts_received: Optional[int] = None,
9391
):
9492
if isinstance(target, self.__class__):
9593
return self.node.unpack_to(
9694
self.idx,
9795
target.node,
9896
target.idx,
99-
ts_origin,
100-
ts_received,
10197
)
10298
else:
10399
raise ValueError(
@@ -486,27 +482,21 @@ def unpack_to(
486482
r_idx: int,
487483
target_node,
488484
w_idx: int,
489-
ts_orig: Optional[int] = None,
490-
ts_recv: Optional[int] = None,
491485
):
492486
"""
493487
Unpacks a given sample to a destined target.
494488
495489
Args:
496490
r_idx (int): Originating Node index to read from.
497-
ts_orig (Optional[int]): Supposed creation time in ns.
498-
ts_recv (Optional[int]): Supposed arrival time in ns.
499491
target_node (Node): Target node.
500492
w_idx (int): Target Node index to unpack to.
501493
"""
502494
Node._ensure_capacity(self._smps, r_idx + 1)
503495
Node._ensure_capacity(target_node._smps, w_idx + 1)
504496

505497
vn.sample_unpack(
506-
self._smps.get_block(r_idx),
498+
self._smps[r_idx],
507499
target_node._smps.get_block(w_idx),
508-
ts_orig,
509-
ts_recv,
510500
)
511501

512502
def sample_details(self, idx):

python/villas/node/binding.pyi

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ class Node:
3636
def unpack_to(
3737
self,
3838
target: Capsule,
39-
ts_origin: int | None,
40-
ts_received: int | None,
4139
): ...
4240

4341
config: Incomplete
@@ -96,7 +94,5 @@ class Node:
9694
r_idx: int,
9795
target_node,
9896
w_idx: int,
99-
ts_orig: int | None = None,
100-
ts_recv: int | None = None,
10197
): ...
10298
def sample_details(self, idx): ...

python/villas/node/python_binding.pyi

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ def sample_pack(
6262
def sample_unpack(
6363
arg0: capsule,
6464
arg1: capsule,
65-
arg2: Optional[int],
66-
arg3: Optional[int],
6765
) -> None: ...
6866
def sample_details(arg0: capsule) -> dict: ...
6967
def smps_array(arg0: int) -> SamplesArray: ...

tests/integration/python/test_binding_wrapper.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,16 @@ def test_sample_pack_unpack(self):
181181
)
182182
self.test_node[2].pack_from(42, int(1e9), int(1e9) + 100)
183183
self.test_node[3].pack_from(self.test_node[1], int(1e9), int(1e9) + 100)
184-
self.test_node[2].unpack_to(self.test_node[1], int(1e9), int(1e9) + 100)
184+
self.test_node[2].unpack_to(self.test_node[1])
185185
self.assertEqual([42.0], self.test_node[1].details()["data"])
186-
self.test_node[0].unpack_to(self.test_node[1], int(2e9), int(2e9) + 100)
186+
self.test_node[0].unpack_to(self.test_node[1])
187187
self.assertEqual(
188188
[0.01, 1.01, 2.01, 3.01, 4.01],
189189
self.test_node[1].details()["data"],
190190
)
191-
self.test_node[0].unpack_to(self.test_node[2], int(2e9), int(2e9) + 100)
192-
self.test_node[0].unpack_to(self.test_node[4], int(2e9), int(2e9) + 100)
193-
self.test_node[1].unpack_to(self.test_node[2], int(2e9), int(2e9) + 100)
191+
self.test_node[0].unpack_to(self.test_node[2])
192+
self.test_node[0].unpack_to(self.test_node[4])
193+
self.test_node[1].unpack_to(self.test_node[2])
194194
except Exception as e:
195195
self.fail(f"err: {e}")
196196

@@ -202,7 +202,7 @@ def test_samplesarray_size(self):
202202
self.assertEqual(len(node), 100)
203203
node[199].pack_from([1.01, 2.01, 3.01, 4.01, 5.01], int(1e9), int(1e9) + 100)
204204
self.assertEqual(len(node), 200)
205-
node[199].unpack_to(node[299], int(2e9), int(2e9) + 100)
205+
node[199].unpack_to(node[299])
206206
self.assertEqual(len(node), 300)
207207
except Exception as e:
208208
self.fail(f"err: {e}")

0 commit comments

Comments
 (0)