Skip to content

Commit 5e8d111

Browse files
committed
value operations refactoring
1 parent 65591fa commit 5e8d111

File tree

4 files changed

+100
-111
lines changed

4 files changed

+100
-111
lines changed

src/nixproperty.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ namespace nixproperty {
5555
{
5656
nix::Property prop = input.entity<nix::Property>(1);
5757
prop.deleteValues();
58-
std::vector<nix::Value> getVals = input.extractFromStruct(2);
58+
std::vector<nix::Value> getVals = input.vec(2);
5959
prop.values(getVals);
6060
}
6161

src/utils/arguments.h

Lines changed: 35 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,44 @@ class extractor : public argument_helper<const mxArray> {
126126
}
127127

128128
std::vector<nix::Value> vec(size_t pos) const {
129-
mwSize size = mxGetNumberOfElements(array[pos]);
130-
131-
mwIndex index;
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+
*/
132136
std::vector<nix::Value> vals;
133137
const mxArray *cell_element_ptr;
134138

135-
for (index = 0; index < size; index++) {
136-
cell_element_ptr = mxGetCell(array[pos], index);
137-
vals.push_back(mx_array_to_value(cell_element_ptr));
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+
}
138167
}
139168

140169
return vals;
@@ -193,108 +222,6 @@ class extractor : public argument_helper<const mxArray> {
193222
return mxGetPr(array[pos]);
194223
}
195224

196-
std::vector<nix::Value> extractFromStruct(size_t pos) const {
197-
198-
// Note: nix::Value is not able to its attributes "uncertainty"
199-
// "checksum", "filename", "encoder" or "reference" at the moment.
200-
// The setters are implemented and the attribute values are
201-
// correctly set to the nix::Value entity, but they will not
202-
// actually be written to the nix file. Once this issue has been
203-
// fixed on the nix side, the current implementation should work
204-
// fine.
205-
206-
std::vector<nix::Value> vals;
207-
208-
mwSize total_num_of_cells = mxGetNumberOfElements(array[pos]);
209-
for (mwIndex index = 0; index<total_num_of_cells; index++) {
210-
const mxArray *cell_element_ptr = mxGetCell(array[pos], index);
211-
212-
if (mxGetClassID(cell_element_ptr) == mxSTRUCT_CLASS){
213-
214-
nix::Value currVal;
215-
216-
mwSize total_num_of_elements = mxGetNumberOfElements(cell_element_ptr);
217-
int number_of_fields = mxGetNumberOfFields(cell_element_ptr);
218-
219-
for (mwIndex struct_idx = 0; struct_idx < total_num_of_elements; struct_idx++) {
220-
for (int field_index = 0; field_index < number_of_fields; field_index++) {
221-
const char *field_name = mxGetFieldNameByNumber(cell_element_ptr, field_index);
222-
const mxArray *field_array_ptr = mxGetFieldByNumber(cell_element_ptr, struct_idx, field_index);
223-
224-
if (field_array_ptr != nullptr) {
225-
if (strcmp(field_name, "value") == 0){
226-
if (mxGetClassID(field_array_ptr) == mxDOUBLE_CLASS){
227-
double curr;
228-
const void *data = mxGetData(field_array_ptr);
229-
memcpy(&curr, data, sizeof(double));
230-
currVal.set(curr);
231-
}
232-
else if (mxGetClassID(field_array_ptr) == mxLOGICAL_CLASS){
233-
const mxLogical *curr = mxGetLogicals(field_array_ptr);
234-
currVal.set(curr[0]);
235-
}
236-
else if (mxGetClassID(field_array_ptr) == mxCHAR_CLASS){
237-
char *tmp = mxArrayToString(field_array_ptr);
238-
std::string curr_string = tmp;
239-
currVal.set(curr_string);
240-
mxFree(tmp);
241-
}
242-
else { mexPrintf("Unsupported value data type\n"); }
243-
244-
}
245-
else if (strcmp(field_name, "uncertainty") == 0){
246-
if (mxGetClassID(field_array_ptr) == mxDOUBLE_CLASS){
247-
double curr;
248-
const void *data = mxGetData(field_array_ptr);
249-
memcpy(&curr, data, sizeof(double));
250-
currVal.uncertainty = curr;
251-
}
252-
}
253-
else if (strcmp(field_name, "checksum") == 0){
254-
if (mxGetClassID(field_array_ptr) == mxCHAR_CLASS){
255-
char *tmp = mxArrayToString(field_array_ptr);
256-
std::string curr_string = tmp;
257-
currVal.checksum = curr_string;
258-
mxFree(tmp);
259-
}
260-
}
261-
else if (strcmp(field_name, "encoder") == 0){
262-
if (mxGetClassID(field_array_ptr) == mxCHAR_CLASS){
263-
char *tmp = mxArrayToString(field_array_ptr);
264-
std::string curr_string = tmp;
265-
currVal.encoder = curr_string;
266-
mxFree(tmp);
267-
}
268-
}
269-
else if (strcmp(field_name, "filename") == 0){
270-
if (mxGetClassID(field_array_ptr) == mxCHAR_CLASS){
271-
char *tmp = mxArrayToString(field_array_ptr);
272-
std::string curr_string = tmp;
273-
currVal.filename = curr_string;
274-
mxFree(tmp);
275-
}
276-
}
277-
else if (strcmp(field_name, "reference") == 0){
278-
if (mxGetClassID(field_array_ptr) == mxCHAR_CLASS){
279-
char *tmp = mxArrayToString(field_array_ptr);
280-
std::string curr_string(tmp);
281-
currVal.reference = tmp;
282-
mxFree(tmp);
283-
}
284-
}
285-
}
286-
}
287-
}
288-
vals.push_back(currVal);
289-
}
290-
else
291-
{
292-
mexWarnMsgTxt("Unsupported value wrapper data type");
293-
}
294-
}
295-
return vals;
296-
}
297-
298225
private:
299226
};
300227

