Files
pvxs/ioc/iocsource.h
T

140 lines
5.5 KiB
C++

/*
* Copyright - See the COPYRIGHT that is included with this distribution.
* pvxs is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*
* Author George S. McIntyre <george@level-n.com>, 2023
*
*/
#ifndef PVXS_IOCSOURCE_H
#define PVXS_IOCSOURCE_H
#include <pvxs/data.h>
#include "dbeventcontextdeleter.h"
#include "field.h"
#include "metadata.h"
#include "singlesrcsubscriptionctx.h"
#include "credentials.h"
#include "securitylogger.h"
#include "securityclient.h"
struct AllMetadataSize {
DBRstatus
DBRamsg
DBRunits
DBRprecision
DBRtime
DBRutag
DBRenumStrs
DBRgrDouble
DBRctrlDouble
DBRalDouble
};
// Maximum amount of space that metadata can use in the buffer returned by dbGetField()
#define MAX_METADATA_SIZE sizeof(AllMetadataSize)
namespace pvxs {
namespace ioc {
// To specify the get desired operation
typedef enum {
FOR_VALUE_AND_PROPERTIES,
FOR_VALUE,
FOR_METADATA,
FOR_PROPERTIES,
} GetOperationType;
// For alignment, we need this kind of union as the basis for our buffer
typedef union {
double _scalar;
char _string[MAX_STRING_SIZE];
} ScalarValueBuffer;
// For this is a structure that is the maximum length for a scalar value with metadata
// DON'T use _max_scalar to reference the value
typedef struct {
double _max_meta[MAX_METADATA_SIZE];
ScalarValueBuffer _max_scalar;
} ValueBuffer;
class IOCSource {
public:
static void get(dbChannel* pDbValueChannel, dbChannel* pDbPropertiesChannel, Value& valuePrototype,
GetOperationType getOperationType,
db_field_log* pDbFieldLog);
static void put(dbChannel* pDbChannel, const Value& value);
static void putScalar(dbChannel* pDbChannel, const Value& value);
static void putArray(dbChannel* pDbChannel, const Value& value);
static void doPostProcessing(dbChannel* pDbChannel, TriState forceProcessing);
static void doPreProcessing(dbChannel* pDbChannel, SecurityLogger& securityLogger, const Credentials& credentials,
const SecurityClient& securityClient);
static void doFieldPreProcessing(const SecurityClient& securityClient);
//////////////////////////////
// Get & Subscription
//////////////////////////////
// Get a return value from the given database value buffer
static void getValueFromBuffer(Value& valueTarget, const void* pValueBuffer);
// Get a return value from the given database value buffer
static void getValueFromBuffer(Value& valueTarget, const void* pValueBuffer, const long& nElements);
/**
* Set the value field of the given return value to a scalar pointed to by pValueBuffer
* Supported types are:
* TypeCode::Int8 TypeCode::UInt8
* TypeCode::Int16 TypeCode::UInt16
* TypeCode::Int32 TypeCode::UInt32
* TypeCode::Int64 TypeCode::UInt64
* TypeCode::Float32 TypeCode::Float64
*
* @tparam valueType the type of the scalar stored in the buffer. One of the supported types
* @param valueTarget the return value
* @param pValueBuffer the pointer to the data containing the database data to store in the return value
*/
template<typename valueType> static void getValueFromBuffer(Value& valueTarget, const void* pValueBuffer) {
valueTarget = ((valueType*)pValueBuffer)[0];
}
// Get a return value from the given database value buffer (templated)
template<typename valueType>
static void getValueFromBuffer(Value& valueTarget, const void* pValueBuffer, const long& nElements);
//////////////////////////////
// Set
//////////////////////////////
// Set the value into the given database value buffer
static void setValueInBuffer(const Value& valueSource, char* pValueBuffer, dbChannel* pDbChannel);
// Set the value into the given database value buffer
static void setValueInBuffer(const Value& valueSource, char* pValueBuffer, long nElements);
// Set string value in the given buffer
static void setStringValueInBuffer(const Value& valueSource, char* pValueBuffer);
// Set the value into the given database value buffer (templated)
template<typename valueType> static void setValueInBuffer(const Value& valueSource, void* pValueBuffer) {
((valueType*)pValueBuffer)[0] = valueSource.as<valueType>();
}
// Set the value into the given database value buffer (templated)
template<typename valueType>
static void setValueInBuffer(const Value& valueSource, void* pValueBuffer, long nElements);
//////////////////////////////
// Common Utils
//////////////////////////////
// Utility function to get the TypeCode that the given database channel is configured for
static TypeCode getChannelValueType(const dbChannel* pDbChannel, bool errOnLinks = false);
static void getScalar(dbChannel* pDbValueChannel, dbChannel* pDbPropertiesChannel, Value& value, Value& valueTarget,
uint32_t& requestedOptions, GetOperationType getOperationType, db_field_log* pDbFieldLog);
static void getArray(dbChannel* pDbValueChannel, dbChannel* pDbPropertiesChannel, Value& value, Value& valueTarget,
uint32_t& requestedOptions, GetOperationType getOperationType, db_field_log* pDbFieldLog);
static void getMetadata(Value& valuePrototype, void*& pValueBuffer, const uint32_t& requestedOptions,
const uint32_t& actualOptions);
static void
setForceProcessingFlag(const Value& pvRequest, const std::shared_ptr<SecurityControlObject>& securityControlObject);
};
} // pvxs
} // ioc
#endif //PVXS_IOCSOURCE_H