Skip to content

Commit 834fad7

Browse files
committed
Use unordered maps to simplify templated methods in pvxs converter
1 parent 71eccb5 commit 834fad7

File tree

2 files changed

+109
-57
lines changed

2 files changed

+109
-57
lines changed

ADApp/ntndArrayConverterSrc/ntndArrayConverter.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ typedef std::tr1::shared_ptr<NTNDArrayConverter> NTNDArrayConverterPtr;
7373
#include <ntndArrayConverterAPI.h>
7474
#include <NDArray.h>
7575
#include <pvxs/data.h>
76+
#include <typeindex>
77+
#include <typeinfo>
78+
#include <unordered_map>
7679

7780
typedef struct NTNDArrayInfo
7881
{
@@ -101,24 +104,27 @@ class NTNDARRAYCONVERTER_API NTNDArrayConverter
101104

102105
private:
103106
pvxs::Value m_value;
107+
std::unordered_map<std::type_index, NDAttrDataType_t> m_typeMap;
108+
std::unordered_map<std::type_index, std::string> m_fieldNameMap;
109+
std::unordered_map<std::type_index, pvxs::ArrayType> m_arrayTypeMap;
104110
NDColorMode_t getColorMode (void);
105111

106112
template <typename arrayType>
107-
void toValue (NDArray *dest, std::string fieldName);
113+
void toValue (NDArray *dest);
108114
void toValue (NDArray *dest);
109115

110116
void toDimensions (NDArray *dest);
111117
void toTimeStamp (NDArray *dest);
112118
void toDataTimeStamp (NDArray *dest);
113119

114120
template <typename valueType>
115-
void toAttribute (NDArray *dest, pvxs::Value attribute, NDAttrDataType_t dataType);
121+
void toAttribute (NDArray *dest, pvxs::Value attribute);
116122
void toStringAttribute (NDArray *dest, pvxs::Value attribute);
117123
void toUndefinedAttribute (NDArray *dest, pvxs::Value attribute);
118124
void toAttributes (NDArray *dest);
119125

120-
// template <typename arrayType>
121-
// void fromValue (NDArray *src, const char* field_name);
126+
template <typename arrayType>
127+
void fromValue (NDArray *src);
122128
void fromValue (NDArray *src);
123129

124130
void fromDimensions (NDArray *src);

ADApp/ntndArrayConverterSrc/ntndArrayConverter_pvxs.cpp

Lines changed: 99 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,46 @@ struct freeNDArray {
1111
void operator()(dataType *data) { array->release(); }
1212
};
1313

14-
NTNDArrayConverter::NTNDArrayConverter (pvxs::Value value) : m_value(value) {}
14+
NTNDArrayConverter::NTNDArrayConverter (pvxs::Value value) : m_value(value) {
15+
m_typeMap = {
16+
{typeid(int8_t), NDAttrDataType_t::NDAttrInt8},
17+
{typeid(uint8_t), NDAttrDataType_t::NDAttrUInt8},
18+
{typeid(int16_t), NDAttrDataType_t::NDAttrInt16},
19+
{typeid(uint16_t), NDAttrDataType_t::NDAttrUInt16},
20+
{typeid(int32_t), NDAttrDataType_t::NDAttrInt32},
21+
{typeid(uint32_t), NDAttrDataType_t::NDAttrUInt32},
22+
{typeid(int64_t), NDAttrDataType_t::NDAttrInt64},
23+
{typeid(uint64_t), NDAttrDataType_t::NDAttrUInt64},
24+
{typeid(float_t), NDAttrDataType_t::NDAttrFloat32},
25+
{typeid(double_t), NDAttrDataType_t::NDAttrFloat64}
26+
};
27+
28+
m_fieldNameMap = {
29+
{typeid(int8_t), "value->byteValue"},
30+
{typeid(uint8_t), "value->ubyteValue"},
31+
{typeid(int16_t), "value->shortValue"},
32+
{typeid(uint16_t), "value->ushortValue"},
33+
{typeid(int32_t), "value->intValue"},
34+
{typeid(uint32_t), "value->uintValue"},
35+
{typeid(int64_t), "value->longValue"},
36+
{typeid(uint64_t), "value->ulongValue"},
37+
{typeid(float_t), "value->floatValue"},
38+
{typeid(double_t), "value->doubleValue"}
39+
};
40+
41+
m_arrayTypeMap = {
42+
{typeid(int8_t), pvxs::ArrayType::Int8},
43+
{typeid(uint8_t), pvxs::ArrayType::UInt8},
44+
{typeid(int16_t), pvxs::ArrayType::Int16},
45+
{typeid(int32_t), pvxs::ArrayType::Int32},
46+
{typeid(uint32_t), pvxs::ArrayType::UInt32},
47+
{typeid(int64_t), pvxs::ArrayType::Int64},
48+
{typeid(uint64_t), pvxs::ArrayType::UInt64},
49+
{typeid(float_t), pvxs::ArrayType::Float32},
50+
{typeid(double_t), pvxs::ArrayType::Float64}
51+
};
52+
53+
}
1554

1655
NDColorMode_t NTNDArrayConverter::getColorMode (void)
1756
{
@@ -48,16 +87,16 @@ NTNDArrayInfo_t NTNDArrayConverter::getInfo (void)
4887

4988
if (info.codec.empty()) {
5089
switch (m_value["value->"].type().code) {
51-
case pvxs::TypeCode::Int8A: {dt = NDDataType_t::NDInt8; bpe = sizeof(int8_t); break;}
52-
case pvxs::TypeCode::UInt8A: {dt = NDDataType_t::NDUInt8; bpe = sizeof(uint8_t); break;}
53-
case pvxs::TypeCode::Int16A: {dt = NDDataType_t::NDInt16; bpe = sizeof(int16_t); break;}
54-
case pvxs::TypeCode::UInt16A: {dt = NDDataType_t::NDUInt16; bpe = sizeof(uint16_t); break;}
55-
case pvxs::TypeCode::Int32A: {dt = NDDataType_t::NDInt32; bpe = sizeof(int32_t); break;}
56-
case pvxs::TypeCode::UInt32A: {dt = NDDataType_t::NDUInt32; bpe = sizeof(uint32_t); break;}
57-
case pvxs::TypeCode::Int64A: {dt = NDDataType_t::NDInt64; bpe = sizeof(int64_t); break;}
58-
case pvxs::TypeCode::UInt64A: {dt = NDDataType_t::NDUInt64; bpe = sizeof(uint64_t); break;}
59-
case pvxs::TypeCode::Float32A: {dt = NDDataType_t::NDFloat32; bpe = sizeof(float_t); break;}
60-
case pvxs::TypeCode::Float64A: {dt = NDDataType_t::NDFloat64; bpe = sizeof(double_t); break;}
90+
case pvxs::TypeCode::Int8A: {dt = NDInt8; bpe = sizeof(int8_t); break;}
91+
case pvxs::TypeCode::UInt8A: {dt = NDUInt8; bpe = sizeof(uint8_t); break;}
92+
case pvxs::TypeCode::Int16A: {dt = NDInt16; bpe = sizeof(int16_t); break;}
93+
case pvxs::TypeCode::UInt16A: {dt = NDUInt16; bpe = sizeof(uint16_t); break;}
94+
case pvxs::TypeCode::Int32A: {dt = NDInt32; bpe = sizeof(int32_t); break;}
95+
case pvxs::TypeCode::UInt32A: {dt = NDUInt32; bpe = sizeof(uint32_t); break;}
96+
case pvxs::TypeCode::Int64A: {dt = NDInt64; bpe = sizeof(int64_t); break;}
97+
case pvxs::TypeCode::UInt64A: {dt = NDUInt64; bpe = sizeof(uint64_t); break;}
98+
case pvxs::TypeCode::Float32A: {dt = NDFloat32; bpe = sizeof(float_t); break;}
99+
case pvxs::TypeCode::Float64A: {dt = NDFloat64; bpe = sizeof(double_t); break;}
61100
default: throw std::runtime_error("invalid value data type");
62101
}
63102
// TODO get datatype
@@ -157,12 +196,15 @@ void NTNDArrayConverter::fromArray (NDArray *src)
157196
}
158197

159198
template <typename arrayType>
160-
void NTNDArrayConverter::toValue (NDArray *dest, std::string fieldName)
199+
void NTNDArrayConverter::toValue (NDArray *dest)
161200
{
162201
NTNDArrayInfo_t info = getInfo();
163202
dest->codec.name = info.codec;
164203
dest->dataType = info.dataType;
165204

205+
206+
std::string fieldName = m_fieldNameMap[typeid(arrayType)];
207+
166208
auto value = m_value[fieldName].as<pvxs::shared_array<const arrayType>>();
167209
memcpy(dest->pData, value.data(), info.totalBytes);
168210

@@ -173,16 +215,16 @@ void NTNDArrayConverter::toValue (NDArray *dest, std::string fieldName)
173215
void NTNDArrayConverter::toValue (NDArray *dest)
174216
{
175217
switch (m_value["value->"].type().code) {
176-
case pvxs::TypeCode::Int8A: {toValue<int8_t>(dest, std::string("value->byteValue")); break;}
177-
case pvxs::TypeCode::UInt8A: {toValue<uint8_t>(dest, std::string("value->ubyteValue")); break;}
178-
case pvxs::TypeCode::Int16A: {toValue<int16_t>(dest, std::string("value->shortValue")); break;}
179-
case pvxs::TypeCode::UInt16A: {toValue<uint16_t>(dest, std::string("value->ushortValue")); break;}
180-
case pvxs::TypeCode::Int32A: {toValue<int32_t>(dest, std::string("value->intValue")); break;}
181-
case pvxs::TypeCode::UInt32A: {toValue<uint32_t>(dest, std::string("value->uintValue")); break;}
182-
case pvxs::TypeCode::Int64A: {toValue<int64_t>(dest, std::string("value->longValue")); break;}
183-
case pvxs::TypeCode::UInt64A: {toValue<uint64_t>(dest, std::string("value->ulongValue")); break;}
184-
case pvxs::TypeCode::Float32A: {toValue<float_t>(dest, std::string("value->floatValue")); break;}
185-
case pvxs::TypeCode::Float64A: {toValue<double_t>(dest, std::string("value->doubleValue")); break;}
218+
case pvxs::TypeCode::Int8A: {toValue<int8_t>(dest); break;}
219+
case pvxs::TypeCode::UInt8A: {toValue<uint8_t>(dest); break;}
220+
case pvxs::TypeCode::Int16A: {toValue<int16_t>(dest); break;}
221+
case pvxs::TypeCode::UInt16A: {toValue<uint16_t>(dest); break;}
222+
case pvxs::TypeCode::Int32A: {toValue<int32_t>(dest); break;}
223+
case pvxs::TypeCode::UInt32A: {toValue<uint32_t>(dest); break;}
224+
case pvxs::TypeCode::Int64A: {toValue<int64_t>(dest); break;}
225+
case pvxs::TypeCode::UInt64A: {toValue<uint64_t>(dest); break;}
226+
case pvxs::TypeCode::Float32A: {toValue<float_t>(dest); break;}
227+
case pvxs::TypeCode::Float64A: {toValue<double_t>(dest); break;}
186228
default: throw std::runtime_error("invalid value data type");
187229
}
188230
}
@@ -221,14 +263,14 @@ void NTNDArrayConverter::toDataTimeStamp (NDArray *dest)
221263
}
222264

223265
template <typename valueType>
224-
void NTNDArrayConverter::toAttribute (NDArray *dest, pvxs::Value attribute, NDAttrDataType_t dataType)
266+
void NTNDArrayConverter::toAttribute (NDArray *dest, pvxs::Value attribute)
225267
{
226-
// TODO, can we make dataType a template parameter?
227268
auto name = attribute["name"].as<std::string>();
228269
auto desc = attribute["descriptor"].as<std::string>();
229270
auto source = attribute["source"].as<std::string>();
230271
NDAttrSource_t sourceType = (NDAttrSource_t) attribute["sourceType"].as<int32_t>();
231272
valueType value = attribute["value"].as<valueType>();
273+
NDAttrDataType_t dataType = m_typeMap[typeid(valueType)];
232274

233275
NDAttribute *attr = new NDAttribute(name.c_str(), desc.c_str(), sourceType, source.c_str(), dataType, (void*)&value);
234276
dest->pAttributeList->add(attr);
@@ -264,53 +306,57 @@ void NTNDArrayConverter::toAttributes (NDArray *dest)
264306
pvxs::Value value = attributes[i]["value"];
265307
switch (attributes[i]["value->"].type().code) {
266308
// use indirection on Any container to get specified type
267-
case pvxs::TypeCode::Int8: toAttribute<int8_t> (dest, attributes[i], NDAttrDataType_t::NDAttrInt8); break;
268-
case pvxs::TypeCode::UInt8: toAttribute<uint8_t> (dest, attributes[i], NDAttrDataType_t::NDAttrUInt8); break;
269-
case pvxs::TypeCode::Int16: toAttribute<int16_t> (dest, attributes[i], NDAttrDataType_t::NDAttrInt16); break;
270-
case pvxs::TypeCode::UInt16: toAttribute<uint16_t> (dest, attributes[i], NDAttrDataType_t::NDAttrUInt16); break;
271-
case pvxs::TypeCode::Int32: toAttribute<int32_t> (dest, attributes[i], NDAttrDataType_t::NDAttrInt32); break;
272-
case pvxs::TypeCode::UInt32: toAttribute<uint32_t> (dest, attributes[i], NDAttrDataType_t::NDAttrUInt32); break;
273-
case pvxs::TypeCode::Int64: toAttribute<int64_t> (dest, attributes[i], NDAttrDataType_t::NDAttrInt64); break;
274-
case pvxs::TypeCode::UInt64: toAttribute<uint64_t> (dest, attributes[i], NDAttrDataType_t::NDAttrUInt64); break;
275-
case pvxs::TypeCode::Float32: toAttribute<float_t> (dest, attributes[i], NDAttrDataType_t::NDAttrFloat32); break;
276-
case pvxs::TypeCode::Float64: toAttribute<double_t> (dest, attributes[i], NDAttrDataType_t::NDAttrFloat64); break;
309+
case pvxs::TypeCode::Int8: toAttribute<int8_t> (dest, attributes[i]); break;
310+
case pvxs::TypeCode::UInt8: toAttribute<uint8_t> (dest, attributes[i]); break;
311+
case pvxs::TypeCode::Int16: toAttribute<int16_t> (dest, attributes[i]); break;
312+
case pvxs::TypeCode::UInt16: toAttribute<uint16_t> (dest, attributes[i]); break;
313+
case pvxs::TypeCode::Int32: toAttribute<int32_t> (dest, attributes[i]); break;
314+
case pvxs::TypeCode::UInt32: toAttribute<uint32_t> (dest, attributes[i]); break;
315+
case pvxs::TypeCode::Int64: toAttribute<int64_t> (dest, attributes[i]); break;
316+
case pvxs::TypeCode::UInt64: toAttribute<uint64_t> (dest, attributes[i]); break;
317+
case pvxs::TypeCode::Float32: toAttribute<float_t> (dest, attributes[i]); break;
318+
case pvxs::TypeCode::Float64: toAttribute<double_t> (dest, attributes[i]); break;
277319
case pvxs::TypeCode::String: toStringAttribute (dest, attributes[i]); break;
278320
case pvxs::TypeCode::Null: toUndefinedAttribute (dest, attributes[i]); break;
279321
default: throw std::runtime_error("invalid value data type");
280322
}
281323
}
282324
}
283325

284-
void NTNDArrayConverter::fromValue (NDArray *src) {
326+
template <typename dataType>
327+
void NTNDArrayConverter::fromValue(NDArray *src) {
285328
NDArrayInfo_t arrayInfo;
286329
src->getInfo(&arrayInfo);
287330

288331
m_value["compressedSize"] = src->compressedSize;
289332
m_value["uncompressedSize"] = arrayInfo.totalBytes;
290-
std::string field_name;
291-
pvxs::ArrayType arrayType;
333+
std::string fieldName = m_fieldNameMap[typeid(dataType)];
334+
auto arrayType = m_arrayTypeMap[typeid(dataType)];
335+
const auto val = pvxs::detail::copyAs(
336+
arrayType, arrayType, (const void*) src->pData, arrayInfo.nElements).freeze();
337+
m_value[fieldName] = val;
338+
m_value["codec.name"] = src->codec.name; // compression codec
339+
// The uncompressed data type would be lost when converting to NTNDArray,
340+
// so we must store it somewhere. codec.parameters seems like a good place.
341+
m_value["codec.parameters"] = (int32_t) src->dataType;
342+
}
343+
344+
void NTNDArrayConverter::fromValue (NDArray *src) {
292345
switch(src->dataType) {
293-
case NDDataType_t::NDInt8: {arrayType = pvxs::ArrayType::Int8; field_name = std::string("value->byteValue"); break;};
294-
case NDDataType_t::NDUInt8: {arrayType = pvxs::ArrayType::UInt8; field_name = std::string("value->ubyteValue"); break;};
295-
case NDDataType_t::NDInt16: {arrayType = pvxs::ArrayType::Int16; field_name = std::string("value->shortValue"); break;};
296-
case NDDataType_t::NDInt32: {arrayType = pvxs::ArrayType::Int32; field_name = std::string("value->intValue"); break;};
297-
case NDDataType_t::NDUInt32: {arrayType = pvxs::ArrayType::UInt32; field_name = std::string("value->uintValue"); break;};
298-
case NDDataType_t::NDInt64: {arrayType = pvxs::ArrayType::Int64; field_name = std::string("value->longValue"); break;};
299-
case NDDataType_t::NDUInt64: {arrayType = pvxs::ArrayType::UInt64; field_name = std::string("value->ulongValue"); break;};
300-
case NDDataType_t::NDFloat32: {arrayType = pvxs::ArrayType::Float32; field_name = std::string("value->floatValue"); break;};
301-
case NDDataType_t::NDFloat64: {arrayType = pvxs::ArrayType::Float64; field_name = std::string("value->doubleValue"); break;};
346+
case NDDataType_t::NDInt8: {fromValue<int8_t>(src); break;};
347+
case NDDataType_t::NDUInt8: {fromValue<uint8_t>(src); break;};
348+
case NDDataType_t::NDInt16: {fromValue<int16_t>(src); break;};
349+
case NDDataType_t::NDInt32: {fromValue<int32_t>(src); break;};
350+
case NDDataType_t::NDUInt32: {fromValue<uint32_t>(src); break;};
351+
case NDDataType_t::NDInt64: {fromValue<int64_t>(src); break;};
352+
case NDDataType_t::NDUInt64: {fromValue<uint64_t>(src); break;};
353+
case NDDataType_t::NDFloat32: {fromValue<float_t>(src); break;};
354+
case NDDataType_t::NDFloat64: {fromValue<double_t>(src); break;};
302355
default: {
303356
throw std::runtime_error("invalid value data type");
304357
break;
305358
}
306359
}
307-
const auto val = pvxs::detail::copyAs(
308-
arrayType, arrayType, (const void*) src->pData, arrayInfo.nElements).freeze();
309-
m_value[field_name] = val;
310-
m_value["codec.name"] = src->codec.name; // compression codec
311-
// The uncompressed data type would be lost when converting to NTNDArray,
312-
// so we must store it somewhere. codec.parameters seems like a good place.
313-
m_value["codec.parameters"] = (int32_t) src->dataType;
314360
}
315361

316362
void NTNDArrayConverter::fromDimensions (NDArray *src) {

0 commit comments

Comments
 (0)