Skip to content

Commit e7c88e0

Browse files
committed
Refs #23753. Fix warning
Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev>
1 parent f34ffca commit e7c88e0

1 file changed

Lines changed: 143 additions & 37 deletions

File tree

fastdds_python/src/swig/fastdds/rtps/common/InstanceHandle.i

Lines changed: 143 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
// limitations under the License.
1414

1515
%{
16+
#include <stdexcept>
17+
#include <vector>
18+
1619
#include "fastdds/rtps/common/InstanceHandle.hpp"
1720

1821
// Define a hash method in global scope for InstanceHandle_t types
@@ -26,60 +29,119 @@ long hash(const eprosima::fastdds::rtps::InstanceHandle_t& handle)
2629
}
2730
return ret;
2831
}
29-
3032
%}
3133

3234
// SWIG does not support type conversion operators correctly unless converted to a normal method
3335
%rename(get_guid) eprosima::fastdds::rtps::InstanceHandle_t::operator const GUID_t&;
3436

3537
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator [] const;
38+
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator [];
3639
%ignore eprosima::fastdds::rtps::operator <<(std::ostream&, const InstanceHandle_t&);
3740
%ignore eprosima::fastdds::rtps::operator >>(std::istream&, InstanceHandle_t&);
38-
%rename(read_pointer_cast) eprosima::fastdds::rtps::InstanceHandleValue_t::operator const octet* () const;
39-
%rename(write_pointer_cast) eprosima::fastdds::rtps::InstanceHandleValue_t::operator octet* ();
40-
41-
%typemap(in) eprosima::fastdds::rtps::InstanceHandleValue_t*(eprosima::fastdds::rtps::InstanceHandleValue_t temp)
42-
{
43-
if (PyTuple_Check($input))
44-
{
45-
eprosima::fastdds::rtps::octet* buf = temp;
46-
if (!PyArg_ParseTuple($input, "BBBBBBBBBBBBBBBB",
47-
buf, buf+1, buf+2, buf+3, buf+4, buf+5, buf+6, buf+7, buf+8,
48-
buf+9, buf+10, buf+11, buf+12, buf+13, buf+14, buf+15))
41+
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator const octet* () const;
42+
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator octet* ();
43+
44+
%extend eprosima::fastdds::rtps::InstanceHandleValue_t {
45+
46+
// Constructor from sequence of 16 bytes (tupla/lista/bytes/bytearray)
47+
InstanceHandleValue_t(PyObject* seq) {
48+
eprosima::fastdds::rtps::InstanceHandleValue_t* self = new eprosima::fastdds::rtps::InstanceHandleValue_t();
49+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
50+
51+
// Fast-path: bytes
52+
if (PyBytes_Check(seq)) {
53+
if (PyBytes_GET_SIZE(seq) == 16)
54+
{
55+
const char* b = PyBytes_AS_STRING(seq);
56+
for (int i = 0; i < 16; ++i) (*self)[i] = (uint8_t)(unsigned char)b[i];
57+
}
58+
else
59+
{
60+
delete self;
61+
self = nullptr;
62+
PyErr_SetString(PyExc_ValueError, "Expected 16 bytes");
63+
}
64+
}
65+
// Fast-path: bytearray
66+
else if (PyByteArray_Check(seq))
4967
{
50-
PyErr_SetString(PyExc_TypeError, "tuple must have 16 elements");
51-
SWIG_fail;
68+
if (PyByteArray_GET_SIZE(seq) == 16)
69+
{
70+
const char* b = PyByteArray_AS_STRING(seq);
71+
for (int i = 0; i < 16; ++i) (*self)[i] = (uint8_t)(unsigned char)b[i];
72+
}
73+
else
74+
{
75+
delete self;
76+
self = nullptr;
77+
PyErr_SetString(PyExc_ValueError, "Expected 16 bytes");
78+
}
5279
}
53-
$1 = &temp;
54-
}
55-
else
56-
{
57-
PyErr_SetString(PyExc_TypeError, "expected a tuple.");
58-
SWIG_fail;
80+
else
81+
{
82+
// Generic fallback: iterable from 16 ints 0..255
83+
PyObject* it = PyObject_GetIter(seq);
84+
size_t count {0};
85+
if (it)
86+
{
87+
PyObject* item {nullptr};
88+
while ((item = PyIter_Next(it)))
89+
{
90+
long val = PyLong_AsLong(item);
91+
Py_DECREF(item);
92+
if (val == -1 && PyErr_Occurred())
93+
{
94+
delete self;
95+
self = nullptr;
96+
PyErr_SetString(PyExc_TypeError, "Sequence must contain integers");
97+
break;
98+
}
99+
else if (val < 0 || val > 255)
100+
{
101+
delete self;
102+
self = nullptr;
103+
PyErr_SetString(PyExc_ValueError, "Each value must be in 0..255");
104+
break;
105+
}
106+
107+
(*self)[count] = static_cast<uint8_t>(val);
108+
++count;
109+
}
110+
Py_DECREF(it);
111+
if (count != 16)
112+
{
113+
delete self;
114+
self = nullptr;
115+
PyErr_SetString(PyExc_ValueError, "Expected 16 elements");
116+
}
117+
}
118+
else
119+
{
120+
delete self;
121+
self = nullptr;
122+
PyErr_SetString(PyExc_TypeError, "Expected a sequence of 16 integers (0..255) or 16-byte object");
123+
}
124+
}
125+
126+
SWIG_PYTHON_THREAD_END_BLOCK;
127+
128+
return self;
59129
}
60-
}
61130

62-
%typemap(out) eprosima::fastdds::rtps::InstanceHandleValue_t*
63-
{
64-
constexpr size_t ih_size = std::tuple_size<eprosima::fastdds::rtps::KeyHash_t>::value;
65-
PyObject* python_tuple = PyTuple_New(ih_size);
131+
size_t __len__() const { return 16; }
66132

67-
if (python_tuple)
68-
{
69-
for(size_t count = 0; count < ih_size; ++count)
70-
{
71-
PyTuple_SetItem(python_tuple, count, PyInt_FromLong((*$1)[count]));
72-
}
133+
uint8_t __getitem__(size_t i) const {
134+
if (i >= 16) throw std::out_of_range("index out of range");
135+
return $self->operator[](i);
73136
}
74137

75-
$result = python_tuple;
138+
void __setitem__(size_t i, uint8_t v) {
139+
if (i >= 16) throw std::out_of_range("index out of range");
140+
$self->operator[](i) = v;
141+
}
76142
}
77143

78-
// Template for std::vector<InstanceHandle_t>
79-
%template(InstanceHandleVector) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>;
80-
%typemap(doctype) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>"InstanceHandleVector";
81-
82-
%include "fastdds/rtps/common/InstanceHandle.hpp"
144+
%ignore eprosima::fastdds::rtps::InstanceHandle_t::value;
83145

84146
// Declare the comparison operators as internal to the class
85147
%extend eprosima::fastdds::rtps::InstanceHandle_t {
@@ -106,4 +168,48 @@ long hash(const eprosima::fastdds::rtps::InstanceHandle_t& handle)
106168
{
107169
return hash(*$self);
108170
}
171+
172+
// Setter from sequence (tuple/list/bytes/bytearray)
173+
void from_sequence(PyObject* seq) {
174+
// Reutiliza el constructor para validar y copiar
175+
eprosima::fastdds::rtps::InstanceHandleValue_t* tmp = new_eprosima_fastdds_rtps_InstanceHandleValue_t(seq);
176+
for (int i = 0; i < 16; ++i) $self->value[i] = (*tmp)[i];
177+
delete tmp; // evitar fuga
178+
}
179+
180+
// Getter: return a tuple of 16 ints (0..255)
181+
PyObject* to_sequence() const {
182+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
183+
184+
PyObject* python_tuple = PyTuple_New(16);
185+
186+
if (python_tuple)
187+
{
188+
for(size_t count = 0; count < 16; ++count)
189+
{
190+
PyTuple_SetItem(python_tuple, count, PyInt_FromLong($self->value[count]));
191+
}
192+
}
193+
194+
SWIG_PYTHON_THREAD_END_BLOCK;
195+
196+
return python_tuple;
197+
}
109198
}
199+
200+
// Template for std::vector<InstanceHandle_t>
201+
%template(InstanceHandleVector) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>;
202+
%typemap(doctype) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>"InstanceHandleVector";
203+
204+
%include "fastdds/rtps/common/InstanceHandle.hpp"
205+
206+
%pythoncode %{
207+
def _ihv_get_value(self):
208+
return self.to_sequence()
209+
210+
def _ihv_set_value(self, seq):
211+
self.from_sequence(seq)
212+
213+
InstanceHandle_t.value = property(_ihv_get_value, _ihv_set_value,
214+
doc="16-byte value as list/tuple/bytes/bytearray")
215+
%}

0 commit comments

Comments
 (0)