src/utils/nix2mx.cc

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <math.h>
33
#include <string.h>
44
#include <vector>
5+
#include <map>
56
#include "mex.h"
67

78
#include <nix.hpp>
@@ -71,7 +72,11 @@ bool mx_array_to_bool(const mxArray *arr) {
7172
return l[0];
7273
}
7374

74-
nix::Value mx_array_to_value(const mxArray *arr) {
75+
76+
nix::Value mx_array_to_value_from_scalar(const mxArray *arr) {
77+
/*
78+
Assuming arr is a scalar mxArray.
79+
*/
7580
nix::Value val;
7681

7782
switch (mxGetClassID(arr)) {
@@ -95,3 +100,38 @@ nix::Value mx_array_to_value(const mxArray *arr) {
95100
return val;
96101
}
97102

103+
nix::Value mx_array_to_value_from_struct(const mxArray *arr) {
104+
/*
105+
Assuming arr is a struct mxArray.
106+
*/
107+
static std::map<std::string, int> arg_map = {
108+
{ "value", 0 },
109+
{ "uncertainty", 1 },
110+
{ "checksum", 2 },
111+
{ "encoder", 3 },
112+
{ "filename", 4 },
113+
{ "reference", 5 }
114+
};
115+
116+
nix::Value val;
117+
bool has_value = false;
118+
119+
int number_of_fields = mxGetNumberOfFields(arr);
120+
for (int idx = 0; idx < number_of_fields; idx++) {
121+
const char *field_name = mxGetFieldNameByNumber(arr, idx);
122+
const mxArray *field_array_ptr = mxGetFieldByNumber(arr, 0, idx);
123+
124+
std::string arg_name = field_name;
125+
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;
132+
default: throw std::invalid_argument(strcat("Field is not supported: ", field_name));
133+
}
134+
}
135+
136+
return val;
137+
}

src/utils/nix2mx.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,29 @@ T mx_array_to_num(const mxArray *arr);
1616

1717
bool mx_array_to_bool(const mxArray *arr);
1818

19-
nix::Value mx_array_to_value(const mxArray *arr);
19+
template<typename T>
20+
inline std::vector<nix::Value> mx_array_to_value_from_array(const mxArray *arr) {
21+
/*
22+
Assuming arr is a regular mxArray.
23+
*/
24+
std::vector<nix::Value> res;
25+
26+
T *pr;
27+
pr = (T *)mxGetData(arr);
28+
29+
mwSize input_size = mxGetNumberOfElements(arr);
30+
for (mwSize index = 0; index < input_size; index++) {
31+
nix::Value val;
32+
val.set(*pr++);
33+
res.push_back(val);
34+
}
35+
36+
return res;
37+
}
38+
39+
nix::Value mx_array_to_value_from_scalar(const mxArray *arr);
40+
41+
nix::Value mx_array_to_value_from_struct(const mxArray *arr);
2042

2143
mxArray *nmCreateScalar(uint32_t val);
2244

0 commit comments

Comments
 (0)