diff --git a/+ b/+ new file mode 100644 index 0000000..e76a62a --- /dev/null +++ b/+ @@ -0,0 +1,276 @@ +### psi specific - select compiler +#source +# default is sf +# +module unload gcc +module load gcc/7.3.0 +### psi specific - end + +rm -f configure.ac +ln -s configurePSI.ac configure.ac + +rm -f ./aclocal.m4 +rm -rf ./autom4te.cache +aclocal --force -I m4 +/opt/gfa/python-3.7/latest/bin/libtoolize --force --copy #select libtools 2.4.6 +autoconf --force #interprets configure.ac +autoheader --force +automake --force --add-missing --copy +#autoreconf not wanted + +#Check what the EPICS RELEASE IS from ${EPICS}/base +#Used by ./configure +#Assumes format ${EPICS}/base-3.14.12 +#source cafeVersion-gcc-7.3.0 +CAFE_V="cafe-1.14.1" +#For later check of existence of HOST_ARCH for $EPICS/include/os/$HOST_ARCH +#Assume Linux but check if Darwin +CAFE_HOST_FLAG_DARWIN=$(echo ${EPICS_HOST_ARCH} | grep -c "Darwin") +export CAFE_HOST_FLAG_DARWIN=$CAFE_HOST_FLAG_DARWIN + +RETURN_ON_WRONG_INPUT=true +RETURN_FLAG=false + +EPICS_BASE=$(readlink ${EPICS}/base) +#EB=$(readlink /afs/psi.ch/project/cafe/gitworkspace/CAFE/cpp/base) +echo $EPICS_BASE +if [ -z "$EPICS_BASE" ] +then + EPICS_BASE='base-7.4.1' #7.0 = 7+0 = 7 for major release +fi + +echo 'input' "$0" "$1" "$2" +echo $EPICS_BASE + +FACILITY=$(echo "$1" | tr '[:upper:]' '[:lower:]') +CACLIENT=$(echo "$2" | tr '[:upper:]' '[:lower:]') + +FACILITY_DEFAULT="sf" +CACLIENT_DEFAULT="python" + +FACILITY_TEMP="" +CACLIENT_TEMP="" + +echo 'input arg. facility/target' $FACILITY $CACLIENT + +if [ -n "$FACILITY" ] +then + if [ "$FACILITY" = "matlab" ] || [ "$FACILITY" = "python" ] || \ + [ "$FACILITY" = "py37" ] || [ "$FACILITY" = "py35" ] || \ + [ "$FACILITY" = "julia" ] || [ "$FACILITY" = "cpp" ] || \ + [ "$FACILITY" = "cc" ] + then + CACLIENT_TEMP=$FACILITY + FACILITY_TEMP=$2 + fi +fi + +if [ -n "$CACLIENT" ] +then + if [ "$CACLIENT" = "sls" ] || [ "$CACLIENT" = "sls2" ] || \ + [ "$CACLIENT" = "sf" ] || [ "$CACLIENT" = "swissfel" ] || \ + [ "$CACLIENT" = "sfel" ] || [ "$CACLIENT" = "hipa" ] + then + if [ -z $FACILITY_TEMP ] + then + FACILITY_TEMP=$CACLIENT + CACLIENT_TEMP=$1 + fi + fi +fi + + + +if [ -z "$FACILITY" ] +then + FACILITY="sf" + echo "FACILITY = " $FACILITY + if [ -z $CACLIENT ] + then + CACLIENT=$CACLIENT_DEFAULT + fi +elif [ "$FACILITY" = "sls" ] || [ "$FACILITY" = "sls2" ] || \ + [ "$FACILITY" = "sf" ] || [ "$FACILITY" = "swissfel" ] || \ + [ "$FACILITY" = "sfel" ] || [ "$FACILITY" = "hipa" ] +then + echo "FACILITY = " $FACILITY +elif [ -n "$FACILITY_TEMP" ] +then + if [ "$FACILITY_TEMP" = "sls" ] || [ "$FACILITY_TEMP" = "sls2" ] || \ + [ "$FACILITY_TEMP" = "sf" ] || [ "$FACILITY_TEMP" = "swissfel" ] || \ + [ "$FACILITY_TEMP" = "sfel" ] || [ "$FACILITY_TEMP" = "hipa" ] + then + + + FACILITY=$FACILITY_TEMP + else + if [ -n "$2" ] + then + echo "***UNRECOGNIZED INPUT FACILITY***" $FACILITY + echo "***VALID VALUES ARE: sls sls2 sf hipa" + RETURN_FLAG=true + fi + echo "***OTHERWISE THE DEFAULT FACILITY IS:" $FACILITY_DEFAULT + FACILITY=$FACILITY_DEFAULT + fi +else + echo "***UNRECOGNIZED INPUT FACILITY***" $FACILITY + echo "***VALID VALUES ARE: sls sls2 sf hipa" + RETURN_FLAG=true + echo "***OTHERWISE THE DEFAULT FACILITY IS: " $FACILITY_DEFAULT + FACILITY=$FACILITY_DEFAULT +fi + +if [ -n "$CACLIENT" ] +then + if [ "$CACLIENT" = "matlab" ] || [ "$CACLIENT" = "python" ] || \ + [ "$CACLIENT" = "py37" ] || [ "$CACLIENT" = "py35" ] || \ + [ "$CACLIENT" = "julia" ] || [ "$CACLIENT" = "cpp" ] || \ + [ "$CACLIENT" = "cc" ] + then + echo "CA TARGET = " $CACLIENT + else + if [ -n "$CACLIENT_TEMP" ] + then + if [ "$CACLIENT_TEMP" = "matlab" ] || [ "$CACLIENT_TEMP" = "python" ] || \ + [ "$CACLIENT_TEMP" = "py37" ] || [ "$CACLIENT_TEMP" = "py35" ] || \ + [ "$CACLIENT_TEMP" = "julia" ] || [ "$CACLIENT_TEMP" = "cpp" ] || \ + [ "$CACLIENT_TEMP" = "cc" ] + then + CACLIENT=$CACLIENT_TEMP + else + echo "***UNRECOGNIZED INPUT CA TARGET***" $CACLIENT + echo "***VALID VALUES ARE: cpp matlab python" + RETURN_FLAG=true + echo "***OTHERWISE THE DEFAULT CA TARGET IS:" $CACLIENT_DEFAULT + CACLIENT=$CACLIENT_DEFAULT + fi + else + echo "***UNRECOGNIZED INPUT CA TARGET***" $CACLIENT + echo "***VALID VALUES ARE: cpp matlab python" + RETURN_FLAG=true + echo "***OTHERWISE THE DEFAULT CA TARGET IS:" $CACLIENT_DEFAULT + CACLIENT=$CACLIENT_DEFAULT + fi + fi +else + CACLIENT=$CACLIENT_DEFAULT +fi + + + +if [ $RETURN_ON_WRONG_INPUT = true ] ; then + if [ $RETURN_FLAG = true ] ; then + return 1 2>/dev/null + exit 1 + fi +fi + +echo "FACILITY SELECTED = " $FACILITY +echo "CA TARGET SELECTED = " $CACLIENT + +ENABLE_OPTIONS="--enable-boost-inc" + +if [ "$FACILITY" = "sfel" ] || [ "$FACILITY" = "swissfel" ] +then + FACILITY="sf" +fi + +if [ "$CACLIENT" = "python" ] || [ "$CACLIENT" = "julia" ] +then + CACLIENT="py37" +fi + + +if [ "$FACILITY" = "sls2" ] +then + ENABLE_OPTIONS+=" --enable-epics7" + CAFE_V+="-sls2" +else + ENABLE_OPTIONS+=" --enable-epics3" + if [ "$FACILITY" = "sf" ] && [ "$CACLIENT" != "matlab" ] + then + CAFE_V+="-sf" + fi +fi + +if [ "$CACLIENT" = "py35" ] +then + ENABLE_OPTIONS+=" --enable-python35" + ENABLE_OPTIONS+=" --enable-qt4" + CAFE_V+="-py35" +elif [ "$CACLIENT" = "py37" ] +then + ENABLE_OPTIONS+=" --enable-python37" + ENABLE_OPTIONS+=" --enable-qt5" + CAFE_V+="-py37" +#else + #ENABLE_OPTIONS+=" --enable-qt5" +fi + +if [ "$FACILITY" = "sf" ] && [ "$CACLIENT" != "matlab" ] +then + #rm -f src/PyCafe.cpp + #ln -s PyCafe3.cpp src/PyCafe.cpp + ENABLE_OPTIONS+=" --enable-json" + ENABLE_OPTIONS+=" --enable-zeromq" + ENABLE_OPTIONS+=" --enable-curl" + ENABLE_OPTIONS+=" --enable-lz4" +#else + #rm -f src/PyCafe.cpp + #ln -s PyCafe_sls.cpp src/PyCafe.cpp +fi + +CAFE_V+="-gcc-"$GCC_VERSION + +echo "CAFE VERSION: $CAFE_V" + +#echo 'EPICS BASE IS='$EPICS_BASE +#echo 'EPICS BASE DIR='${EPICS}/base-7.0.4.1 + +EB1=$(echo $EPICS_BASE | sed -e "s/[a-zA-Z]*-//g") +EBMAJ=$(echo $EB1 | sed -e "s/[[:punct:]].*//g") +EBMIN1=$(echo $EB1 | sed -e "s/^[[:digit:]]*[[:punct:]]//g") +EBMIN=$(echo $EBMIN1 | sed -e "s/[[:punct:]][[:digit:]]*//g") +EBPAT=$(echo $EB1 | sed -e "s/[[:digit:]]*[[:punct:]]//g") +echo EPICS_MAJOR=$EBMAJ +echo EPICS_MINOR=$EBMIN +echo EPICS_PATCH=$EBPAT +#echo $EBMIN1 + +export CAFE_EPICS_V_MAJOR=$EBMAJ +export CAFE_EPICS_V_MINOR=$EBMIN +export CAFE_EPICS_V_PATCH=$EBPAT + +#ENABLE_OPTIONS+=" --enable-qt5" +##ENABLE_OPTIONS+=" --enable-qt4" +#ENABLE_OPTIONS+=" --enable-python37" +##ENABLE_OPTIONS+=" --enable-python35" +#ENABLE_OPTIONS+=" --enable-json" +#ENABLE_OPTIONS+=" --enable-zeromq" +#ENABLE_OPTIONS+=" --enable-curl" +#ENABLE_OPTIONS+=" --enable-lz4" + +echo 'ENABLE_OPTIONS='$ENABLE_OPTIONS + +./configure \ + --prefix=/opt/gfa/cafe/cpp/${CAFE_V} \ + --libdir=/opt/gfa/cafe/cpp/${CAFE_V}/lib/${EPICS_HOST_ARCH} \ + ${ENABLE_OPTIONS} \ + --with-boost-inc=/opt/gfa/cafe/boost/boost_1_61_0/include \ + --with-epics7=${EPICS}/base-7.0.4.1 \ + --with-epics3=${EPICS}/base \ + --with-python37=/opt/gfa/python-3.7/latest \ + --with-python35=/opt/gfa/python-3.5/latest \ + --with-qt5=/opt/gfa/python-3.7/latest \ + --with-qt4=/opt/gfa/python-3.5/latest \ + --with-json=/opt/gfa/zmsglog/json/jsoncpp-src-0.6.0-rc2 \ + --with-zeromq=/opt/gfa/zmq/zeromq-4.2.3-gcc-6.3.0 \ + --with-curl=/opt/gfa/zmq/curl-7.55.1 \ + --with-lz4=/opt/gfa/zmq/lz4/lib + +unset CAFE_EPICS_V_PATCH +unset CAFE_EPICS_V_MINOR +unset CAFE_EPICS_V_MAJOR + +unset CAFE_HOST_FLAG_DARWIN diff --git a/autogen_psi.sh b/autogen_psi.sh index f0e5ae7..a1099af 100644 --- a/autogen_psi.sh +++ b/autogen_psi.sh @@ -22,7 +22,7 @@ automake --force --add-missing --copy #Used by ./configure #Assumes format ${EPICS}/base-3.14.12 #source cafeVersion-gcc-7.3.0 -CAFE_V="cafe-1.14.1" +CAFE_V="cafe-1.14.2" #For later check of existence of HOST_ARCH for $EPICS/include/os/$HOST_ARCH #Assume Linux but check if Darwin CAFE_HOST_FLAG_DARWIN=$(echo ${EPICS_HOST_ARCH} | grep -c "Darwin") @@ -36,7 +36,7 @@ EPICS_BASE=$(readlink ${EPICS}/base) echo $EPICS_BASE if [ -z "$EPICS_BASE" ] then - EPICS_BASE='base-7.4.1' #7.0 = 7+0 = 7 for major release + EPICS_BASE='base-7' #7.0 = 7+0 = 7 for major release fi echo 'input' "$0" "$1" "$2" @@ -258,7 +258,7 @@ echo 'ENABLE_OPTIONS='$ENABLE_OPTIONS --libdir=/opt/gfa/cafe/cpp/${CAFE_V}/lib/${EPICS_HOST_ARCH} \ ${ENABLE_OPTIONS} \ --with-boost-inc=/opt/gfa/cafe/boost/boost_1_61_0/include \ - --with-epics7=${EPICS}/base-7.0.4.1 \ + --with-epics7=${EPICS}/base-7 \ --with-epics3=${EPICS}/base \ --with-python37=/opt/gfa/python-3.7/latest \ --with-python35=/opt/gfa/python-3.5/latest \ diff --git a/autogen_slsbd.sh b/autogen_slsbd.sh new file mode 100644 index 0000000..9793f85 --- /dev/null +++ b/autogen_slsbd.sh @@ -0,0 +1,277 @@ +### psi specific - select compiler +#source +# default is sf +# +module unload gcc +module load gcc/7.3.0 +### psi specific - end + +rm -f configure.ac +ln -s configurePSI.ac configure.ac + +rm -f ./aclocal.m4 +rm -rf ./autom4te.cache +aclocal --force -I m4 +/opt/gfa/python-3.7/latest/bin/libtoolize --force --copy #select libtools 2.4.6 +autoconf --force #interprets configure.ac +autoheader --force +automake --force --add-missing --copy +#autoreconf not wanted + +#Check what the EPICS RELEASE IS from ${EPICS}/base +#Used by ./configure +#Assumes format ${EPICS}/base-3.14.12 +#source cafeVersion-gcc-7.3.0 +CAFE_V="cafe-1.14.1" +#For later check of existence of HOST_ARCH for $EPICS/include/os/$HOST_ARCH +#Assume Linux but check if Darwin +CAFE_HOST_FLAG_DARWIN=$(echo ${EPICS_HOST_ARCH} | grep -c "Darwin") +export CAFE_HOST_FLAG_DARWIN=$CAFE_HOST_FLAG_DARWIN + +RETURN_ON_WRONG_INPUT=true +RETURN_FLAG=false + +EPICS_BASE=$(readlink ${EPICS}/base) +#EB=$(readlink /afs/psi.ch/project/cafe/gitworkspace/CAFE/cpp/base) +echo $EPICS_BASE +if [ -z "$EPICS_BASE" ] +then + EPICS_BASE='base-7.4.1' #7.0 = 7+0 = 7 for major release +fi + +echo 'input' "$0" "$1" "$2" +echo $EPICS_BASE + +FACILITY=$(echo "$1" | tr '[:upper:]' '[:lower:]') +CACLIENT=$(echo "$2" | tr '[:upper:]' '[:lower:]') + +FACILITY_DEFAULT="sf" +CACLIENT_DEFAULT="python" + +FACILITY_TEMP="" +CACLIENT_TEMP="" + +echo 'input arg. facility/target' $FACILITY $CACLIENT + +if [ -n "$FACILITY" ] +then + if [ "$FACILITY" = "matlab" ] || [ "$FACILITY" = "python" ] || \ + [ "$FACILITY" = "py37" ] || [ "$FACILITY" = "py35" ] || \ + [ "$FACILITY" = "julia" ] || [ "$FACILITY" = "cpp" ] || \ + [ "$FACILITY" = "cc" ] + then + CACLIENT_TEMP=$FACILITY + FACILITY_TEMP=$2 + fi +fi + +if [ -n "$CACLIENT" ] +then + if [ "$CACLIENT" = "sls" ] || [ "$CACLIENT" = "sls2" ] || \ + [ "$CACLIENT" = "sf" ] || [ "$CACLIENT" = "swissfel" ] || \ + [ "$CACLIENT" = "sfel" ] || [ "$CACLIENT" = "hipa" ] + then + if [ -z $FACILITY_TEMP ] + then + FACILITY_TEMP=$CACLIENT + CACLIENT_TEMP=$1 + fi + fi +fi + + + +if [ -z "$FACILITY" ] +then + FACILITY="sf" + echo "FACILITY = " $FACILITY + if [ -z $CACLIENT ] + then + CACLIENT=$CACLIENT_DEFAULT + fi +elif [ "$FACILITY" = "sls" ] || [ "$FACILITY" = "sls2" ] || \ + [ "$FACILITY" = "sf" ] || [ "$FACILITY" = "swissfel" ] || \ + [ "$FACILITY" = "sfel" ] || [ "$FACILITY" = "hipa" ] +then + echo "FACILITY = " $FACILITY +elif [ -n "$FACILITY_TEMP" ] +then + if [ "$FACILITY_TEMP" = "sls" ] || [ "$FACILITY_TEMP" = "sls2" ] || \ + [ "$FACILITY_TEMP" = "sf" ] || [ "$FACILITY_TEMP" = "swissfel" ] || \ + [ "$FACILITY_TEMP" = "sfel" ] || [ "$FACILITY_TEMP" = "hipa" ] + then + + + FACILITY=$FACILITY_TEMP + else + if [ -n "$2" ] + then + echo "***UNRECOGNIZED INPUT FACILITY***" $FACILITY + echo "***VALID VALUES ARE: sls sls2 sf hipa" + RETURN_FLAG=true + fi + echo "***OTHERWISE THE DEFAULT FACILITY IS:" $FACILITY_DEFAULT + FACILITY=$FACILITY_DEFAULT + fi +else + echo "***UNRECOGNIZED INPUT FACILITY***" $FACILITY + echo "***VALID VALUES ARE: sls sls2 sf hipa" + RETURN_FLAG=true + echo "***OTHERWISE THE DEFAULT FACILITY IS: " $FACILITY_DEFAULT + FACILITY=$FACILITY_DEFAULT +fi + +if [ -n "$CACLIENT" ] +then + if [ "$CACLIENT" = "matlab" ] || [ "$CACLIENT" = "python" ] || \ + [ "$CACLIENT" = "py37" ] || [ "$CACLIENT" = "py35" ] || \ + [ "$CACLIENT" = "julia" ] || [ "$CACLIENT" = "cpp" ] || \ + [ "$CACLIENT" = "cc" ] + then + echo "CA TARGET = " $CACLIENT + else + if [ -n "$CACLIENT_TEMP" ] + then + if [ "$CACLIENT_TEMP" = "matlab" ] || [ "$CACLIENT_TEMP" = "python" ] || \ + [ "$CACLIENT_TEMP" = "py37" ] || [ "$CACLIENT_TEMP" = "py35" ] || \ + [ "$CACLIENT_TEMP" = "julia" ] || [ "$CACLIENT_TEMP" = "cpp" ] || \ + [ "$CACLIENT_TEMP" = "cc" ] + then + CACLIENT=$CACLIENT_TEMP + else + echo "***UNRECOGNIZED INPUT CA TARGET***" $CACLIENT + echo "***VALID VALUES ARE: cpp matlab python" + RETURN_FLAG=true + echo "***OTHERWISE THE DEFAULT CA TARGET IS:" $CACLIENT_DEFAULT + CACLIENT=$CACLIENT_DEFAULT + fi + else + echo "***UNRECOGNIZED INPUT CA TARGET***" $CACLIENT + echo "***VALID VALUES ARE: cpp matlab python" + RETURN_FLAG=true + echo "***OTHERWISE THE DEFAULT CA TARGET IS:" $CACLIENT_DEFAULT + CACLIENT=$CACLIENT_DEFAULT + fi + fi +else + CACLIENT=$CACLIENT_DEFAULT +fi + + + +if [ $RETURN_ON_WRONG_INPUT = true ] ; then + if [ $RETURN_FLAG = true ] ; then + return 1 2>/dev/null + exit 1 + fi +fi + +echo "FACILITY SELECTED = " $FACILITY +echo "CA TARGET SELECTED = " $CACLIENT + +ENABLE_OPTIONS="--enable-boost-inc" + +if [ "$FACILITY" = "sfel" ] || [ "$FACILITY" = "swissfel" ] +then + FACILITY="sf" +fi + +if [ "$CACLIENT" = "python" ] || [ "$CACLIENT" = "julia" ] +then + CACLIENT="py37" +fi + + +if [ "$FACILITY" = "sls2" ] +then + ENABLE_OPTIONS+=" --enable-epics7" + CAFE_V+="-sls2" +else + ENABLE_OPTIONS+=" --enable-epics3" + if [ "$FACILITY" = "sf" ] && [ "$CACLIENT" != "matlab" ] + then + CAFE_V+="-sf" + fi +fi + +if [ "$CACLIENT" = "py35" ] +then + ENABLE_OPTIONS+=" --enable-python35" + ENABLE_OPTIONS+=" --enable-qt4" + CAFE_V+="-py35" +elif [ "$CACLIENT" = "py37" ] +then + ENABLE_OPTIONS+=" --enable-python37" + ENABLE_OPTIONS+=" --enable-qt5" + CAFE_V+="-py37" +#else + #ENABLE_OPTIONS+=" --enable-qt5" +fi + +if [ "$FACILITY" = "sf" ] && [ "$CACLIENT" != "matlab" ] +then + #rm -f src/PyCafe.cpp + #ln -s PyCafe3.cpp src/PyCafe.cpp + ENABLE_OPTIONS+=" --enable-json" + ENABLE_OPTIONS+=" --enable-zeromq" + ENABLE_OPTIONS+=" --enable-curl" + ENABLE_OPTIONS+=" --enable-lz4" +#else + #rm -f src/PyCafe.cpp + #ln -s PyCafe_sls.cpp src/PyCafe.cpp +fi + +CAFE_V+="-gcc-"$GCC_VERSION + +echo "CAFE VERSION: $CAFE_V" + +#echo 'EPICS BASE IS='$EPICS_BASE +#echo 'EPICS BASE DIR='${EPICS}/base-7.0.4.1 + +EB1=$(echo $EPICS_BASE | sed -e "s/[a-zA-Z]*-//g") +EBMAJ=$(echo $EB1 | sed -e "s/[[:punct:]].*//g") +EBMIN1=$(echo $EB1 | sed -e "s/^[[:digit:]]*[[:punct:]]//g") +EBMIN=$(echo $EBMIN1 | sed -e "s/[[:punct:]][[:digit:]]*//g") +EBPAT=$(echo $EB1 | sed -e "s/[[:digit:]]*[[:punct:]]//g") +echo EPICS_MAJOR=$EBMAJ +echo EPICS_MINOR=$EBMIN +echo EPICS_PATCH=$EBPAT +#echo $EBMIN1 + +export CAFE_EPICS_V_MAJOR=$EBMAJ +export CAFE_EPICS_V_MINOR=$EBMIN +export CAFE_EPICS_V_PATCH=$EBPAT + +#ENABLE_OPTIONS+=" --enable-qt5" +##ENABLE_OPTIONS+=" --enable-qt4" +#ENABLE_OPTIONS+=" --enable-python37" +##ENABLE_OPTIONS+=" --enable-python35" +#ENABLE_OPTIONS+=" --enable-json" +#ENABLE_OPTIONS+=" --enable-zeromq" +#ENABLE_OPTIONS+=" --enable-curl" +#ENABLE_OPTIONS+=" --enable-lz4" + +echo 'ENABLE_OPTIONS='$ENABLE_OPTIONS +echo 'EPICS='${EPICS} + +./configure \ + --prefix=/opt/gfa/cafe/cpp/${CAFE_V} \ + --libdir=/opt/gfa/cafe/cpp/${CAFE_V}/lib/${EPICS_HOST_ARCH} \ + ${ENABLE_OPTIONS} \ + --with-boost-inc=/afs/psi.ch/project/cafe/gitlab/CAFE/boost/boost_1_61_0/include \ + --with-epics7=${EPICS}/base-7.0.4.1 \ + --with-epics3=${EPICS}/base \ + --with-python37=/opt/gfa/python-3.7/latest \ + --with-python35=/opt/gfa/python-3.5/latest \ + --with-qt5=/opt/gfa/python-3.7/latest \ + --with-qt4=/opt/gfa/python-3.5/latest \ + --with-json=/opt/gfa/zmsglog/json/jsoncpp-src-0.6.0-rc2 \ + --with-zeromq=/opt/gfa/zmq/zeromq-4.2.3-gcc-6.3.0 \ + --with-curl=/opt/gfa/zmq/curl-7.55.1 \ + --with-lz4=/opt/gfa/zmq/lz4/lib + +unset CAFE_EPICS_V_PATCH +unset CAFE_EPICS_V_MINOR +unset CAFE_EPICS_V_MAJOR + +unset CAFE_HOST_FLAG_DARWIN diff --git a/configurePSI.ac b/configurePSI.ac index fbf3e0b..bfa357a 100644 --- a/configurePSI.ac +++ b/configurePSI.ac @@ -9,7 +9,7 @@ # Standard macros AC_PREREQ(2.63) AC_COPYRIGHT([CAFE,Jan Chrin, 2010-2021]) -AC_INIT([CAFE], [1.14.1], [Bug reports to: jan.chrin@psi.ch]) +AC_INIT([CAFE], [1.14.2], [Bug reports to: jan.chrin@psi.ch]) AC_CONFIG_AUX_DIR(./) diff --git a/examples/cafeTest/cafeTest b/examples/cafeTest/cafeTest index 3bff291..5b902db 100755 Binary files a/examples/cafeTest/cafeTest and b/examples/cafeTest/cafeTest differ diff --git a/examples/cafeTest/cafeTest- b/examples/cafeTest/cafeTest- new file mode 100755 index 0000000..3bff291 Binary files /dev/null and b/examples/cafeTest/cafeTest- differ diff --git a/examples/cafeTest/makefile b/examples/cafeTest/makefile index 80f088a..25d7e9b 100644 --- a/examples/cafeTest/makefile +++ b/examples/cafeTest/makefile @@ -7,7 +7,7 @@ #CAFE version to link to -CAFE_VERSION=cafe-1.12.5-gcc-7.3.0 +CAFE_VERSION=cafe-1.14.1-gcc-7.3.0 #PYTHON_INCLUDE=/opt/gfa/python-3.5/latest/include/python3.5m #PYTHON_LIB=/opt/gfa/python-3.5/latest/lib @@ -18,9 +18,6 @@ EPICS_BASE=${EPICS}/base CAFE_BASE=/opt/gfa/cafe CAFE_CPP_BASE=${CAFE_BASE}/cpp -CAFE_BASE=/afs/psi.ch/project/cafe/gitlab/CAFE/ -CAFE_CPP_BASE=${CAFE_BASE} -CAFE_VERSION=cpp BOOST_BASE=${CAFE_BASE}/boost/boost_1_61_0/include @@ -32,10 +29,12 @@ INCLUDE_PATH += -I$(CAFE_CPP_BASE)/$(CAFE_VERSION)/include \ LIB_DIR += -L$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \ -Wl,-rpath,$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \ - -L$(CAFE_CPP_BASE)/$(CAFE_VERSION)/lib \ - -Wl,-rpath,$(CAFE_CPP_BASE)/$(CAFE_VERSION)/lib + -L$(CAFE_CPP_BASE)/$(CAFE_VERSION)/lib/${EPICS_HOST_ARCH} \ + -Wl,-rpath,$(CAFE_CPP_BASE)/$(CAFE_VERSION)/lib/${EPICS_HOST_ARCH} \ + -L/opt/gfa/python-3.7/latest/lib \ + -Wl,-rpath,/opt/gfa/python-3.7/latest/lib -LIBS += -lcafe -lca -lCom +LIBS += -lcafe -lca -lCom -lQt5Core cafeTest: cafeTest.cc callbacks.h g++ cafeTest.cc -o cafeTest \ diff --git a/examples/cafeTest/makefile_local b/examples/cafeTest/makefile_local new file mode 100644 index 0000000..a8b9611 --- /dev/null +++ b/examples/cafeTest/makefile_local @@ -0,0 +1,46 @@ +# +# Jan Chrin +# June 2016 +# +# Makefile to build a simple C++ cafe client +# + + +#CAFE version to link to +CAFE_VERSION=cafe-1.14.1-gcc-7.3.0 + +#PYTHON_INCLUDE=/opt/gfa/python-3.5/latest/include/python3.5m +#PYTHON_LIB=/opt/gfa/python-3.5/latest/lib + +EPICS_BASE=${EPICS}/base + +#CAFE project base +CAFE_BASE=/opt/gfa/cafe +CAFE_CPP_BASE=${CAFE_BASE}/cpp + +CAFE_BASE=/afs/psi.ch/project/cafe/gitlab/CAFE/ +CAFE_CPP_BASE=${CAFE_BASE} +CAFE_VERSION=cpp + + +BOOST_BASE=${CAFE_BASE}/boost/boost_1_61_0/include + +INCLUDE_PATH += -I$(CAFE_CPP_BASE)/$(CAFE_VERSION)/include \ + -I$(EPICS_BASE)/include -I$(EPICS_BASE)/include/os/Linux \ + -I$(BOOST_BASE) + #-I$(BOOST_BASE)/boost + +LIB_DIR += -L$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \ + -Wl,-rpath,$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \ + -L$(CAFE_CPP_BASE)/$(CAFE_VERSION)/lib \ + -Wl,-rpath,$(CAFE_CPP_BASE)/$(CAFE_VERSION)/lib + +LIBS += -lcafe -lca -lCom + +cafeTest: cafeTest.cc callbacks.h + g++ cafeTest.cc -o cafeTest \ + $(INCLUDE_PATH) $(LIB_DIR) $(LIBS) + +clean: + rm -f cafeTest.o cafeTest + diff --git a/include/handleHelper.h b/include/handleHelper.h index 7114ce7..a94c227 100644 --- a/include/handleHelper.h +++ b/include/handleHelper.h @@ -83,6 +83,17 @@ public: ca_client_context * getContextFromPV (const char * _pv); ca_client_context * getContextFromHandle (unsigned int _handle); + cafeConduit_set_by_handle::iterator getIterFromHandle(unsigned int handle); + cafeConduit_set_by_handle & getcsHandleIndex(); + int modifyHandleIndexStatus(unsigned int handle, long status); + int modifyChannelRequestMetaDataClient(unsigned int handle, + ChannelRequestMetaDataClient channelRequestMetaDataClient); + int modifyChannelRequestStatusGet(unsigned int handle, + ChannelRequestStatus channelRequestStatusGet); + + int modifyChannelTimeoutPolicyGet(unsigned int handle, + ChannelTimeoutPolicy channelTimeoutPolicyGet); + const char * getPVFromHandle (unsigned int _handle); const char * getPVFromHandle (unsigned int _handle, ca_client_context * ccc); @@ -93,6 +104,8 @@ public: const char * getPVAlias (unsigned int _handle); const char * getPVAlias (unsigned int _handle, ca_client_context * ccc); + + unsigned int getHandleFromPV (const char * _pv); unsigned int getHandleFromPV (const char * _pv, ca_client_context * ccc); unsigned int getHandleFromPVAlias(const char * _pv); diff --git a/include/instant.cpp b/include/instant.cpp index da20f5d..e4f2d61 100644 --- a/include/instant.cpp +++ b/include/instant.cpp @@ -8,6 +8,8 @@ #ifndef INSTANT_CPP #define INSTANT_CPP +//include + /** * \brief Set values of data type CTYPE * \param _handle input: handle to CAFEConduit object @@ -44,6 +46,8 @@ template int Instant::set(const unsigned int _handle, con cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; + + it_handle = handle_index.find(_handle); if (it_handle != handle_index.end()) @@ -139,12 +143,11 @@ template int Instant::get(const unsigned int _handle, std::cout << "CAFE WILL THUS TAKE CONTROL OF ALLOCATING APPROPIATE DBR_TYPE" << std::endl; } + + cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; - - it_handle = handle_index.find(_handle); - if (it_handle != handle_index.end()) { @@ -184,6 +187,8 @@ template int Instant::get(const unsigned int _handle, else { std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; + const char * _pv = helper.getPVFromHandle(_handle); + std::cout << "Failed to find handle " << _handle << " for pv " << _pv << std::endl; cafeStatus.report(ECAFE_INVALID_HANDLE); return ECAFE_INVALID_HANDLE; } diff --git a/include/instant.h b/include/instant.h index 588e7ae..32e89aa 100644 --- a/include/instant.h +++ b/include/instant.h @@ -1,455 +1,3713 @@ -/// -/// \file instant.h -/// \author Jan Chrin, PSI -/// \date Release: February 2015 -/// \version CAFE 1.0.0 -/// - -#ifndef INSTANT_H -#define INSTANT_H - -#include -#include -#include - - -template class Instant -{ - -private: - Transpose renderString; // 0 - Transpose renderShort; // 1 - Transpose renderFloat; // 2 - Transpose renderEnum; // 3 - Transpose renderChar; // 4 - Transpose renderLong; // 5 - Transpose renderDouble; // 6 - - CAFEStatus cafeStatus; - Granules cafeGranules; - - PolicyHelper policyHelper; - - HandleHelper helper; - - Conduit cc; - ChannelTimeoutPolicy channelTimeoutPolicyGet; - ChannelRequestPolicy channelRequestPolicyGet; - ChannelRequestStatus channelRequestStatusGet; - ChannelRequestDataTypePolicy channelRequestDataTypePolicy; - - ChannelRequestMetaDataClient channelRequestMetaDataClient; //-1 - - int status; - - int clientRequests(const unsigned int _handle, const chtype dbrType, const CTYPE * _val); - - int clientRequests(const unsigned int _handle, const chtype dbrType, CTYPE * _val, - dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, - bool isCacheRequest); -public: - - Instant () {}; - ~Instant () {}; - - int set(const unsigned int *handleArray, const unsigned int nelem, - const chtype _dbrType, const CTYPE * val, int *statusArray); - - int set(const unsigned int _handle, const chtype dbrType, const CTYPE * _val); - - int get(const unsigned int _handle, const chtype dbrType, CTYPE * _val, - dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts); - - int get(const unsigned int _handle, const chtype dbrType, CTYPE * _val, - dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity) - { - epicsTimeStamp ts; - return get(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); - }; - - int get(const unsigned int _handle, const chtype dbrType, CTYPE * _val) - { - dbr_short_t alarmStatus; - dbr_short_t alarmSeverity; - epicsTimeStamp ts; - return get(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); - }; - - int getCache(const unsigned int _handle, const chtype dbrType, CTYPE * _val, - dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts); - - int getCache(const unsigned int _handle, const chtype dbrType, CTYPE * _val, - dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity) - { - epicsTimeStamp ts; - return getCache(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); - }; - - int getCache(const unsigned int _handle, const chtype dbrType, CTYPE * _val) - { - dbr_short_t alarmStatus; - dbr_short_t alarmSeverity; - epicsTimeStamp ts; - return getCache(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); - }; - - int getCache(const unsigned int *handleArray, const unsigned int nelem, - const chtype _dbrType, CTYPE * val, int *statusArray, - dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity, epicsTimeStamp *ts); - - int getCache(const unsigned int *handleArray, const unsigned int nelem, - const chtype _dbrType, CTYPE * val, int *statusArray, - dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity ) - { - epicsTimeStamp * ts; - return getCache(handleArray, nelem, _dbrType, val, statusArray, - alarmStatus, alarmSeverity, ts); - }; - int getCache(const unsigned int *handleArray, const unsigned int nelem, - const chtype _dbrType, CTYPE * val, int *statusArray) - { - dbr_short_t * alarmStatus; - dbr_short_t * alarmSeverity; - epicsTimeStamp * ts; - return getCache(handleArray, nelem, _dbrType, val, statusArray, - alarmStatus, alarmSeverity, ts); - }; - - int setAndGet(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, CTYPE &valGet); - int setAndMatch(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, const unsigned int handleMatch, - CTYPE tolerance, double timeout, bool printFlag); - - int setAndMatchMany(std::vector handleSetV, const chtype dbrType, std::vector valSet, std::vector handleMatch, - CTYPE tolerance, double timeout, bool printFlag); - - int setTriggerAndMatchMany(std::vector handleSetV, const chtype dbrType, std::vector valSet, - std::vector handleAction, std::vector valAction, std::vector handleMatch, - CTYPE tolerance, double timeout, bool printFlag); - - int matchMany( const chtype dbrType, std::vector valSet, std::vector handleMatch, - CTYPE tolerance, double timeout, bool printFlag); - - int match( const chtype dbrType, CTYPE valSet, unsigned int handleMatch, - CTYPE tolerance, double timeout, bool printFlag); - - int setMany(std::vector handleSet, const chtype dbrType, std::vector valSet, bool printFlag); - - - - int compareAndMatchMany(std::vector handleSet, const chtype dbrType, std::vector valSet, std::vector handleMatch, - CTYPE tolerance, double timeout, bool printFlag); - - - - int setManyString(std::vector handleSet, std::vector valSet, bool printFlag) - { - -#define __METHOD__ "Instant::setMany(vectorhandleSet, chtype, vectorvalSet)" - - CAFEStatus cstat; - - - status=ICAFE_NORMAL; - - if (handleSet.size() != valSet.size() ) - { - return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH; - } - - for (size_t i=0; i< handleSet.size(); ++i) - { - - if (!helper.isChannelConnected(handleSet[i])) - { - std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; - std::cout << "NOT ALL CHANNELS CONNECTED: " << std::endl; - if (!helper.isChannelConnected(handleSet[i])) - { - helper.printHandle(handleSet[i]); - status=helper.getStatus(handleSet[i]); - } - } - - } - - - if (status!=ICAFE_NORMAL) - { - return status; - } - - if(printFlag) - { - std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; - } - - - if (printFlag) - { - - for (size_t i=0; i< handleSet.size(); ++i) - { - - std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << valSet[i] << std::endl; - - - } //for - - } //if - - - for (size_t i=0; i< handleSet.size(); ++i) - { - - - - //set No of Elements to 1 - - unsigned int nelemPrevious, nelemRequestedCheck=0; - unsigned int nelemRequested=1; - - nelemPrevious=helper.getNelemClient(handleSet[i]); - //Check the number of elements requested? - if (nelemPrevious>1) - { - nelemRequestedCheck = helper.setNelem(handleSet[i],nelemRequested); - if (nelemRequestedCheck != nelemRequested) - { - std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; - std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " - << nelemPrevious << std::endl; - std::cout << "to: " << nelemRequested << " but got instead: " - << nelemRequestedCheck << std::endl; - } - } - - - - //policy set synchronous - ChannelRequestPolicy polPrevious, polNow; - - policyHelper.getChannelRequestPolicyPut(handleSet[i], polPrevious); - - polNow.setMethodKind(WITHOUT_CALLBACK); - polNow.setWaitKind(WAIT); - polNow.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); - - policyHelper.setChannelRequestPolicyPut(handleSet[i], polNow); - - dbr_string_t valSetA[1]; - - - helper.removeLeadingAndTrailingSpaces(valSet[i].c_str(), valSetA[0]); - - - status=set(handleSet[i], DBR_STRING, valSetA); - - if (status!=ICAFE_NORMAL) - { - std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; - cstat.report(status); - } - - policyHelper.setChannelRequestPolicyPut(handleSet[i], polPrevious); - - - unsigned int nelemPreviousCheck=nelemPrevious; - nelemRequested=1; - //Switch back to previous value - //if (nelemPrevious>1) { - if(helper.getNelemRequest(handleSet[i])!= nelemPrevious) - { - nelemPreviousCheck= helper.setNelem(handleSet[i],nelemPrevious); - if (nelemPreviousCheck != nelemPrevious) - { - std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; - std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " - << nelemRequested << std::endl; - std::cout << "to the previous: " << nelemPrevious << " but got instead: " - << nelemPreviousCheck << std::endl; - } - } - - - } //for size_t - - return status; -#undef __METHOD__ - } - - /** - * \brief Set followed by an immediate get - * \param handleSet input: handle - * \param valSet input: string value to set - * \param valGet output: string value to get - * \return ECA_NORMAL if all OK else first ECAFE error encountered, else ICAFE_SET_AND_GET_MISMATCH; - */ - int setAndGetString(const unsigned int handleSet, std::string valSet, std::string &valGet) - { -#define __METHOD__ "Instant::setAndGetString(const unsigned int handleSet, std::string valSet, std::string &valGet" - //CheckPolicy - - dbr_string_t valGetA[1]; - dbr_string_t valSetA[1]; - - strcpy(valGetA[0],"0"); - valGet="0"; - - helper.removeLeadingAndTrailingSpaces(valSet.c_str(), valSetA[0]); - - status=Instant::set(handleSet, DBR_STRING, valSetA); - if (status==ICAFE_NORMAL) - { - status=Instant::get(handleSet, DBR_STRING, valGetA); - - valGet=valGetA[0]; - } - else - { - return status; - } - - if (strcmp(valSetA[0],valGetA[0])==0) - { - return ICAFE_NORMAL; - } - - //Check if number - std::istringstream ins, ous; - double oud=0; - ous.clear(); - ous.str(valGetA[0]); - ous>>oud; - double ind=0; - ins.clear(); - ins.str(valSetA[0]); - ins>>ind; - - - if ( !ous.fail() && !ins.fail()) - { - if (ind==oud) - { - return ICAFE_NORMAL; - } - } - //Cater for enums that are refered to by their integer values in string format - else if (!ins.fail()) - { - short enumval=-1; - - enumval=helper.getEnumFromString(handleSet, valGet); - - //Convert integer to string - - std::stringstream ss; - ss << enumval; - valGet= ss.str(); - if ((short)ind==enumval) - { - return ICAFE_NORMAL; - } - - } - - - std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; - std::cout << "Process Variable = " << helper.getPVFromHandle(handleSet) << std::endl; - std::cout << "Set Value: " << valSetA[0] << " Get Value: " << valGet.c_str() << std::endl; - return ICAFE_SET_AND_GET_MISMATCH; -#undef __METHOD__ - - }; - - - /** - * \brief Set followed by an immediate get - * \param handleSet input: handle - * \param valSet input: dbr_string_t value to set - * \param valGet output: dbr_string_t value to get - * \return ECA_NORMAL if all OK else first ECAFE error encountered, else ICAFE_SET_AND_GET_MISMATCH; - */ - int setAndGetDbrString(const unsigned int handleSet, dbr_string_t valSet, dbr_string_t &valGet) - { -#define __METHOD__ "Instant::setAndGetDbrString(const unsigned int handleSet, dbr_string_tvalSet, dbr_string_t &valGet" - //CheckPolicy - - dbr_string_t valGetA[1]; - dbr_string_t valSetA[1]; - - strcpy(valGetA[0],"0"); - strcpy(valGet,"0"); - - helper.removeLeadingAndTrailingSpaces(valSet, valSetA[0]); - - status=Instant::set(handleSet, DBR_STRING, valSetA); - if (status==ICAFE_NORMAL) - { - status=Instant::get(handleSet, DBR_STRING, valGetA); - - strcpy(valGet,valGetA[0]); - } - else - { - return status; - } - - if (strcmp(valSetA[0],valGetA[0])==0) - { - return ICAFE_NORMAL; - } - - //Check if number - //Check if number - std::istringstream ins, ous; - double oud=0; - ous.clear(); - ous.str(valGetA[0]); - ous>>oud; - double ind=0; - ins.clear(); - ins.str(valSetA[0]); - ins>>ind; - - if ( !ous.fail() && !ins.fail()) - { - if (ind==oud) - { - return ICAFE_NORMAL; - } - } - //Cater for enums that are refered to by their integer values in string format - else if (!ins.fail()) - { - short enumval=-1; - - enumval=helper.getEnumFromString(handleSet, valGet); - - //Convert integer to string - std::stringstream ss; - ss << enumval; - strcpy(valGet, ss.str().c_str()); - - if ((short) ind==enumval) - { - return ICAFE_NORMAL; - } - - - } - - - std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; - std::cout << "Process Variable = " << helper.getPVFromHandle(handleSet) << std::endl; - std::cout << "Set Value: " << valSetA[0] << " Get Value: " << valGet << std::endl; - return ICAFE_SET_AND_GET_MISMATCH; -#undef __METHOD__ - - }; - -}; - -#include - -#endif // INSTANT_H - +/// +/// \file instant.h +/// \author Jan Chrin, PSI +/// \date Release: February 2015 +/// \version CAFE 1.0.0 +/// + +#ifndef INSTANT_H +#define INSTANT_H + +#include +#include +#include +//include + +//extern cafeConduit_set cs; + +template class Instant +{ + +private: + Transpose renderString; // 0 + Transpose renderShort; // 1 + Transpose renderFloat; // 2 + Transpose renderEnum; // 3 + Transpose renderChar; // 4 + Transpose renderLong; // 5 + Transpose renderDouble; // 6 + + CAFEStatus cafeStatus; + Granules cafeGranules; + + PolicyHelper policyHelper; + + HandleHelper helper; + + Conduit cc; + ChannelTimeoutPolicy channelTimeoutPolicyGet; + ChannelRequestPolicy channelRequestPolicyGet; + ChannelRequestStatus channelRequestStatusGet; + ChannelRequestDataTypePolicy channelRequestDataTypePolicy; + + ChannelRequestMetaDataClient channelRequestMetaDataClient; //-1 + + //cafeConduit_set_by_handle & handle_index = cs.get (); + + bool useHandleHelper; //instantiating global extern cs for use in pybind11 + + int status; + + int clientRequests(const unsigned int _handle, const chtype dbrType, const CTYPE * _val); + + int clientRequests(const unsigned int _handle, const chtype dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, + bool isCacheRequest); +public: + + Instant () {useHandleHelper = true;}; + ~Instant () {}; + + int set(const unsigned int *handleArray, const unsigned int nelem, + const chtype _dbrType, const CTYPE * val, int *statusArray); + + int set(const unsigned int _handle, const chtype dbrType, const CTYPE * _val); + + int get(const unsigned int _handle, const chtype dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts); + + int get(const unsigned int _handle, const chtype dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity) + { + epicsTimeStamp ts; + return get(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); + }; + + int get(const unsigned int _handle, const chtype dbrType, CTYPE * _val) + { + dbr_short_t alarmStatus; + dbr_short_t alarmSeverity; + epicsTimeStamp ts; + return get(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); + }; + + int getCache(const unsigned int _handle, const chtype dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts); + + int getCache(const unsigned int _handle, const chtype dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity) + { + epicsTimeStamp ts; + return getCache(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); + }; + + int getCache(const unsigned int _handle, const chtype dbrType, CTYPE * _val) + { + dbr_short_t alarmStatus; + dbr_short_t alarmSeverity; + epicsTimeStamp ts; + return getCache(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts); + }; + + int getCache(const unsigned int *handleArray, const unsigned int nelem, + const chtype _dbrType, CTYPE * val, int *statusArray, + dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity, epicsTimeStamp *ts); + + int getCache(const unsigned int *handleArray, const unsigned int nelem, + const chtype _dbrType, CTYPE * val, int *statusArray, + dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity ) + { + epicsTimeStamp * ts; + return getCache(handleArray, nelem, _dbrType, val, statusArray, + alarmStatus, alarmSeverity, ts); + }; + int getCache(const unsigned int *handleArray, const unsigned int nelem, + const chtype _dbrType, CTYPE * val, int *statusArray) + { + dbr_short_t * alarmStatus; + dbr_short_t * alarmSeverity; + epicsTimeStamp * ts; + return getCache(handleArray, nelem, _dbrType, val, statusArray, + alarmStatus, alarmSeverity, ts); + }; + + int setAndGet(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, CTYPE &valGet); + int setAndMatch(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, const unsigned int handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + + int setAndMatchMany(std::vector handleSetV, const chtype dbrType, std::vector valSet, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + + int setTriggerAndMatchMany(std::vector handleSetV, const chtype dbrType, std::vector valSet, + std::vector handleAction, std::vector valAction, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + + int matchMany( const chtype dbrType, std::vector valSet, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + + int match( const chtype dbrType, CTYPE valSet, unsigned int handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + + int setMany(std::vector handleSet, const chtype dbrType, std::vector valSet, bool printFlag); + + + + int compareAndMatchMany(std::vector handleSet, const chtype dbrType, std::vector valSet, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + + + + int setManyString(std::vector handleSet, std::vector valSet, bool printFlag) + { + +#define __METHOD__ "Instant::setManyString(vectorhandleSet, chtype, vectorvalSet)" + + CAFEStatus cstat; + + + status=ICAFE_NORMAL; + + if (handleSet.size() != valSet.size() ) + { + return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH; + } + + for (size_t i=0; i< handleSet.size(); ++i) + { + + if (!helper.isChannelConnected(handleSet[i])) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "NOT ALL CHANNELS CONNECTED: " << std::endl; + if (!helper.isChannelConnected(handleSet[i])) + { + helper.printHandle(handleSet[i]); + status=helper.getStatus(handleSet[i]); + } + } + + } + + + if (status!=ICAFE_NORMAL) + { + return status; + } + + if(printFlag) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + } + + + if (printFlag) + { + + for (size_t i=0; i< handleSet.size(); ++i) + { + + std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << valSet[i] << std::endl; + + + } //for + + } //if + + + for (size_t i=0; i< handleSet.size(); ++i) + { + + + + //set No of Elements to 1 + + unsigned int nelemPrevious, nelemRequestedCheck=0; + unsigned int nelemRequested=1; + + nelemPrevious=helper.getNelemClient(handleSet[i]); + //Check the number of elements requested? + if (nelemPrevious>1) + { + nelemRequestedCheck = helper.setNelem(handleSet[i],nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + + + //policy set synchronous + ChannelRequestPolicy polPrevious, polNow; + + policyHelper.getChannelRequestPolicyPut(handleSet[i], polPrevious); + + polNow.setMethodKind(WITHOUT_CALLBACK); + polNow.setWaitKind(WAIT); + polNow.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + policyHelper.setChannelRequestPolicyPut(handleSet[i], polNow); + + dbr_string_t valSetA[1]; + + + helper.removeLeadingAndTrailingSpaces(valSet[i].c_str(), valSetA[0]); + + + status=set(handleSet[i], DBR_STRING, valSetA); + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + policyHelper.setChannelRequestPolicyPut(handleSet[i], polPrevious); + + + unsigned int nelemPreviousCheck=nelemPrevious; + nelemRequested=1; + //Switch back to previous value + //if (nelemPrevious>1) { + if(helper.getNelemRequest(handleSet[i])!= nelemPrevious) + { + nelemPreviousCheck= helper.setNelem(handleSet[i],nelemPrevious); + if (nelemPreviousCheck != nelemPrevious) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPrevious << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + } //for size_t + + return status; +#undef __METHOD__ + } + + /** + * \brief Set followed by an immediate get + * \param handleSet input: handle + * \param valSet input: string value to set + * \param valGet output: string value to get + * \return ECA_NORMAL if all OK else first ECAFE error encountered, else ICAFE_SET_AND_GET_MISMATCH; + */ + int setAndGetString(const unsigned int handleSet, std::string valSet, std::string &valGet) + { +#define __METHOD__ "Instant::setAndGetString(const unsigned int handleSet, std::string valSet, std::string &valGet" + //CheckPolicy + + dbr_string_t valGetA[1]; + dbr_string_t valSetA[1]; + + strcpy(valGetA[0],"0"); + valGet="0"; + + helper.removeLeadingAndTrailingSpaces(valSet.c_str(), valSetA[0]); + + status=Instant::set(handleSet, DBR_STRING, valSetA); + if (status==ICAFE_NORMAL) + { + status=Instant::get(handleSet, DBR_STRING, valGetA); + + valGet=valGetA[0]; + } + else + { + return status; + } + + if (strcmp(valSetA[0],valGetA[0])==0) + { + return ICAFE_NORMAL; + } + + //Check if number + std::istringstream ins, ous; + double oud=0; + ous.clear(); + ous.str(valGetA[0]); + ous>>oud; + double ind=0; + ins.clear(); + ins.str(valSetA[0]); + ins>>ind; + + + if ( !ous.fail() && !ins.fail()) + { + if (ind==oud) + { + return ICAFE_NORMAL; + } + } + //Cater for enums that are refered to by their integer values in string format + else if (!ins.fail()) + { + short enumval=-1; + + enumval=helper.getEnumFromString(handleSet, valGet); + + //Convert integer to string + + std::stringstream ss; + ss << enumval; + valGet= ss.str(); + if ((short)ind==enumval) + { + return ICAFE_NORMAL; + } + + } + + + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Process Variable = " << helper.getPVFromHandle(handleSet) << std::endl; + std::cout << "Set Value: " << valSetA[0] << " Get Value: " << valGet.c_str() << std::endl; + return ICAFE_SET_AND_GET_MISMATCH; +#undef __METHOD__ + + }; + + + /** + * \brief Set followed by an immediate get + * \param handleSet input: handle + * \param valSet input: dbr_string_t value to set + * \param valGet output: dbr_string_t value to get + * \return ECA_NORMAL if all OK else first ECAFE error encountered, else ICAFE_SET_AND_GET_MISMATCH; + */ + int setAndGetDbrString(const unsigned int handleSet, dbr_string_t valSet, dbr_string_t &valGet) + { +#define __METHOD__ "Instant::setAndGetDbrString(const unsigned int handleSet, dbr_string_tvalSet, dbr_string_t &valGet" + //CheckPolicy + + dbr_string_t valGetA[1]; + dbr_string_t valSetA[1]; + + strcpy(valGetA[0],"0"); + strcpy(valGet,"0"); + + helper.removeLeadingAndTrailingSpaces(valSet, valSetA[0]); + + status=Instant::set(handleSet, DBR_STRING, valSetA); + if (status==ICAFE_NORMAL) + { + status=Instant::get(handleSet, DBR_STRING, valGetA); + + strcpy(valGet,valGetA[0]); + } + else + { + return status; + } + + if (strcmp(valSetA[0],valGetA[0])==0) + { + return ICAFE_NORMAL; + } + + //Check if number + //Check if number + std::istringstream ins, ous; + double oud=0; + ous.clear(); + ous.str(valGetA[0]); + ous>>oud; + double ind=0; + ins.clear(); + ins.str(valSetA[0]); + ins>>ind; + + if ( !ous.fail() && !ins.fail()) + { + if (ind==oud) + { + return ICAFE_NORMAL; + } + } + //Cater for enums that are refered to by their integer values in string format + else if (!ins.fail()) + { + short enumval=-1; + + enumval=helper.getEnumFromString(handleSet, valGet); + + //Convert integer to string + std::stringstream ss; + ss << enumval; + strcpy(valGet, ss.str().c_str()); + + if ((short) ind==enumval) + { + return ICAFE_NORMAL; + } + + + } + + + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Process Variable = " << helper.getPVFromHandle(handleSet) << std::endl; + std::cout << "Set Value: " << valSetA[0] << " Get Value: " << valGet << std::endl; + return ICAFE_SET_AND_GET_MISMATCH; +#undef __METHOD__ + + }; + +}; + + + + +//include + + + + +/** + * \brief Set values of data type CTYPE + * \param _handle input: handle to CAFEConduit object + * \param _dbrType input: chtype + * \param _val value/array of values of datatype const CTYPE + * \return ECA_NORMAL if all OK else CAFE_ or ECA_ error + * \return CAFE_ error if CAFEConduit::putCallback() operation is not to be executed: + * \return ECAFE_INVALID_HANDLE - Invalid reference handle + * \return ECAFE_NOWTACCESS - Write access denied + * \return ICAFE_CA_OP_CONN_DOWN - Channel is not connected + * \return ECA_ error from CAFEConduit::putCallback() operation: + * \return (*) should not arise due to pre-checks + * \return ECA_NORMAL - Normal successful completion + * \return ECA_BADCHID - Corrupted Channel Identifier (chid) + * \return ECA_BADTYPE (*) - Invalid DBR_XXX type + * \return ECA_BADCOUNT (*) - Requested count larger than native element count + * \return ECA_NOWTACCESS (*) - Write access denied + * \return ECA_ALLOCMEM - Unable to allocate memory + * \return ECA_DISCONN (*) - Channel is disconnected + */ +template int Instant::set(const unsigned int _handle, const chtype _dbrType, + const CTYPE * _val ) +{ +#define __METHOD__ "Instant::set(_handle, _dbrType, _val)" + + status=ICAFE_NORMAL; + + if (_dbrType > DBR_DOUBLE) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "INTERNAL CAFE ERROR: HOW DID THIS PERCULIAR DATA TYPE: " + << dbr_type_to_text(_dbrType) << " GET THROUGH!" << std::endl; + } + + cafeConduit_set_by_handle & handle_index = cs.get (); + cafeConduit_set_by_handle::iterator it_handle; + + if (useHandleHelper) { + it_handle = helper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } + + + if (it_handle != handle_index.end()) + { + + if ( (status=cafeGranules.channelVerifyPut(_handle, _dbrType)) != ICAFE_NORMAL) + { + return status; + } + + if ( (status=cafeGranules.channelPreparePut(_handle)) != ICAFE_NORMAL) + { + return status; + } + + if ( (status=clientRequests(_handle, _dbrType, _val)) != ICAFE_NORMAL) + { + return status; + } + + if ( (status=cafeGranules.channelExecutePut(_handle)) != ICAFE_NORMAL) + { + return status; + } + + } + else + { + std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; + cafeStatus.report(ECAFE_INVALID_HANDLE); + return ECAFE_INVALID_HANDLE; + } + + if(MUTEX) + { + cafeMutex.lock(); + }; //lock + + if (useHandleHelper) { + helper.modifyHandleIndexStatus(_handle, status); + } else { + handle_index.modify(it_handle, change_status(status)); + } + + if(MUTEX) + { + cafeMutex.unlock(); + }; //unlock + + return status; + +#undef __METHOD__ +} + +/** + * \brief Retrieve values of data type CTYPE + * \param _handle input: handle to CAFEConduit object + * \param _dbrType input: chtype + * \param _val output: value/array of values of datatype const CTYPE + * \param alarmStatus output + * \param alarmSeverity output + * \param ts output: epicsTimeStamp + * \return ECA_NORMAL if all OK else CAFE_ or ECA_ error + * \return CAFE_ error if CAFEConduit::get() operation is not to be executed: + * \return ECAFE_INVALID_HANDLE - Invalid reference handle + * \return ECAFE_NORDACCESS - Read access denied + * \return ICAFE_CA_OP_CONN_DOWN - Channel is not connected + * \return ECA_ error from CAFEConduit::get() operation: + * \return (*) should not arise due to pre-checks + * \return ECA_NORMAL - Normal successful completion + * \return ECA_BADCHID - Corrupted Channel Identifier (chid) + * \return ECA_BADTYPE (*) - Invalid DBR_XXX type + * \return ECA_BADCOUNT (*) - Requested count larger than native element count + * \return ECA_NORDACCESS(*)- Read access denied + * \return ECA_ALLOCMEM - Unable to allocate memory + * \return ECA_DISCONN (*) - Channel is disconnected + */ +template int Instant::get(const unsigned int _handle, + const chtype _dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts) +{ +#define __METHOD__ "Instant::get(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts) " + + //std::cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << std::endl; + + status=ICAFE_NORMAL; + + if (_dbrType > DBR_CTRL_DOUBLE) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "INTERNAL CAFE ERROR: HOW DID THIS PERCULIAR DATA TYPE: " + << dbr_type_to_text(_dbrType) << " GET THROUGH!" << std::endl; + } + else if (_dbrType > DBR_TIME_DOUBLE) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "INTERNAL CAFE ERROR: METHOD NOT MEANT FOR THIS DATA TYPE: " + << dbr_type_to_text(_dbrType) << std::endl; + std::cout << "CAFE WILL THUS TAKE CONTROL OF ALLOCATING APPROPIATE DBR_TYPE" << std::endl; + } + + + cafeConduit_set_by_handle & handle_index = cs.get (); + cafeConduit_set_by_handle::iterator it_handle; + + if (useHandleHelper) { + it_handle = helper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } + + + //pybind11 July 2021 - Discovered that handle_index.find(_handle) + //does not work, and neither does handle_index.modify + //cafeConduit_set_by_handle & handle_index = helper.getcsHandleIndex(); + + + if (it_handle != handle_index.end()) + { + + if ( (*it_handle).getChannelGetActionWhenMonitorPolicy().getActionKind() == CAFENUM::GET_FROM_CACHE) + { + if ( helper.getNmonitorData(_handle) >0) + { + return Instant::getCache(_handle, _dbrType, _val, alarmStatus, alarmSeverity, ts); + } + } + + if ( (status=cafeGranules.channelVerifyGet(_handle, _dbrType)) != ICAFE_NORMAL) + { + return status; + } + + //Here fill channelRequestMetaData + + if ( (status=cafeGranules.channelPrepareGet(_handle)) != ICAFE_NORMAL) + { + return status; + } + + if ( (status=cafeGranules.channelExecuteGet(_handle)) != ICAFE_NORMAL) + { + return status; + } + + channelRequestMetaDataClient = (*it_handle).getChannelRequestMetaDataClient(); + + status=clientRequests( _handle, channelRequestMetaDataClient.getDbrDataType(), + _val, alarmStatus, alarmSeverity, ts, false); + + } + else + { + + std::cout << "Value of MUTEX " << MUTEX << std::endl; + std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; + std::cout << "Failed to find handle " << _handle << std::endl; + cafeStatus.report(ECAFE_INVALID_HANDLE); + return ECAFE_INVALID_HANDLE; + } + + if(MUTEX) + { + cafeMutex.lock(); + }; //lock + + if (useHandleHelper) { + helper.modifyHandleIndexStatus(_handle, status); + } + else { + handle_index.modify(it_handle, change_status(status)); + } + + if(MUTEX) + { + cafeMutex.unlock(); + }; //unlock + + + return status; + +#undef __METHOD__ +} + + +/** + * \brief Retrieve cached values of data type CTYPE + * \param _handle input: handle to CAFEConduit object + * \param _dbrType input: chtype + * \param _val output: value/array of values of datatype const CTYPE + * \param alarmStatus output + * \param alarmSeverity output + * \param ts output: epicsTimeStamp + * \return ECA_NORMAL if all OK else CAFE_ or ECA_ error + * \return CAFE_ error if CAFEConduit::get() operation is not to be executed: + * \return ECAFE_INVALID_HANDLE - Invalid reference handle + * \return ECAFE_NORDACCESS - Read access denied + * \return ICAFE_CA_OP_CONN_DOWN - Channel is not connected + * \return ECA_ error from CAFEConduit::get() operation: + * \return (*) should not arise due to pre-checks + * \return ECA_NORMAL - Normal successful completion + * \return ECA_BADCHID - Corrupted Channel Identifier (chid) + * \return ECA_BADTYPE (*) - Invalid DBR_XXX type + * \return ECA_BADCOUNT (*) - Requested count larger than native element count + * \return ECA_NORDACCESS(*)- Read access denied + * \return ECA_ALLOCMEM - Unable to allocate memory + * \return ECA_DISCONN (*) - Channel is disconnected + */ +template int Instant::getCache(const unsigned int _handle, + const chtype _dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts) +{ +#define __METHOD__ "Instant::getCache(_handle, _dbrType, _val, alarmStatus, alarmSeverity, ts) " + + //std::cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << std::endl; + //std::cout << "handle " << _handle << " dbr input type " << _dbrType << std::endl; + + status=ICAFE_NORMAL; + + ts.secPastEpoch= 0; // default value if cache does not have timeStamp + ts.nsec = 0; // default value if cache does not have timeStamp + alarmStatus =-1; // default value if cache does not have alarmStatus + alarmSeverity =-1; // default value if cache does not have alarmSeverity + + cafeConduit_set_by_handle & handle_index = cs.get (); + cafeConduit_set_by_handle::iterator it_handle; + + + if (useHandleHelper) { + it_handle = helper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } + + + if (it_handle != handle_index.end()) + { + + //std::cout << __METHOD__ << "__" << __LINE__ << std::endl; + //std::cout << "(*it_handle).getChannelGetCacheWaitPolicy().getWaitKind()" << + //(*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() << " 0=NO_CHECK 1=NO_WAIT 2=WAIT " << std::endl; + + //Let us check input type against client request type. + chtype _dataTypeClient = (*it_handle).getChannelRequestMetaDataClient().getDataType(); + chtype _dbrTypePlain = _dbrType; + + //reduce _dbrType ton_dataTypeClient + + if (dbr_type_is_STS(_dbrType) ) + { + _dbrTypePlain = _dbrType%(LAST_TYPE+1); //DBR_STS_STRING; + } + else if (dbr_type_is_TIME(_dbrType) ) + { + _dbrTypePlain = _dbrType%(LAST_TYPE+1); //DBR_TIME_STRING; + } + + // If they do not agrre - change the data tzype in the client space for the handle!! + // std::cout << _dataTypeClient << " //COMPARISON// " << _dbrTypePlain << std::endl; + + if (_dataTypeClient != _dbrTypePlain) + { + + channelRequestMetaDataClient= (*it_handle).getChannelRequestMetaDataClient(); + + channelRequestMetaDataClient.setDataType (_dbrTypePlain); + channelRequestMetaDataClient.setDbrDataType(_dbrType); + + channelRequestMetaDataClient.setCafeDbrType( + (CAFENUM::DBR_TYPE) helper.convertToCAFEDbrTypeClass(_dbrType) ); + + if(MUTEX) + { + cafeMutex.lock(); //lock + } + + + if (useHandleHelper) { + helper.modifyChannelRequestMetaDataClient(_handle, channelRequestMetaDataClient); + } + else { + + handle_index.modify(it_handle, + change_channelRequestMetaDataClient(channelRequestMetaDataClient)); + } + + if(MUTEX) + { + cafeMutex.unlock(); //unlock + } + + } + + + //ifNeverConnected - return error + if ( (*it_handle).getChannelRegalia().getCafeConnectionState() == ICAFE_CS_NEVER_CONN) + { + return ICAFE_CS_NEVER_CONN; + } + else if ( (*it_handle).getChannelRegalia().getCafeConnectionState()==ICAFE_CS_CLOSED) + { + return ICAFE_CS_CLOSED; + } + + + // Meant for use in callbacks in monitors! + // Does not check what the client is requesting. + // If the datadatype render, i.e., dbrType does not correspond to the clientDataType in hash + // then there is a risk that that the data will be unfolded from the buffer incorrectly + // especially when strings are involved + // Solved with the above modification + + if ( (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_NO_CHECK) + { + //std::cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << std::endl; + status=clientRequests(_handle, _dbrType, _val, alarmStatus, alarmSeverity, ts, true); + //std::cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << std::endl; + return status; + } + + + if (_dbrType > DBR_CTRL_DOUBLE) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "INTERNAL CAFE ERROR: HOW DID THIS PERCULIAR DATA TYPE: " + << dbr_type_to_text(_dbrType) << " GET THROUGH!" << std::endl; + } + else if (_dbrType > DBR_TIME_DOUBLE) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "INTERNAL CAFE ERROR: METHOD NOT MEANT FOR THIS DATA TYPE: " + << dbr_type_to_text(_dbrType) << std::endl; + std::cout << "CAFE WILL THUS TAKE CONTROL OF ALLOCATING APPROPIATE DBR_TYPE" << std::endl; + } + + chtype dbrtype =(*it_handle).getChannelRequestMetaData().getDbrDataType(); + + + //MetaData will have true DBR_XXX_YYY type + //Client is asking from cache for DBR_MMM_NNN + //Therefore have to prepare DBR_MMM_NNN from DBR_XXX_YY + CAFENUM::DBR_TYPE cafedbrtype= (*it_handle).getChannelRequestMetaData().getCafeDbrType(); + + + switch (cafedbrtype) + { + case CAFENUM::DBR_TIME: + dbrtype = dbf_type_to_DBR_TIME(_dbrType%DBR_STS_STRING); + break; + case CAFENUM::DBR_STS: + dbrtype = dbf_type_to_DBR_STS(_dbrType%DBR_STS_STRING); + break; + case CAFENUM::DBR_PRIMITIVE: + dbrtype = dbf_type_to_DBR(_dbrType%DBR_STS_STRING); + break; + default: + dbrtype = (*it_handle).getChannelRequestMetaData().getDbrDataType(); + std::cout << __METHOD__ << "/" << __LINE__ < int Instant::getCache(const unsigned int *handleArray, const unsigned int nelem, + const chtype _dbrType, CTYPE * val, int *statusArray, + dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity, epicsTimeStamp *ts) +{ +#define __METHOD__ "Instant::getCache(handleArray, nelem, _dbrType, val, statusArray) " + + unsigned int nelemPrevious=1; + HandleHelper helper; + int gStatus=ICAFE_NORMAL; + bool statusSet=false; + + //std::cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << std::endl; + + for (unsigned int i=0; i (); + cafeConduit_set_by_handle::iterator it_handle; + + if (useHandleHelper) { + it_handle = helper.getIterFromHandle(handleArray[i]); + } + else { + it_handle = handle_index.find(handleArray[i]); + } + + + channelRequestStatusGet =(*it_handle).getChannelRequestStatusGet(); + + if (channelRequestStatusGet.getCallbackProgressKind() == CAFENUM::PENDING + && helper.getNmonitorData(handleArray[i])==0 + && (*it_handle).getChannelRequestPolicyGet().getMethodKind() + != CAFENUM::WITH_CALLBACK_USER_SUPPLIED + && (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_WAIT + && (*it_handle).isConnected() + ) + { + + channelTimeoutPolicyGet = (*it_handle).getChannelTimeoutPolicyGet(); + + ca_flush_io(); + status=cafeGranules.waitForGetEvent(handleArray[i], channelTimeoutPolicyGet.getTimeout()); + + + if (status==ECAFE_TIMEOUT && channelTimeoutPolicyGet.getSelfGoverningTimeout()) + { + unsigned short ntries=0; + while (status==ECAFE_TIMEOUT && ntries int Instant::set(const unsigned int *handleArray, const unsigned int nelem, + const chtype _dbrType, const CTYPE * val, int *statusArray) +{ +#define __METHOD__ \ +"Instant::set(unsigned int *handleArray, unsigned int nelem, const chtype _dbrType, dbr_double_t * val, int *statusArray)" + + int overallStatus=ICAFE_NORMAL; + bool isGood=true; + + //std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + + unsigned int nelemPrevious=1; + + for (unsigned int i=0; i int Instant::clientRequests( + const unsigned int _handle, const chtype _dbrType, const CTYPE * _val) +{ +#define __METHOD__ "Instant::clientRequests(*it_handle, _dbrType, _val)" + + cafeConduit_set_by_handle & handle_index = cs.get (); + cafeConduit_set_by_handle::iterator it_handle; + + status=ICAFE_NORMAL; + + it_handle = handle_index.find(_handle); + + if (it_handle != handle_index.end()) + { + //May 2017 Caught by Cython - These variables are set but never used + //Hence comment them out + /* + union db_access_val * PVDataL; + unsigned int nelem; + //unsigned int offset; + chtype dbrTypeRequest_DataBuffer; + + PVDataL = (*it_handle).getPutBuffer (); + nelem = (*it_handle).getChannelRequestMetaPrimitive().getNelem(); + dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaPrimitive().getDbrDataType(); + */ + + switch(_dbrType) + { + case DBR_STRING: + status=renderString.putString(_handle, (dbr_string_t *) _val); + break; + case DBR_SHORT: + status=renderShort.put(_handle, (dbr_short_t *) _val, _dbrType ); + break; + case DBR_FLOAT: + status=renderFloat.put(_handle, (dbr_float_t *) _val, _dbrType); + break; + case DBR_ENUM: + status=renderEnum.put(_handle, (dbr_enum_t *) _val, _dbrType); + break; + case DBR_CHAR: + status=renderChar.put(_handle, (dbr_char_t *) _val, _dbrType); + break; + case DBR_LONG: + status=renderLong.put(_handle, (dbr_long_t *) _val, _dbrType); + break; + case DBR_DOUBLE: + status=renderDouble.put(_handle, (dbr_double_t *) _val, _dbrType); + break; + default: + std::cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; + cafeStatus.report(ECAFE_INVALID_SWITCH_CASE); + std::cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << + _dbrType < int Instant::setAndGet(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, CTYPE &valGet) +{ +#define __METHOD__ "Instant::setAndGet(const unsigned int handleSet,const chtype dbrType, CTYPE valSet, CTYPE &valGet" + //CheckPolicy + + CTYPE valGetA[1]; + CTYPE valSetA[1]; + + valGetA[0]=0; + valGet=0; + + valSetA[0] = (CTYPE) valSet; + + status=Instant::set(handleSet, dbrType, valSetA); + if (status==ICAFE_NORMAL) + { + + unsigned int nelemPrevious, nelemRequestedCheck=0; + unsigned int nelemRequested=1; + nelemPrevious=helper.getNelemClient(handleSet); + //Check the number of elements requested? + if (nelemPrevious>1) + { + nelemRequestedCheck = helper.setNelem(handleSet,nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + status=Instant::get(handleSet, dbrType, valGetA); + + if (nelemPrevious>1) + { + helper.setNelem(handleSet,nelemPrevious); + } + + valGet=valGetA[0]; + } + else + { + return status; + } + if(valSet==valGet) + { + return ICAFE_NORMAL; + } + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Process Variable = " << helper.getPVFromHandle(handleSet) << std::endl; + std::cout << "Set Value: " << valSet << " Get Value: " << valGet << std::endl; + return ICAFE_SET_AND_GET_MISMATCH; +#undef __METHOD__ +} + + + +template int Instant::setMany(std::vector handleSet, const chtype dbrType, std::vector valSet, bool printFlag) +{ + +#define __METHOD__ "Instant::setMany(std::vectorhandleSet, chtype, std::vectorvalSet)" + + CAFEStatus cstat; + + CTYPE valSetA[1]; + + status=ICAFE_NORMAL; + + if (handleSet.size() != valSet.size() ) + { + return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH; + } + + for (size_t i=0; i< handleSet.size(); ++i) + { + + if (!helper.isChannelConnected(handleSet[i])) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "NOT ALL CHANNELS CONNECTED: " << std::endl; + if (!helper.isChannelConnected(handleSet[i])) + { + helper.printHandle(handleSet[i]); + status=helper.getStatus(handleSet[i]); + } + } + + } + + + if (status!=ICAFE_NORMAL) + { + return status; + } + + if(printFlag) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + } + + + if (printFlag) + { + + for (size_t i=0; i< handleSet.size(); ++i) + { + + if (dbrType==DBR_CHAR) + { + std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << (unsigned short) valSet[i] << std::endl; + } + else + { + std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << valSet[i] << std::endl; + } + + } //for + + } //if + + + for (size_t i=0; i< handleSet.size(); ++i) + { + + + + //set No of Elements to 1 + + unsigned int nelemPrevious, nelemRequestedCheck=0; + unsigned int nelemRequested=1; + + nelemPrevious=helper.getNelemClient(handleSet[i]); + //Check the number of elements requested? + if (nelemPrevious>1) + { + nelemRequestedCheck = helper.setNelem(handleSet[i],nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + + + //policy set synchronous + ChannelRequestPolicy polPrevious, polNow; + + policyHelper.getChannelRequestPolicyPut(handleSet[i], polPrevious); + + polNow.setMethodKind(WITHOUT_CALLBACK); + polNow.setWaitKind(WAIT); + polNow.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + policyHelper.setChannelRequestPolicyPut(handleSet[i], polNow); + + valSetA[0] = (CTYPE) valSet[i]; + + status=set(handleSet[i], dbrType, valSetA); + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + policyHelper.setChannelRequestPolicyPut(handleSet[i], polPrevious); + + + unsigned int nelemPreviousCheck=nelemPrevious; + nelemRequested=1; + //Switch back to previous value + //if (nelemPrevious>1) { + if(helper.getNelemRequest(handleSet[i])!= nelemPrevious) + { + nelemPreviousCheck= helper.setNelem(handleSet[i],nelemPrevious); + if (nelemPreviousCheck != nelemPrevious) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPrevious << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + } //for size_t + + + return status; +} +#undef __METHOD__ + + + +/** + * \brief Set Channels followed by a corresponding readback of Channels \n + * Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n + * Method returns with ECA_NORMAL as soon as a match is reached + * \param handleSet input: vector of handleSet + * \param dbrType input: chtype of set value + * \param valSet input: vector of CTYPE values to set + * \param handleMatch input: vector of handles of readback channel + * \param tolerance input: CTYPE of tolerance margin + * \param timeout input: double value; maximum time allowed for agreement to occur + * \param printFlag input: bool, set to true for diagnostics + * \return ECA_NORMAL if all OK, else first ECAFE error encountered, else ECAFE_TIMEOUT_SET_AND_MATCH + */ + +template int Instant::compareAndMatchMany(std::vector handleSet, const chtype dbrType, std::vector valSet, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag) +{ +//template int Instant::setTriggerAndMatchMany(std::vector handleSet, chtype dbrType, std::vector valSet, +// std::vector handleAction, std::vector valAction, std::vector handleMatch, +// CTYPE tolerance, double timeout, bool printFlag){ +#define __METHOD__ "Instant::compareAndMatchMany(chtype, std::vectorvalSet, std::vectorhandleMatch, tolerance, timeout, printFlag)" + + + Connect connect; + CAFEStatus cstat; + + CTYPE valGetA[1]; //CTYPE valSetA[1]; + + status=ICAFE_NORMAL; + + + if (handleMatch.size() != valSet.size() ) + { + return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH; + } + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + if (!helper.isChannelConnected(handleMatch[i])) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "NOT ALL CHANNELS CONNECTED: " << std::endl; + + if (!helper.isChannelConnected(handleMatch[i])) + { + helper.printHandle(handleMatch[i]); + status=helper.getStatus(handleMatch[i]); + } + } + + } + + + if (status!=ICAFE_NORMAL) + { + return status; + } + + if(printFlag) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + } + + if (printFlag) + { + + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + + if (dbrType==DBR_CHAR) + { + std::cout << "SETTING PV= " << helper.getPVFromHandle(handleSet[i]) << " to " << (unsigned short) valSet[i] << std::endl; + } + else + { + std::cout << "SETTING PV= " << helper.getPVFromHandle(handleSet[i]) << " to " << valSet[i] << std::endl; + } + + std::cout << "READBACK PV=" << helper.getPVFromHandle(handleMatch[i]) + << " tolerance= " << fabs( (double) tolerance) << std::endl; + std::cout << "TIME ALLOWED FOR MATCH IS " << timeout << " (sec) " << std::endl; + + } //for + + } //if + + + std::vector valSetUpper; + std::vector valSetLower; + + std::vector monitorID; + std::vector statMonitor; + std::vector nMonitors; + std::vector valGet; + + + std::vector nelemPreviousCache; + + valSetUpper.reserve( valSet.size()); + + + valSetLower.reserve( valSet.size()); + monitorID.reserve( valSet.size()); + statMonitor.reserve( valSet.size()); + valGet.reserve( valSet.size()); + nMonitors.reserve( valSet.size() ); + + + nelemPreviousCache.reserve( valSet.size()); + + + for (size_t i=0; i< valSet.size(); ++i) + { + + + switch (dbrType) + { + case DBR_LONG : + case DBR_SHORT : + case DBR_ENUM: + valSetUpper[i] = valSet[i] + abs((int)tolerance); + valSetLower[i] = valSet[i] - abs((int)tolerance); + break; + case DBR_CHAR : + valSetUpper[i] = (unsigned short) valSet[i] + abs((unsigned short) tolerance); + valSetLower[i] = (unsigned short) valSet[i] - abs((unsigned short) tolerance); + break; + case DBR_FLOAT: + case DBR_DOUBLE: + default: + + valSetUpper[i] = (CTYPE) (valSet[i] + fabs((double)tolerance)); + valSetLower[i] = (CTYPE) (valSet[i] - fabs((double)tolerance)); + + break; + } + + + + std::vector mpVMatch; + mpVMatch.clear(); + + helper.getMonitorPolicyVector(handleMatch[i], mpVMatch); + + + nMonitors[i]=mpVMatch.size(); + + monitorID[i]=0; + + ////valGetA[0][i]=0; + valGet[i]=0; + + statMonitor[i]=ICAFE_NORMAL; + + } + + + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + //what is monitorpolicy?? + if (nMonitors[i]==0) + { + + unsigned int _nelemPrevious, _nelemRequestedCheck=0; + unsigned int _nelemRequested=1; + _nelemPrevious=helper.getNelemClient(handleMatch[i]); + //Check the number of elements requested? + if (_nelemPrevious>1) + { + _nelemRequestedCheck = helper.setNelem(handleMatch[i],_nelemRequested); + if (_nelemRequestedCheck != _nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << _nelemPrevious << std::endl; + std::cout << "to: " << _nelemRequested << " but got instead: " + << _nelemRequestedCheck << std::endl; + } + } + + //first do get to update cache before monitor starts + status=Instant::get(handleMatch[i], dbrType, valGetA); + + valGet[i]=valGetA[0]; + + if (_nelemPrevious>1) + { + helper.setNelem(handleMatch[i],_nelemPrevious); + } + + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + ChannelWhenToFlushSendBufferPolicyKind whenKind= + connect.channelMonitorPolicy.getWhenToFlushSendBuffer(); + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + statMonitor[i]=connect.monitorStart(handleMatch[i], monitorID[i]); + + if (statMonitor[i]!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(statMonitor[i]); + } + else + { + if(printFlag) + { + std::cout << "MONITOR NOW IN PLACE FOR READBACK CHANNEL " << helper.getPVFromHandle(handleMatch[i]) << " WITH ID=" << monitorID[i] << std::endl; + } + } + //revert to previous + if (whenKind != FLUSH_AUTOMATIC) + { + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(whenKind); + } + + } //if nMonitors + + + + + + //No of elements to get from Cache + + //unsigned int nelemPreviousCheck=0; + unsigned int nelemRequested=1; + unsigned int nelemRequestedCheck=0; + nelemPreviousCache[i]=helper.getNelemRequest(handleMatch[i]); + + //Check the number of elements requested + //See set and Match; this needs to be checked + //Avoid problem when readback channel is the very same as the set(!) + if (nelemPreviousCache[i]>0 && helper.getNelemNative(handleMatch[i])>1) + { + nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch[i],nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPreviousCache[i] << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + + } //for size_t + + + + + //start time + + + + + double timeElapsed=0; + double timeElapsed2=0; + double timeElapsedBase=0; + using namespace boost::posix_time; + + ptime timeStart(microsec_clock::local_time()); + + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + valGetA[0]=0; + + status=Instant::getCache(handleMatch[i], dbrType, valGetA); + + valGet[i]=valGetA[0]; + + + if (status !=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + ///valGet[i]=valGetA[0][i]; + if (dbrType==DBR_CHAR) + { + valGet[i] = (unsigned short) valGetA[0]; + } + + if(printFlag) + { + //std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + if (dbrType==DBR_CHAR) + { + std::cout << "Current Cached Value = " << (unsigned short) valGet[i] << std::endl; + std::cout << "Lower/Upper Target Values = " << (unsigned short) valSetLower[i] << " and " << (unsigned short) valSetUpper[i] << std::endl; + } + else + { + std::cout << "Current Cached Value = " << valGet[i] << std::endl; + std::cout << "Lower/Upper Target Values = " << valSetLower[i] << " and " << valSetUpper[i] << std::endl; + } + } + + } //for size_t + + + + ptime timeEnd(microsec_clock::local_time()); + time_duration duration(timeEnd-timeStart); + timeElapsed= (double) duration.total_microseconds()/1000000.0; + + + for (size_t i=0; i< valSet.size(); ++i) + { + + + while ( (valGet[i]>valSetUpper[i] || valGet[i]1 && status==ICAFE_NORMAL) + { + + + for (size_t ij=0; ij< handleMatch.size(); ++ij) + { + status=Instant::getCache(handleMatch[ij], dbrType, valGetA); + valGet[ij]=valGetA[0]; + if (valGet[ij]>valSetUpper[ij] || valGet[ij]1) + { + nelemPreviousCheck= helper.setNelemToRetrieveFromCache(handleMatch[i],nelemPreviousCache[i]); + if (nelemPreviousCheck != nelemPreviousCache[i]) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPreviousCache[i] << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + + if (nMonitors[i]==0 && statMonitor[i]==ICAFE_NORMAL && printFlag) + { + std::cout << "MONITOR NOW STOPPED FOR READBACK CHANNEL " << helper.getPVFromHandle(handleMatch[i]) << " WITH ID =" << monitorID[i] << std::endl; + int statm; + statm=connect.monitorStop(handleMatch[i], monitorID[i]); + if (status==ICAFE_NORMAL) + { + status=statm; + } + } + + } //for + + + return status; +#undef __METHOD__ + +} + + + + + +/** + * \brief Set Channels followed by a corresponding readback of Channels \n + * Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n + * Method returns with ECA_NORMAL as soon as a match is reached + * \param handleSet input: vector of handleSet + * \param dbrType input: chtype of set value + * \param valSet input: vector of CTYPE values to set + * \param handleMatch input: vector of handles of readback channel + * \param tolerance input: CTYPE of tolerance margin + * \param timeout input: double value; maximum time allowed for agreement to occur + * \param printFlag input: bool, set to true for diagnostics + * \return ECA_NORMAL if all OK, else first ECAFE error encountered, else ECAFE_TIMEOUT_SET_AND_MATCH + */ +template int Instant::setAndMatchMany(std::vector handleSet, chtype dbrType, std::vector valSet, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag) +{ +#define __METHOD__ "Instant::setAndMatchMany(std::vectorhandleSet, chtype, std::vectorvalSet, std::vectorhandleMatch, tolerance, timeout, printFlag)" + + Connect connect; + CAFEStatus cstat; + + CTYPE valGetA[1]; + CTYPE valSetA[1]; + + status=ICAFE_NORMAL; + + if (handleSet.size() != handleMatch.size() ) + { + return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH; + } + + if (handleSet.size() != valSet.size() ) + { + return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH; + } + + for (size_t i=0; i< handleSet.size(); ++i) + { + + if (!helper.isChannelConnected(handleSet[i]) + || !helper.isChannelConnected(handleMatch[i])) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "NOT ALL CHANNELS CONNECTED: " << std::endl; + if (!helper.isChannelConnected(handleSet[i])) + { + helper.printHandle(handleSet[i]); + status=helper.getStatus(handleSet[i]); + } + if (!helper.isChannelConnected(handleMatch[i])) + { + helper.printHandle(handleMatch[i]); + status=helper.getStatus(handleMatch[i]); + } + } + + } + + + if (status!=ICAFE_NORMAL) + { + return status; + } + + if(printFlag) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + } + + + for (size_t i=0; i< handleSet.size(); ++i) + { + + + if (printFlag) + { + + if (dbrType==DBR_CHAR) + { + std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << (unsigned short) valSet[i] << std::endl; + } + else + { + std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << valSet[i] << std::endl; + } + + std::cout << "READBACK PV=" << helper.getPVFromHandle(handleMatch[i]) + << " tolerance= " << fabs( (double) tolerance) << std::endl; + std::cout << "TIME ALLOWED FOR MATCH IS " << timeout << " (sec) " << std::endl; + + } + + } + + + std::vector valSetUpper; + std::vector valSetLower; + + std::vector monitorID; + std::vector statMonitor; + std::vector nMonitors; + std::vector valGet; + + + std::vector nelemPreviousCache; + + valSetUpper.reserve( handleSet.size()); + + + valSetLower.reserve( handleSet.size()); + monitorID.reserve( handleSet.size()); + statMonitor.reserve( handleSet.size()); + valGet.reserve( handleSet.size()); + nMonitors.reserve( handleSet.size() ); + + + nelemPreviousCache.reserve(handleSet.size()); + + + for (size_t i=0; i< handleSet.size(); ++i) + { + + + switch (dbrType) + { + case DBR_LONG : + case DBR_SHORT : + case DBR_ENUM: + valSetUpper[i] = valSet[i] + abs((int)tolerance); + valSetLower[i] = valSet[i] - abs((int)tolerance); + break; + case DBR_CHAR : + valSetUpper[i] = (unsigned short) valSet[i] + abs((unsigned short) tolerance); + valSetLower[i] = (unsigned short) valSet[i] - abs((unsigned short) tolerance); + break; + case DBR_FLOAT: + case DBR_DOUBLE: + default: + + valSetUpper[i] = (CTYPE) (valSet[i] + fabs((double)tolerance)); + valSetLower[i] = (CTYPE) (valSet[i] - fabs((double)tolerance)); + + break; + } + + + + std::vector mpVMatch; + mpVMatch.clear(); + + helper.getMonitorPolicyVector(handleMatch[i], mpVMatch); + + + nMonitors[i]=mpVMatch.size(); + + monitorID[i]=0; + + ////valGetA[0][i]=0; + valGet[i]=0; + + statMonitor[i]=ICAFE_NORMAL; + + } + + + + for (size_t i=0; i< handleSet.size(); ++i) + { + + //what is monitorpolicy?? + if (nMonitors[i]==0) + { + + unsigned int _nelemPrevious, _nelemRequestedCheck=0; + unsigned int _nelemRequested=1; + _nelemPrevious=helper.getNelemClient(handleMatch[i]); + //Check the number of elements requested? + if (_nelemPrevious>1) + { + _nelemRequestedCheck = helper.setNelem(handleMatch[i],_nelemRequested); //change handleSet to handleMatch 23/3/17 + if (_nelemRequestedCheck != _nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << _nelemPrevious << std::endl; + std::cout << "to: " << _nelemRequested << " but got instead: " + << _nelemRequestedCheck << std::endl; + } + } + + //first do get to update cache before monitor starts + status=Instant::get(handleMatch[i], dbrType, valGetA); + + valGet[i]=valGetA[0]; + + if (_nelemPrevious>1) + { + helper.setNelem(handleMatch[i],_nelemPrevious); //change handleSet to handleMatch 23/3/17 + } + + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + ChannelWhenToFlushSendBufferPolicyKind whenKind= + connect.channelMonitorPolicy.getWhenToFlushSendBuffer(); + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + statMonitor[i]=connect.monitorStart(handleMatch[i], monitorID[i]); + + if (statMonitor[i]!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(statMonitor[i]); + } + else + { + if(printFlag) + { + std::cout << "MONITOR NOW IN PLACE FOR READBACK CHANNEL " << helper.getPVFromHandle(handleMatch[i]) << " WITH ID=" << monitorID[i] << std::endl; + } + } + //revert to previous + if (whenKind != FLUSH_AUTOMATIC) + { + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(whenKind); + } + + } //if nMonitors + + ////valSetA[0][i]=valSet[i]; + + //set No of Elements to 1 + + unsigned int nelemPrevious, nelemRequestedCheck=0; + unsigned int nelemRequested=1; + + nelemPrevious=helper.getNelemClient(handleSet[i]); + //Check the number of elements requested? + if (nelemPrevious>1) + { + nelemRequestedCheck = helper.setNelem(handleSet[i],nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + + //policy set synchronous + ChannelRequestPolicy polPrevious, polNow; + + policyHelper.getChannelRequestPolicyPut(handleSet[i], polPrevious); + + polNow.setMethodKind(WITHOUT_CALLBACK); + polNow.setWaitKind(WAIT); + polNow.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + policyHelper.setChannelRequestPolicyPut(handleSet[i], polNow); + + + valSetA[0] = (CTYPE) valSet[i]; + + status=set(handleSet[i], dbrType, valSetA); + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + policyHelper.setChannelRequestPolicyPut(handleSet[i], polPrevious); + + unsigned int nelemPreviousCheck=nelemPrevious; + nelemRequested=1; + //Switch back to previous value + //if (nelemPrevious>1) { + if(helper.getNelemRequest(handleSet[i])!= nelemPrevious) + { + nelemPreviousCheck= helper.setNelem(handleSet[i],nelemPrevious); + if (nelemPreviousCheck != nelemPrevious) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPrevious << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + //No of elements to get from Cache + + nelemPreviousCheck=0; + nelemRequested=1; + nelemRequestedCheck=0; + nelemPreviousCache[i]=helper.getNelemRequest(handleMatch[i]); + + //Check the number of elements requested + //See set and Match; this needs to be checked + //Avoid problem when readback channel is the very same as the set(!) + if (nelemPreviousCache[i]>0 && helper.getNelemNative(handleMatch[i])>1) + { + nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch[i],nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPreviousCache[i] << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + + } //for size_t + + //start time + + + + + double timeElapsed=0; + double timeElapsed2=0; + double timeElapsedBase=0; + using namespace boost::posix_time; + + ptime timeStart(microsec_clock::local_time()); + + + for (size_t i=0; i< handleSet.size(); ++i) + { + + + + valGetA[0]=0; + + status=Instant::getCache(handleMatch[i], dbrType, valGetA); + + valGet[i]=valGetA[0]; + + + + if (status !=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + ///valGet[i]=valGetA[0][i]; + if (dbrType==DBR_CHAR) + { + valGet[i] = (unsigned short) valGetA[0]; + } + + if(printFlag) + { + //std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + if (dbrType==DBR_CHAR) + { + std::cout << "Current Cached Value = " << (unsigned short) valGet[i] << std::endl; + std::cout << "Lower/Upper Target Values = " << (unsigned short) valSetLower[i] << " and " << (unsigned short) valSetUpper[i] << std::endl; + } + else + { + std::cout << "Current Cached Value = " << valGet[i] << std::endl; + std::cout << "Lower/Upper Target Values = " << valSetLower[i] << " and " << valSetUpper[i] << std::endl; + } + } + + } //for size_t + + + + ptime timeEnd(microsec_clock::local_time()); + time_duration duration(timeEnd-timeStart); + timeElapsed= (double) duration.total_microseconds()/1000000.0; + + + for (size_t i=0; i< handleSet.size(); ++i) + { + + + while ( (valGet[i]>valSetUpper[i] || valGet[i]1 && status==ICAFE_NORMAL) + { + + + + for (size_t ij=0; ij< handleMatch.size(); ++ij) + { + status=Instant::getCache(handleMatch[ij], dbrType, valGetA); + valGet[ij]=valGetA[0]; + if (valGet[ij]>valSetUpper[ij] || valGet[ij]1) + { + nelemPreviousCheck= helper.setNelemToRetrieveFromCache(handleMatch[i],nelemPreviousCache[i]); + if (nelemPreviousCheck != nelemPreviousCache[i]) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPreviousCache[i] << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + + if (nMonitors[i]==0 && statMonitor[i]==ICAFE_NORMAL && printFlag) + { + std::cout << "MONITOR NOW STOPPED FOR READBACK CHANNEL " << helper.getPVFromHandle(handleMatch[i]) << " WITH ID =" << monitorID[i] << std::endl; + int statm; + statm=connect.monitorStop(handleMatch[i], monitorID[i]); + if (status==ICAFE_NORMAL) + { + status=statm; + } + } + + } //for + + + return status; +#undef __METHOD__ +} + + + +/** + * \brief Set Channel 1 followed by a readback of Channel 2 \n + * Method verifies whether or not the 2 values agree within the given tolerance and timeout \n + * Method returns with ECA_NORMAL as soon as a match is reached + * \param handleSet input: handleSet + * \param dbrType input: chtype of set value + * \param valSet input: CTYPE value to set + * \param handleMatch input: handle of readback channel + * \param tolerance input: CTYPE of tolerance margin + * \param timeout input: double value; maximum time allowed for agreement to occur + * \param printFlag input: bool, set to true for diagnostics + * \return ECA_NORMAL if all OK else first ECAFE error encountered + */ +template int Instant::setAndMatch(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, const unsigned int handleMatch, + CTYPE tolerance, double timeout, bool printFlag) +{ +#define __METHOD__ "Instant::setAndMatch(handleSet, dbrType, valSet, handleMatch, tolerance, timeout, printFlag)" + //check both handles exists before proceeding + + Connect connect; + CAFEStatus cstat; + + if (!helper.isChannelConnected(handleSet) + || !helper.isChannelConnected(handleMatch)) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "NOT ALL CHANNELS CONNECTED: " << std::endl; + if (!helper.isChannelConnected(handleSet)) + { + helper.printHandle(handleSet); + return helper.getStatus(handleSet); + } + if (!helper.isChannelConnected(handleMatch)) + { + helper.printHandle(handleMatch); + return helper.getStatus(handleMatch); + } + } + + if (printFlag) + { + + if (dbrType==DBR_CHAR) + { + std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet) << " to " << (unsigned short) valSet << std::endl; + } + else + { + std::cout << "SETTING PV=" << helper.getPVFromHandle(handleSet) << " to " << valSet << std::endl; + } + std::cout << "READBACK PV=" << helper.getPVFromHandle(handleMatch) + << " tolerance= " << fabs((double)tolerance) << std::endl; + std::cout << "TIME ALLOWED FOR MATCH " << timeout << " (sec) " << std::endl; + } + + std::vector mpVMatch; + helper.getMonitorPolicyVector(handleMatch, mpVMatch); + + unsigned short nMonitors=mpVMatch.size(); + + + CTYPE valSetUpper; + CTYPE valSetLower; + + + switch (dbrType) + { + case DBR_LONG : + case DBR_SHORT : + case DBR_ENUM: + valSetUpper = valSet + abs((int)tolerance); + valSetLower = valSet - abs((int)tolerance); + break; + case DBR_CHAR : + valSetUpper = (unsigned short) valSet + abs((unsigned short) tolerance); + valSetLower = (unsigned short) valSet - abs((unsigned short) tolerance); + break; + case DBR_FLOAT: + case DBR_DOUBLE: + default: + valSetUpper = (CTYPE) (valSet + fabs((double)tolerance)); + valSetLower = (CTYPE) (valSet - fabs((double)tolerance)); + break; + } + + + CTYPE valGetA[1]= {0}; + CTYPE valGet=valGetA[0]; + + int statMonitor=ICAFE_NORMAL; + + unsigned int monitorIDis=0; + + //what is monitorpolicy?? + if (nMonitors==0) + { + + unsigned int _nelemPrevious, _nelemRequestedCheck=0; + unsigned int _nelemRequested=1; + _nelemPrevious=helper.getNelemClient(handleMatch); + //Check the number of elements requested? + if (_nelemPrevious>1) + { + _nelemRequestedCheck = helper.setNelem(handleMatch,_nelemRequested); ////change handleSet to handleMatch 23/3/17 + if (_nelemRequestedCheck != _nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << _nelemPrevious << std::endl; + std::cout << "to: " << _nelemRequested << " but got instead: " + << _nelemRequestedCheck << std::endl; + } + } + + //first do get to update cache before monitor starts + status=Instant::get(handleMatch, dbrType, valGetA); + //valGet=valGetA[0]; + + + if (_nelemPrevious>1) + { + helper.setNelem(handleMatch,_nelemPrevious); ////change handleSet to handleMatch 23/3/17 + } + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + ChannelWhenToFlushSendBufferPolicyKind whenKind= + connect.channelMonitorPolicy.getWhenToFlushSendBuffer(); + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + statMonitor=connect.monitorStart(handleMatch, monitorIDis); + + if (statMonitor!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(statMonitor); + } + else + { + if(printFlag) + { + std::cout << "MONITOR STARTED WITH ID=" << monitorIDis<< std::endl; + } + } + //revert to previous + if (whenKind != FLUSH_AUTOMATIC) + { + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(whenKind); + } + } + + CTYPE valSetA[1]; + valSetA[0]=valSet; + + //set No of Elements to 1 + + unsigned int nelemPrevious, nelemRequestedCheck=0; + unsigned int nelemRequested=1; + nelemPrevious=helper.getNelemClient(handleSet); + //Check the number of elements requested? + if (nelemPrevious>1) + { + nelemRequestedCheck = helper.setNelem(handleSet,nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + //policy set synchronous + ChannelRequestPolicy polPrevious, polNow; + + policyHelper.getChannelRequestPolicyPut(handleSet, polPrevious); + + polNow.setMethodKind(WITHOUT_CALLBACK); + polNow.setWaitKind(WAIT); + polNow.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + policyHelper.setChannelRequestPolicyPut(handleSet, polNow); + + status=set(handleSet, dbrType, valSetA); + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + policyHelper.setChannelRequestPolicyPut(handleSet, polPrevious); + + unsigned int nelemPreviousCheck=nelemPrevious; + nelemRequested=1; + //Switch back to previous value + //if (nelemPrevious>1) { + if(helper.getNelemRequest(handleSet)!= nelemPrevious) + { + nelemPreviousCheck= helper.setNelem(handleSet,nelemPrevious); + if (nelemPreviousCheck != nelemPrevious) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPrevious << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + //start time + + double timeElapsed=0; + double timeElapsed2=0; + double timeElapsedBase=0; + using namespace boost::posix_time; + + ptime timeStart(microsec_clock::local_time()); + + // PVDataHolder pvdMatch; + // status=getCache(handleMatch, dbrType, pvdMatch); + + + //No of elements to get from Cache + + nelemPreviousCheck=0; + nelemRequested=1; + nelemRequestedCheck=0; + nelemPrevious=helper.getNelemRequest(handleMatch); + + + + //Check the number of elements requested + if (nelemPrevious>0) + { + nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch,nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + + + + + status=Instant::getCache(handleMatch, dbrType, valGetA); + + + + + ///if (dbrType==DBR_CHAR) {valGet = (unsigned short) valGetA[0];} + + + + if (status !=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + + + + if(printFlag) + { + //std::cout << __METHOD__ << std::endl; + std::cout << "Current Cached Value = " ; + if (dbrType==DBR_CHAR) + { + std::cout << (unsigned short) valGetA[0] << std::endl; + std::cout << "Lower/Upper Target Values = " << (unsigned short) valSetLower << " and " << (unsigned short) valSetUpper << std::endl; + } + else + { + std::cout << valGetA[0] << std::endl; + std::cout << "Lower/Upper Target Values = " << valSetLower << " and " << valSetUpper << std::endl; + } + } + + + + ptime timeEnd(microsec_clock::local_time()); + time_duration duration(timeEnd-timeStart); + timeElapsed= (double) duration.total_microseconds()/1000000.0; + + + + if (dbrType==DBR_CHAR) + { + valGet= (unsigned short) valGetA[0]; + } + + else + { + valGet=valGetA[0]; + } + + + + while ( (valGet>valSetUpper || valGetvalSetUpper || pvdMatch.getAsDouble()1) { + nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch,nelemRequested); + if (nelemRequestedCheck != nelemRequested) { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + */ + + status=Instant::getCache(handleMatch, dbrType, valGetA); + + valGet=valGetA[0]; + + if (dbrType==DBR_CHAR) + { + valGet = (unsigned short) valGetA[0]; + } + //std::cout << "getCache(handleMatch, dbrType, valGetA) = " << valGet << std::endl; + //std::cout << valSetUpper << " U/L " << valSetLower << std::endl; + + ptime timeEnd(microsec_clock::local_time()); + time_duration duration(timeEnd-timeStart); + timeElapsed= (double) duration.total_microseconds()/1000000.0; + + timeElapsed2=timeElapsed-timeElapsedBase; + + if (printFlag && timeElapsed2>1 && status==ICAFE_NORMAL) + { + + if (dbrType==DBR_CHAR) + { + std::cout << "SET VALUE " << (unsigned short) valSet << " CURRENT VALUE " << (unsigned short) valGetA[0] + << " TimeElapsed " << timeElapsed << " (sec) " << std::endl; + } + else + { + std::cout << "SET VALUE " << valSet << " CURRENT VALUE " << valGetA[0] //pvdMatch.getAsDouble() + << " TimeElapsed " << timeElapsed << " (sec) " << std::endl; + } + + + timeElapsedBase=timeElapsed; + + } + + +#if HAVE_BOOST_THREAD + boost::this_thread::sleep_for(boost::chrono::microseconds(20)); +#else +#if HAVE_LINUX + usleep(20); +#endif +#endif + } + + + if (timeout <=timeElapsed ) + { + std::cout << "*****TIMEOUT REACHED****** AFTER " << timeout << " (sec) " << std::endl; + + status=ECAFE_TIMEOUT_SET_AND_MATCH; + } + else + { + if (printFlag) + { + status=Instant::getCache(handleMatch, dbrType, valGetA); + if (dbrType==DBR_CHAR) + { + std::cout << "GAME SET AND MATCH: SET VALUE= " << (unsigned short) valSet + << " LAST VALUE READ= " << (unsigned short) valGetA[0] //pvdMatch.getAsDouble() + << " TimeElapsed " << timeElapsed << " (sec) " << std::endl; + } + else + { + std::cout << "GAME SET AND MATCH: SET VALUE= " << valSet << " LAST VALUE READ= " << valGetA[0] //pvdMatch.getAsDouble() + << " TimeElapsed " << timeElapsed << " (sec) " << std::endl; + } + + } + } + + + + + if (nelemPrevious>1) + { + nelemPreviousCheck= helper.setNelemToRetrieveFromCache(handleMatch,nelemPrevious); + if (nelemPreviousCheck != nelemPrevious) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPrevious << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + + + if (nMonitors==0 && statMonitor==ICAFE_NORMAL) + { + if (monitorIDis !=0 ) + { + std::cout << "STOPPED MONITOR WITH ID =" << monitorIDis << std::endl; + int statm; + statm=connect.monitorStop(handleMatch, monitorIDis); + + if (status==ICAFE_NORMAL) + { + status=statm; + } + } + } + + return status; +#undef __METHOD__ +} + + +/** + * \brief Set Channel followed by a corresponding readback of Channel \n + * Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n + * Method returns with ECA_NORMAL as soon as a match is reached + * \param dbrType input: chtype of set value + * \param valSet input: CTYPE value to set + * \param handleMatch input: handle of readback channel + * \param tolerance input: CTYPE of tolerance margin + * \param timeout input: double value; maximum time allowed for agreement to occur + * \param printFlag input: bool, set to true for diagnostics + * \return ECA_NORMAL if all OK else first ECAFE error encountered + */ +template int Instant::match(const chtype dbrType, CTYPE valSet, unsigned int handleMatch, + CTYPE tolerance, double timeout, bool printFlag) +{ +#define __METHOD__ "Instant::match(const chtype dbrType, CTYPE valSet, unsigned int handleMatch, \ + CTYPE tolerance,double timeout, bool printFlag)" + + std::vector valSetV; + std::vectorhandleMatchV; + valSetV.reserve(1); + handleMatchV.reserve(1); + valSetV.push_back(valSet); + handleMatchV.push_back(handleMatch); + + return matchMany(dbrType, valSetV, handleMatchV, tolerance, timeout, printFlag); +#undef __METHOD__ +} + + +/** + * \brief Set Channels followed by a corresponding readback of Channels \n + * Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n + * Method returns with ECA_NORMAL as soon as a match is reached + * \param dbrType input: chtype of set value + * \param valSet input: vector of CTYPE values to set + * \param handleMatch input: vector of handles of readback channel + * \param tolerance input: CTYPE of tolerance margin + * \param timeout input: double value; maximum time allowed for agreement to occur + * \param printFlag input: bool, set to true for diagnostics + * \return ECA_NORMAL if all OK else first ECAFE error encountered + */ +template int Instant::matchMany(const chtype dbrType, std::vector valSet, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag) +{ +#define __METHOD__ "Instant::matchMany(const chtype dbrType, std::vectorvalSet, std::vectorhandleMatch, \ + CTYPE tolerance, double timeout, bool printFlag)" + + + Connect connect; + CAFEStatus cstat; + + CTYPE valGetA[1]; + ////CTYPE valSetA[1]; + + status=ICAFE_NORMAL; + + + if (handleMatch.size() != valSet.size() ) + { + return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH; + } + + for (size_t i=0; i< handleMatch.size(); ++i) + { + if ( !helper.isChannelConnected(handleMatch[i])) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "NOT ALL CHANNELS CONNECTED: " << std::endl; + + helper.printHandle(handleMatch[i]); + status=helper.getStatus(handleMatch[i]); + } + } + + + if (status!=ICAFE_NORMAL) + { + return status; + } + + + for (size_t i=0; i< handleMatch.size(); ++i) + { + if (printFlag) + { + std::cout << "SET VALUE IS = " << valSet[i] << std::endl; + std::cout << "READBACK PV=" << helper.getPVFromHandle(handleMatch[i]) + << " tolerance= " << fabs((double)tolerance) << std::endl; + std::cout << "TIME ALLOWED FOR MATCH IS " << timeout << " (sec) " << std::endl; + } + } + + + std::vector valSetUpper; + std::vector valSetLower; + + std::vector monitorID; + std::vector statMonitor; + std::vector nMonitors; + std::vector valGet; + + std::vector nelemPreviousCache; + + valSetUpper.reserve( handleMatch.size()); + valSetLower.reserve( handleMatch.size()); + monitorID.reserve( handleMatch.size()); + statMonitor.reserve( handleMatch.size()); + valGet.reserve( handleMatch.size()); + nMonitors.reserve( handleMatch.size() ); + + nelemPreviousCache.reserve(handleMatch.size()); + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + switch (dbrType) + { + case DBR_LONG : + case DBR_SHORT : + case DBR_ENUM: + valSetUpper[i] = valSet[i] + abs((int)tolerance); + valSetLower[i] = valSet[i] - abs((int)tolerance); + break; + case DBR_CHAR : + valSetUpper[i] = (unsigned short) valSet[i] + abs((unsigned short) tolerance); + valSetLower[i] = (unsigned short) valSet[i] - abs((unsigned short) tolerance); + break; + case DBR_FLOAT: + case DBR_DOUBLE: + default: + + valSetUpper[i] = (CTYPE) (valSet[i] + fabs((double)tolerance)); + valSetLower[i] = (CTYPE) (valSet[i] - fabs((double)tolerance)); + + break; + } + + + std::vector mpVMatch; + mpVMatch.clear(); + + helper.getMonitorPolicyVector(handleMatch[i], mpVMatch); + + nMonitors[i]=mpVMatch.size(); + + monitorID[i]=0; + + ////valGetA[0][i]=0; + valGet[i]=0; + + statMonitor[i]=ICAFE_NORMAL; + + } + + + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + //what is monitorpolicy?? + if (nMonitors[i]==0) + { + + unsigned int _nelemPrevious, _nelemRequestedCheck=0; + unsigned int _nelemRequested=1; + _nelemPrevious=helper.getNelemClient(handleMatch[i]); + //Check the number of elements requested? + if (_nelemPrevious>1) + { + _nelemRequestedCheck = helper.setNelem(handleMatch[i],_nelemRequested); + if (_nelemRequestedCheck != _nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << _nelemPrevious << std::endl; + std::cout << "to: " << _nelemRequested << " but got instead: " + << _nelemRequestedCheck << std::endl; + } + } + + //first do get to update cache before monitor starts + status=Instant::get(handleMatch[i], dbrType, valGetA); + + valGet[i]=valGetA[0]; + + if (_nelemPrevious>1) + { + helper.setNelem(handleMatch[i],_nelemPrevious); + } + + + if (status!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + ChannelWhenToFlushSendBufferPolicyKind whenKind= + connect.channelMonitorPolicy.getWhenToFlushSendBuffer(); + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC); + + statMonitor[i]=connect.monitorStart(handleMatch[i], monitorID[i]); + + if (statMonitor[i]!=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(statMonitor[i]); + } + else + { + if(printFlag) + { + std::cout << "MONITOR STARTED WITH ID=" << monitorID[i] << std::endl; + } + } + //revert to previous + if (whenKind != FLUSH_AUTOMATIC) + { + connect.channelMonitorPolicy.setWhenToFlushSendBuffer(whenKind); + } + + } //if nMonitors + + ////valSetA[0][i]=valSet[i]; + + //set No of Elements to 1 + + unsigned int nelemPrevious, nelemRequestedCheck=0; + unsigned int nelemRequested=1; + + + nelemPrevious=helper.getNelemClient(handleMatch[i]); + //Check the number of elements requested? + if (nelemPrevious>1) + { + nelemRequestedCheck = helper.setNelem(handleMatch[i],nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPrevious << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + //No of elements to get from Cache + + ////unsigned int nelemPreviousCheck=0; + nelemRequested=1; + nelemRequestedCheck=0; + nelemPreviousCache[i]=helper.getNelemRequest(handleMatch[i]); + + //Check the number of elements requested + //See set and Match; this needs to be checked + //Avoid problem when readback channel is the very same as the set(!) + if (nelemPreviousCache[i]>0 && helper.getNelemNative(handleMatch[i])>1) + { + nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch[i],nelemRequested); + if (nelemRequestedCheck != nelemRequested) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " + << nelemPreviousCache[i] << std::endl; + std::cout << "to: " << nelemRequested << " but got instead: " + << nelemRequestedCheck << std::endl; + } + } + + } //if size_t + + //start time + + double timeElapsed=0; + double timeElapsed2=0; + double timeElapsedBase=0; + using namespace boost::posix_time; + + ptime timeStart(microsec_clock::local_time()); + + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + valGetA[0]=0; + + status=Instant::getCache(handleMatch[i], dbrType, valGetA); + + valGet[i]=valGetA[0]; + + if (status !=ICAFE_NORMAL) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + cstat.report(status); + } + + ///valGet[i]=valGetA[0][i]; + if (dbrType==DBR_CHAR) + { + valGet[i] = (unsigned short) valGet[i]; + } + + if(printFlag) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Current Cached Value = " << valGet[i] << std::endl; + std::cout << "Lower/Upper Target Values = " << valSetLower[i] << " and " << valSetUpper[i] << std::endl; + } + + } //for size_t + + + + ptime timeEnd(microsec_clock::local_time()); + time_duration duration(timeEnd-timeStart); + timeElapsed= (double) duration.total_microseconds()/1000000.0; + + + for (size_t i=0; i< handleMatch.size(); ++i) + { + + + while ( (valGet[i]>valSetUpper[i] || valGet[i]1 && status==ICAFE_NORMAL) + { + + for (size_t ij=0; ij< handleMatch.size(); ++ij) + { + status=Instant::getCache(handleMatch[ij], dbrType, valGetA); + valGet[ij]=valGetA[0]; + if (valGet[ij]>valSetUpper[ij] || valGet[ij]1) + { + nelemPreviousCheck= helper.setNelemToRetrieveFromCache(handleMatch[i],nelemPreviousCache[i]); + if (nelemPreviousCheck != nelemPreviousCache[i]) + { + std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl; + std::cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " + << nelemRequested << std::endl; + std::cout << "to the previous: " << nelemPreviousCache[i] << " but got instead: " + << nelemPreviousCheck << std::endl; + } + } + + + + if (nMonitors[i]==0 && statMonitor[i]==ICAFE_NORMAL) + { + std::cout << "STOPPING MONITOR WITH ID =" << monitorID[i] << std::endl; + int statm; + statm=connect.monitorStop(handleMatch[i], monitorID[i]); + if(status==ICAFE_NORMAL) + { + status=statm; + } + } + + } //for + + + return status; +#undef __METHOD__ +} + + + + + + +#endif // INSTANT_H + diff --git a/include/instantT.h b/include/instantT.h new file mode 100644 index 0000000..4f96e32 --- /dev/null +++ b/include/instantT.h @@ -0,0 +1,61 @@ +/// +/// \file instantT.h +/// \author Jan Chrin, PSI +/// \date Release: July 2021 +/// \version CAFE 1.14.2 +/// + + +#ifndef INSTANT_T_H +#define INSTANT_T_H + +#include + +template int Instant::set(const unsigned int _handle, + const chtype _dbrType, const CTYPE * _val ); + +template int Instant::get(const unsigned int _handle, + const chtype _dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts); + +template int Instant::getCache(const unsigned int _handle, +const chtype _dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts); + +template int Instant::getCache(const unsigned int *handleArray, const unsigned int nelem, +const chtype _dbrType, CTYPE * val, int *statusArray, + dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity, epicsTimeStamp *ts); + +template int Instant::set(const unsigned int *handleArray, const unsigned int nelem, + onst chtype _dbrType, const CTYPE * val, int *statusArray); + +template int Instant::clientRequests( + const unsigned int _handle, + const chtype _dbrType, CTYPE * _val, + dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, bool isCacheRequest); + + +template int Instant::clientRequests( + const unsigned int _handle, const chtype _dbrType, const CTYPE * _val); + + +template int Instant::setAndGet(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, CTYPE &valGet); +template int Instant::setMany(std::vector handleSet, const chtype dbrType, std::vector valSet, bool printFlag); +template int Instant::compareAndMatchMany(std::vector handleSet, const chtype dbrType, std::vector valSet, std::vector handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + +//template int Instant::setTriggerAndMatchMany(std::vector handleSet, chtype dbrType, std::vector valSet, +template int Instant::setAndMatchMany(std::vector handleSet, chtype dbrType, std::vector valSet, std::vector handleMatch, +CTYPE tolerance, double timeout, bool printFlag); + +template int Instant::setAndMatch(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, const unsigned int handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + +template int Instant::match(const chtype dbrType, CTYPE valSet, unsigned int handleMatch, + CTYPE tolerance, double timeout, bool printFlag); + + +template int Instant::matchMany(const chtype dbrType, std::vector valSet, std::vector handleMatch, CTYPE tolerance, double timeout, bool printFlag); + + +#endif diff --git a/include/makefile b/include/makefile index 1f6ec55..40a9f49 100644 --- a/include/makefile +++ b/include/makefile @@ -188,9 +188,9 @@ CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing aclocal-1.13 AMTAR = $${TAR-tar} -AM_CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml +AM_CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base-7/include/ -I/usr/local/epics/base-7/include/os/Linux -I/usr/local/epics/base-7/include/compiler/gcc -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml AM_DEFAULT_VERBOSITY = 1 -AM_LDFLAGS = -L/usr/local/epics/base/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib +AM_LDFLAGS = -L/usr/local/epics/base-7/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base-7/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib AR = ar AUTOCONF = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing autoconf AUTOHEADER = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing autoheader @@ -201,7 +201,7 @@ CC = /opt/psi/Programming/gcc/7.3.0/bin/gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CPP = /opt/psi/Programming/gcc/7.3.0/bin/gcc -E -CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml +CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base-7/include/ -I/usr/local/epics/base-7/include/os/Linux -I/usr/local/epics/base-7/include/compiler/gcc -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml CXX = /opt/psi/Programming/gcc/7.3.0/bin/g++ CXXCPP = /opt/psi/Programming/gcc/7.3.0/bin/g++ -E CXXDEPMODE = depmode=gcc3 @@ -225,7 +225,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s LD = /usr/bin/ld -m elf_x86_64 -LDFLAGS = -L/usr/local/epics/base/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib +LDFLAGS = -L/usr/local/epics/base-7/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base-7/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib LIBOBJS = LIBS = -lQt5Xml -lQt5Core LIBTOOL = $(SHELL) $(top_builddir)/libtool @@ -245,17 +245,17 @@ OTOOL64 = PACKAGE = cafe PACKAGE_BUGREPORT = Bug reports to: jan.chrin@psi.ch PACKAGE_NAME = CAFE -PACKAGE_STRING = CAFE 1.14.1 +PACKAGE_STRING = CAFE 1.14.2 PACKAGE_TARNAME = cafe PACKAGE_URL = -PACKAGE_VERSION = 1.14.1 +PACKAGE_VERSION = 1.14.2 PATH_SEPARATOR = : RANLIB = ranlib SED = /usr/bin/sed SET_MAKE = SHELL = /bin/sh STRIP = strip -VERSION = 1.14.1 +VERSION = 1.14.2 abs_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/include abs_srcdir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/include abs_top_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp @@ -290,7 +290,7 @@ htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh -libdir = /opt/gfa/cafe/cpp/cafe-1.14.1-gcc-7.3.0/lib/RHEL7-x86_64 +libdir = /opt/gfa/cafe/cpp/cafe-1.14.2-sls2-gcc-7.3.0/lib/RHEL7-x86_64 libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var @@ -298,7 +298,7 @@ mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} -prefix = /opt/gfa/cafe/cpp/cafe-1.14.1-gcc-7.3.0 +prefix = /opt/gfa/cafe/cpp/cafe-1.14.2-sls2-gcc-7.3.0 program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin diff --git a/include/transpose.h b/include/transpose.h index 3ba1a57..e185c08 100644 --- a/include/transpose.h +++ b/include/transpose.h @@ -28,7 +28,7 @@ template class Transpose { public: - Transpose () {}; + Transpose () {useHandleHelper = true;}; ~Transpose () {}; HandleHelper handleHelper; @@ -109,6 +109,8 @@ private: chtype _dataTypeClient; char stig [MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]; + bool useHandleHelper; //instantiating global extern cs for use in pybind11 + }; @@ -269,8 +271,15 @@ template int Transpose::put(const unsigned int _handle, cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; + + + if (useHandleHelper) { + it_handle = handleHelper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } - it_handle = handle_index.find(_handle); if (it_handle != handle_index.end()) { @@ -711,7 +720,7 @@ template int Transpose::put(const unsigned int _handle, //long Transpose::put( const unsigned int _handle, // CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt) -template int Transpose::put( const unsigned int _handle, +template int Transpose::put( const unsigned int _handle, CAFE_DATATYPE_UNION_SEQ val, CAFE_DATATYPE cdt) { #define __METHOD__ "Transpose::put()" @@ -720,7 +729,13 @@ template int Transpose::put( const unsigned int _handle, cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; - it_handle = handle_index.find(_handle); + + if (useHandleHelper) { + it_handle = handleHelper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } if (it_handle != handle_index.end()) { @@ -987,7 +1002,14 @@ template int Transpose::putString cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; - it_handle = handle_index.find(_handle); + + + if (useHandleHelper) { + it_handle = handleHelper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } if (it_handle != handle_index.end()) { @@ -1264,7 +1286,7 @@ template int Transpose::putString /** * \brief Retrieves data transmitted by CA with dbrTypeRequest_DataBuffer - * and then converts to CTYPE i.e. _dataTypeClient + * and then converts to CTYPE i.e. _dataTypeClient * \param _handle input: handle to Conduit object * \param val output: CTYPE datatype * \param alarmStatus output: dbr_short_t @@ -1281,7 +1303,19 @@ template int Transpose::get( cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; - it_handle = handle_index.find(_handle); + + + //pybind11 fix + //cafeConduit_set_by_handle & handle_index = helper.getcsHandleIndex(); + + + if (useHandleHelper) { + it_handle = handleHelper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } + //std::cout << __FILE__ << "//" << __METHOD__ << std::endl; @@ -1840,7 +1874,14 @@ template int Transpose::getCtrl ( cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; - it_handle = handle_index.find(_handle); + + + if (useHandleHelper) { + it_handle = handleHelper.getIterFromHandle(_handle); + } + else { + it_handle = handle_index.find(_handle); + } if (it_handle != handle_index.end()) { diff --git a/libtool b/libtool index 9e883f0..1d3a83b 100755 --- a/libtool +++ b/libtool @@ -1,5 +1,5 @@ #! /bin/sh -# Generated automatically by config.status (cafe) 1.14.1 +# Generated automatically by config.status (cafe) 1.14.2 # Libtool was configured on host sf-lc7a.psi.ch: # NOTE: Changes made to this file will be lost: look at ltmain.sh. @@ -285,7 +285,7 @@ hardcode_into_libs=yes sys_lib_search_path_spec="/afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/7.3.0/lib/gcc/x86_64-pc-linux-gnu/7.3.0 /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/7.3.0/lib/gcc /opt/psi/Programming/gcc/7.3.0/lib64 /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/7.3.0/lib64 /lib64 /usr/lib64 /opt/psi/Programming/gcc/7.3.0/lib /afs/psi.ch/sys/psi.x86_64_slp6/Programming/gcc/7.3.0/lib /lib /usr/lib " # Detected run-time system search path for libraries. -sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib64/atlas /usr/lib64//bind9-export/ /usr/lib64/dyninst /usr/lib64/mysql /usr/lib64/tcl8.5/tclx8.4 " +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib64/atlas /usr/lib64//bind9-export/ /usr/lib64/dyninst /usr/lib64/mysql /usr/lib/oracle/12.2/client64/lib /usr/lib64/tcl8.5/tclx8.4 " # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path="" diff --git a/makefile b/makefile index 651e73d..8d2898a 100644 --- a/makefile +++ b/makefile @@ -232,9 +232,9 @@ am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ distcleancheck_listfiles = find . -type f -print ACLOCAL = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing aclocal-1.13 AMTAR = $${TAR-tar} -AM_CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml -I$(top_srcdir)/include +AM_CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base-7/include/ -I/usr/local/epics/base-7/include/os/Linux -I/usr/local/epics/base-7/include/compiler/gcc -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml -I$(top_srcdir)/include AM_DEFAULT_VERBOSITY = 1 -AM_LDFLAGS = -L/usr/local/epics/base/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib @CAFE_LIBS@ +AM_LDFLAGS = -L/usr/local/epics/base-7/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base-7/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib @CAFE_LIBS@ AR = ar AUTOCONF = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing autoconf AUTOHEADER = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing autoheader @@ -245,7 +245,7 @@ CC = /opt/psi/Programming/gcc/7.3.0/bin/gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CPP = /opt/psi/Programming/gcc/7.3.0/bin/gcc -E -CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml +CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base-7/include/ -I/usr/local/epics/base-7/include/os/Linux -I/usr/local/epics/base-7/include/compiler/gcc -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml CXX = /opt/psi/Programming/gcc/7.3.0/bin/g++ CXXCPP = /opt/psi/Programming/gcc/7.3.0/bin/g++ -E CXXDEPMODE = depmode=gcc3 @@ -269,7 +269,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s LD = /usr/bin/ld -m elf_x86_64 -LDFLAGS = -L/usr/local/epics/base/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib +LDFLAGS = -L/usr/local/epics/base-7/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base-7/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib LIBOBJS = LIBS = -lQt5Xml -lQt5Core LIBTOOL = $(SHELL) $(top_builddir)/libtool @@ -289,17 +289,17 @@ OTOOL64 = PACKAGE = cafe PACKAGE_BUGREPORT = Bug reports to: jan.chrin@psi.ch PACKAGE_NAME = CAFE -PACKAGE_STRING = CAFE 1.14.1 +PACKAGE_STRING = CAFE 1.14.2 PACKAGE_TARNAME = cafe PACKAGE_URL = -PACKAGE_VERSION = 1.14.1 +PACKAGE_VERSION = 1.14.2 PATH_SEPARATOR = : RANLIB = ranlib SED = /usr/bin/sed SET_MAKE = SHELL = /bin/sh STRIP = strip -VERSION = 1.14.1 +VERSION = 1.14.2 abs_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp abs_srcdir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp abs_top_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp @@ -334,7 +334,7 @@ htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh -libdir = /opt/gfa/cafe/cpp/cafe-1.14.1-gcc-7.3.0/lib/RHEL7-x86_64 +libdir = /opt/gfa/cafe/cpp/cafe-1.14.2-sls2-gcc-7.3.0/lib/RHEL7-x86_64 libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var @@ -342,7 +342,7 @@ mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} -prefix = /opt/gfa/cafe/cpp/cafe-1.14.1-gcc-7.3.0 +prefix = /opt/gfa/cafe/cpp/cafe-1.14.2-sls2-gcc-7.3.0 program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin diff --git a/src/handleHelper.cpp b/src/handleHelper.cpp index 105f347..30ef2bf 100644 --- a/src/handleHelper.cpp +++ b/src/handleHelper.cpp @@ -1657,6 +1657,123 @@ const char * HandleHelper::getPVAlias(unsigned int handle, ca_client_context * c #undef __METHOD__ } +cafeConduit_set_by_handle::iterator HandleHelper::getIterFromHandle(unsigned int handle) +{ +#define __METHOD__ "HandleHelper::getIterFromHandle(unsigned int handle)" + + cafeConduit_set_by_handle & handle_index=cs.get(); + cafeConduit_set_by_handle::iterator it_handle; + it_handle = handle_index.find(handle); + if (it_handle != handle_index.end()) { + //std::cout << __METHOD__ << " pv " << (*it_handle).getPV() << " // " << (*it_handle).handle << std::endl; + return it_handle; + } + else {return it_handle;} + +#undef __METHOD__ +} + + +cafeConduit_set_by_handle & HandleHelper::getcsHandleIndex() +{ +#define __METHOD__ "HandleHelper::getcsHandleIndex()" + + return cs.get(); + +#undef __METHOD__ +} + + +int HandleHelper::modifyHandleIndexStatus(unsigned int handle, long status) +{ +#define __METHOD__ "HandleHelper::modifyHandleIndexStatus()" + + cafeConduit_set_by_handle & handle_index=cs.get(); + cafeConduit_set_by_handle::iterator it_handle; + it_handle = handle_index.find(handle); + if (it_handle != handle_index.end()) { + handle_index.modify(it_handle, change_status(status)); + } + else + { + std::cout << "Handle=" << handle << " either never existed or no longer exists " << std::endl; + return ECAFE_INVALID_HANDLE; + } + return ICAFE_NORMAL; + +#undef __METHOD__ +} + + +int HandleHelper::modifyChannelTimeoutPolicyGet(unsigned int handle, + ChannelTimeoutPolicy channelTimeoutPolicyGet) +{ +#define __METHOD__ "HandleHelper::modifyChannelTimeoutPolicyGet()" + + cafeConduit_set_by_handle & handle_index=cs.get(); + cafeConduit_set_by_handle::iterator it_handle; + it_handle = handle_index.find(handle); + if (it_handle != handle_index.end()) { + handle_index.modify(it_handle, + change_channelTimeoutPolicyGet(channelTimeoutPolicyGet)); + } + else + { + std::cout << "Handle=" << handle << " either never existed or no longer exists " << std::endl; + return ECAFE_INVALID_HANDLE; + } + return ICAFE_NORMAL; + +#undef __METHOD__ +} + + +int HandleHelper::modifyChannelRequestStatusGet(unsigned int handle, + ChannelRequestStatus channelRequestStatusGet) +{ +#define __METHOD__ "HandleHelper::modifyChannelRequestStatusGet()" + + cafeConduit_set_by_handle & handle_index=cs.get(); + cafeConduit_set_by_handle::iterator it_handle; + it_handle = handle_index.find(handle); + if (it_handle != handle_index.end()) { + handle_index.modify(it_handle, + change_channelRequestStatusGet(channelRequestStatusGet)); + } + else + { + std::cout << "Handle=" << handle << " either never existed or no longer exists " << std::endl; + return ECAFE_INVALID_HANDLE; + } + return ICAFE_NORMAL; + +#undef __METHOD__ +} + + +int HandleHelper::modifyChannelRequestMetaDataClient(unsigned int handle, + ChannelRequestMetaDataClient channelRequestMetaDataClient) +{ +#define __METHOD__ "HandleHelper::modifyChannelRequestMetaDataClient()" + + cafeConduit_set_by_handle & handle_index=cs.get(); + cafeConduit_set_by_handle::iterator it_handle; + it_handle = handle_index.find(handle); + if (it_handle != handle_index.end()) { + handle_index.modify(it_handle, + change_channelRequestMetaDataClient(channelRequestMetaDataClient)); + } + else + { + std::cout << "Handle=" << handle << " either never existed or no longer exists " << std::endl; + return ECAFE_INVALID_HANDLE; + } + return ICAFE_NORMAL; + +#undef __METHOD__ +} + + /** * \brief Retrieves the process variable from a given handle @@ -1689,9 +1806,14 @@ const char * HandleHelper::getPVFromHandle(unsigned int handle, ca_client_contex cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); + //std::cout << __METHOD__ << "handle_index ==> " << &handle_index << std::endl; + //std::cout << __METHOD__ << "handle_index ==> " << &handle_index << std::endl; + //std::cout << __METHOD__ << "cs " << &cs << std::endl; if (it_handle != handle_index.end()) { + //std::cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << std::endl; + //std::cout << "Client context: " << ccc << std::endl; return (*it_handle).getPV(); } else @@ -1706,9 +1828,9 @@ const char * HandleHelper::getPVFromHandle(unsigned int handle, ca_client_contex if ( (*itcs).getHandle()==handle && (*itcs).getClientContext() == ccc) { - //cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl; - //cout << " INFORMATION to author: MATCHed Handle= " << handle << " to PV= " << (*itcs).getPV() << endl; - //cout << " by looping through tcs::iterator, while the by_handle::iterator was NOT found! " << endl; + cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl; + cout << " INFORMATION to author: MATCHed Handle= " << handle << " to PV= " << (*itcs).getPV() << endl; + cout << " by looping through tcs::iterator, while the by_handle::iterator was NOT found! " << endl; return (*itcs).getPV(); } } @@ -2491,7 +2613,6 @@ int HandleHelper::getAlarmStatusSeverityAsString(unsigned int _handle, std::stri - /** * \brief Rerieves vector of handles for given vector of PVs * \param pvV input: vector of PVS diff --git a/src/makefile b/src/makefile index 5b84d82..e17631c 100644 --- a/src/makefile +++ b/src/makefile @@ -249,9 +249,9 @@ AMTAR = $${TAR-tar} #if HAVE_PYTHON_ #libcafe_la_SOURCES += pycafe/PyCafe.cpp #endif -AM_CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml -I$(top_srcdir)/include +AM_CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base-7/include/ -I/usr/local/epics/base-7/include/os/Linux -I/usr/local/epics/base-7/include/compiler/gcc -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml -I$(top_srcdir)/include AM_DEFAULT_VERBOSITY = 1 -AM_LDFLAGS = -L/usr/local/epics/base/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib +AM_LDFLAGS = -L/usr/local/epics/base-7/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base-7/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib AR = ar AUTOCONF = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing autoconf AUTOHEADER = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/missing autoheader @@ -262,7 +262,7 @@ CC = /opt/psi/Programming/gcc/7.3.0/bin/gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 CPP = /opt/psi/Programming/gcc/7.3.0/bin/gcc -E -CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base/include/ -I/usr/local/epics/base/include/os/Linux -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml +CPPFLAGS = -fexceptions -fPIC -std=c++1z -I/usr/local/epics/base-7/include/ -I/usr/local/epics/base-7/include/os/Linux -I/usr/local/epics/base-7/include/compiler/gcc -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/python-3.7/latest/include/qt -I/opt/gfa/python-3.7/latest/include/qt/QtCore -I/opt/gfa/python-3.7/latest/include/qt/QtXml CXX = /opt/psi/Programming/gcc/7.3.0/bin/g++ CXXCPP = /opt/psi/Programming/gcc/7.3.0/bin/g++ -E CXXDEPMODE = depmode=gcc3 @@ -286,7 +286,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s LD = /usr/bin/ld -m elf_x86_64 -LDFLAGS = -L/usr/local/epics/base/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib +LDFLAGS = -L/usr/local/epics/base-7/lib/RHEL7-x86_64 -Wl,-rpath,/usr/local/epics/base-7/lib/RHEL7-x86_64 -L/opt/gfa/python-3.7/latest/lib -Wl,-rpath,/opt/gfa/python-3.7/latest/lib LIBOBJS = LIBS = -lQt5Xml -lQt5Core LIBTOOL = $(SHELL) $(top_builddir)/libtool @@ -306,17 +306,17 @@ OTOOL64 = PACKAGE = cafe PACKAGE_BUGREPORT = Bug reports to: jan.chrin@psi.ch PACKAGE_NAME = CAFE -PACKAGE_STRING = CAFE 1.14.1 +PACKAGE_STRING = CAFE 1.14.2 PACKAGE_TARNAME = cafe PACKAGE_URL = -PACKAGE_VERSION = 1.14.1 +PACKAGE_VERSION = 1.14.2 PATH_SEPARATOR = : RANLIB = ranlib SED = /usr/bin/sed SET_MAKE = SHELL = /bin/sh STRIP = strip -VERSION = 1.14.1 +VERSION = 1.14.2 abs_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/src abs_srcdir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/src abs_top_builddir = /afs/psi.ch/project/cafe/gitlab/CAFE/cpp @@ -351,7 +351,7 @@ htmldir = ${docdir} includedir = ${prefix}/include infodir = ${datarootdir}/info install_sh = ${SHELL} /afs/psi.ch/project/cafe/gitlab/CAFE/cpp/install-sh -libdir = /opt/gfa/cafe/cpp/cafe-1.14.1-gcc-7.3.0/lib/RHEL7-x86_64 +libdir = /opt/gfa/cafe/cpp/cafe-1.14.2-sls2-gcc-7.3.0/lib/RHEL7-x86_64 libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var @@ -359,7 +359,7 @@ mandir = ${datarootdir}/man mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} -prefix = /opt/gfa/cafe/cpp/cafe-1.14.1-gcc-7.3.0 +prefix = /opt/gfa/cafe/cpp/cafe-1.14.2-sls2-gcc-7.3.0 program_transform_name = s,x,x, psdir = ${docdir} sbindir = ${exec_prefix}/sbin @@ -379,7 +379,7 @@ lib_LTLIBRARIES = libcafe.la #2nd: age #3rd: revision #1.9.1 1.10.2 1.11.0 1.11.1 1.12.0 1.12.1 1.12.2 1.12.4 -libcafe_la_LDFLAGS = -version-info 15:1:14 +libcafe_la_LDFLAGS = -version-info 15:2:14 libcafe_la_SOURCES = cafe.cpp cafeCache.cpp cafeGroup.cpp \ cafeVectors.cpp cafeXML.cpp callbackHandlerCreate.cpp \ callbackHandlerMonitor.cpp conduit.cpp connect.cpp \ diff --git a/src/makefile.am b/src/makefile.am index 98d0b6c..7ea27cc 100644 --- a/src/makefile.am +++ b/src/makefile.am @@ -12,13 +12,13 @@ lib_LTLIBRARIES = libcafe.la #2nd: age #3rd: revision #1.9.1 1.10.2 1.11.0 1.11.1 1.12.0 1.12.1 1.12.2 1.12.4 -libcafe_la_LDFLAGS = -version-info 15:1:14 +libcafe_la_LDFLAGS = -version-info 15:2:14 libcafe_la_SOURCES = cafe.cpp cafeCache.cpp cafeGroup.cpp cafeVectors.cpp cafeXML.cpp \ callbackHandlerCreate.cpp callbackHandlerMonitor.cpp conduit.cpp connect.cpp connectCallbacks.cpp \ exceptionsHelper.cpp granules.cpp handleHelper.cpp loadCollectionXMLParser.cpp \ loadGroupXMLParser.cpp methodCallbacks.cpp helper.cpp policyHelper.cpp \ - conduitGroup.cpp connectGroup.cpp transpose.cpp restorePVGroupXMLParser.cpp + conduitGroup.cpp connectGroup.cpp transpose.cpp restorePVGroupXMLParser.cpp #if HAVE_PYCAFE_EXT_ diff --git a/src/transpose.cpp b/src/transpose.cpp index a1b92e3..c15c433 100644 --- a/src/transpose.cpp +++ b/src/transpose.cpp @@ -670,21 +670,18 @@ int Transpose::get( { #define __METHOD__ "Transpose::get()" - //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; + //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeConduit_set_by_handle & handle_index=cs.get(); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(_handle); - if (it_handle != handle_index.end()) { PVDataL = (*it_handle).getDataBuffer (); offset = (*it_handle).getChannelRequestMetaDataClient().getOffset(); - - if(isCacheRequest) { offset = (*it_handle).getChannelRequestMetaData().getOffset( ); @@ -697,8 +694,6 @@ int Transpose::get( } - - //Something wrong, just read last element if (nelem <=0) {