62 Commits

Author SHA1 Message Date
Andrew Johnson bc9ac8422c Update version numbers for release 2020-05-28 15:49:41 -05:00
mrkraimer c3aec4e27b get ready for next epics7 release 2020-05-20 14:01:16 -04:00
Marty Kraimer 0abfeef5ed Merge pull request #65 from dirk-zimoch/CleanupWhitespace
Cleanup whitespace
2020-05-20 08:50:14 -04:00
zimoch 745119cf77 removed empty lines at end of file 2020-04-15 17:51:17 +02:00
zimoch 9f794721ab removed spaces at end of line 2020-04-15 17:49:54 +02:00
zimoch 8f21ac8b9d replaced tabs with spaces 2020-04-15 17:45:02 +02:00
Marty Kraimer 9add9daf85 Merge pull request #64 from epics-base/issue#63
fix issue 63; add PvaClientData::getSinglePVField; simplify getDouble…
2019-12-04 05:46:44 -05:00
mrkraimer aaacadb42d fix issue 63; add PvaClientData::getSinglePVField; simplify getDouble, putDouble, etc 2019-12-02 10:32:48 -05:00
Andrew Johnson 5961c83477 Incr version and set development flag after release 2019-11-01 12:28:27 -05:00
Andrew Johnson b724b72624 Clear development flag for 4.7.0 release 2019-11-01 12:20:59 -05:00
Andrew Johnson fc42cf798e Release notes for 4.7.0 2019-11-01 11:09:28 -05:00
Marty Kraimer 71181afc93 Update .travis.yml 2019-09-13 09:15:35 -04:00
Ralph Lange b92a3ddaa4 rtd-ci: add read-the-docs integration 2019-09-06 14:18:19 +02:00
Andrew Johnson 246cceae3e Update version number to 4.7.0 DEVELOPMENT 2019-08-13 10:46:37 -05:00
mrkraimer 3f4df39ee0 fix issue #62 PvaClientData::parse bug 2019-08-12 06:03:55 -04:00
Marty Kraimer 837924af2e Update RELEASE_NOTES.md 2019-08-02 08:45:10 -04:00
Marty Kraimer 7b0e2b5986 Merge pull request #61 from mrkraimer/master
add JSON support
2019-08-02 08:42:29 -04:00
mrkraimer c84b24bb30 Merge https://github.com/epics-base/pvaClientCPP
merge to get latest hanges from epics-base
2019-08-02 05:44:42 -04:00
Andrew Johnson aba40922e6 Release notes for 4.6.0 2019-07-29 11:47:36 -05:00
Andrew Johnson 2c1cb03cd0 Use new CONFIG_PVACLIENT_VERSION file for SHRLIB_VERSION 2019-07-29 11:46:54 -05:00
mrkraimer f58c5159fc add streamJSON 2019-07-19 09:49:40 -04:00
mrkraimer a91ba8ef9e fixed a bug 2019-07-17 10:43:13 -04:00
mrkraimer ddb36536fe add zeroArrayLength 2019-07-16 10:33:39 -04:00
mrkraimer 9153036ccc added JSON support 2019-07-16 09:42:08 -04:00
Marty Kraimer 4c56116827 Merge pull request #60 from mrkraimer/master
working on issue #56; still problems with monitor
2019-04-26 12:51:02 -04:00
mrkraimer 81f5e25276 working on issue #56; still problems with monitor 2019-04-26 10:09:56 -04:00
Marty Kraimer 703b2224ce Merge pull request #59 from mrkraimer/master
fix issue #57
2019-04-25 05:07:20 -04:00
mrkraimer ed0b1cbf08 fix issue #57 2019-04-24 14:53:18 -04:00
Marty Kraimer 914e382dea Merge pull request #58 from mrkraimer/master
address issue #54
2019-04-24 05:18:19 -04:00
mrkraimer fd77d35b20 address issue #54 2019-04-23 14:04:13 -04:00
Andrew Johnson 428adb270e Update version numbers to 4.5.0 for EPICS 7.0.2.2 release 2019-04-15 11:27:27 -05:00
Marty Kraimer 3111e90de8 Merge pull request #55 from mrkraimer/master
address issue #53 plus more for getDouble, putDouble, getString, putDouble, etc
2019-04-11 14:50:03 -04:00
mrkraimer 365a0b846f update RELEASE_NOTES 2019-04-11 14:13:53 -04:00
mrkraimer 440c8fa496 update RELEASE_NOTES 2019-04-11 14:11:03 -04:00
mrkraimer 150ac45de3 bug in pvaClientData; fix doxygen warning; update doc 2019-04-09 11:15:00 -04:00
mrkraimer fb6f4355f3 getDoubleArray and putDoubleArray now work for all numeric scalar arrays 2019-04-09 06:19:14 -04:00
mrkraimer 0bb17d5b09 make them work if not top level value field 2019-04-08 14:23:58 -04:00
mrkraimer 00103f8207 getStringArray and putStringArray support all numeric array types 2019-04-08 14:11:27 -04:00
mrkraimer 522a050945 add double and string methods to pvaClientChannel 2019-04-07 14:34:56 -04:00
mrkraimer 99a7e3b0b5 more changes 2019-04-06 11:30:10 -04:00
mrkraimer 763c41caa3 setElementData=>setData 2019-04-05 14:37:05 -04:00
mrkraimer 9ffeffd23f mistake 2019-04-04 16:27:53 -04:00
mrkraimer 3f6d93b22f lots of minor changes 2019-04-04 16:02:47 -04:00
mrkraimer d650865a6f address issue #53; reorganize Client*Data 2019-04-03 10:32:45 -04:00
Andrew Johnson b1c101578b Update version numbers and formatting in documentation 2018-12-17 16:17:52 -06:00
Andrew Johnson 8ab4dd1fdb Correct SHRLIB_VERSION 2018-12-17 16:16:59 -06:00
Andrew Johnson 5242540725 Update and unify README.md 2018-12-17 16:16:06 -06:00
Michael Davidsaver a8f296ceb3 update travis-ci 2018-10-29 18:02:20 -07:00
Marty Kraimer 6633d4f21e Merge pull request #52 from mrkraimer/master
with multiple threads callback can occur before create completes
2018-10-06 05:59:14 -04:00
mrkraimer 8745dd03b3 with multithreads callback can occur before create completes 2018-10-05 15:59:59 -04:00
Marty Kraimer cfc3c9b998 Merge pull request #51 from mrkraimer/master
several changes
2018-09-28 07:00:34 -04:00
mrkraimer d57893b566 remove #include <pv/pvCopy.h> 2018-09-27 15:34:02 -04:00
mrkraimer b7ea0fe59a fix bug that causes failure in monotor::stop for privider ca 2018-07-27 05:43:47 -04:00
Marty Kraimer 4e4554af4e Merge pull request #50 from mrkraimer/master
re-implement methods used by pvaPy
2018-01-30 09:11:28 -05:00
mrkraimer d6d5bcf771 merge with epics-base 2018-01-12 15:20:47 -05:00
mrkraimer 6bcc036c71 reimplement methods called by pvaPy
The methods are:
static PvaClientPtr create() EPICS_DEPRECATED;
and
static PvaClientMonitorPtr create(
    PvaClientPtr const &pvaClient,
    std::string const & channelName,
    std::string const & providerName,
    std::string const & request,
    PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester
            = PvaClientChannelStateChangeRequesterPtr(),
    PvaClientMonitorRequesterPtr const & monitorRequester
            = PvaClientMonitorRequesterPtr()
) EPICS_DEPRECATED;
2018-01-12 13:51:13 -05:00
Marty Kraimer a405dd7bdb Merge pull request #49 from epics-base/revert-48-master
Revert "Minor changes"
2018-01-09 15:58:58 -05:00
Marty Kraimer 22e260351c Revert "Minor changes" 2018-01-09 15:14:30 -05:00
Marty Kraimer 5a5b8f809d Merge pull request #48 from mrkraimer/master
Minor changes
2018-01-09 11:16:52 -05:00
mrkraimer 9d5f06c11d pull latest from epics-base 2018-01-08 09:20:13 -05:00
mrkraimer 28a23dc5a8 remove a create method from monitor; remove unused channelStateChange methods 2018-01-05 14:38:42 -05:00
Ralph Lange dcda03c9fc jenkins-ci: fix CloudBees doc job 2017-12-19 09:20:11 +01:00
38 changed files with 1286 additions and 1363 deletions
+2 -13
View File
@@ -1,21 +1,10 @@
#!/bin/sh
set -e -x
# set RTEMS to eg. "4.9" or "4.10"
# requires qemu, bison, flex, texinfo, install-info
if [ -n "$RTEMS" ]
then
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi
make -j2 $EXTRA
if [ "$TEST" != "NO" ]
then
make tapfiles
make -s test-results
make -j2 tapfiles
make -j2 -s test-results
fi
+11 -80
View File
@@ -3,35 +3,6 @@ set -e -x
CURDIR="$PWD"
QDIR="$HOME/.cache/qemu"
if [ -n "$RTEMS" -a "$TEST" = "YES" ]
then
git clone --quiet --branch vme --depth 10 https://github.com/mdavidsaver/qemu.git "$HOME/.build/qemu"
cd "$HOME/.build/qemu"
HEAD=`git log -n1 --pretty=format:%H`
echo "HEAD revision $HEAD"
[ -e "$HOME/.cache/qemu/built" ] && BUILT=`cat "$HOME/.cache/qemu/built"`
echo "Cached revision $BUILT"
if [ "$HEAD" != "$BUILT" ]
then
echo "Building QEMU"
git submodule --quiet update --init
install -d "$HOME/.build/qemu/build"
cd "$HOME/.build/qemu/build"
"$HOME/.build/qemu/configure" --prefix="$HOME/.cache/qemu/usr" --target-list=i386-softmmu --disable-werror
make -j2
make install
echo "$HEAD" > "$HOME/.cache/qemu/built"
fi
fi
cat << EOF > $CURDIR/configure/RELEASE.local
EPICS_BASE=$HOME/.source/epics-base
EOF
@@ -39,24 +10,6 @@ EOF
install -d "$HOME/.source"
cd "$HOME/.source"
add_base_module() {
MODULE=$1
BRANCH=$2
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $MODULE/$BRANCH https://github.com/${REPOBASE:-epics-base}/epics-base.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_module() {
MODULE=$1
REPOOWNER=$2
REPONAME=$3
BRANCH=$4
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_flat() {
MODULE=$1
REPOOWNER=$2
@@ -71,23 +24,12 @@ ${MODULE_UC}=$HOME/.source/$MODULE
EOF
}
if [ "$BRBASE" ]
then
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
(cd epics-base && git log -n1 )
add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_flat pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
add_gh_flat normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
else
git clone --quiet --depth 5 --branch core/"${BRCORE:-master}" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
( cd epics-base && git log -n1 )
add_base_module libcom "${BRLIBCOM:-master}"
add_base_module ca "${BRCA:-master}"
add_base_module database "${BRDATABASE:-master}"
add_gh_module pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_module pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
add_gh_module normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
fi
# not recursive
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
(cd epics-base && git log -n1 )
add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_flat pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
add_gh_flat normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
if [ -e $CURDIR/configure/RELEASE.local ]
then
@@ -150,31 +92,20 @@ EOF
if [ -n "$RTEMS" ]
then
echo "Cross RTEMS${RTEMS} for pc386"
install -d /home/travis/.cache
curl -L "https://github.com/mdavidsaver/rsb/releases/download/travis-20160306-2/rtems${RTEMS}-i386-trusty-20190306-2.tar.gz" \
| tar -C /home/travis/.cache -xj
curl -L "https://github.com/mdavidsaver/rsb/releases/download/20171203-${RTEMS}/i386-rtems${RTEMS}-trusty-20171203-${RTEMS}.tar.bz2" \
| tar -C / -xmj
sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' epics-base/configure/os/CONFIG_SITE.Common.RTEMS
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.RTEMS
RTEMS_VERSION=$RTEMS
RTEMS_BASE=/home/travis/.cache/rtems${RTEMS}-i386
RTEMS_BASE=$HOME/.rtems
EOF
cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS+=RTEMS-pc386
CROSS_COMPILER_TARGET_ARCHS += RTEMS-pc386-qemu
EOF
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi
make -j2 -C epics-base $EXTRA
if [ "$BRBASE" ]
then
make -j2 -C pvData $EXTRA
make -j2 -C pvAccess $EXTRA
make -j2 -C normativeTypes $EXTRA
fi
make -j2 -C pvAccess $EXTRA
+17
View File
@@ -0,0 +1,17 @@
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the documentation/ directory with Sphinx
sphinx:
configuration: documentation/conf.py
# Build documentation with MkDocs
#mkdocs:
# configuration: mkdocs.yml
# Optionally build your docs in additional formats such as PDF and ePub
formats: all
+12 -11
View File
@@ -11,19 +11,20 @@ addons:
- perl
- clang
- g++-mingw-w64-i686
- qemu-system-x86
install:
- ./.ci/travis-prepare.sh
script:
- ./.ci/travis-build.sh
env:
- BRCORE=master BRLIBCOM=master BRPVD=master BRPVA=master BRNT=master TEST=NO
- CMPLR=clang TEST=NO
- USR_CXXFLAGS=-std=c++11 TEST=NO
- CMPLR=clang USR_CXXFLAGS=-std=c++11 TEST=NO
- WINE=32 TEST=NO STATIC=YES
- WINE=32 TEST=NO STATIC=NO
- RTEMS=4.10 TEST=NO
- RTEMS=4.9 TEST=NO
- BRBASE=3.16 TEST=NO
- BRBASE=3.15 TEST=NO
- BRBASE=3.14 TEST=NO
- BRBASE=7.0
- BRBASE=7.0 CMPLR=clang
- BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++98"
- BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++11"
- BRBASE=7.0 CMPLR=clang EXTRA="CMD_CXXFLAGS=-std=c++11"
- BRBASE=7.0 WINE=32 TEST=NO STATIC=YES
- BRBASE=7.0 WINE=32 TEST=NO STATIC=NO
- BRBASE=7.0 RTEMS=4.10 TEST=NO
- BRBASE=7.0 RTEMS=4.9 TEST=NO
- BRBASE=3.16
- BRBASE=3.15
+7 -6
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = pvaClientCPP
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER =
PROJECT_NUMBER = 4.7.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -152,7 +152,7 @@ FULL_PATH_NAMES = YES
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
STRIP_FROM_PATH = src
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
@@ -161,7 +161,7 @@ STRIP_FROM_PATH =
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
STRIP_FROM_INC_PATH = src
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
@@ -765,7 +765,8 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = include
INPUT = src \
src/pv
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -796,7 +797,7 @@ FILE_PATTERNS =
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = YES
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
@@ -1035,7 +1036,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = documentation/html
HTML_OUTPUT = html/doxygen
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
+11 -17
View File
@@ -1,23 +1,17 @@
pvaClientCPP
============
# pvaClientCPP
pvaClient is a synchronous client interface to pvAccess,
which is callback based.
pvaClient is thus easier to use than pvAccess itself.
The **pvaClient** API provides a synchronous client interface that was designed to be easier to use than the original basic pvAccess client API.
See documentation/pvaClientCPP.html for details.
The pvaClientCPP module implements the pvaClient API for C++ client applications.
Building
--------
## Links
If a proper RELEASE.local file exists one directory level above pvaClientCPP
then just type:
- General information about EPICS can be found at the
[EPICS Controls website](https://epics-controls.org).
- API documentation for this module can be found in its
documentation directory, in particular the file
pvaClientCPP.html
make
It can also be built by:
cp configure/ExampleRELEASE.local configure/RELEASE.local
edit configure/RELEASE.local
make
## Building
This module is included as a submodule of a full EPICS 7 release and will be compiled during builds of that software.
+12
View File
@@ -0,0 +1,12 @@
# Version number for the PVA Client API and shared library
EPICS_PVACLIENT_MAJOR_VERSION = 4
EPICS_PVACLIENT_MINOR_VERSION = 7
EPICS_PVACLIENT_MAINTENANCE_VERSION = 1
# Development flag, set to zero for release versions
EPICS_PVACLIENT_DEVELOPMENT_FLAG = 0
# Immediately after a release the MAINTENANCE_VERSION
# will be incremented and the DEVELOPMENT_FLAG set to 1
+2
View File
@@ -2,6 +2,8 @@ TOP=..
include $(TOP)/configure/CONFIG
CFG += CONFIG_PVACLIENT_VERSION
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
+69 -19
View File
@@ -1,18 +1,74 @@
pvaClientCPP Version 4.3.0
==========================
pwd# pvaClientCPP Module
Works with pvDataCPP-7.0 and pvAccessCPP-6.0 versions
-----------------------------------------------------
This document summarizes the changes to the module between releases.
Will not work with older versions of these modules.
## Release 4.7.1 (EPICS 7.0.3.2 May 2020)
destroy methods removed
-----------------------
* support access to a union field that is a scalar or scalarArray
* fixed issues #62 and #63
All the destroy methods are removed since implementation is RAII compliant.
## Release 4.7.0 (EPICS 7.0.3.1, Nov 2019)
API changes to PvaClientMonitor
-------------------------------
* added JSON support for put and putGet
* Fix for
[GitHub issue #62](https://github.com/epics-base/pvaClientCPP/issues/62)
* Doxygen updates and read-the-docs integration.
## Release 4.6.0 (EPICS 7.0.3, Jul 2019)
* pvaClient now handles exceptions from the server properly (issue #54).
* MultiChannel classes now properly handle PV structures that don't have a top-level `value` field (issue #56), and are more tolerant of other missing fields (issue #57).
## Release 4.5.0 (EPICS 7.0.2.2, Apr 2019)
Changes have been made for getDouble, putDouble, getDoubleArray, putDoubleArray, getString, putString, getStringArray, and putStringArray.
1) Previously each only had support for a top level field named value.
Each now allows access to a single sub field that has the correct type.
Thus pvRequest must select a single field. For example
pva->channel("PVRdumbPowerSupply")->putDouble(1.0,"power.value" );
2) PvaChannel now has a method for each of the above.
For example instead of
PvaClientChannelPtr channel = pva->channel("PVRdouble");
PvaClientPutPtr clientPut = channel->put();
PvaClientPutDataPtr putData = clientPut->getData();
putData->putDouble(1.0); clientPut->put();
now it can be
pva->channel("PVRdouble")->putDouble(1.0 );
3) getDoubleArray and putDoubleArray work with any numeric scalar array
4) getStringArray and putStringArray work with any scalar array.
## Release 4.4 (EPICS 7.0.2, Dec 2018)
### API changes to PvaClientMonitor
The create method that had arguments for stateChangeRequester and monitorRequester no longer exists.
### API changes to PvaClientGet, ..., PvaClientMonitor
Previously the pvaClientGet, ..., pvaClientMonitor classes all implemented PvaClientChannelStateChangeRequester(). This method was never called and has been removed.
## Release 4.3 (EPICS 7.0.1, Dec 2017)
### Requires pvDataCPP-7.0 and pvAccessCPP-6.0 versions
This release will not work with older versions of these modules.
### Destroy methods removed
All the destroy() methods have been removed, implementation is RAII compliant.
### API changes to PvaClientMonitor
The second argument of method
@@ -22,7 +78,7 @@ The second argument of method
epics::pvData::PVStructurePtr const &pvRequest
);
Is now changed to
is now changed to
static PvaClientMonitorPtr create(
PvaClientPtr const &pvaClient,
@@ -42,22 +98,16 @@ A new method is also implemented
);
pvaClientCPP Version 4.2
========================
## Release 4.2 (EPICS V4.6, Aug 2016)
* The examples are moved to exampleCPP.
* Support for channelRPC is now available.
* In PvaClientMultiChannel checkConnected() now throws an exception if connect fails.
pvaClientCPP Version 4.1
========================
## Release 4.1 (EPICS V4.5, Oct 2015)
pvaClient is a synchronous API for pvAccess.
This is the first release of pvaClientCPP.
It provides an API that is similar to pvaClientJava.
+7
View File
@@ -0,0 +1,7 @@
.wy-side-nav-search {
background-color: #18334B;
}
.wy-side-nav-search input[type="text"] {
border-color: #18334b;
}
+80
View File
@@ -0,0 +1,80 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'normativeTypes (C++)'
copyright = '2019, EPICS Controls.'
author = 'EPICS'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.intersphinx',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# Intersphinx links to subprojects
intersphinx_mapping = {
}
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = [
'css/custom.css',
]
master_doc = 'index'
html_theme_options = {
'logo_only': True,
}
html_logo = "images/EPICS_white_logo_v02.png"
html_extra_path = [
'../html',
'pvaClientCPP.html',
]
# -- Run Doxygen ------------------------------------------------------------
import subprocess
subprocess.call('cd ..; mkdir -p html/doxygen; doxygen', shell=True)
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

