12
12
#include " struct.h"
13
13
#include " datatypes.h"
14
14
15
+ // helpers
15
16
16
17
void check_arg_type (const mxArray *arr, nix::DataType dtype) {
17
18
if (dtype_mex2nix (arr) != dtype) {
18
19
throw std::invalid_argument (" wrong type" );
19
20
}
20
21
}
21
22
23
+
24
+
25
+ // TODO move this to mkarray
22
26
mxArray *nmCreateScalar (uint32_t val) {
23
27
mxArray *arr = mxCreateNumericMatrix (1 , 1 , mxUINT32_CLASS, mxREAL);
24
28
void *data = mxGetData (arr);
25
29
memcpy (data, &val, sizeof (uint32_t ));
26
30
return arr;
27
31
}
28
32
29
- nix::NDSize mx_array_to_ndsize (const mxArray *arr) {
33
+ // extractors
34
+
35
+ nix::NDSize mx_to_ndsize (const mxArray *arr) {
30
36
31
37
size_t m = mxGetM (arr);
32
38
size_t n = mxGetN (arr);
@@ -44,49 +50,76 @@ nix::NDSize mx_array_to_ndsize(const mxArray *arr) {
44
50
return size;
45
51
}
46
52
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;
49
61
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);
53
67
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
+ }
57
71
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);
60
76
}
61
77
62
- const void *data = mxGetData (arr);
63
- T res;
64
- memcpy (&res, data, sizeof (T));
65
78
return res;
66
79
}
67
80
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) {
69
103
check_arg_type (arr, nix::DataType::Bool);
70
104
71
105
const mxLogical *l = mxGetLogicals (arr);
72
106
return l[0 ];
73
107
}
74
108
75
-
76
- nix::Value mx_array_to_value_from_scalar (const mxArray *arr) {
109
+ nix::Value mx_to_value_from_scalar (const mxArray *arr) {
77
110
/*
78
111
Assuming arr is a scalar mxArray.
79
112
*/
80
113
nix::Value val;
81
114
82
115
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 ;
90
123
91
124
case mxSINGLE_CLASS: throw std::invalid_argument (" Element type is not supported" );
92
125
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) {
100
133
return val;
101
134
}
102
135
103
- nix::Value mx_array_to_value_from_struct (const mxArray *arr) {
136
+ nix::Value mx_to_value_from_struct (const mxArray *arr) {
104
137
/*
105
138
Assuming arr is a struct mxArray.
106
139
*/
@@ -123,15 +156,49 @@ nix::Value mx_array_to_value_from_struct(const mxArray *arr) {
123
156
124
157
std::string arg_name = field_name;
125
158
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 ;
132
165
default : throw std::invalid_argument (strcat (" Field is not supported: " , field_name));
133
166
}
134
167
}
135
168
136
169
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;
137
204
}
0 commit comments