Skip to content

Commit f1a92de

Browse files
committed
moved extractors implementation to mknix
1 parent 3ff7e66 commit f1a92de

File tree

3 files changed

+151
-171
lines changed

3 files changed

+151
-171
lines changed

src/utils/arguments.h

Lines changed: 14 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@ class argument_helper {
4444
return res;
4545
}
4646

47-
void check_arg_type(size_t pos, nix::DataType dtype) const {
48-
check_size(pos);
49-
50-
if (dtype_mex2nix(array[pos]) != dtype) {
51-
throw std::invalid_argument("wrong type");
52-
}
53-
}
54-
5547
protected:
5648
T **array;
5749
size_t number;
@@ -61,151 +53,49 @@ class extractor : public argument_helper<const mxArray> {
6153
public:
6254
extractor(const mxArray **arr, int n) : argument_helper(arr, n) { }
6355

56+
// extractors
57+
6458
std::string str(size_t pos) const {
65-
return mx_array_to_str(array[pos]);
59+
return mx_to_str(array[pos]);
6660
}
6761

6862
template<typename T>
6963
T num(size_t pos) const {
70-
check_arg_type(pos, nix::to_data_type<T>::value);
71-
72-
if (mxGetNumberOfElements(array[pos]) < 1) {
73-
throw std::runtime_error("array empty");
74-
}
75-
76-
const void *data = mxGetData(array[pos]);
77-
T res;
78-
memcpy(&res, data, sizeof(T));
79-
return res;
64+
return mx_to_num<T>(array[pos]);
8065
}
8166

8267
template<typename T>
8368
std::vector<T> vec(size_t pos) const {
84-
std::vector<T> res;
85-
86-
T *pr;
87-
void *voidp = mxGetData(array[pos]);
88-
assert(sizeof(pr) == sizeof(voidp));
89-
memcpy(&pr, &voidp, sizeof(pr));
90-
91-
mwSize input_size = mxGetNumberOfElements(array[pos]);
92-
for (mwSize index = 0; index < input_size; index++) {
93-
res.push_back(*pr++);
94-
}
95-
96-
return res;
69+
return mx_to_vector<T>(array[pos]);
9770
}
9871

9972
template<>
10073
std::vector<std::string> vec(size_t pos) const {
101-
/*
102-
To convert to a string vector we actually expect a cell
103-
array of strings. It's a logical representation since matlab
104-
arrays require that elements have equal length.
105-
*/
106-
std::vector<std::string> res;
107-
const mxArray *el_ptr;
108-
109-
mwSize length = mxGetNumberOfElements(array[pos]);
110-
mwIndex index;
111-
112-
for (index = 0; index < length; index++) {
113-
el_ptr = mxGetCell(array[pos], index);
114-
115-
if (!mxIsChar(el_ptr)) {
116-
throw std::invalid_argument("All elements of a cell array should be of a string type");
117-
}
118-
119-
char *tmp = mxArrayToString(el_ptr);
120-
std::string the_string(tmp);
121-
res.push_back(the_string);
122-
mxFree(tmp);
123-
}
124-
125-
return res;
74+
return mx_to_strings(array[pos]);
12675
}
12776

12877
std::vector<nix::Value> vec(size_t pos) const {
129-
/*
130-
To convert to a vector of Values we actually expect either
131-
- a cell array with scalar values, or
132-
- a cell array with structs each having Value attrs
133-
(uncertainty, checksum etc.) as fields, or
134-
- a regular array
135-
*/
136-
std::vector<nix::Value> vals;
137-
const mxArray *cell_element_ptr;
138-
139-
if (mxGetClassID(array[pos]) == mxCELL_CLASS) {
140-
141-
mwSize size = mxGetNumberOfElements(array[pos]);
142-
for (mwIndex index = 0; index < size; index++) {
143-
cell_element_ptr = mxGetCell(array[pos], index);
144-
145-
if (mxGetClassID(cell_element_ptr) == mxSTRUCT_CLASS) {
146-
// assume values are given as matlab structs
147-
vals.push_back(mx_array_to_value_from_struct(cell_element_ptr));
148-
}
149-
else {
150-
// assume just a scalar value given
151-
vals.push_back(mx_array_to_value_from_scalar(cell_element_ptr));
152-
}
153-
}
154-
}
155-
else {
156-
mxClassID cls = mxGetClassID(array[pos]);
157-
158-
switch (cls) {
159-
case mxDOUBLE_CLASS: vals = mx_array_to_value_from_array<double>(array[pos]); break;
160-
case mxUINT32_CLASS: vals = mx_array_to_value_from_array<uint32_t>(array[pos]); break;
161-
case mxINT32_CLASS: vals = mx_array_to_value_from_array<int32_t>(array[pos]); break;
162-
case mxUINT64_CLASS: vals = mx_array_to_value_from_array<uint64_t>(array[pos]); break;
163-
case mxINT64_CLASS: vals = mx_array_to_value_from_array<int64_t>(array[pos]); break;
164-
165-
default: std::invalid_argument("This type of values is not supported");
166-
}
167-
}
168-
169-
return vals;
78+
return mx_to_values(array[pos]);
17079
}
17180

17281
nix::NDSize ndsize(size_t pos) const {
173-
return mx_array_to_ndsize(array[pos]);
82+
return mx_to_ndsize(array[pos]);
17483
}
17584

17685
nix::DataType dtype(size_t pos) const {
17786
return dtype_mex2nix(array[pos]);
17887
}
17988

180-
nix::LinkType ltype(size_t pos) const
181-
{
182-
const uint8_t link_type = num<uint8_t>(pos);
183-
nix::LinkType retLinkType;
184-
185-
switch (link_type) {
186-
case 0: retLinkType = nix::LinkType::Tagged; break;
187-
case 1: retLinkType = nix::LinkType::Untagged; break;
188-
case 2: retLinkType = nix::LinkType::Indexed; break;
189-
default: throw std::invalid_argument("unkown link type");
190-
}
191-
192-
return retLinkType;
89+
nix::LinkType ltype(size_t pos) const {
90+
return mx_to_linktype(array[pos]);
19391
}
19492

195-
bool logical(size_t pos) const {
196-
check_arg_type(pos, nix::DataType::Bool);
197-
198-
const mxLogical *l = mxGetLogicals(array[pos]);
199-
return l[0];
200-
}
201-
202-
template<typename T>
203-
T get(size_t pos) const {
204-
check_size(pos);
205-
206-
return mx_array_to_nix(array[pos]);
93+
bool logical(size_t pos) const {
94+
return mx_to_bool(array[pos]);
20795
}
20896

97+
// helpers
98+
20999
template<typename T>
210100
T entity(size_t pos) const {
211101
return hdl(pos).get<T>();

src/utils/mknix.cc

Lines changed: 98 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,27 @@
1212
#include "struct.h"
1313
#include "datatypes.h"
1414

15+
// helpers
1516

1617
void check_arg_type(const mxArray *arr, nix::DataType dtype) {
1718
if (dtype_mex2nix(arr) != dtype) {
1819
throw std::invalid_argument("wrong type");
1920
}
2021
}
2122

23+
24+
25+
// TODO move this to mkarray
2226
mxArray *nmCreateScalar(uint32_t val) {
2327
mxArray *arr = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
2428
void *data = mxGetData(arr);
2529
memcpy(data, &val, sizeof(uint32_t));
2630
return arr;
2731
}
2832

29-
nix::NDSize mx_array_to_ndsize(const mxArray *arr) {
33+
// extractors
34+
35+
nix::NDSize mx_to_ndsize(const mxArray *arr) {
3036

3137
size_t m = mxGetM(arr);
3238
size_t n = mxGetN(arr);
@@ -44,49 +50,76 @@ nix::NDSize mx_array_to_ndsize(const mxArray *arr) {
4450
return size;
4551
}
4652

47-
std::string mx_array_to_str(const mxArray *arr) {
48-
check_arg_type(arr, nix::DataType::String);
53+
std::vector<std::string> mx_to_strings(const mxArray *arr) {
54+
/*
55+
To convert to a string vector we actually expect a cell
56+
array of strings. It's a logical representation since matlab
57+
arrays require that elements have equal length.
58+
*/
59+
std::vector<std::string> res;
60+
const mxArray *el_ptr;
4961

50-
std::string the_string = mxArrayToString(arr);
51-
return the_string;
52-
}
62+
mwSize length = mxGetNumberOfElements(arr);
63+
mwIndex index;
64+
65+
for (index = 0; index < length; index++) {
66+
el_ptr = mxGetCell(arr, index);
5367

54-
template<typename T>
55-
T mx_array_to_num(const mxArray *arr) {
56-
check_arg_type(arr, nix::to_data_type<T>::value);
68+
if (!mxIsChar(el_ptr)) {
69+
throw std::invalid_argument("All elements of a cell array should be of a string type");
70+
}
5771

58-
if (mxGetNumberOfElements(arr) < 1) {
59-
throw std::runtime_error("array empty");
72+
char *tmp = mxArrayToString(el_ptr);
73+
std::string the_string(tmp);
74+
res.push_back(the_string);
75+
mxFree(tmp);
6076
}
6177

62-
const void *data = mxGetData(arr);
63-
T res;
64-
memcpy(&res, data, sizeof(T));
6578
return res;
6679
}
6780

68-
bool mx_array_to_bool(const mxArray *arr) {
81+
nix::LinkType mx_to_linktype(const mxArray *arr) {
82+
const uint8_t link_type = mx_to_num<uint8_t>(arr);
83+
nix::LinkType retLinkType;
84+
85+
switch (link_type) {
86+
case 0: retLinkType = nix::LinkType::Tagged; break;
87+
case 1: retLinkType = nix::LinkType::Untagged; break;
88+
case 2: retLinkType = nix::LinkType::Indexed; break;
89+
default: throw std::invalid_argument("unkown link type");
90+
}
91+
92+
return retLinkType;
93+
}
94+
95+
std::string mx_to_str(const mxArray *arr) {
96+
check_arg_type(arr, nix::DataType::String);
97+
98+
std::string the_string = mxArrayToString(arr);
99+
return the_string;
100+
}
101+
102+
bool mx_to_bool(const mxArray *arr) {
69103
check_arg_type(arr, nix::DataType::Bool);
70104

71105
const mxLogical *l = mxGetLogicals(arr);
72106
return l[0];
73107
}
74108

75-
76-
nix::Value mx_array_to_value_from_scalar(const mxArray *arr) {
109+
nix::Value mx_to_value_from_scalar(const mxArray *arr) {
77110
/*
78111
Assuming arr is a scalar mxArray.
79112
*/
80113
nix::Value val;
81114

82115
switch (mxGetClassID(arr)) {
83-
case mxLOGICAL_CLASS: val.set(mx_array_to_bool(arr)); break;
84-
case mxCHAR_CLASS: val.set(mx_array_to_str(arr)); break;
85-
case mxDOUBLE_CLASS: val.set(mx_array_to_num<double>(arr)); break;
86-
case mxUINT32_CLASS: val.set(mx_array_to_num<uint32_t>(arr)); break;
87-
case mxINT32_CLASS: val.set(mx_array_to_num<int32_t>(arr)); break;
88-
case mxUINT64_CLASS: val.set(mx_array_to_num<uint64_t>(arr)); break;
89-
case mxINT64_CLASS: val.set(mx_array_to_num<int64_t>(arr)); break;
116+
case mxLOGICAL_CLASS: val.set(mx_to_bool(arr)); break;
117+
case mxCHAR_CLASS: val.set(mx_to_str(arr)); break;
118+
case mxDOUBLE_CLASS: val.set(mx_to_num<double>(arr)); break;
119+
case mxUINT32_CLASS: val.set(mx_to_num<uint32_t>(arr)); break;
120+
case mxINT32_CLASS: val.set(mx_to_num<int32_t>(arr)); break;
121+
case mxUINT64_CLASS: val.set(mx_to_num<uint64_t>(arr)); break;
122+
case mxINT64_CLASS: val.set(mx_to_num<int64_t>(arr)); break;
90123

91124
case mxSINGLE_CLASS: throw std::invalid_argument("Element type is not supported");
92125
case mxUINT8_CLASS: throw std::invalid_argument("Element type is not supported");
@@ -100,7 +133,7 @@ nix::Value mx_array_to_value_from_scalar(const mxArray *arr) {
100133
return val;
101134
}
102135

103-
nix::Value mx_array_to_value_from_struct(const mxArray *arr) {
136+
nix::Value mx_to_value_from_struct(const mxArray *arr) {
104137
/*
105138
Assuming arr is a struct mxArray.
106139
*/
@@ -123,15 +156,49 @@ nix::Value mx_array_to_value_from_struct(const mxArray *arr) {
123156

124157
std::string arg_name = field_name;
125158
switch (arg_map[arg_name]) {
126-
case 0: val = mx_array_to_value_from_scalar(field_array_ptr); break;
127-
case 1: val.uncertainty = mx_array_to_num<double>(field_array_ptr); break;
128-
case 2: val.checksum = mx_array_to_str(field_array_ptr); break;
129-
case 3: val.encoder = mx_array_to_str(field_array_ptr); break;
130-
case 4: val.filename = mx_array_to_str(field_array_ptr); break;
131-
case 5: val.reference = mx_array_to_str(field_array_ptr); break;
159+
case 0: val = mx_to_value_from_scalar(field_array_ptr); break;
160+
case 1: val.uncertainty = mx_to_num<double>(field_array_ptr); break;
161+
case 2: val.checksum = mx_to_str(field_array_ptr); break;
162+
case 3: val.encoder = mx_to_str(field_array_ptr); break;
163+
case 4: val.filename = mx_to_str(field_array_ptr); break;
164+
case 5: val.reference = mx_to_str(field_array_ptr); break;
132165
default: throw std::invalid_argument(strcat("Field is not supported: ", field_name));
133166
}
134167
}
135168

136169
return val;
170+
}
171+
172+
std::vector<nix::Value> mx_to_values(const mxArray *arr) {
173+
/*
174+
To convert to a vector of Values we actually expect either
175+
- a cell array with scalar values, or
176+
- a cell array with structs each having Value attrs
177+
(uncertainty, checksum etc.) as fields, or
178+
- a regular array
179+
*/
180+
std::vector<nix::Value> vals;
181+
const mxArray *cell_element_ptr;
182+
183+
if (mxGetClassID(arr) == mxCELL_CLASS) {
184+
185+
mwSize size = mxGetNumberOfElements(arr);
186+
for (mwIndex index = 0; index < size; index++) {
187+
cell_element_ptr = mxGetCell(arr, index);
188+
189+
if (mxGetClassID(cell_element_ptr) == mxSTRUCT_CLASS) {
190+
// assume values are given as matlab structs
191+
vals.push_back(mx_to_value_from_struct(cell_element_ptr));
192+
}
193+
else {
194+
// assume just a scalar value given
195+
vals.push_back(mx_to_value_from_scalar(cell_element_ptr));
196+
}
197+
}
198+
}
199+
else {
200+
throw std::invalid_argument("Values must be given as cell array");
201+
}
202+
203+
return vals;
137204
}

0 commit comments

Comments
 (0)