+17
View File
@@ -0,0 +1,17 @@
pvaClient (C++) Library
========================
.. toctree::
:hidden:
EPICS Website <https://epics-controls.org>
EPICS Documentation Home <https://docs.epics-controls.org>
.. toctree::
:maxdepth: 1
:caption: pvaClientCPP
Reference Manual <https://docs.epics-controls.org/projects/pvaclient-cpp/en/latest/pvaClientCPP.html>
API Documentation <https://docs.epics-controls.org/projects/pvaclient-cpp/en/latest/doxygen>
Source Code Repository on GitHub <https://github.com/epics-base/pvaClientCPP>
+7 -7
View File
@@ -26,13 +26,13 @@
<div class="head">
<h1>EPICS pvaClientCPP</h1>
<h2 class="nocount">Release 4.3.0 - 2017-12-14</h2>
<h2 class="nocount">Release 4.4 - April 2019</h2>
<h2 class="nocount">Abstract</h2>
<p>pvaClient is a software library that provides, to an EPICS client programmer, a friendly
client side programming interface to the data of an EPICS based control system. It is intended
for such uses as rapid development of ad hoc programs by controls engineers, or to provide
client side programming interface to the data of an EPICS based control system. It is intended
for such uses as rapid development of ad hoc programs by controls engineers, or to provide
scientists a way to directly develop analytical applications.</p>
<p>Specifically, pvaClient provides a synchronous interface for pvAccess, which is the
@@ -41,7 +41,7 @@ pvAccess provides a callback based interface, which can be hard to use.
pvaClient provides an interface that does not require callbacks even for monitors.
</p>
<p>
pvaClientChannel provides many "convenience" methods to directly get and put
pvaClientChannel provides many "convenience" methods to directly get and put
scalar and scalarArray data types.
Additional methods provide access to the full features of pvAccess.
</p>
@@ -62,11 +62,11 @@ The data for the channels is presented via normative type NTMultiChannel.
</div> <!-- head -->
<div id="contents" class="contents">
<div id="contents" class="contents">
<hr />
<h2>Overview</h2>
<p>
pvaClientCPP is one of the components of
pvaClientCPP is one of the components of
<a href="http://epics-pvdata.sourceforge.net">
EPICS Version 4
</a>
@@ -79,7 +79,7 @@ It is intended for developers that want to use pvaClientCPP.
<h2>Developer Guide</h2>
<p>A guide for developers is available at
<a
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
href="https://mrkraimer.github.io/website/developerGuide/developerGuide.html">
developerGuide
</a>
</p>
+1 -8
View File
@@ -21,14 +21,7 @@ installE4 () {
local module=$1
local branch=$2
# If microbench version does not exist, try without
if [ "${MB}" = "WITH_MICROBENCH" ]; then
if ! wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=WITH_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz; then
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
else
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
tar -xzf ${module}.CB-dist.tar.gz
}
+2 -1
View File
@@ -6,12 +6,13 @@ include $(TOP)/configure/CONFIG
LIBRARY += pvaClient
# shared library ABI version.
SHRLIB_VERSION ?= 4.3.0
SHRLIB_VERSION ?= $(EPICS_PVACLIENT_MAJOR_VERSION).$(EPICS_PVACLIENT_MINOR_VERSION).$(EPICS_PVACLIENT_MAINTENANCE_VERSION)
INC += pv/pvaClient.h
INC += pv/pvaClientMultiChannel.h
LIBSRCS += pvaClient.cpp
LIBSRCS += pvaClientData.cpp
LIBSRCS += pvaClientPutData.cpp
LIBSRCS += pvaClientGetData.cpp
LIBSRCS += pvaClientMonitorData.cpp
+204 -284
View File
@@ -17,13 +17,13 @@
#include <list>
#include <iostream>
#include <sstream>
#include <ostream>
#include <sstream>
#include <pv/requester.h>
#include <pv/status.h>
#include <pv/event.h>
#include <pv/lock.h>
#include <pv/pvData.h>
#include <pv/pvCopy.h>
#include <pv/pvTimeStamp.h>
#include <pv/timeStamp.h>
#include <pv/pvAlarm.h>
@@ -36,15 +36,17 @@
#ifdef pvaClientEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef pvaClientEpicsExportSharedSymbols
# undef pvaClientEpicsExportSharedSymbols
#endif
#include <shareLib.h>
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
class PvaClient;
typedef std::tr1::shared_ptr<PvaClient> PvaClientPtr;
class PvaClientData;
typedef std::tr1::shared_ptr<PvaClientData> PvaClientDataPtr;
class PvaClientGetData;
typedef std::tr1::shared_ptr<PvaClientGetData> PvaClientGetDataPtr;
class PvaClientPutData;
@@ -120,6 +122,12 @@ public:
/** @brief Get the requester name.
* @return The name.
*/
/** @brief Create an instance of PvaClient with providerName "pva ca".
* @return shared pointer to the single instance
* @deprecated This method will go away in future versions. Use get instead.
*/
static PvaClientPtr create() EPICS_DEPRECATED;
std::string getRequesterName();
/** @brief A new message.
*
@@ -153,7 +161,7 @@ public:
PvaClientChannelPtr createChannel(
std::string const & channelName,
std::string const & providerName = "pva");
/** @brief Set a requester.
*
* The default is for PvaClient to handle messages by printing to System.out.
@@ -196,7 +204,7 @@ class PvaClientPutCache;
typedef std::tr1::shared_ptr<PvaClientPutCache> PvaClientPutCachePtr;
/**
/**
* @brief A callback for change in connection status.
*
* <a href = "../htmldoxygen/pvaClientChannelStateChangeRequester.html">Overview of PvaClientChannelStateChangeRequester</a>
@@ -220,7 +228,7 @@ public:
virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected) = 0;
};
/**
/**
* @brief An easy to use alternative to directly calling the Channel methods of pvAccess.
*
* <a href = "../htmldoxygen/pvaClientChannel.html">Overview of PvaClientChannel</a>
@@ -237,7 +245,7 @@ public:
*/
~PvaClientChannel();
/** @brief Set a client stateChangeRequester.
*
*
* @param stateChangeRequester The client stateChangeRequester implementation.
*/
void setStateChangeRequester(PvaClientChannelStateChangeRequesterPtr const &stateChangeRequester);
@@ -282,7 +290,7 @@ public:
* @throw runtime_error if failure.
*/
PvaClientProcessPtr createProcess(std::string const & request = "");
/** Creates a PvaClientProcess.
/** Creates a PvaClientProcess.
*
* @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData.
* @return The interface.
@@ -306,13 +314,44 @@ public:
PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)");
/** @brief Creates an PvaClientGet.
*
* @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData.
* @param pvRequest The syntax of request is defined by the copy facility of pvData.
* @return The interface.
* @return The interface.
* @throw runtime_error if failure.
*/
PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest);
/** @brief Get the value as a double.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
double getDouble(std::string const & request = "field(value)");
/** Get the value as a string.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
std::string getString(std::string const & request = "field(value)");
/** @brief Get the value as a double array.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const double> getDoubleArray(
std::string const & request = "field(value)");
/** @brief Get the value as a string array.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const std::string> getStringArray(
std::string const & request = "field(value)");
/** @brief create a PvaClientPut.
*
*
* Get a cached PvaClientPut or create and connect to a new PvaClientPut.
* Then call it's get method.
* @param request The syntax of request is defined by the copy facility of pvData.
@@ -334,6 +373,44 @@ public:
* @return The interface.
*/
PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest);
/** @brief Put the value as a double.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putDouble(double value,std::string const & request = "field(value)");
/** @brief Put the value as a string.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putString(std::string const & value,std::string const & request = "field(value)");
/** @brief Copy the array to the value field.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putDoubleArray(
epics::pvData::shared_vector<const double> const & value,
std::string const & request = "field(value)");
/** @brief Copy array to the value field.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putStringArray(
epics::pvData::shared_vector<const std::string> const & value,
std::string const & request = "field(value)");
/** @brief Copy array to the value field.
* @param value The data used to update the channel value.
* @param request The request as a string to pass to createRequest.
* @throw runtime_error if failure.
*/
void putStringArray(std::vector<std::string> const & value,std::string const & request = "field(value)");
/** @brief create a PvaClientPutGet.
*
* First call createRequest as implemented by pvDataJava and then calls the next method.
@@ -373,7 +450,7 @@ public:
* @throw runtime_error if failure.
*/
PvaClientMonitorPtr monitor(std::string const & request = "field(value,alarm,timeStamp)");
/** @brief Call the next method with request = "field(value,alarm,timeStamp)"
/** @brief Call the next method with request = "field(value,alarm,timeStamp)"
*
* @param pvaClientMonitorRequester The client callback.
* @return The interface.
@@ -462,7 +539,7 @@ private:
std::string channelName;
std::string providerName;
ConnectState connectState;
epics::pvData::CreateRequest::shared_pointer createRequest;
PvaClientGetCachePtr pvaClientGetCache;
PvaClientPutCachePtr pvaClientPutCache;
@@ -484,19 +561,19 @@ public:
friend class PvaClient;
};
/**
* @brief A class that holds data returned by PvaClientGet or PvaClientPutGet
/**
* @brief A base class for PvaClientGetData, PvaClientPutData, and PvaClientMonitorData.
*
* <a href = "../htmldoxygen/pvaClientGetData.html">Overview of PvaClientGetData</a>
* <a href = "../htmldoxygen/pvaClientData.html">Overview of PvaClientData</a>
*/
class epicsShareClass PvaClientGetData
class epicsShareClass PvaClientData
{
public:
POINTER_DEFINITIONS(PvaClientGetData);
POINTER_DEFINITIONS(PvaClientData);
/**
* @brief Destructor
*/
~PvaClientGetData() {}
~PvaClientData() {}
/** @brief Set a prefix for throw messages.
*
* This is called by other pvaClient classes.
@@ -537,6 +614,7 @@ public:
void setData(
epics::pvData::PVStructurePtr const & pvStructureFrom,
epics::pvData::BitSetPtr const & bitSetFrom);
/** @brief Is there a top level field named value.
* @return The answer.
*/
@@ -603,6 +681,75 @@ public:
* @return The timeStamp.
*/
epics::pvData::TimeStamp getTimeStamp();
/** @brief parse from args
*
* Accepts arguments of the form json or field='value' where value is json syntax.
* field is name.name...
* @param args The arguments
* @throw runtime_error if failure.
*/
void parse(const std::vector<std::string> &args);
/** @brief generate JSON output from the current PVStructure
*
* @param strm output stream
* @param ignoreUnprintable false or true; default is true.
* @param multiline false or true; default is false
*
* @throw runtime_error if failure.
*/
void streamJSON(
std::ostream& strm,
bool ignoreUnprintable = true,
bool multiLine = false);
/** @brief set length of all array fields to 0
*/
void zeroArrayLength();
/** @brief Factory method for creating an instance of PvaClientData.
*
* NOTE: Not normally called by clients
* @param structure Introspection interface
* @throw runtime_error if failure.
*/
static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure);
protected:
PvaClientData(epics::pvData::StructureConstPtr const & structure);
epics::pvData::PVFieldPtr getSinglePVField();
void checkValue();
std::string messagePrefix;
private:
void parse(
const std::string &arg,
const epics::pvData::PVFieldPtr &dest,
epics::pvData::BitSetPtr &bitSet);
void parse(
const std::string &arg,
const epics::pvData::PVUnionPtr &dest);
void zeroArrayLength(const epics::pvData::PVStructurePtr &pvStructure);
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;
friend class PvaClientGet;
friend class PvaClientPutGet;
};
/**
* @brief A class that holds data returned by PvaClientGet or PvaClientPutGet
*
* <a href = "../htmldoxygen/pvaClientGetData.html">Overview of PvaClientGetData</a>
*/
class epicsShareClass PvaClientGetData : public PvaClientData
{
public:
POINTER_DEFINITIONS(PvaClientGetData);
/**
* @brief Destructor
*/
~PvaClientGetData() {}
/** @brief Factory method for creating an instance of PvaClientGetData.
*
* NOTE: Not normally called by clients
@@ -612,120 +759,24 @@ public:
static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure);
private:
PvaClientGetData(epics::pvData::StructureConstPtr const & structure);
void checkValue();
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;
friend class PvaClientGet;
friend class PvaClientPutGet;
};
class PvaClientPostHandlerPvt; // private to PvaClientPutData
/**
/**
* @brief A class that holds data given to by PvaClientPut or PvaClientPutGet
*
* <a href = "../htmldoxygen/pvaClientPutData.html">Overview of PvaClientPutData</a>
*/
class epicsShareClass PvaClientPutData
class epicsShareClass PvaClientPutData : public PvaClientData
{
public:
POINTER_DEFINITIONS(PvaClientPutData);
/**
* @brief Destructor
*/
*/
~PvaClientPutData() {}
/** @brief Set a prefix for throw messages.
*
* @param value The prefix.
*/
void setMessagePrefix(std::string const & value);
/** @brief Get the structure.
*
* @return The Structure
* @throw runtime_error if failure.
*/
epics::pvData::StructureConstPtr getStructure();
/** @brief Get the pvStructure.
*
* @return the pvStructure.
* @throw runtime_error if failure.
*/
epics::pvData::PVStructurePtr getPVStructure();
/** @brief Get the changed BitSet for the pvStructure
*
* This shows which fields have changed values.
* @return The bitSet
* @throw runtime_error if failure.
*/
epics::pvData::BitSetPtr getChangedBitSet();
/** @brief Show the fields that have changed values.
*
* @param out The stream that shows the changed fields.
* @return The stream that was passed as out.
*/
std::ostream & showChanged(std::ostream & out);
/**
* @brief Is there a top level field named value.
*
* @return The answer.
*/
bool hasValue();
/** @brief Is the value field a scalar?
*
* @return The answer.
*/
bool isValueScalar();
/** @brief Is the value field a scalar array?
* @return The answer.
*/
bool isValueScalarArray();
/** Get the interface to the value field.
*
* @return The interface. an excetion is thrown if a value field does not exist.
*/
epics::pvData::PVFieldPtr getValue();
/** @brief Get the interface to a scalar value field.
*
* @return The interface for a scalar value field.
* @throw runtime_error if failure.
*/
epics::pvData::PVScalarPtr getScalarValue();
/** @brief Get the interface to an array value field.
* @return The interface.
* An exception is thown if no array value field.
*/
std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue();
/** @brief Get the interface to a scalar array value field.
* @return Return the interface.
* @throw runtime_error if failure.
*/
std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue();
/** @brief Get the value as a double.
*
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
double getDouble();
/** @brief Get the value as a string.
* @return The value.
* @throw runtime_error if failure.
*/
std::string getString();
/** @brief Get the value as a double array.
* If the value is not a numeric array an exception is thrown.
* @return The value.
*/
epics::pvData::shared_vector<const double> getDoubleArray();
/** @brief Get the value as a string array.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const std::string> getStringArray();
/** @brief Put the value as a double.
* @param value The new value.
* An exception is also thrown if the actualy type can cause an overflow.
@@ -759,17 +810,9 @@ public:
static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure);
private:
PvaClientPutData(epics::pvData::StructureConstPtr const &structure);
void checkValue();
void postPut(size_t fieldNumber);
std::vector<epics::pvData::PostHandlerPtr> postHandler;
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
friend class PvaClientPostHandlerPvt;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
friend class PvaClientPut;
friend class PvaClientPutGet;
};
@@ -779,35 +822,14 @@ private:
*
* <a href = "../htmldoxygen/pvaClientMonitorData.html">Overview of PvaClientMonitorData</a>
*/
class epicsShareClass PvaClientMonitorData
class epicsShareClass PvaClientMonitorData : public PvaClientData
{
public:
POINTER_DEFINITIONS(PvaClientMonitorData);
/**
* @brief Destructor
*/
*/
~PvaClientMonitorData() {}
/** @brief Set a prefix for throw messages.
* @param value The prefix.
*/
void setMessagePrefix(std::string const & value);
/** @brief Get the structure.
* @return The Structure
* @throw runtime_error if failure.
*/
epics::pvData::StructureConstPtr getStructure();
/** @brief Get the pvStructure.
* @return the pvStructure.
* @throw runtime_error if failure.
*/
epics::pvData::PVStructurePtr getPVStructure();
/** @brief Get the changed BitSet for the pvStructure,
*
* This shows which fields have changed value.
* @return The bitSet
* @throw runtime_error if failure.
*/
epics::pvData::BitSetPtr getChangedBitSet();
/** @brief Get the overrun BitSet for the pvStructure
* This shows which fields have had more than one change.
* @return The bitSet
@@ -818,111 +840,21 @@ public:
* @param out The stream that shows the changed fields.
* @return The stream that was passed as out.
*/
std::ostream & showChanged(std::ostream & out);
/** @brief Show the fields that have overrun.
* @param out The stream that shows the overrun fields.
* @return The stream that was passed as out
*/
std::ostream & showOverrun(std::ostream & out);
/** @brief Is there a top level field named value.
* @return The answer.
*/
bool hasValue();
/** @brief Is the value field a scalar?
* @return The answer.
*/
bool isValueScalar();
/** @brief Is the value field a scalar array?
* @return The answer.
*/
bool isValueScalarArray();
/** @brief Get the interface to the value field.
* @return The interface. an excetion is thrown if a value field does not exist.
*/
epics::pvData::PVFieldPtr getValue();
/** @brief Get the interface to a scalar value field.
* @return The interface for a scalar value field.
* @throw runtime_error if failure.
* An exception is thown if no scalar value field.
*/
epics::pvData::PVScalarPtr getScalarValue();
/** @brief Get the interface to an array value field.
* @return The interface.
* @throw runtime_error if failure.
* An exception is thown if no array value field.
*/
std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue();
/** @brief Get the interface to a scalar array value field.
* @return Return the interface.
* @throw runtime_error if failure.
* An exception is thown if no scalar array value field.
*/
std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue();
/** @brief Get the value as a double.
*
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
double getDouble();
/** @brief Get the value as a string.
*
* If value is not a scalar an exception is thrown
* @return The value.
* @throw runtime_error if failure.
*/
std::string getString();
/** @brief Get the value as a double array.
*
* If the value is not a numeric array an exception is thrown.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const double> getDoubleArray();
/** @brief Get the value as a string array.
*
* If the value is not a string array an exception is thrown.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const std::string> getStringArray();
/** @brief Get the alarm.
*
* If the pvStructure as an alarm field it's values are returned.
* If no then alarm shows that not alarm defined.
* @return The alarm.
* @throw runtime_error if failure.
*/
epics::pvData::Alarm getAlarm();
/** @brief Get the timeStamp.
*
* If the pvStructure has a timeStamp field, it's values are returned.
* If no then all fields are 0.
* @return The timeStamp.
*/
epics::pvData::TimeStamp getTimeStamp();
/** Factory method for creating an instance of PvaClientGetData.
* NOTE: Not normally called by clients
* @param structure Introspection interface
*/
static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure);
/** Put data into PVStructure from monitorElement
* NOTE: Not normally called by clients
* @param monitorElement the monitorElement that has new data.
*/
void setData(epics::pvData::MonitorElementPtr const & monitorElement);
/** Factory method for creating an instance of PvaClientGetData.
* NOTE: Not normally called by clients
* @param structure Introspection interface
*/
static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure);
private:
PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure);
void checkValue();
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr changedBitSet;
epics::pvData::BitSetPtr overrunBitSet;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;
friend class PvaClientMonitor;
};
@@ -967,14 +899,13 @@ typedef std::tr1::shared_ptr<ChannelProcessRequesterImpl> ChannelProcessRequeste
* <a href = "../htmldoxygen/pvaClientProcess.html">Overview of PvaClientProcess</a>
*/
class epicsShareClass PvaClientProcess :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientProcess>
{
public:
POINTER_DEFINITIONS(PvaClientProcess);
/** @brief Create a PvaClientProcess.
* @param &pvaClient Interface to PvaClient
* @param channel Interface to Channel
* @param pvaClient Interface to PvaClient
* @param pvaClientChannel Interface to Channel
* @param pvRequest The request structure.
* @return The interface to the PvaClientProcess.
*/
@@ -983,7 +914,7 @@ public:
PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest
);
/** @brief Destructor
*/
~PvaClientProcess();
@@ -1037,7 +968,7 @@ private:
PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest);
void checkProcessState();
enum ProcessConnectState {connectIdle,connectActive,connected};
@@ -1054,13 +985,11 @@ private:
ProcessConnectState connectState;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientProcessRequesterWPtr pvaClientProcessRequester;
enum ProcessState {processIdle,processActive,processComplete};
ProcessState processState;
ChannelProcessRequesterImplPtr channelProcessRequester;
public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelProcessRequesterImpl;
};
@@ -1104,7 +1033,6 @@ public:
* <a href = "../htmldoxygen/pvaClientGet.html">Overview of PvaClientGet</a>
*/
class epicsShareClass PvaClientGet :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientGet>
{
public:
@@ -1183,7 +1111,7 @@ private:
PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest);
void checkGetState();
void checkConnectState();
enum GetConnectState {connectIdle,connectActive,connected};
PvaClient::weak_pointer pvaClient;
@@ -1200,14 +1128,12 @@ private:
GetConnectState connectState;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientGetRequesterWPtr pvaClientGetRequester;
enum GetState {getIdle,getActive,getComplete};
GetState getState;
ChannelGetRequesterImplPtr channelGetRequester;
public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelGetRequesterImpl;
};
@@ -1263,14 +1189,13 @@ public:
* <a href = "../htmldoxygen/pvaClientPut.html">Overview of PvaClientPut</a>
*/
class epicsShareClass PvaClientPut :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientPut>
{
public:
POINTER_DEFINITIONS(PvaClientPut);
/** @brief Create a PvaClientPut.
* @param &pvaClient Interface to PvaClient
* @param channel Interface to Channel
* @param pvaClient Interface to PvaClient
* @param pvaClientChannel Interface to Channel
* @param pvRequest The request structure.
* @return The interface to the PvaClientPut.
*/
@@ -1354,8 +1279,8 @@ private :
PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest);
void checkPutState();
void checkConnectState();
enum PutConnectState {connectIdle,connectActive,connected};
PvaClient::weak_pointer pvaClient;
@@ -1374,10 +1299,8 @@ private :
enum PutState {putIdle,getActive,putActive,putComplete};
PutState putState;
ChannelPutRequesterImplPtr channelPutRequester;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientPutRequesterWPtr pvaClientPutRequester;
public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelPutRequesterImpl;
};
@@ -1434,24 +1357,23 @@ public:
PvaClientPutGetPtr const & clientPutGet)
{
}
};
/**
/**
* @brief An easy to use alternative to ChannelPutGet.
*
* <a href = "../htmldoxygen/pvaClientPutGet.html">Overview of PvaClientPutGet</a>
*/
class epicsShareClass PvaClientPutGet :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientPutGet>
{
public:
POINTER_DEFINITIONS(PvaClientPutGet);
/** @brief Create a PvaClientPutGet.
* @param &pvaClient Interface to PvaClient
* @param channel Interface to Channel
* @param pvaClient Interface to PvaClient
* @param pvaClientChannel Interface to Channel
* @param pvRequest The request structure.
* @return The interface to the PvaClientPutGet.
*/
@@ -1526,11 +1448,11 @@ public:
/** @brief Get the put data.
* @return The interface.
*/
PvaClientPutDataPtr getPutData();
PvaClientPutDataPtr getPutData();
/** @brief Get the get data.
* @return The interface.
*/
PvaClientGetDataPtr getGetData();
PvaClientGetDataPtr getGetData();
/** @brief Get the PvaClientChannel;
*
* @return The interface.
@@ -1584,10 +1506,8 @@ private :
enum PutGetState {putGetIdle,putGetActive,putGetComplete};
PutGetState putGetState;
ChannelPutGetRequesterImplPtr channelPutGetRequester;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientPutGetRequesterWPtr pvaClientPutGetRequester;
public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelPutGetRequesterImpl;
};
@@ -1639,7 +1559,7 @@ typedef std::tr1::shared_ptr<MonitorRequesterImpl> MonitorRequesterImplPtr;
* <a href = "../htmldoxygen/pvaClientMonitor.html">Overview of PvaClientMonitor</a>
*/
class epicsShareClass PvaClientMonitor :
public PvaClientChannelStateChangeRequester,
public PvaClientChannelStateChangeRequester, // remove when deprecated create removed
public PvaClientMonitorRequester,
public std::tr1::enable_shared_from_this<PvaClientMonitor>
{
@@ -1664,6 +1584,7 @@ public:
* @param stateChangeRequester The state change requester. Can be null.
* @param monitorRequester The monitor requester. Can be null;
* @return The new instance.
* @deprecated client can create PvaClientMonitor on first channel connect.
*/
static PvaClientMonitorPtr create(
PvaClientPtr const &pvaClient,
@@ -1672,9 +1593,9 @@ public:
std::string const & request,
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester
= PvaClientChannelStateChangeRequesterPtr(),
PvaClientMonitorRequesterPtr const & monitorRequester
PvaClientMonitorRequesterPtr const & monitorRequester
= PvaClientMonitorRequesterPtr()
);
) EPICS_DEPRECATED;
/** @brief Destructor
*/
~PvaClientMonitor();
@@ -1735,7 +1656,7 @@ public:
*
* @return The interface.
*/
PvaClientMonitorDataPtr getData();
PvaClientMonitorDataPtr getData();
private:
std::string getRequesterName();
void message(std::string const & message,epics::pvData::MessageType messageType);
@@ -1766,16 +1687,15 @@ private:
epics::pvData::Status monitorConnectStatus;
epics::pvData::MonitorPtr monitor;
epics::pvData::MonitorElementPtr monitorElement;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientMonitorRequesterWPtr pvaClientMonitorRequester;
MonitorConnectState connectState;
bool userPoll;
bool userWait;
MonitorRequesterImplPtr monitorRequester;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; //deprecate
public:
void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected);
void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected); //deprecate
void event(PvaClientMonitorPtr const & monitor);
friend class MonitorRequesterImpl;
};
@@ -1844,7 +1764,7 @@ public:
* @brief Set a timeout for a request.
* @param responseTimeout The time in seconds to wait for a request to complete.
*/
void setResponseTimeout(double responseTimeout)
void setResponseTimeout(double responseTimeout)
{
this->responseTimeout = responseTimeout;
}
@@ -1914,18 +1834,19 @@ private:
PvaClient::weak_pointer pvaClient;
epics::pvAccess::Channel::weak_pointer channel;
epics::pvData::PVStructurePtr pvRequest;
epics::pvData::Mutex mutex;
epics::pvData::Event waitForConnect;
epics::pvData::Event waitForDone;
PvaClientRPCRequesterWPtr pvaClientRPCRequester;
PvaClientRPCRequesterWPtr pvaClientRPCRequester;
RPCRequesterImplPtr rpcRequester;
epics::pvAccess::ChannelRPC::shared_pointer channelRPC;
epics::pvData::PVStructurePtr pvResponse;
enum RPCState {rpcIdle,rpcActive,rpcComplete};
RPCState rpcState;
epics::pvData::Status requestStatus;
double responseTimeout;
friend class RPCRequesterImpl;
};
@@ -1937,6 +1858,5 @@ private:
/** @page Overview Documentation
*
* <a href = "../pvaClientCPP.html">pvaClientCPP.html</a>
*
*
*/
+24 -22
View File
@@ -21,14 +21,14 @@
#ifdef pvaClientMultiChannelEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef pvaClientMultiChannelEpicsExportSharedSymbols
# undef pvaClientMultiChannelEpicsExportSharedSymbols
#endif
#include <pv/pvaClient.h>
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
class PvaClientMultiChannel;
@@ -115,7 +115,7 @@ public:
* @brief create a pvaClientMultiGetDouble
* @return The interface.
*/
PvaClientMultiGetDoublePtr createGet();
PvaClientMultiGetDoublePtr createGet();
/**
* @brief Create a pvaClientMultiPutDouble.
* @return The interface.
@@ -152,7 +152,7 @@ private:
std::string const & providerName,
size_t maxNotConnected);
void checkConnected();
PvaClientPtr pvaClient;
epics::pvData::shared_vector<const std::string> channelName;
std::string providerName;
@@ -176,7 +176,7 @@ class epicsShareClass PvaClientMultiGetDouble :
public:
POINTER_DEFINITIONS(PvaClientMultiGetDouble);
/**
* @brief Create a PvaClientMultiGetDouble.
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
@@ -214,7 +214,7 @@ private:
PvaClientChannelArray pvaClientChannelArray;
size_t nchannel;
epics::pvData::Mutex mutex;
epics::pvData::shared_vector<double> doubleValue;
std::vector<PvaClientGetPtr> pvaClientGet;
bool isGetConnected;
@@ -229,7 +229,7 @@ class epicsShareClass PvaClientMultiPutDouble :
public:
POINTER_DEFINITIONS(PvaClientMultiPutDouble);
/** @brief Create a PvaClientMultiPutDouble.
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
* @param pvaClientChannelArray The PvaClientChannel array.
@@ -277,7 +277,7 @@ class epicsShareClass PvaClientMultiMonitorDouble :
public:
POINTER_DEFINITIONS(PvaClientMultiMonitorDouble);
/** @brief Create a PvaClientMultiMonitorDouble.
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
* @param pvaClientChannelArray The PvaClientChannel array.
@@ -360,8 +360,10 @@ public:
void connect();
/**
* @brief Get each channel.
*
* @param valueOnly use only value for union.
*/
void get();
void get(bool valueOnly = true);
/**
* @brief Get the data from the last get.
* @return the pvaClientNTMultiData.
@@ -386,8 +388,8 @@ private:
epics::pvData::PVStructurePtr pvRequest;
size_t nchannel;
epics::pvData::Mutex mutex;
PvaClientNTMultiDataPtr pvaClientNTMultiData;
std::vector<PvaClientGetPtr> pvaClientGet;
bool isConnected;
@@ -411,7 +413,7 @@ public:
static PvaClientNTMultiPutPtr create(
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
PvaClientChannelArray const &pvaClientChannelArray);
~PvaClientNTMultiPut();
/**
* @brief Connect a channelPut for each channel.
@@ -476,10 +478,11 @@ public:
/**
* @brief Poll each channel.
*
* @param valueOnly use only value for union.
* If any has new data it is used to update the double[].
* @return (false,true) if (no, at least one) value was updated.
*/
bool poll();
bool poll(bool valueOnly = true);
/**
* @brief Wait until poll returns true.
* @param secondsToWait The time to keep trying.
@@ -540,27 +543,28 @@ public:
PvaClientChannelArray const &pvaClientChannelArray,
epics::pvData::PVStructurePtr const & pvRequest);
~PvaClientNTMultiData();
/**
* @brief Get the number of channels.
* @return The number of channels.
*/
size_t getNumber();
/**
* @brief Set the timeStamp base for computing deltaTimes.
* @brief Set the timeStamp base for computing deltaTimes.
*/
void startDeltaTime();
/**
* @brief Update NTMultiChannel fields.
*
* @param valueOnly use only value for union.
*/
void endDeltaTime();
void endDeltaTime(bool valueOnly = true);
/**
* @brief Get the time when the last get was made.
* @return The timeStamp.
*/
epics::pvData::TimeStamp getTimeStamp();
epics::pvData::TimeStamp getTimeStamp();
/**
* @brief Get the NTMultiChannel.
* @return The value.
@@ -579,7 +583,6 @@ private:
PvaClientMultiChannelPtr const &pvaNTMultiChannel,
PvaClientChannelArray const &pvaClientChannelArray,
epics::pvData::PVStructurePtr const & pvRequest);
void setStructure(epics::pvData::StructureConstPtr const & structure,size_t index);
void setPVStructure(
epics::pvData::PVStructurePtr const &pvStructure,size_t index);
@@ -591,7 +594,7 @@ private:
std::vector<epics::pvData::PVStructurePtr> topPVStructure;
bool gotAlarm;
bool gotTimeStamp;
epics::pvData::StructureConstPtr ntMultiChannelStructure;
epics::pvData::shared_vector<epics::pvData::PVUnionPtr> unionValue;
epics::pvData::shared_vector<epics::pvData::int32> severity;
@@ -612,4 +615,3 @@ private:
}}
#endif /* PVACLIENTMULTICHANNEL_H */
+6 -7
View File
@@ -18,13 +18,12 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvAccess::ca;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
class epicsShareClass PvaClientChannelCache
@@ -43,7 +42,7 @@ public:
private:
map<string,PvaClientChannelPtr> pvaClientChannelMap;
};
PvaClientChannelPtr PvaClientChannelCache::getChannel(
string const & channelName,
string const & providerName)
@@ -78,7 +77,7 @@ void PvaClientChannelCache::showCache()
string providerName = channel->getProvider()->getProviderName();
cout << "channel " << channelName << " provider " << providerName << endl;
pvaChannel->showCache();
}
}
}
size_t PvaClientChannelCache::cacheSize()
@@ -111,6 +110,7 @@ PvaClientPtr PvaClient::get(std::string const & providerNames)
return master;
}
PvaClientPtr PvaClient::create() {return get();}
PvaClient::PvaClient(std::string const & providerNames)
: pvaClientChannelCache(new PvaClientChannelCache()),
@@ -137,7 +137,7 @@ PvaClient::PvaClient(std::string const & providerNames)
}
CAClientFactory::start();
caStarted = true;
} else {
} else {
if(!channelRegistry->getProvider(providerName)) {
cerr << "PvaClient::get provider " << providerName << " not known" << endl;
}
@@ -191,7 +191,7 @@ PvaClientChannelPtr PvaClient::channel(
std::string const & providerName,
double timeOut)
{
PvaClientChannelPtr pvaClientChannel =
PvaClientChannelPtr pvaClientChannel =
pvaClientChannelCache->getChannel(channelName,providerName);
if(pvaClientChannel) return pvaClientChannel;
pvaClientChannel = createChannel(channelName,providerName);
@@ -231,4 +231,3 @@ size_t PvaClient::cacheSize()
}
}}
+71 -11
View File
@@ -18,7 +18,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -170,6 +169,7 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin
<< endl;
}
Lock xx(mutex);
this->channel = channel;
if(connectState==connected) return;
if(connectState!=connectActive) {
string message("PvaClientChannel::channelCreated");
@@ -183,7 +183,7 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin
throw std::runtime_error(message);
}
if(channel->isConnected()) {
connectState = connected;
connectState = connected;
waitForConnect.signal();
}
}
@@ -198,15 +198,17 @@ void PvaClientChannel::channelStateChange(
<< " " << Channel::ConnectionStateNames[connectionState]
<< endl;
}
bool waitingForConnect = false;
if(connectState==connectActive) waitingForConnect = true;
if(connectionState!=Channel::CONNECTED) {
Lock xx(mutex);
string mess(channelName +
" connection state " + Channel::ConnectionStateNames[connectionState]);
message(mess,errorMessage);
connectState = notConnected;
} else {
Lock xx(mutex);
this->channel = channel;
connectState = connected;
}
if(waitingForConnect) {
@@ -265,7 +267,7 @@ void PvaClientChannel::connect(double timeout)
Status status = waitConnect(timeout);
if(status.isOK()) return;
if(PvaClient::getDebug()) cout << "PvaClientChannel::connect waitConnect failed\n";
string message = string("channel ") + channelName
string message = string("channel ") + channelName
+ " PvaClientChannel::connect " + status.getMessage();
throw std::runtime_error(message);
}
@@ -328,7 +330,7 @@ PvaClientProcessPtr PvaClientChannel::createProcess(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
string message = string("channel ") + channelName
string message = string("channel ") + channelName
+ " PvaClientChannel::createProcess invalid pvRequest: "
+ createRequest->getMessage();
throw std::runtime_error(message);
@@ -362,7 +364,7 @@ PvaClientGetPtr PvaClientChannel::createGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
string message = string("channel ") + channelName
string message = string("channel ") + channelName
+ " PvaClientChannel::createGet invalid pvRequest: "
+ createRequest->getMessage();
throw std::runtime_error(message);
@@ -378,6 +380,26 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest)
return PvaClientGet::create(yyy,shared_from_this(),pvRequest);
}
double PvaClientChannel::getDouble(string const & request)
{
return get(request)->getData()->getDouble();
}
string PvaClientChannel::getString(string const & request)
{
return get(request)->getData()->getString();
}
shared_vector<const double> PvaClientChannel::getDoubleArray(string const & request)
{
return get(request)->getData()->getDoubleArray();
}
shared_vector<const std::string> PvaClientChannel::getStringArray(string const & request)
{
return get(request)->getData()->getStringArray();
}
PvaClientPutPtr PvaClientChannel::put(string const & request)
{
@@ -397,7 +419,7 @@ PvaClientPutPtr PvaClientChannel::createPut(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
string message = string("channel ") + channelName
string message = string("channel ") + channelName
+ " PvaClientChannel::createPut invalid pvRequest: "
+ createRequest->getMessage();
throw std::runtime_error(message);
@@ -413,11 +435,49 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest)
return PvaClientPut::create(yyy,shared_from_this(),pvRequest);
}
void PvaClientChannel::putDouble(double value,string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
putData->putDouble(value); clientPut->put();
}
void PvaClientChannel::putString(std::string const & value,string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
putData->putString(value); clientPut->put();
}
void PvaClientChannel::putDoubleArray(
shared_vector<const double> const & value,
string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
size_t n = value.size();
shared_vector<double> valueArray(n);
for(size_t i=0; i<n; ++i) valueArray[i] = value[i];
putData->putDoubleArray(freeze(valueArray)); clientPut->put();
}
void PvaClientChannel::putStringArray(
shared_vector<const string> const & value,
string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
size_t n = value.size();
shared_vector<string> valueArray(n);
for(size_t i=0; i<n; ++i) valueArray[i] = value[i];
putData->putStringArray(freeze(valueArray)); clientPut->put();
}
PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
string message = string("channel ") + channelName
string message = string("channel ") + channelName
+ " PvaClientChannel::createPutGet invalid pvRequest: "
+ createRequest->getMessage();
throw std::runtime_error(message);
@@ -439,7 +499,7 @@ PvaClientArrayPtr PvaClientChannel::createArray(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
string message = string("channel ") + channelName
string message = string("channel ") + channelName
+ " PvaClientChannel::createArray invalid pvRequest: "
+ createRequest->getMessage();
throw std::runtime_error(message);
@@ -481,7 +541,7 @@ PvaClientMonitorPtr PvaClientChannel::createMonitor(string const & request)
{
PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) {
string message = string("channel ") + channelName
string message = string("channel ") + channelName
+ " PvaClientChannel::createMonitor invalid pvRequest: "
+ createRequest->getMessage();
throw std::runtime_error(message);
@@ -501,7 +561,7 @@ PVStructurePtr PvaClientChannel::rpc(
PVStructurePtr const & pvRequest,
PVStructurePtr const & pvArgument)
{
PvaClientRPCPtr rpc = createRPC(pvRequest);
return rpc->request(pvArgument);
}
+440
View File
@@ -0,0 +1,440 @@
/* pvaClientData.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2019.04
*/
#include <typeinfo>
#include <sstream>
#include <istream>
#include <ostream>
#include <pv/createRequest.h>
#include <pv/convert.h>
#include <pv/pvEnumerated.h>
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
# include <pv/json.h>
# define USE_JSON
#endif
#define epicsExportSharedSymbols
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvaClient {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string noAlarm("no alarm");
static string noTimeStamp("no timeStamp");
PvaClientDataPtr PvaClientData::create(StructureConstPtr const & structure)
{
if(PvaClient::getDebug()) cout << "PvaClientData::create\n";
PvaClientDataPtr epv(new PvaClientData(structure));
return epv;
}
PvaClientData::PvaClientData(StructureConstPtr const & structure)
: structure(structure)
{
}
PVFieldPtr PvaClientData::getSinglePVField()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getSinglePVField\n";
PVStructurePtr pvStructure = getPVStructure();
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()==0) {
throw std::logic_error("PvaClientData::getSinglePVField() pvRequest for empty structure");
}
if(fieldPtrArray.size()!=1) {
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type!=epics::pvData::structure) return pvValue;
}
throw std::logic_error("PvaClientData::getSinglePVField() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type!=epics::pvData::structure) return pvField;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
void PvaClientData::checkValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::checkValue\n";
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientData::getStructure()
{
return structure;
}
PVStructurePtr PvaClientData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaClientData::getChangedBitSet()
{
if(bitSet)return bitSet;
throw std::runtime_error(messagePrefix + noStructure);
}
std::ostream & PvaClientData::showChanged(std::ostream & out)
{
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
void PvaClientData::setData(
PVStructurePtr const & pvStructureFrom,
BitSetPtr const & bitSetFrom)
{
if(PvaClient::getDebug()) cout << "PvaClientData::setData\n";
pvStructure = pvStructureFrom;
bitSet = bitSetFrom;
pvValue = pvStructure->getSubField("value");
}
bool PvaClientData::hasValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::hasValue\n";
if(!pvValue) return false;
return true;
}
bool PvaClientData::isValueScalar()
{
if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalar\n";
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientData::isValueScalarArray()
{
if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalarArray\n";
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientData::getValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getValue\n";
checkValue();
return pvValue;
}
PVScalarPtr PvaClientData::getScalarValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getScalarValue\n";
checkValue();
if(pvValue->getField()->getType()!=scalar) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pvStructure->getSubField<PVScalar>("value");
}
PVArrayPtr PvaClientData::getArrayValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getArrayValue\n";
checkValue();
Type type = pvValue->getField()->getType();
if(type!=scalarArray && type!=structureArray && type!=unionArray) {
throw std::runtime_error(messagePrefix + noArray);
}
return pvStructure->getSubField<PVArray>("value");
}
PVScalarArrayPtr PvaClientData::getScalarArrayValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getScalarArrayValue\n";
checkValue();
Type type = pvValue->getField()->getType();
if(type!=scalarArray) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pvStructure->getSubField<PVScalarArray>("value");
}
double PvaClientData::getDouble()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getDouble\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalar) {
throw std::logic_error("PvaClientData::getDouble() did not find a scalar field");
}
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error(
"PvaClientData::getDouble() did not find a numeric scalar field");
}
return convert->toDouble(pvScalar);
}
string PvaClientData::getString()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getString\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalar) {
throw std::logic_error("PvaClientData::getString() did not find a scalar field");
}
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientData::getDoubleArray()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalarArray) {
throw std::logic_error("PvaClientData::getDoubleArray() did not find a scalarArray field");
}
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error(
"PvaClientData::getDoubleArray() did not find a numeric scalarArray field");
}
shared_vector<const double> retValue;
pvScalarArray->getAs<const double>(retValue);
return retValue;
}
shared_vector<const string> PvaClientData::getStringArray()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getStringArray\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalarArray) {
throw std::logic_error("PvaClientData::getStringArray() did not find a scalarArray field");
}
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
shared_vector<const string> retValue;
pvScalarArray->getAs<const string>(retValue);
return retValue;
}
Alarm PvaClientData::getAlarm()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getAlarm\n";
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("alarm");
if(!pvs) throw std::runtime_error(messagePrefix + noAlarm);
pvAlarm.attach(pvs);
if(pvAlarm.isAttached()) {
Alarm alarm;
pvAlarm.get(alarm);
pvAlarm.detach();
return alarm;
}
throw std::runtime_error(messagePrefix + noAlarm);
}
TimeStamp PvaClientData::getTimeStamp()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getTimeStamp\n";
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("timeStamp");
if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp);
pvTimeStamp.attach(pvs);
if(pvTimeStamp.isAttached()) {
TimeStamp timeStamp;
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
return timeStamp;
}
throw std::runtime_error(messagePrefix + noTimeStamp);
}
void PvaClientData::zeroArrayLength()
{
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
zeroArrayLength(pvStructure);
}
void PvaClientData::parse(
const std::string &arg,const PVFieldPtr &dest,BitSetPtr & bitSet)
{
#ifdef USE_JSON
std::istringstream strm(arg);
parseJSON(strm, dest,&(*bitSet));
#else
throw std::runtime_error("JSON support not built");
#endif
}
void PvaClientData::parse(
const std::string &arg,const PVUnionPtr &pvUnion)
{
if(pvUnion->getUnion()->isVariant()) {
throw std::runtime_error(messagePrefix + "varient union not implemented");
}
size_t iequals = arg.find_first_of('=');
string field;
string rest;
if(iequals==std::string::npos) {
string mess(arg);
mess += " was expected to start with field=";
throw std::runtime_error(messagePrefix + mess);
}
field = arg.substr(0,iequals);
rest = arg.substr(iequals+1);
PVFieldPtr pvField(pvUnion->select(field));
if(pvField->getField()->getType()==epics::pvData::union_) {
PVUnionPtr pvu = static_pointer_cast<PVUnion>(pvField);
parse(rest,pvu);
return;
}
BitSetPtr bs;
parse(rest,pvField,bs);
return;
}
void PvaClientData::parse(const std::vector<std::string> &args)
{
if(!pvStructure) throw std::runtime_error(messagePrefix + noStructure);
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t num = args.size();
if(num<1) throw std::runtime_error(messagePrefix + " no arguments");
for(size_t i=0; i<num; ++i)
{
string val = args[i];
size_t iequals = val.find_first_of('=');
string field;
string rest(val);
if(iequals==std::string::npos) {
parse(rest,pvStructure,bitSet);
continue;
}
field = val.substr(0,iequals);
rest = val.substr(iequals+1);
if(field.size()==std::string::npos) {
parse(rest,pvStructure,bitSet);
continue;
}
PVFieldPtr pvField(pvStructure->getSubField(field));
if(!pvField) throw std::runtime_error(messagePrefix + field +" does not exist");
// look for enumerated structure
PVEnumerated pvEnumerated;
bool result = pvEnumerated.attach(pvField);
if(result) {
PVStringArray::const_svector choices(pvEnumerated.getChoices());
for(size_t i=0; i<choices.size(); ++i) {
if(choices[i]==rest) {
pvEnumerated.setIndex(i);
return;
}
}
}
// look for union
PVUnionPtr pvUnion(pvStructure->getSubField<PVUnion>(field));
if(pvUnion) {
parse(rest,pvUnion);
bitSet->set(pvUnion->getFieldOffset());
return;
}
parse(rest,pvField,bitSet);
}
}
void PvaClientData::streamJSON(
std::ostream& strm,
bool ignoreUnprintable,
bool multiLine)
{
#ifdef USE_JSON
JSONPrintOptions opts;
opts.ignoreUnprintable = ignoreUnprintable;
opts.multiLine = multiLine;
printJSON(strm,*pvStructure,*bitSet,opts);
#else
throw std::runtime_error("JSON support not built");
#endif
}
void PvaClientData::zeroArrayLength(const epics::pvData::PVStructurePtr &pvStructure)
{
const PVFieldPtrArray pvFields(pvStructure->getPVFields());
for(size_t i=0; i<pvFields.size(); ++i) {
PVFieldPtr pvField = pvFields[i];
Type type(pvField->getField()->getType());
switch(type) {
case epics::pvData::scalarArray:
{
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
pvScalarArray->setLength(0);
}
break;
case epics::pvData::structureArray:
{
PVStructureArrayPtr pvStructureArray = static_pointer_cast<PVStructureArray>(pvField);
pvStructureArray->setLength(0);
}
break;
case epics::pvData::structure:
{
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
zeroArrayLength(pvStructure);
}
break;
default:
break;
}
}
}
}}
+33 -63
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -56,7 +55,7 @@ public:
{
PvaClientGetPtr clientGet(pvaClientGet.lock());
if(!clientGet) return;
clientGet->channelGetConnect(status,channelGet,structure);
clientGet->channelGetConnect(status,channelGet,structure);
}
virtual void getDone(
@@ -99,50 +98,29 @@ PvaClientGet::PvaClientGet(
getState(getIdle)
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::PvaClientGet::PvaClientGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::PvaClientGet channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
}
PvaClientGet::~PvaClientGet()
{
if(PvaClient::getDebug()) {
cout<< "PvaClientGet::~PvaClientGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout<< "PvaClientGet::~PvaClientGet channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
}
void PvaClientGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientGet::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!channelGet)
{
connectState = connectActive;
channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientGet::checkGetState()
void PvaClientGet::checkConnectState()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::checkGetState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::checkConnectState channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
if(!pvaClientChannel->getChannel()->isConnected()) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientGet::checkGetState channel not connected ";
+ " PvaClientGet::checkConnectState channel not connected ";
throw std::runtime_error(message);
}
if(connectState==connectIdle) {
@@ -177,10 +155,10 @@ void PvaClientGet::channelGetConnect(
StructureConstPtr const & structure)
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::channelGetConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
cout << "PvaClientGet::channelGetConnect channelName "
<< pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
<< "\n";
}
{
Lock xx(mutex);
@@ -204,7 +182,7 @@ void PvaClientGet::channelGetConnect(
req->channelGetConnect(status,shared_from_this());
}
waitForConnect.signal();
}
void PvaClientGet::getDone(
@@ -214,10 +192,10 @@ void PvaClientGet::getDone(
BitSetPtr const & bitSet)
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::getDone"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
cout << "PvaClientGet::getDone channelName "
<< pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
<< "\n";
}
{
Lock xx(mutex);
@@ -237,9 +215,8 @@ void PvaClientGet::getDone(
void PvaClientGet::connect()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::connect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::connect channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
issueConnect();
Status status = waitConnect();
@@ -252,9 +229,8 @@ void PvaClientGet::connect()
void PvaClientGet::issueConnect()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::issueConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::issueConnect channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
if(connectState!=connectIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
@@ -269,9 +245,8 @@ void PvaClientGet::issueConnect()
Status PvaClientGet::waitConnect()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitConnect"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::waitConnect channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
{
Lock xx(mutex);
@@ -293,9 +268,8 @@ Status PvaClientGet::waitConnect()
void PvaClientGet::get()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::get"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::get channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
issueGet();
Status status = waitGet();
@@ -308,9 +282,8 @@ void PvaClientGet::get()
void PvaClientGet::issueGet()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::issueGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::issueGet channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
if(connectState==connectIdle) connect();
if(getState==getActive) {
@@ -325,9 +298,8 @@ void PvaClientGet::issueGet()
Status PvaClientGet::waitGet()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitGet"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::waitGet channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
{
Lock xx(mutex);
@@ -348,11 +320,10 @@ Status PvaClientGet::waitGet()
PvaClientGetDataPtr PvaClientGet::getData()
{
if(PvaClient::getDebug()) {
cout<< "PvaClientGet::getData"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout<< "PvaClientGet::getData channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
checkGetState();
checkConnectState();
if(getState==getIdle) get();
return pvaClientData;
}
@@ -360,9 +331,8 @@ PvaClientGetDataPtr PvaClientGet::getData()
void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester)
{
if(PvaClient::getDebug()) {
cout << "PvaClientGet::setRequester"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
cout << "PvaClientGet::setRequester channelName "
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
}
this->pvaClientGetRequester = pvaClientGetRequester;
}
+3 -203
View File
@@ -19,7 +19,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -27,214 +26,15 @@ using namespace std;
namespace epics { namespace pvaClient {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
static string noAlarm("no alarm");
static string noTimeStamp("no timeStamp");
PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure)
{
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::create"
<< endl;
}
if(PvaClient::getDebug()) cout << "PvaClientGetData::create\n";
PvaClientGetDataPtr epv(new PvaClientGetData(structure));
return epv;
}
PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure)
: structure(structure),
pvStructure(getPVDataCreate()->createPVStructure(structure)),
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
{
messagePrefix = "";
pvValue = pvStructure->getSubField("value");
}
void PvaClientGetData::checkValue()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::checkValue"
<< endl;
}
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientGetData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientGetData::getStructure()
{return structure;}
PVStructurePtr PvaClientGetData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaClientGetData::getChangedBitSet()
{
if(bitSet)return bitSet;
throw std::runtime_error(messagePrefix + noStructure);
}
std::ostream & PvaClientGetData::showChanged(std::ostream & out)
{
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
void PvaClientGetData::setData(
PVStructurePtr const & pvStructureFrom,
BitSetPtr const & bitSetFrom)
{
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::setData"
<< endl;
}
pvStructure = pvStructureFrom;
bitSet = bitSetFrom;
pvValue = pvStructure->getSubField("value");
}
bool PvaClientGetData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaClientGetData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientGetData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientGetData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaClientGetData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) throw std::runtime_error(messagePrefix + noScalar);
return pv;
}
PVArrayPtr PvaClientGetData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + noArray);
return pv;
}
PVScalarArrayPtr PvaClientGetData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + noScalarArray);
return pv;
}
double PvaClientGetData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaClientGetData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientGetData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray);
return pv->view();
}
shared_vector<const string> PvaClientGetData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notStringArray);
return pv->view();
}
Alarm PvaClientGetData::getAlarm()
{
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("alarm");
if(!pvs) throw std::runtime_error(messagePrefix + noAlarm);
pvAlarm.attach(pvs);
if(pvAlarm.isAttached()) {
Alarm alarm;
pvAlarm.get(alarm);
pvAlarm.detach();
return alarm;
}
throw std::runtime_error(messagePrefix + noAlarm);
}
TimeStamp PvaClientGetData::getTimeStamp()
{
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("timeStamp");
if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp);
pvTimeStamp.attach(pvs);
if(pvTimeStamp.isAttached()) {
TimeStamp timeStamp;
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
return timeStamp;
}
throw std::runtime_error(messagePrefix + noTimeStamp);
}
: PvaClientData(structure)
{}
}}
+13 -28
View File
@@ -17,8 +17,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -59,21 +57,21 @@ public:
{
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
if(!clientMonitor) return;
clientMonitor->monitorConnect(status,monitor,structure);
clientMonitor->monitorConnect(status,monitor,structure);
}
virtual void unlisten(epics::pvData::MonitorPtr const & monitor)
{
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
if(!clientMonitor) return;
clientMonitor->unlisten(monitor);
clientMonitor->unlisten(monitor);
}
virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor)
{
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
if(!clientMonitor) return;
clientMonitor->monitorEvent(monitor);
clientMonitor->monitorEvent(monitor);
}
};
@@ -83,11 +81,6 @@ PvaClientMonitorPtr PvaClientMonitor::create(
PvaClientChannelPtr const & pvaClientChannel,
PVStructurePtr const &pvRequest)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::create(pvaClient,pvaClientChannel,pvRequest)\n"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
clientMonitor->monitorRequester = MonitorRequesterImplPtr(
new MonitorRequesterImpl(clientMonitor,pvaClient));
@@ -137,7 +130,9 @@ PvaClientMonitor::PvaClientMonitor(
userWait(false)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::PvaClientMonitor()" << endl;
cout<< "PvaClientMonitor::PvaClientMonitor\n"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
}
@@ -174,6 +169,11 @@ void PvaClientMonitor::channelStateChange(PvaClientChannelPtr const & channel, b
void PvaClientMonitor::event(PvaClientMonitorPtr const & monitor)
{
if(PvaClient::getDebug()) {
cout << "PvaClientMonitor::event"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock());
if(req) req->event(monitor);
}
@@ -276,7 +276,7 @@ void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor)
cout << "PvaClientMonitor::monitorEvent"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
}
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
if(req) req->event(shared_from_this());
if(userWait) waitForEvent.signal();
@@ -300,7 +300,7 @@ void PvaClientMonitor::connect()
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
string message = string("channel ")
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::connect "
+ status.getMessage();
@@ -434,16 +434,6 @@ bool PvaClientMonitor::poll()
<< endl;
}
checkMonitorState();
if(!isStarted) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::poll illegal state ";
throw std::runtime_error(message);
}
if(userPoll) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::poll did not release last";
throw std::runtime_error(message);
}
monitorElement = monitor->poll();
if(!monitorElement) return false;
userPoll = true;
@@ -481,11 +471,6 @@ void PvaClientMonitor::releaseEvent()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(!isStarted) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::releaseEvent monitor not started ";
throw std::runtime_error(message);
}
if(!userPoll) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::releaseEvent did not call poll";
+6 -183
View File
@@ -19,7 +19,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -53,43 +52,16 @@ PvaClientMonitorDataPtr PvaClientMonitorData::create(StructureConstPtr const & s
}
PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure)
: structure(structure)
: PvaClientData(structure)
{
messagePrefix = "";
}
void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement)
{
pvStructure = monitorElement->pvStructurePtr;
changedBitSet = monitorElement->changedBitSet;
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
BitSetPtr changedBitSet = monitorElement->changedBitSet;
PvaClientData::setData(pvStructure,changedBitSet);
overrunBitSet = monitorElement->overrunBitSet;
pvValue = pvStructure->getSubField("value");
}
void PvaClientMonitorData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientMonitorData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientMonitorData::getStructure()
{return structure;}
PVStructurePtr PvaClientMonitorData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaClientMonitorData::getChangedBitSet()
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
return changedBitSet;
}
BitSetPtr PvaClientMonitorData::getOverrunBitSet()
@@ -98,24 +70,6 @@ BitSetPtr PvaClientMonitorData::getOverrunBitSet()
return overrunBitSet;
}
std::ostream & PvaClientMonitorData::showChanged(std::ostream & out)
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = changedBitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = changedBitSet->nextSetBit(nextSet+1);
}
return out;
}
std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
{
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
@@ -123,9 +77,9 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
pvField = getPVStructure();
} else {
pvField = pvStructure->getSubField(nextSet);
pvField = getPVStructure()->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
@@ -134,135 +88,4 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
return out;
}
bool PvaClientMonitorData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaClientMonitorData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientMonitorData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientMonitorData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaClientMonitorData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pv;
}
PVArrayPtr PvaClientMonitorData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noArray);
}
return pv;
}
PVScalarArrayPtr PvaClientMonitorData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pv;
}
double PvaClientMonitorData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaClientMonitorData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientMonitorData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> PvaClientMonitorData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
Alarm PvaClientMonitorData::getAlarm()
{
if(!pvStructure) {
throw std::runtime_error(messagePrefix + noAlarm);
}
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("alarm");
if(!pvs) throw std::runtime_error(messagePrefix + noAlarm);
pvAlarm.attach(pvs);
if(pvAlarm.isAttached()) {
Alarm alarm;
pvAlarm.get(alarm);
pvAlarm.detach();
return alarm;
}
throw std::runtime_error(messagePrefix + noAlarm);
}
TimeStamp PvaClientMonitorData::getTimeStamp()
{
if(!pvStructure) {
throw std::runtime_error(messagePrefix + noTimeStamp);
}
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("timeStamp");
if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp);
pvTimeStamp.attach(pvs);
if(pvTimeStamp.isAttached()) {
TimeStamp timeStamp;
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
return timeStamp;
}
throw std::runtime_error(messagePrefix + noTimeStamp);
}
}}
+2 -5
View File
@@ -17,9 +17,6 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -83,7 +80,7 @@ Status PvaClientMultiChannel::connect(double timeout)
Status status = Status::Ok;
size_t numBad = 0;
for(size_t i=0; i< numChannel; ++i) {
if(numBad==0) {
if(numBad==0) {
status = pvaClientChannelArray[i]->waitConnect(timeout);
} else {
status = pvaClientChannelArray[i]->waitConnect(.001);
@@ -143,7 +140,7 @@ PvaClientPtr PvaClientMultiChannel::getPvaClient()
return pvaClient;
}
PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet()
{
+3 -4
View File
@@ -16,13 +16,12 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
PvaClientMultiGetDoublePtr PvaClientMultiGetDouble::create(
@@ -80,7 +79,7 @@ epics::pvData::shared_vector<double> PvaClientMultiGetDouble::get()
{
if(!isGetConnected) connect();
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
for(size_t i=0; i<nchannel; ++i)
{
if(isConnected[i]) {
@@ -97,7 +96,7 @@ epics::pvData::shared_vector<double> PvaClientMultiGetDouble::get()
throw std::runtime_error(message);
}
}
for(size_t i=0; i<nchannel; ++i)
{
if(isConnected[i])
+1 -2
View File
@@ -16,13 +16,12 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
PvaClientMultiMonitorDoublePtr PvaClientMultiMonitorDouble::create(
+1 -2
View File
@@ -16,13 +16,12 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
PvaClientMultiPutDoublePtr PvaClientMultiPutDouble::create(
+34 -28
View File
@@ -15,13 +15,12 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
PvaClientNTMultiDataPtr PvaClientNTMultiData::create(
epics::pvData::UnionConstPtr const & u,
@@ -45,10 +44,6 @@ PvaClientNTMultiData::PvaClientNTMultiData(
gotTimeStamp(false)
{
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::PvaClientNTMultiData()\n";
PVFieldPtr pvValue = pvRequest->getSubField("field.value");
if(!pvValue) {
throw std::runtime_error("pvRequest did not specify value");
}
topPVStructure.resize(nchannel);
unionValue.resize(nchannel);
PVDataCreatePtr pvDataCreate = getPVDataCreate();
@@ -68,7 +63,7 @@ PvaClientNTMultiData::PvaClientNTMultiData(
severity.resize(nchannel);
status.resize(nchannel);
message.resize(nchannel);
}
if(pvRequest->getSubField("field.timeStamp")) {
gotTimeStamp = true;
@@ -89,18 +84,6 @@ PvaClientNTMultiData::~PvaClientNTMultiData()
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::~PvaClientNTMultiData()\n";
}
void PvaClientNTMultiData::setStructure(StructureConstPtr const & structure,size_t index)
{
FieldConstPtr field = structure->getField("value");
if(!field) {
string message = "channel "
+ pvaClientChannelArray[index]->getChannel()->getChannelName()
+ " does not have top level value field";
throw std::runtime_error(message);
}
}
void PvaClientNTMultiData::setPVStructure(
PVStructurePtr const &pvStructure,size_t index)
{
@@ -138,7 +121,7 @@ void PvaClientNTMultiData::startDeltaTime()
}
void PvaClientNTMultiData::endDeltaTime()
void PvaClientNTMultiData::endDeltaTime(bool valueOnly)
{
for(size_t i=0; i<nchannel; ++i)
{
@@ -146,20 +129,43 @@ void PvaClientNTMultiData::endDeltaTime()
if(!pvst) {
unionValue[i] = PVUnionPtr();
} else if(unionValue[i]) {
unionValue[i]->set(pvst->getSubField("value"));
if(valueOnly) {
PVFieldPtr pvValue = pvst->getSubField("value");
if(pvValue) {
unionValue[i]->set(pvst->getSubField("value"));
} else {
unionValue[i] = PVUnionPtr();
}
} else {
unionValue[i]->set(pvst);
}
if(gotAlarm)
{
severity[i] = pvst->getSubField<PVInt>("alarm.severity")->get();
status[i] = pvst->getSubField<PVInt>("alarm.status")->get();
message[i] = pvst->getSubField<PVString>("alarm.message")->get();
PVIntPtr pvSeverity = pvst->getSubField<PVInt>("alarm.severity");
PVIntPtr pvStatus = pvst->getSubField<PVInt>("alarm.status");
PVStringPtr pvMessage = pvst->getSubField<PVString>("alarm.message");
if(pvSeverity&&pvStatus&&pvMessage) {
severity[i] = pvSeverity->get();
status[i] = pvStatus->get();
message[i] = pvMessage->get();
} else {
severity[i] = undefinedAlarm;
status[i] = undefinedStatus;
message[i] = "no alarm field";
}
}
if(gotTimeStamp)
{
secondsPastEpoch[i] = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch")->get();
nanoseconds[i] = pvst->getSubField<PVInt>("timeStamp.nanoseconds")->get();
userTag[i] = pvst->getSubField<PVInt>("timeStamp.userTag")->get();
PVLongPtr pvEpoch = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch");
PVIntPtr pvNano = pvst->getSubField<PVInt>("timeStamp.nanoseconds");
PVIntPtr pvTag = pvst->getSubField<PVInt>("timeStamp.userTag");
if(pvEpoch&&pvNano&&pvTag) {
secondsPastEpoch[i] = pvEpoch->get();
nanoseconds[i] = pvNano->get();
userTag[i] = pvTag->get();
}
}
}
}
}
}
+7 -11
View File
@@ -15,13 +15,12 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
PvaClientNTMultiGetPtr PvaClientNTMultiGet::create(
@@ -64,13 +63,10 @@ void PvaClientNTMultiGet::connect()
{
pvaClientGet.resize(nchannel);
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
string request = "value";
if(pvRequest->getSubField("field.alarm")) request += ",alarm";
if(pvRequest->getSubField("field.timeStamp")) request += ",timeStamp";
for(size_t i=0; i<nchannel; ++i)
{
if(isConnected[i]) {
pvaClientGet[i] = pvaClientChannelArray[i]->createGet(request);
pvaClientGet[i] = pvaClientChannelArray[i]->createGet(pvRequest);
pvaClientGet[i]->issueConnect();
}
}
@@ -79,7 +75,7 @@ void PvaClientNTMultiGet::connect()
if(isConnected[i]) {
Status status = pvaClientGet[i]->waitConnect();
if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelGet::waitConnect " + status.getMessage();
throw std::runtime_error(message);
}
@@ -87,11 +83,11 @@ void PvaClientNTMultiGet::connect()
this->isConnected = true;
}
void PvaClientNTMultiGet::get()
void PvaClientNTMultiGet::get(bool valueOnly)
{
if(!isConnected) connect();
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
for(size_t i=0; i<nchannel; ++i)
{
if(isConnected[i]) {
@@ -103,7 +99,7 @@ void PvaClientNTMultiGet::get()
if(isConnected[i]) {
Status status = pvaClientGet[i]->waitGet();
if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelGet::waitGet " + status.getMessage();
throw std::runtime_error(message);
}
@@ -115,7 +111,7 @@ void PvaClientNTMultiGet::get()
pvaClientNTMultiData->setPVStructure(pvaClientGet[i]->getData()->getPVStructure(),i);
}
}
pvaClientNTMultiData->endDeltaTime();
pvaClientNTMultiData->endDeltaTime(valueOnly);
}
PvaClientNTMultiDataPtr PvaClientNTMultiGet::getData()
+5 -9
View File
@@ -18,13 +18,12 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
PvaClientNTMultiMonitorPtr PvaClientNTMultiMonitor::create(
PvaClientMultiChannelPtr const &pvaMultiChannel,
@@ -68,13 +67,10 @@ void PvaClientNTMultiMonitor::connect()
{
pvaClientMonitor.resize(nchannel);
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
string request = "value";
if(pvRequest->getSubField("field.alarm")) request += ",alarm";
if(pvRequest->getSubField("field.timeStamp")) request += ",timeStamp";
for(size_t i=0; i<nchannel; ++i)
{
if(isConnected[i]) {
pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(request);
pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(pvRequest);
pvaClientMonitor[i]->issueConnect();
}
}
@@ -83,7 +79,7 @@ void PvaClientNTMultiMonitor::connect()
if(isConnected[i]) {
Status status = pvaClientMonitor[i]->waitConnect();
if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelMonitor::waitConnect " + status.getMessage();
throw std::runtime_error(message);
}
@@ -95,7 +91,7 @@ void PvaClientNTMultiMonitor::connect()
this->isConnected = true;
}
bool PvaClientNTMultiMonitor::poll()
bool PvaClientNTMultiMonitor::poll(bool valueOnly)
{
if(!isConnected) connect();
bool result = false;
@@ -112,7 +108,7 @@ bool PvaClientNTMultiMonitor::poll()
}
}
}
if(result) pvaClientNTMultiData->endDeltaTime();
if(result) pvaClientNTMultiData->endDeltaTime(valueOnly);
return result;
}
+5 -6
View File
@@ -17,13 +17,12 @@
#include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::nt;
using namespace std;
namespace epics { namespace pvaClient {
namespace epics { namespace pvaClient {
PvaClientNTMultiPutPtr PvaClientNTMultiPut::create(
PvaClientMultiChannelPtr const &pvaMultiChannel,
@@ -68,7 +67,7 @@ void PvaClientNTMultiPut::connect()
if(isConnected[i]) {
Status status = pvaClientPut[i]->waitConnect();
if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelPut::waitConnect " + status.getMessage();
throw std::runtime_error(message);
}
@@ -84,7 +83,7 @@ void PvaClientNTMultiPut::connect()
if(isConnected[i]) {
Status status = pvaClientPut[i]->waitGet();
if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelPut::waitGet " + status.getMessage();
throw std::runtime_error(message);
}
@@ -122,9 +121,9 @@ void PvaClientNTMultiPut::put()
if(isConnected[i]) {
Status status = pvaClientPut[i]->waitPut();
if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelPut::waitPut " + status.getMessage();
throw std::runtime_error(message);
throw std::runtime_error(message);
}
}
}
+5 -49
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -55,7 +54,7 @@ public:
{
PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
if(!clientProcess) return;
clientProcess->channelProcessConnect(status,channelProcess);
clientProcess->channelProcessConnect(status,channelProcess);
}
virtual void processDone(
@@ -112,50 +111,6 @@ PvaClientProcess::~PvaClientProcess()
}
}
void PvaClientProcess::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientProcess::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected)
{
connectState = connectActive;
channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientProcess::checkProcessState()
{
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::checkProcessState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(!pvaClientChannel->getChannel()->isConnected()) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientProcess::checkProcessState channel not connected ";
throw std::runtime_error(message);
}
if(connectState==connectIdle) {
connect();
}
if(connectState==connectActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " "
+ channelProcessConnectStatus.getMessage();
throw std::runtime_error(message);
}
if(processState==processIdle) process();
}
// from ChannelProcessRequester
string PvaClientProcess::getRequesterName()
{
@@ -201,7 +156,7 @@ void PvaClientProcess::channelProcessConnect(
req->channelProcessConnect(status,shared_from_this());
}
waitForConnect.signal();
}
void PvaClientProcess::processDone(
@@ -219,7 +174,7 @@ void PvaClientProcess::processDone(
channelProcessStatus = status;
processState = processComplete;
}
PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
if(req) {
req->processDone(status,shared_from_this());
@@ -255,6 +210,7 @@ void PvaClientProcess::issueConnect()
throw std::runtime_error(message);
}
connectState = connectActive;
channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
}
@@ -302,7 +258,7 @@ void PvaClientProcess::issueProcess()
<< endl;
}
if(connectState==connectIdle) connect();
if(processState!=processIdle) {
if(processState==processActive) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientProcess::issueProcess process aleady active ";
throw std::runtime_error(message);
+44 -49
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -56,7 +55,7 @@ public:
{
PvaClientPutPtr clientPut(pvaClientPut.lock());
if(!clientPut) return;
clientPut->channelPutConnect(status,channelPut,structure);
clientPut->channelPutConnect(status,channelPut,structure);
}
virtual void getDone(
@@ -118,29 +117,11 @@ PvaClientPut::~PvaClientPut()
}
}
void PvaClientPut::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientPut::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!channelPut)
{
connectState = connectActive;
channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientPut::checkPutState()
void PvaClientPut::checkConnectState()
{
if(PvaClient::getDebug()) {
cout << "PvaClientPut::checkPutState"
cout << "PvaClientPut::checkConnectState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
@@ -202,7 +183,7 @@ void PvaClientPut::channelPutConnect(
req->channelPutConnect(status,shared_from_this());
}
waitForConnect.signal();
}
void PvaClientPut::getDone(
@@ -217,13 +198,17 @@ void PvaClientPut::getDone(
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
}
channelGetPutStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = pvaClientData->getPVStructure();
pvs->copyUnchecked(*pvStructure,*bitSet);
BitSetPtr bs = pvaClientData->getChangedBitSet();
bs->clear();
*bs |= *bitSet;
{
Lock xx(mutex);
channelGetPutStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = pvaClientData->getPVStructure();
pvs->copyUnchecked(*pvStructure,*bitSet);
BitSetPtr bs = pvaClientData->getChangedBitSet();
bs->clear();
*bs |= *bitSet;
putState = putComplete;
}
}
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
if(req) {
@@ -242,7 +227,11 @@ void PvaClientPut::putDone(
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
}
channelGetPutStatus = status;
{
Lock xx(mutex);
channelGetPutStatus = status;
putState = putComplete;
}
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
if(req) {
req->putDone(status,shared_from_this());
@@ -260,7 +249,7 @@ void PvaClientPut::connect()
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
string message = string("channel ")
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::connect "
+ status.getMessage();
@@ -282,7 +271,7 @@ void PvaClientPut::issueConnect()
connectState = connectActive;
channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest);
}
Status PvaClientPut::waitConnect()
@@ -319,7 +308,7 @@ void PvaClientPut::get()
issueGet();
Status status = waitGet();
if(status.isOK()) return;
string message = string("channel ")
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::get "
+ status.getMessage();
@@ -351,14 +340,17 @@ Status PvaClientPut::waitGet()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putState!=getActive){
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::waitGet illegal put state";
throw std::runtime_error(message);
{
Lock xx(mutex);
if(putState==putComplete) return channelGetPutStatus;
if(putState!=getActive){
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::waitGet illegal put state";
throw std::runtime_error(message);
}
}
waitForGetPut.wait();
putState = putComplete;
return channelGetPutStatus;
}
@@ -384,7 +376,7 @@ void PvaClientPut::issuePut()
if(PvaClient::getDebug()) {
cout << "PvaClientPut::issuePut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " pvStructure\n" << pvaClientData->getPVStructure()
<< " pvStructure\n" << pvaClientData->getPVStructure()
<< " bitSet " << *pvaClientData->getChangedBitSet() << endl
<< endl;
}
@@ -392,7 +384,7 @@ void PvaClientPut::issuePut()
if(putState==getActive || putState==putActive) {
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ "PvaClientPut::issueGet get or put aleady active ";
+ "PvaClientPut::issuePut get or put aleady active ";
throw std::runtime_error(message);
}
putState = putActive;
@@ -406,14 +398,17 @@ Status PvaClientPut::waitPut()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putState!=putActive){
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::waitPut illegal put state";
throw std::runtime_error(message);
{
Lock xx(mutex);
if(putState==putComplete) return channelGetPutStatus;
if(putState!=putActive){
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::waitPut illegal put state";
throw std::runtime_error(message);
}
}
waitForGetPut.wait();
putState = putComplete;
if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear();
return channelGetPutStatus;
}
@@ -425,7 +420,7 @@ PvaClientPutDataPtr PvaClientPut::getData()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
checkPutState();
checkConnectState();
if(putState==putIdle) get();
return pvaClientData;
}
+59 -168
View File
@@ -25,6 +25,10 @@ using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvaClient {
static ConvertPtr convert = getConvert();
static string notCompatibleScalar("value is not a compatible scalar");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
class PvaClientPostHandlerPvt: public PostHandler
{
@@ -36,28 +40,21 @@ public:
void postPut() { putData->postPut(fieldNumber);}
};
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noValue("no value field");
static string notScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string notArray("value is not an array");
static string notScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure)
{
if(PvaClient::getDebug()) cout << "PvaClientPutData::create\n";
PvaClientPutDataPtr epv(new PvaClientPutData(structure));
return epv;
}
PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure)
: structure(structure),
pvStructure(getPVDataCreate()->createPVStructure(structure)),
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
: PvaClientData(structure)
{
messagePrefix = "";
if(PvaClient::getDebug()) cout << "PvaClientPutData::PvaClientPutData\n";
PVStructurePtr pvStructure(getPVDataCreate()->createPVStructure(structure));
BitSetPtr bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())));
setData(pvStructure,bitSet);
size_t nfields = pvStructure->getNumberFields();
postHandler.resize(nfields);
PVFieldPtr pvField;
@@ -71,145 +68,18 @@ PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure)
}
pvField->setPostHandler(postHandler[i]);
}
pvValue = pvStructure->getSubField("value");
}
void PvaClientPutData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientPutData::postPut(size_t fieldNumber)
{
bitSet->set(fieldNumber);
}
void PvaClientPutData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientPutData::getStructure()
{return structure;}
PVStructurePtr PvaClientPutData::getPVStructure()
{return pvStructure;}
BitSetPtr PvaClientPutData::getChangedBitSet()
{return bitSet;}
std::ostream & PvaClientPutData::showChanged(std::ostream & out)
{
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
bool PvaClientPutData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaClientPutData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientPutData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientPutData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaClientPutData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) throw std::runtime_error(messagePrefix + notScalar);
return pv;
}
PVArrayPtr PvaClientPutData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notArray);
return pv;
}
PVScalarArrayPtr PvaClientPutData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notScalarArray);
return pv;
}
double PvaClientPutData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaClientPutData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientPutData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> PvaClientPutData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
void PvaClientPutData::putDouble(double value)
{
PVScalarPtr pvScalar = getScalarValue();
if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalar) {
throw std::logic_error("PvaClientData::putDouble() did not find a scalar field");
}
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
@@ -217,47 +87,68 @@ void PvaClientPutData::putDouble(double value)
return;
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
throw std::logic_error(
"PvaClientData::putDouble() did not find a numeric scalar field");
}
convert->fromDouble(pvScalar,value);
}
void PvaClientPutData::putString(std::string const & value)
{
PVScalarPtr pvScalar = getScalarValue();
if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalar) {
throw std::logic_error("PvaClientData::putString() did not find a scalar field");
}
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
convert->fromString(pvScalar,value);
}
void PvaClientPutData::putDoubleArray(shared_vector<const double> const & value)
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalarArray) {
throw std::logic_error("PvaClientData::putDoubleArray() did not find a scalarArray field");
}
pv->replace(value);
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error(
"PvaClientData::putDoubleArray() did not find a numeric scalarArray field");
}
pvScalarArray->putFrom<const double>(value);
}
void PvaClientPutData::putStringArray(shared_vector<const std::string> const & value)
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n";
PVFieldPtr pvField = getSinglePVField();
Type type = pvField->getField()->getType();
if(type!=scalarArray) {
throw std::logic_error("PvaClientData::putStringArray() did not find a scalarArray field");
}
pv->replace(value);
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
pvScalarArray->putFrom<const string>(value);
return;
}
void PvaClientPutData::putStringArray(std::vector<std::string> const & value)
void PvaClientPutData::putStringArray(std::vector<string> const & value)
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notScalarArray);
}
convert->fromStringArray(pv,0,value.size(),value,0);
size_t length = value.size();
shared_vector<string> val(length);
for(size_t i=0; i < length; ++i) val[i] = value[i];
putStringArray(freeze(val));
return;
}
void PvaClientPutData::postPut(size_t fieldNumber)
{
if(PvaClient::getDebug()) cout << "PvaClientPutData::postPut\n";
getChangedBitSet()->set(fieldNumber);
}
}}
+43 -55
View File
@@ -14,7 +14,6 @@
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -56,7 +55,7 @@ public:
{
PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
if(!clientPutGet) return;
clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
}
virtual void putGetDone(
@@ -131,25 +130,6 @@ PvaClientPutGet::~PvaClientPutGet()
}
}
void PvaClientPutGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientPutGet::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!channelPutGet)
{
connectState = connectActive;
channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientPutGet::checkPutGetState()
{
if(PvaClient::getDebug()) {
@@ -204,7 +184,7 @@ void PvaClientPutGet::channelPutGetConnect(
pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
pvaClientGetData = PvaClientGetData::create(getStructure);
pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
} else {
stringstream ss;
ss << pvRequest;
@@ -219,7 +199,7 @@ void PvaClientPutGet::channelPutGetConnect(
req->channelPutGetConnect(status,shared_from_this());
}
waitForConnect.signal();
}
void PvaClientPutGet::putGetDone(
@@ -234,13 +214,13 @@ void PvaClientPutGet::putGetDone(
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
}
channelPutGetStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = pvaClientGetData->getPVStructure();
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet);
BitSetPtr bs = pvaClientGetData->getChangedBitSet();
bs->clear();
*bs |= *getChangedBitSet;
{
Lock xx(mutex);
channelPutGetStatus = status;
putGetState = putGetComplete;
if(status.isOK()) {
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
}
}
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) {
@@ -261,13 +241,17 @@ void PvaClientPutGet::getPutDone(
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
}
channelPutGetStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = pvaClientPutData->getPVStructure();
pvs->copyUnchecked(*putPVStructure,*putBitSet);
BitSetPtr bs = pvaClientPutData->getChangedBitSet();
bs->clear();
*bs |= *putBitSet;
{
Lock xx(mutex);
channelPutGetStatus = status;
putGetState = putGetComplete;
if(status.isOK()) {
PVStructurePtr pvs = pvaClientPutData->getPVStructure();
pvs->copyUnchecked(*putPVStructure,*putBitSet);
BitSetPtr bs = pvaClientPutData->getChangedBitSet();
bs->clear();
*bs |= *putBitSet;
}
}
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) {
@@ -288,13 +272,13 @@ void PvaClientPutGet::getGetDone(
<< " status.isOK " << (status.isOK() ? "true" : "false")
<< endl;
}
channelPutGetStatus = status;
if(status.isOK()) {
PVStructurePtr pvs = pvaClientGetData->getPVStructure();
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet);
BitSetPtr bs = pvaClientGetData->getChangedBitSet();
bs->clear();
*bs |= *getChangedBitSet;
{
Lock xx(mutex);
channelPutGetStatus = status;
putGetState = putGetComplete;
if(status.isOK()) {
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
}
}
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) {
@@ -313,7 +297,7 @@ void PvaClientPutGet::connect()
issueConnect();
Status status = waitConnect();
if(status.isOK()) return;
string message = string("channel ")
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPutGet::connect "
+ status.getMessage();
@@ -374,7 +358,7 @@ void PvaClientPutGet::putGet()
issuePutGet();
Status status = waitPutGet();
if(status.isOK()) return;
string message = string("channel ")
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::putGet "
+ status.getMessage();
@@ -407,6 +391,7 @@ Status PvaClientPutGet::waitPutGet()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putGetState==putGetComplete) return channelPutGetStatus;
if(putGetState!=putGetActive){
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
@@ -414,7 +399,6 @@ Status PvaClientPutGet::waitPutGet()
throw std::runtime_error(message);
}
waitForPutGet.wait();
putGetState = putGetComplete;
if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear();
return channelPutGetStatus;
}
@@ -429,7 +413,7 @@ void PvaClientPutGet::getGet()
issueGetGet();
Status status = waitGetGet();
if(status.isOK()) return;
string message = string("channel ")
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::getGet "
+ status.getMessage();
@@ -461,6 +445,7 @@ Status PvaClientPutGet::waitGetGet()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putGetState==putGetComplete) return channelPutGetStatus;
if(putGetState!=putGetActive){
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
@@ -468,7 +453,6 @@ Status PvaClientPutGet::waitGetGet()
throw std::runtime_error(message);
}
waitForPutGet.wait();
putGetState = putGetComplete;
return channelPutGetStatus;
}
@@ -482,7 +466,7 @@ void PvaClientPutGet::getPut()
issueGetPut();
Status status = waitGetPut();
if(status.isOK()) return;
string message = string("channel ")
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::getPut "
+ status.getMessage();
@@ -514,6 +498,7 @@ Status PvaClientPutGet::waitGetPut()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(putGetState==putGetComplete) return channelPutGetStatus;
if(putGetState!=putGetActive){
string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
@@ -521,7 +506,6 @@ Status PvaClientPutGet::waitGetPut()
throw std::runtime_error(message);
}
waitForPutGet.wait();
putGetState = putGetComplete;
return channelPutGetStatus;
}
@@ -533,7 +517,10 @@ PvaClientGetDataPtr PvaClientPutGet::getGetData()
<< endl;
}
checkPutGetState();
if(putGetState==putGetIdle) getGet();
if(putGetState==putGetIdle){
getGet();
getPut();
}
return pvaClientGetData;
}
@@ -545,7 +532,10 @@ PvaClientPutDataPtr PvaClientPutGet::getPutData()
<< endl;
}
checkPutGetState();
if(putGetState==putGetIdle) getPut();
if(putGetState==putGetIdle){
getGet();
getPut();
}
return pvaClientPutData;
}
@@ -565,6 +555,4 @@ PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel()
return pvaClientChannel;
}
}}
+20 -12
View File
@@ -12,13 +12,12 @@
#include <sstream>
#include <pv/event.h>
#include <pv/bitSetUtil.h>
#include <pv/rpcService.h>
#define epicsExportSharedSymbols
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
@@ -95,7 +94,7 @@ PvaClientRPC::PvaClientRPC(
PvaClientPtr const &pvaClient,
Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest)
:
:
connectState(connectIdle),
pvaClient(pvaClient),
channel(channel),
@@ -105,7 +104,7 @@ PvaClientRPC::PvaClientRPC(
{
if(PvaClient::getDebug()) {
cout<< "PvaClientRPC::PvaClientRPC()"
<< " channelName " << channel->getChannelName()
<< " channelName " << channel->getChannelName()
<< endl;
}
}
@@ -171,7 +170,7 @@ void PvaClientRPC::rpcConnect(
cout << "PvaClientRPC::rpcConnect calling waitForConnect.signal\n";
}
waitForConnect.signal();
}
void PvaClientRPC::requestDone(
@@ -182,6 +181,7 @@ void PvaClientRPC::requestDone(
PvaClientRPCRequesterPtr req = pvaClientRPCRequester.lock();
{
Lock xx(mutex);
requestStatus = status;
if(PvaClient::getDebug()) {
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
@@ -195,7 +195,7 @@ void PvaClientRPC::requestDone(
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
string message = "channel "
+ channelName
+ channelName
+" PvaClientRPC::requestDone"
+ " but not active";
throw std::runtime_error(message);
@@ -222,11 +222,11 @@ void PvaClientRPC::connect()
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ")
string message = string("channel ")
+ channelName
+ " PvaClientRPC::connect "
+ status.getMessage();
throw std::runtime_error(message);
throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
}
void PvaClientRPC::issueConnect()
@@ -237,7 +237,7 @@ void PvaClientRPC::issueConnect()
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = string("channel ")
+ channelName
+ channelName
+ " pvaClientRPC already connected ";
throw std::runtime_error(message);
}
@@ -307,10 +307,18 @@ PVStructure::shared_pointer PvaClientRPC::request(PVStructure::shared_pointer co
string message = "channel "
+ channelName
+ " PvaClientRPC::request request timeout ";
throw std::runtime_error(message);
throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
}
rpcState = rpcIdle;
return pvResponse;
if(requestStatus.isOK()) return pvResponse;
Channel::shared_pointer chan(channel.lock());
string channelName("disconnected");
if(chan) channelName = chan->getChannelName();
string message = "channel "
+ channelName
+ " PvaClientRPC::request status ";
message += requestStatus.getMessage();
throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
}
@@ -318,7 +326,7 @@ void PvaClientRPC::request(
PVStructure::shared_pointer const & pvArgument,
PvaClientRPCRequesterPtr const & pvaClientRPCRequester)
{
checkRPCState();
checkRPCState();
this->pvaClientRPCRequester = pvaClientRPCRequester;
if(responseTimeout<=0.0) {
{