/** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS pvData is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ /* Author: Michael Davidsaver */ #include #include #include "typeCast.h" using epics::pvData::castUnsafe; using epics::pvData::String; using epics::pvData::ScalarType; using epics::pvData::pvString; namespace { static void noconvert(size_t, void*, const void*) { throw std::runtime_error("castUnsafeV: Conversion not supported"); } template static void castVTyped(size_t count, void *draw, const void *sraw) { TO *dest=(TO*)draw; const FROM *src=(FROM*)sraw; //std::transform(src, src+count, dest, castUnsafe); const FROM *last = src+count; try { while (src != last) { *dest = castUnsafe(*src); ++dest; ++src; } } catch (std::exception& ex) { // do not report index for scalars (or arrays with one element) if (count > 1) { std::ostringstream os; os << "failed to parse element at index " << (src - (FROM*)sraw); os << ": " << ex.what(); throw std::runtime_error(os.str()); } else throw; } } template static void copyV(size_t count, void *draw, const void *sraw) { T *dest=(T*)draw; const T *src=(T*)sraw; std::copy(src, src+count, dest); } typedef void (*convertfn)(size_t, void*, const void*); /* lookup table of converter functions. * first dimension is TO, second is FROM */ static convertfn converters[pvString+1][pvString+1] = { // to pvBoolean { ©V, &noconvert, &noconvert, &noconvert, &noconvert, &noconvert, &noconvert, &noconvert, &noconvert, &noconvert, &noconvert, &castVTyped, }, // to pvByte {&noconvert, ©V, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, }, // to pvShort {&noconvert, &castVTyped, ©V, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, }, // to pvInt {&noconvert, &castVTyped, &castVTyped, ©V, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, }, // to pvLong {&noconvert, &castVTyped, &castVTyped, &castVTyped, ©V, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, }, // to pvUByte {&noconvert, &castVTyped, &castVTyped, &castVTyped, &castVTyped, ©V, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, }, // to pvUShort {&noconvert, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, ©V, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, }, // to pvUInt {&noconvert, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, ©V, &castVTyped, &castVTyped, &castVTyped, &castVTyped, }, // to pvULong {&noconvert, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, ©V, &castVTyped, &castVTyped, &castVTyped, }, // to pvFloat {&noconvert, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, ©V, &castVTyped, &castVTyped, }, // to pvDouble {&noconvert, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, ©V, &castVTyped, }, // to pvString {&castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, &castVTyped, ©V, }, }; } // end namespace namespace epics { namespace pvData { void castUnsafeV(size_t count, ScalarType to, void *dest, ScalarType from, const void *src) { unsigned int ito=to, ifrom=from; if(ito>pvString || ifrom>pvString) throw std::runtime_error("castUnsafeV: Invalid types"); converters[ito][ifrom](count, dest, src); } }}