44 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
34 changed files with 1135 additions and 1036 deletions
+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
-1
View File
@@ -28,4 +28,3 @@ env:
- BRBASE=7.0 RTEMS=4.9 TEST=NO - BRBASE=7.0 RTEMS=4.9 TEST=NO
- BRBASE=3.16 - BRBASE=3.16
- BRBASE=3.15 - BRBASE=3.15
- BRBASE=3.14
+7 -6
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = pvaClientCPP
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = PROJECT_NUMBER = 4.7.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description # 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 # 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. # will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES. # 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 # 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 # 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 # specify the list of include paths that are normally passed to the compiler
# using the -I flag. # 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 # 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 # 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 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # 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 # 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 # 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. # be searched for input files as well.
# The default value is: NO. # The default value is: NO.
RECURSIVE = YES RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should be # 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 # 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. # The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES. # 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 # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp). # generated HTML page (for example: .htm, .php, .asp).
+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 include $(TOP)/configure/CONFIG
CFG += CONFIG_PVACLIENT_VERSION
TARGETS = $(CONFIG_TARGETS) TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS))) CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
+45 -1
View File
@@ -1,7 +1,51 @@
# pvaClientCPP Module pwd# pvaClientCPP Module
This document summarizes the changes to the module between releases. This document summarizes the changes to the module between releases.
## Release 4.7.1 (EPICS 7.0.3.2 May 2020)
* support access to a union field that is a scalar or scalarArray
* fixed issues #62 and #63
## Release 4.7.0 (EPICS 7.0.3.1, Nov 2019)
* 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) ## Release 4.4 (EPICS 7.0.2, Dec 2018)
+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>
+2 -2
View File
@@ -26,7 +26,7 @@
<div class="head"> <div class="head">
<h1>EPICS pvaClientCPP</h1> <h1>EPICS pvaClientCPP</h1>
<h2 class="nocount">Release 4.4 - December 2018</h2> <h2 class="nocount">Release 4.4 - April 2019</h2>
<h2 class="nocount">Abstract</h2> <h2 class="nocount">Abstract</h2>
@@ -79,7 +79,7 @@ It is intended for developers that want to use pvaClientCPP.
<h2>Developer Guide</h2> <h2>Developer Guide</h2>
<p>A guide for developers is available at <p>A guide for developers is available at
<a <a
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html"> href="https://mrkraimer.github.io/website/developerGuide/developerGuide.html">
developerGuide developerGuide
</a> </a>
</p> </p>
+2 -1
View File
@@ -6,12 +6,13 @@ include $(TOP)/configure/CONFIG
LIBRARY += pvaClient LIBRARY += pvaClient
# shared library ABI version. # shared library ABI version.
SHRLIB_VERSION ?= 4.4.0 SHRLIB_VERSION ?= $(EPICS_PVACLIENT_MAJOR_VERSION).$(EPICS_PVACLIENT_MINOR_VERSION).$(EPICS_PVACLIENT_MAINTENANCE_VERSION)
INC += pv/pvaClient.h INC += pv/pvaClient.h
INC += pv/pvaClientMultiChannel.h INC += pv/pvaClientMultiChannel.h
LIBSRCS += pvaClient.cpp LIBSRCS += pvaClient.cpp
LIBSRCS += pvaClientData.cpp
LIBSRCS += pvaClientPutData.cpp LIBSRCS += pvaClientPutData.cpp
LIBSRCS += pvaClientGetData.cpp LIBSRCS += pvaClientGetData.cpp
LIBSRCS += pvaClientMonitorData.cpp LIBSRCS += pvaClientMonitorData.cpp
+185 -258
View File
@@ -17,7 +17,8 @@
#include <list> #include <list>
#include <iostream> #include <iostream>
#include <sstream> #include <ostream>
#include <sstream>
#include <pv/requester.h> #include <pv/requester.h>
#include <pv/status.h> #include <pv/status.h>
#include <pv/event.h> #include <pv/event.h>
@@ -35,15 +36,17 @@
#ifdef pvaClientEpicsExportSharedSymbols #ifdef pvaClientEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef pvaClientEpicsExportSharedSymbols # undef pvaClientEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
class PvaClient; class PvaClient;
typedef std::tr1::shared_ptr<PvaClient> PvaClientPtr; typedef std::tr1::shared_ptr<PvaClient> PvaClientPtr;
class PvaClientData;
typedef std::tr1::shared_ptr<PvaClientData> PvaClientDataPtr;
class PvaClientGetData; class PvaClientGetData;
typedef std::tr1::shared_ptr<PvaClientGetData> PvaClientGetDataPtr; typedef std::tr1::shared_ptr<PvaClientGetData> PvaClientGetDataPtr;
class PvaClientPutData; class PvaClientPutData;
@@ -158,7 +161,7 @@ public:
PvaClientChannelPtr createChannel( PvaClientChannelPtr createChannel(
std::string const & channelName, std::string const & channelName,
std::string const & providerName = "pva"); std::string const & providerName = "pva");
/** @brief Set a requester. /** @brief Set a requester.
* *
* The default is for PvaClient to handle messages by printing to System.out. * The default is for PvaClient to handle messages by printing to System.out.
@@ -201,7 +204,7 @@ class PvaClientPutCache;
typedef std::tr1::shared_ptr<PvaClientPutCache> PvaClientPutCachePtr; typedef std::tr1::shared_ptr<PvaClientPutCache> PvaClientPutCachePtr;
/** /**
* @brief A callback for change in connection status. * @brief A callback for change in connection status.
* *
* <a href = "../htmldoxygen/pvaClientChannelStateChangeRequester.html">Overview of PvaClientChannelStateChangeRequester</a> * <a href = "../htmldoxygen/pvaClientChannelStateChangeRequester.html">Overview of PvaClientChannelStateChangeRequester</a>
@@ -225,7 +228,7 @@ public:
virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected) = 0; virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected) = 0;
}; };
/** /**
* @brief An easy to use alternative to directly calling the Channel methods of pvAccess. * @brief An easy to use alternative to directly calling the Channel methods of pvAccess.
* *
* <a href = "../htmldoxygen/pvaClientChannel.html">Overview of PvaClientChannel</a> * <a href = "../htmldoxygen/pvaClientChannel.html">Overview of PvaClientChannel</a>
@@ -242,7 +245,7 @@ public:
*/ */
~PvaClientChannel(); ~PvaClientChannel();
/** @brief Set a client stateChangeRequester. /** @brief Set a client stateChangeRequester.
* *
* @param stateChangeRequester The client stateChangeRequester implementation. * @param stateChangeRequester The client stateChangeRequester implementation.
*/ */
void setStateChangeRequester(PvaClientChannelStateChangeRequesterPtr const &stateChangeRequester); void setStateChangeRequester(PvaClientChannelStateChangeRequesterPtr const &stateChangeRequester);
@@ -287,7 +290,7 @@ public:
* @throw runtime_error if failure. * @throw runtime_error if failure.
*/ */
PvaClientProcessPtr createProcess(std::string const & request = ""); 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. * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData.
* @return The interface. * @return The interface.
@@ -311,13 +314,44 @@ public:
PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)"); PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)");
/** @brief Creates an PvaClientGet. /** @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. * @return The interface.
* @throw runtime_error if failure. * @throw runtime_error if failure.
*/ */
PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest); 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. /** @brief create a PvaClientPut.
* *
* Get a cached PvaClientPut or create and connect to a new PvaClientPut. * Get a cached PvaClientPut or create and connect to a new PvaClientPut.
* Then call it's get method. * Then call it's get method.
* @param request The syntax of request is defined by the copy facility of pvData. * @param request The syntax of request is defined by the copy facility of pvData.
@@ -339,6 +373,44 @@ public:
* @return The interface. * @return The interface.
*/ */
PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest); 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. /** @brief create a PvaClientPutGet.
* *
* First call createRequest as implemented by pvDataJava and then calls the next method. * First call createRequest as implemented by pvDataJava and then calls the next method.
@@ -378,7 +450,7 @@ public:
* @throw runtime_error if failure. * @throw runtime_error if failure.
*/ */
PvaClientMonitorPtr monitor(std::string const & request = "field(value,alarm,timeStamp)"); 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. * @param pvaClientMonitorRequester The client callback.
* @return The interface. * @return The interface.
@@ -467,7 +539,7 @@ private:
std::string channelName; std::string channelName;
std::string providerName; std::string providerName;
ConnectState connectState; ConnectState connectState;
epics::pvData::CreateRequest::shared_pointer createRequest; epics::pvData::CreateRequest::shared_pointer createRequest;
PvaClientGetCachePtr pvaClientGetCache; PvaClientGetCachePtr pvaClientGetCache;
PvaClientPutCachePtr pvaClientPutCache; PvaClientPutCachePtr pvaClientPutCache;
@@ -489,19 +561,19 @@ public:
friend class PvaClient; 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: public:
POINTER_DEFINITIONS(PvaClientGetData); POINTER_DEFINITIONS(PvaClientData);
/** /**
* @brief Destructor * @brief Destructor
*/ */
~PvaClientGetData() {} ~PvaClientData() {}
/** @brief Set a prefix for throw messages. /** @brief Set a prefix for throw messages.
* *
* This is called by other pvaClient classes. * This is called by other pvaClient classes.
@@ -542,6 +614,7 @@ public:
void setData( void setData(
epics::pvData::PVStructurePtr const & pvStructureFrom, epics::pvData::PVStructurePtr const & pvStructureFrom,
epics::pvData::BitSetPtr const & bitSetFrom); epics::pvData::BitSetPtr const & bitSetFrom);
/** @brief Is there a top level field named value. /** @brief Is there a top level field named value.
* @return The answer. * @return The answer.
*/ */
@@ -608,6 +681,75 @@ public:
* @return The timeStamp. * @return The timeStamp.
*/ */
epics::pvData::TimeStamp getTimeStamp(); 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. /** @brief Factory method for creating an instance of PvaClientGetData.
* *
* NOTE: Not normally called by clients * NOTE: Not normally called by clients
@@ -617,120 +759,24 @@ public:
static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure); static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure);
private: private:
PvaClientGetData(epics::pvData::StructureConstPtr const & structure); 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 PvaClientGet;
friend class PvaClientPutGet; friend class PvaClientPutGet;
}; };
class PvaClientPostHandlerPvt; // private to PvaClientPutData class PvaClientPostHandlerPvt; // private to PvaClientPutData
/** /**
* @brief A class that holds data given to by PvaClientPut or PvaClientPutGet * @brief A class that holds data given to by PvaClientPut or PvaClientPutGet
* *
* <a href = "../htmldoxygen/pvaClientPutData.html">Overview of PvaClientPutData</a> * <a href = "../htmldoxygen/pvaClientPutData.html">Overview of PvaClientPutData</a>
*/ */
class epicsShareClass PvaClientPutData class epicsShareClass PvaClientPutData : public PvaClientData
{ {
public: public:
POINTER_DEFINITIONS(PvaClientPutData); POINTER_DEFINITIONS(PvaClientPutData);
/** /**
* @brief Destructor * @brief Destructor
*/ */
~PvaClientPutData() {} ~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. /** @brief Put the value as a double.
* @param value The new value. * @param value The new value.
* An exception is also thrown if the actualy type can cause an overflow. * An exception is also thrown if the actualy type can cause an overflow.
@@ -764,17 +810,9 @@ public:
static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure); static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure);
private: private:
PvaClientPutData(epics::pvData::StructureConstPtr const &structure); PvaClientPutData(epics::pvData::StructureConstPtr const &structure);
void checkValue();
void postPut(size_t fieldNumber); void postPut(size_t fieldNumber);
std::vector<epics::pvData::PostHandlerPtr> postHandler; std::vector<epics::pvData::PostHandlerPtr> postHandler;
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
friend class PvaClientPostHandlerPvt; friend class PvaClientPostHandlerPvt;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
friend class PvaClientPut; friend class PvaClientPut;
friend class PvaClientPutGet; friend class PvaClientPutGet;
}; };
@@ -784,35 +822,14 @@ private:
* *
* <a href = "../htmldoxygen/pvaClientMonitorData.html">Overview of PvaClientMonitorData</a> * <a href = "../htmldoxygen/pvaClientMonitorData.html">Overview of PvaClientMonitorData</a>
*/ */
class epicsShareClass PvaClientMonitorData class epicsShareClass PvaClientMonitorData : public PvaClientData
{ {
public: public:
POINTER_DEFINITIONS(PvaClientMonitorData); POINTER_DEFINITIONS(PvaClientMonitorData);
/** /**
* @brief Destructor * @brief Destructor
*/ */
~PvaClientMonitorData() {} ~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 /** @brief Get the overrun BitSet for the pvStructure
* This shows which fields have had more than one change. * This shows which fields have had more than one change.
* @return The bitSet * @return The bitSet
@@ -823,111 +840,21 @@ public:
* @param out The stream that shows the changed fields. * @param out The stream that shows the changed fields.
* @return The stream that was passed as out. * @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); 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 /** Put data into PVStructure from monitorElement
* NOTE: Not normally called by clients * NOTE: Not normally called by clients
* @param monitorElement the monitorElement that has new data. * @param monitorElement the monitorElement that has new data.
*/ */
void setData(epics::pvData::MonitorElementPtr const & monitorElement); 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: private:
PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure); PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure);
void checkValue();
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr changedBitSet;
epics::pvData::BitSetPtr overrunBitSet; epics::pvData::BitSetPtr overrunBitSet;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;
friend class PvaClientMonitor; friend class PvaClientMonitor;
}; };
@@ -987,7 +914,7 @@ public:
PvaClientChannelPtr const & pvaClientChannel, PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest epics::pvData::PVStructurePtr const &pvRequest
); );
/** @brief Destructor /** @brief Destructor
*/ */
~PvaClientProcess(); ~PvaClientProcess();
@@ -1041,7 +968,7 @@ private:
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
void checkProcessState(); void checkProcessState();
enum ProcessConnectState {connectIdle,connectActive,connected}; enum ProcessConnectState {connectIdle,connectActive,connected};
@@ -1352,7 +1279,7 @@ private :
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
PvaClientChannelPtr const & pvaClientChannel, PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
void checkConnectState(); void checkConnectState();
enum PutConnectState {connectIdle,connectActive,connected}; enum PutConnectState {connectIdle,connectActive,connected};
@@ -1430,11 +1357,11 @@ public:
PvaClientPutGetPtr const & clientPutGet) PvaClientPutGetPtr const & clientPutGet)
{ {
} }
}; };
/** /**
* @brief An easy to use alternative to ChannelPutGet. * @brief An easy to use alternative to ChannelPutGet.
* *
* <a href = "../htmldoxygen/pvaClientPutGet.html">Overview of PvaClientPutGet</a> * <a href = "../htmldoxygen/pvaClientPutGet.html">Overview of PvaClientPutGet</a>
@@ -1521,11 +1448,11 @@ public:
/** @brief Get the put data. /** @brief Get the put data.
* @return The interface. * @return The interface.
*/ */
PvaClientPutDataPtr getPutData(); PvaClientPutDataPtr getPutData();
/** @brief Get the get data. /** @brief Get the get data.
* @return The interface. * @return The interface.
*/ */
PvaClientGetDataPtr getGetData(); PvaClientGetDataPtr getGetData();
/** @brief Get the PvaClientChannel; /** @brief Get the PvaClientChannel;
* *
* @return The interface. * @return The interface.
@@ -1666,7 +1593,7 @@ public:
std::string const & request, std::string const & request,
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester
= PvaClientChannelStateChangeRequesterPtr(), = PvaClientChannelStateChangeRequesterPtr(),
PvaClientMonitorRequesterPtr const & monitorRequester PvaClientMonitorRequesterPtr const & monitorRequester
= PvaClientMonitorRequesterPtr() = PvaClientMonitorRequesterPtr()
) EPICS_DEPRECATED; ) EPICS_DEPRECATED;
/** @brief Destructor /** @brief Destructor
@@ -1729,7 +1656,7 @@ public:
* *
* @return The interface. * @return The interface.
*/ */
PvaClientMonitorDataPtr getData(); PvaClientMonitorDataPtr getData();
private: private:
std::string getRequesterName(); std::string getRequesterName();
void message(std::string const & message,epics::pvData::MessageType messageType); void message(std::string const & message,epics::pvData::MessageType messageType);
@@ -1760,7 +1687,7 @@ private:
epics::pvData::Status monitorConnectStatus; epics::pvData::Status monitorConnectStatus;
epics::pvData::MonitorPtr monitor; epics::pvData::MonitorPtr monitor;
epics::pvData::MonitorElementPtr monitorElement; epics::pvData::MonitorElementPtr monitorElement;
PvaClientMonitorRequesterWPtr pvaClientMonitorRequester; PvaClientMonitorRequesterWPtr pvaClientMonitorRequester;
MonitorConnectState connectState; MonitorConnectState connectState;
bool userPoll; bool userPoll;
@@ -1837,7 +1764,7 @@ public:
* @brief Set a timeout for a request. * @brief Set a timeout for a request.
* @param responseTimeout The time in seconds to wait for a request to complete. * @param responseTimeout The time in seconds to wait for a request to complete.
*/ */
void setResponseTimeout(double responseTimeout) void setResponseTimeout(double responseTimeout)
{ {
this->responseTimeout = responseTimeout; this->responseTimeout = responseTimeout;
} }
@@ -1907,18 +1834,19 @@ private:
PvaClient::weak_pointer pvaClient; PvaClient::weak_pointer pvaClient;
epics::pvAccess::Channel::weak_pointer channel; epics::pvAccess::Channel::weak_pointer channel;
epics::pvData::PVStructurePtr pvRequest; epics::pvData::PVStructurePtr pvRequest;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
epics::pvData::Event waitForConnect; epics::pvData::Event waitForConnect;
epics::pvData::Event waitForDone; epics::pvData::Event waitForDone;
PvaClientRPCRequesterWPtr pvaClientRPCRequester; PvaClientRPCRequesterWPtr pvaClientRPCRequester;
RPCRequesterImplPtr rpcRequester; RPCRequesterImplPtr rpcRequester;
epics::pvAccess::ChannelRPC::shared_pointer channelRPC; epics::pvAccess::ChannelRPC::shared_pointer channelRPC;
epics::pvData::PVStructurePtr pvResponse; epics::pvData::PVStructurePtr pvResponse;
enum RPCState {rpcIdle,rpcActive,rpcComplete}; enum RPCState {rpcIdle,rpcActive,rpcComplete};
RPCState rpcState; RPCState rpcState;
epics::pvData::Status requestStatus;
double responseTimeout; double responseTimeout;
friend class RPCRequesterImpl; friend class RPCRequesterImpl;
}; };
@@ -1930,6 +1858,5 @@ private:
/** @page Overview Documentation /** @page Overview Documentation
* *
* <a href = "../pvaClientCPP.html">pvaClientCPP.html</a> * <a href = "../pvaClientCPP.html">pvaClientCPP.html</a>
* *
*/ */
+24 -22
View File
@@ -21,14 +21,14 @@
#ifdef pvaClientMultiChannelEpicsExportSharedSymbols #ifdef pvaClientMultiChannelEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef pvaClientMultiChannelEpicsExportSharedSymbols # undef pvaClientMultiChannelEpicsExportSharedSymbols
#endif #endif
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
class PvaClientMultiChannel; class PvaClientMultiChannel;
@@ -115,7 +115,7 @@ public:
* @brief create a pvaClientMultiGetDouble * @brief create a pvaClientMultiGetDouble
* @return The interface. * @return The interface.
*/ */
PvaClientMultiGetDoublePtr createGet(); PvaClientMultiGetDoublePtr createGet();
/** /**
* @brief Create a pvaClientMultiPutDouble. * @brief Create a pvaClientMultiPutDouble.
* @return The interface. * @return The interface.
@@ -152,7 +152,7 @@ private:
std::string const & providerName, std::string const & providerName,
size_t maxNotConnected); size_t maxNotConnected);
void checkConnected(); void checkConnected();
PvaClientPtr pvaClient; PvaClientPtr pvaClient;
epics::pvData::shared_vector<const std::string> channelName; epics::pvData::shared_vector<const std::string> channelName;
std::string providerName; std::string providerName;
@@ -176,7 +176,7 @@ class epicsShareClass PvaClientMultiGetDouble :
public: public:
POINTER_DEFINITIONS(PvaClientMultiGetDouble); POINTER_DEFINITIONS(PvaClientMultiGetDouble);
/** /**
* @brief Create a PvaClientMultiGetDouble. * @brief Create a PvaClientMultiGetDouble.
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel. * @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
@@ -214,7 +214,7 @@ private:
PvaClientChannelArray pvaClientChannelArray; PvaClientChannelArray pvaClientChannelArray;
size_t nchannel; size_t nchannel;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
epics::pvData::shared_vector<double> doubleValue; epics::pvData::shared_vector<double> doubleValue;
std::vector<PvaClientGetPtr> pvaClientGet; std::vector<PvaClientGetPtr> pvaClientGet;
bool isGetConnected; bool isGetConnected;
@@ -229,7 +229,7 @@ class epicsShareClass PvaClientMultiPutDouble :
public: public:
POINTER_DEFINITIONS(PvaClientMultiPutDouble); POINTER_DEFINITIONS(PvaClientMultiPutDouble);
/** @brief Create a PvaClientMultiPutDouble. /** @brief Create a PvaClientMultiPutDouble.
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel. * @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
* @param pvaClientChannelArray The PvaClientChannel array. * @param pvaClientChannelArray The PvaClientChannel array.
@@ -277,7 +277,7 @@ class epicsShareClass PvaClientMultiMonitorDouble :
public: public:
POINTER_DEFINITIONS(PvaClientMultiMonitorDouble); POINTER_DEFINITIONS(PvaClientMultiMonitorDouble);
/** @brief Create a PvaClientMultiMonitorDouble. /** @brief Create a PvaClientMultiMonitorDouble.
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel. * @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
* @param pvaClientChannelArray The PvaClientChannel array. * @param pvaClientChannelArray The PvaClientChannel array.
@@ -360,8 +360,10 @@ public:
void connect(); void connect();
/** /**
* @brief Get each channel. * @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. * @brief Get the data from the last get.
* @return the pvaClientNTMultiData. * @return the pvaClientNTMultiData.
@@ -386,8 +388,8 @@ private:
epics::pvData::PVStructurePtr pvRequest; epics::pvData::PVStructurePtr pvRequest;
size_t nchannel; size_t nchannel;
epics::pvData::Mutex mutex; epics::pvData::Mutex mutex;
PvaClientNTMultiDataPtr pvaClientNTMultiData; PvaClientNTMultiDataPtr pvaClientNTMultiData;
std::vector<PvaClientGetPtr> pvaClientGet; std::vector<PvaClientGetPtr> pvaClientGet;
bool isConnected; bool isConnected;
@@ -411,7 +413,7 @@ public:
static PvaClientNTMultiPutPtr create( static PvaClientNTMultiPutPtr create(
PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientMultiChannelPtr const &pvaClientMultiChannel,
PvaClientChannelArray const &pvaClientChannelArray); PvaClientChannelArray const &pvaClientChannelArray);
~PvaClientNTMultiPut(); ~PvaClientNTMultiPut();
/** /**
* @brief Connect a channelPut for each channel. * @brief Connect a channelPut for each channel.
@@ -476,10 +478,11 @@ public:
/** /**
* @brief Poll each channel. * @brief Poll each channel.
* *
* @param valueOnly use only value for union.
* If any has new data it is used to update the double[]. * If any has new data it is used to update the double[].
* @return (false,true) if (no, at least one) value was updated. * @return (false,true) if (no, at least one) value was updated.
*/ */
bool poll(); bool poll(bool valueOnly = true);
/** /**
* @brief Wait until poll returns true. * @brief Wait until poll returns true.
* @param secondsToWait The time to keep trying. * @param secondsToWait The time to keep trying.
@@ -540,27 +543,28 @@ public:
PvaClientChannelArray const &pvaClientChannelArray, PvaClientChannelArray const &pvaClientChannelArray,
epics::pvData::PVStructurePtr const & pvRequest); epics::pvData::PVStructurePtr const & pvRequest);
~PvaClientNTMultiData(); ~PvaClientNTMultiData();
/** /**
* @brief Get the number of channels. * @brief Get the number of channels.
* @return The number of channels. * @return The number of channels.
*/ */
size_t getNumber(); size_t getNumber();
/** /**
* @brief Set the timeStamp base for computing deltaTimes. * @brief Set the timeStamp base for computing deltaTimes.
*/ */
void startDeltaTime(); void startDeltaTime();
/** /**
* @brief Update NTMultiChannel fields. * @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. * @brief Get the time when the last get was made.
* @return The timeStamp. * @return The timeStamp.
*/ */
epics::pvData::TimeStamp getTimeStamp(); epics::pvData::TimeStamp getTimeStamp();
/** /**
* @brief Get the NTMultiChannel. * @brief Get the NTMultiChannel.
* @return The value. * @return The value.
@@ -579,7 +583,6 @@ private:
PvaClientMultiChannelPtr const &pvaNTMultiChannel, PvaClientMultiChannelPtr const &pvaNTMultiChannel,
PvaClientChannelArray const &pvaClientChannelArray, PvaClientChannelArray const &pvaClientChannelArray,
epics::pvData::PVStructurePtr const & pvRequest); epics::pvData::PVStructurePtr const & pvRequest);
void setStructure(epics::pvData::StructureConstPtr const & structure,size_t index);
void setPVStructure( void setPVStructure(
epics::pvData::PVStructurePtr const &pvStructure,size_t index); epics::pvData::PVStructurePtr const &pvStructure,size_t index);
@@ -591,7 +594,7 @@ private:
std::vector<epics::pvData::PVStructurePtr> topPVStructure; std::vector<epics::pvData::PVStructurePtr> topPVStructure;
bool gotAlarm; bool gotAlarm;
bool gotTimeStamp; bool gotTimeStamp;
epics::pvData::StructureConstPtr ntMultiChannelStructure; epics::pvData::StructureConstPtr ntMultiChannelStructure;
epics::pvData::shared_vector<epics::pvData::PVUnionPtr> unionValue; epics::pvData::shared_vector<epics::pvData::PVUnionPtr> unionValue;
epics::pvData::shared_vector<epics::pvData::int32> severity; epics::pvData::shared_vector<epics::pvData::int32> severity;
@@ -612,4 +615,3 @@ private:
}} }}
#endif /* PVACLIENTMULTICHANNEL_H */ #endif /* PVACLIENTMULTICHANNEL_H */
+5 -7
View File
@@ -18,13 +18,12 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::pvAccess::ca; using namespace epics::pvAccess::ca;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
class epicsShareClass PvaClientChannelCache class epicsShareClass PvaClientChannelCache
@@ -43,7 +42,7 @@ public:
private: private:
map<string,PvaClientChannelPtr> pvaClientChannelMap; map<string,PvaClientChannelPtr> pvaClientChannelMap;
}; };
PvaClientChannelPtr PvaClientChannelCache::getChannel( PvaClientChannelPtr PvaClientChannelCache::getChannel(
string const & channelName, string const & channelName,
string const & providerName) string const & providerName)
@@ -78,7 +77,7 @@ void PvaClientChannelCache::showCache()
string providerName = channel->getProvider()->getProviderName(); string providerName = channel->getProvider()->getProviderName();
cout << "channel " << channelName << " provider " << providerName << endl; cout << "channel " << channelName << " provider " << providerName << endl;
pvaChannel->showCache(); pvaChannel->showCache();
} }
} }
size_t PvaClientChannelCache::cacheSize() size_t PvaClientChannelCache::cacheSize()
@@ -138,7 +137,7 @@ PvaClient::PvaClient(std::string const & providerNames)
} }
CAClientFactory::start(); CAClientFactory::start();
caStarted = true; caStarted = true;
} else { } else {
if(!channelRegistry->getProvider(providerName)) { if(!channelRegistry->getProvider(providerName)) {
cerr << "PvaClient::get provider " << providerName << " not known" << endl; cerr << "PvaClient::get provider " << providerName << " not known" << endl;
} }
@@ -192,7 +191,7 @@ PvaClientChannelPtr PvaClient::channel(
std::string const & providerName, std::string const & providerName,
double timeOut) double timeOut)
{ {
PvaClientChannelPtr pvaClientChannel = PvaClientChannelPtr pvaClientChannel =
pvaClientChannelCache->getChannel(channelName,providerName); pvaClientChannelCache->getChannel(channelName,providerName);
if(pvaClientChannel) return pvaClientChannel; if(pvaClientChannel) return pvaClientChannel;
pvaClientChannel = createChannel(channelName,providerName); pvaClientChannel = createChannel(channelName,providerName);
@@ -232,4 +231,3 @@ size_t PvaClient::cacheSize()
} }
}} }}
+67 -10
View File
@@ -18,7 +18,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -184,7 +183,7 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin
throw std::runtime_error(message); throw std::runtime_error(message);
} }
if(channel->isConnected()) { if(channel->isConnected()) {
connectState = connected; connectState = connected;
waitForConnect.signal(); waitForConnect.signal();
} }
} }
@@ -268,7 +267,7 @@ void PvaClientChannel::connect(double timeout)
Status status = waitConnect(timeout); Status status = waitConnect(timeout);
if(status.isOK()) return; if(status.isOK()) return;
if(PvaClient::getDebug()) cout << "PvaClientChannel::connect waitConnect failed\n"; if(PvaClient::getDebug()) cout << "PvaClientChannel::connect waitConnect failed\n";
string message = string("channel ") + channelName string message = string("channel ") + channelName
+ " PvaClientChannel::connect " + status.getMessage(); + " PvaClientChannel::connect " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -331,7 +330,7 @@ PvaClientProcessPtr PvaClientChannel::createProcess(string const & request)
{ {
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) { if(!pvRequest) {
string message = string("channel ") + channelName string message = string("channel ") + channelName
+ " PvaClientChannel::createProcess invalid pvRequest: " + " PvaClientChannel::createProcess invalid pvRequest: "
+ createRequest->getMessage(); + createRequest->getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -365,7 +364,7 @@ PvaClientGetPtr PvaClientChannel::createGet(string const & request)
{ {
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) { if(!pvRequest) {
string message = string("channel ") + channelName string message = string("channel ") + channelName
+ " PvaClientChannel::createGet invalid pvRequest: " + " PvaClientChannel::createGet invalid pvRequest: "
+ createRequest->getMessage(); + createRequest->getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -381,6 +380,26 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest)
return PvaClientGet::create(yyy,shared_from_this(),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) PvaClientPutPtr PvaClientChannel::put(string const & request)
{ {
@@ -400,7 +419,7 @@ PvaClientPutPtr PvaClientChannel::createPut(string const & request)
{ {
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) { if(!pvRequest) {
string message = string("channel ") + channelName string message = string("channel ") + channelName
+ " PvaClientChannel::createPut invalid pvRequest: " + " PvaClientChannel::createPut invalid pvRequest: "
+ createRequest->getMessage(); + createRequest->getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -416,11 +435,49 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest)
return PvaClientPut::create(yyy,shared_from_this(),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) PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request)
{ {
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) { if(!pvRequest) {
string message = string("channel ") + channelName string message = string("channel ") + channelName
+ " PvaClientChannel::createPutGet invalid pvRequest: " + " PvaClientChannel::createPutGet invalid pvRequest: "
+ createRequest->getMessage(); + createRequest->getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -442,7 +499,7 @@ PvaClientArrayPtr PvaClientChannel::createArray(string const & request)
{ {
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) { if(!pvRequest) {
string message = string("channel ") + channelName string message = string("channel ") + channelName
+ " PvaClientChannel::createArray invalid pvRequest: " + " PvaClientChannel::createArray invalid pvRequest: "
+ createRequest->getMessage(); + createRequest->getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -484,7 +541,7 @@ PvaClientMonitorPtr PvaClientChannel::createMonitor(string const & request)
{ {
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
if(!pvRequest) { if(!pvRequest) {
string message = string("channel ") + channelName string message = string("channel ") + channelName
+ " PvaClientChannel::createMonitor invalid pvRequest: " + " PvaClientChannel::createMonitor invalid pvRequest: "
+ createRequest->getMessage(); + createRequest->getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -504,7 +561,7 @@ PVStructurePtr PvaClientChannel::rpc(
PVStructurePtr const & pvRequest, PVStructurePtr const & pvRequest,
PVStructurePtr const & pvArgument) PVStructurePtr const & pvArgument)
{ {
PvaClientRPCPtr rpc = createRPC(pvRequest); PvaClientRPCPtr rpc = createRPC(pvRequest);
return rpc->request(pvArgument); 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;
}
}
}
}}
+30 -42
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -56,7 +55,7 @@ public:
{ {
PvaClientGetPtr clientGet(pvaClientGet.lock()); PvaClientGetPtr clientGet(pvaClientGet.lock());
if(!clientGet) return; if(!clientGet) return;
clientGet->channelGetConnect(status,channelGet,structure); clientGet->channelGetConnect(status,channelGet,structure);
} }
virtual void getDone( virtual void getDone(
@@ -99,18 +98,16 @@ PvaClientGet::PvaClientGet(
getState(getIdle) getState(getIdle)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::PvaClientGet::PvaClientGet" cout << "PvaClientGet::PvaClientGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
} }
PvaClientGet::~PvaClientGet() PvaClientGet::~PvaClientGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientGet::~PvaClientGet" cout<< "PvaClientGet::~PvaClientGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
} }
@@ -118,9 +115,8 @@ PvaClientGet::~PvaClientGet()
void PvaClientGet::checkConnectState() void PvaClientGet::checkConnectState()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::checkConnectState" cout << "PvaClientGet::checkConnectState channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
if(!pvaClientChannel->getChannel()->isConnected()) { if(!pvaClientChannel->getChannel()->isConnected()) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
@@ -159,10 +155,10 @@ void PvaClientGet::channelGetConnect(
StructureConstPtr const & structure) StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::channelGetConnect" cout << "PvaClientGet::channelGetConnect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << "\n";
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -186,7 +182,7 @@ void PvaClientGet::channelGetConnect(
req->channelGetConnect(status,shared_from_this()); req->channelGetConnect(status,shared_from_this());
} }
waitForConnect.signal(); waitForConnect.signal();
} }
void PvaClientGet::getDone( void PvaClientGet::getDone(
@@ -196,10 +192,10 @@ void PvaClientGet::getDone(
BitSetPtr const & bitSet) BitSetPtr const & bitSet)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::getDone" cout << "PvaClientGet::getDone channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << "\n";
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -219,9 +215,8 @@ void PvaClientGet::getDone(
void PvaClientGet::connect() void PvaClientGet::connect()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::connect" cout << "PvaClientGet::connect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
@@ -234,9 +229,8 @@ void PvaClientGet::connect()
void PvaClientGet::issueConnect() void PvaClientGet::issueConnect()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::issueConnect" cout << "PvaClientGet::issueConnect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
if(connectState!=connectIdle) { if(connectState!=connectIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
@@ -251,9 +245,8 @@ void PvaClientGet::issueConnect()
Status PvaClientGet::waitConnect() Status PvaClientGet::waitConnect()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitConnect" cout << "PvaClientGet::waitConnect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -275,9 +268,8 @@ Status PvaClientGet::waitConnect()
void PvaClientGet::get() void PvaClientGet::get()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::get" cout << "PvaClientGet::get channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
issueGet(); issueGet();
Status status = waitGet(); Status status = waitGet();
@@ -290,9 +282,8 @@ void PvaClientGet::get()
void PvaClientGet::issueGet() void PvaClientGet::issueGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::issueGet" cout << "PvaClientGet::issueGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(getState==getActive) { if(getState==getActive) {
@@ -307,9 +298,8 @@ void PvaClientGet::issueGet()
Status PvaClientGet::waitGet() Status PvaClientGet::waitGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitGet" cout << "PvaClientGet::waitGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -330,9 +320,8 @@ Status PvaClientGet::waitGet()
PvaClientGetDataPtr PvaClientGet::getData() PvaClientGetDataPtr PvaClientGet::getData()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientGet::getData" cout<< "PvaClientGet::getData channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
checkConnectState(); checkConnectState();
if(getState==getIdle) get(); if(getState==getIdle) get();
@@ -342,9 +331,8 @@ PvaClientGetDataPtr PvaClientGet::getData()
void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester) void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::setRequester" cout << "PvaClientGet::setRequester channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
this->pvaClientGetRequester = pvaClientGetRequester; this->pvaClientGetRequester = pvaClientGetRequester;
} }
+3 -203
View File
@@ -19,7 +19,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -27,214 +26,15 @@ using namespace std;
namespace epics { namespace pvaClient { 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) PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) cout << "PvaClientGetData::create\n";
cout << "PvaClientGetData::create"
<< endl;
}
PvaClientGetDataPtr epv(new PvaClientGetData(structure)); PvaClientGetDataPtr epv(new PvaClientGetData(structure));
return epv; return epv;
} }
PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure) PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure)
: structure(structure), : PvaClientData(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);
}
}} }}
+6 -8
View File
@@ -17,8 +17,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -59,21 +57,21 @@ public:
{ {
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
if(!clientMonitor) return; if(!clientMonitor) return;
clientMonitor->monitorConnect(status,monitor,structure); clientMonitor->monitorConnect(status,monitor,structure);
} }
virtual void unlisten(epics::pvData::MonitorPtr const & monitor) virtual void unlisten(epics::pvData::MonitorPtr const & monitor)
{ {
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
if(!clientMonitor) return; if(!clientMonitor) return;
clientMonitor->unlisten(monitor); clientMonitor->unlisten(monitor);
} }
virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor) virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor)
{ {
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
if(!clientMonitor) return; if(!clientMonitor) return;
clientMonitor->monitorEvent(monitor); clientMonitor->monitorEvent(monitor);
} }
}; };
@@ -133,7 +131,7 @@ PvaClientMonitor::PvaClientMonitor(
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::PvaClientMonitor\n" cout<< "PvaClientMonitor::PvaClientMonitor\n"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
} }
@@ -278,7 +276,7 @@ void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor)
cout << "PvaClientMonitor::monitorEvent" cout << "PvaClientMonitor::monitorEvent"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock(); PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
if(req) req->event(shared_from_this()); if(req) req->event(shared_from_this());
if(userWait) waitForEvent.signal(); if(userWait) waitForEvent.signal();
@@ -302,7 +300,7 @@ void PvaClientMonitor::connect()
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::connect " + " PvaClientMonitor::connect "
+ status.getMessage(); + status.getMessage();
+6 -183
View File
@@ -19,7 +19,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -53,43 +52,16 @@ PvaClientMonitorDataPtr PvaClientMonitorData::create(StructureConstPtr const & s
} }
PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure) PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure)
: structure(structure) : PvaClientData(structure)
{ {
messagePrefix = "";
} }
void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement) void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement)
{ {
pvStructure = monitorElement->pvStructurePtr; PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
changedBitSet = monitorElement->changedBitSet; BitSetPtr changedBitSet = monitorElement->changedBitSet;
PvaClientData::setData(pvStructure,changedBitSet);
overrunBitSet = monitorElement->overrunBitSet; 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() BitSetPtr PvaClientMonitorData::getOverrunBitSet()
@@ -98,24 +70,6 @@ BitSetPtr PvaClientMonitorData::getOverrunBitSet()
return overrunBitSet; 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) std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
{ {
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure); if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
@@ -123,9 +77,9 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
PVFieldPtr pvField; PVFieldPtr pvField;
while(nextSet!=string::npos) { while(nextSet!=string::npos) {
if(nextSet==0) { if(nextSet==0) {
pvField = pvStructure; pvField = getPVStructure();
} else { } else {
pvField = pvStructure->getSubField(nextSet); pvField = getPVStructure()->getSubField(nextSet);
} }
string name = pvField->getFullName(); string name = pvField->getFullName();
out << name << " = " << pvField << endl; out << name << " = " << pvField << endl;
@@ -134,135 +88,4 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
return 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> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -83,7 +80,7 @@ Status PvaClientMultiChannel::connect(double timeout)
Status status = Status::Ok; Status status = Status::Ok;
size_t numBad = 0; size_t numBad = 0;
for(size_t i=0; i< numChannel; ++i) { for(size_t i=0; i< numChannel; ++i) {
if(numBad==0) { if(numBad==0) {
status = pvaClientChannelArray[i]->waitConnect(timeout); status = pvaClientChannelArray[i]->waitConnect(timeout);
} else { } else {
status = pvaClientChannelArray[i]->waitConnect(.001); status = pvaClientChannelArray[i]->waitConnect(.001);
@@ -143,7 +140,7 @@ PvaClientPtr PvaClientMultiChannel::getPvaClient()
return pvaClient; return pvaClient;
} }
PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet() PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet()
{ {
+3 -4
View File
@@ -16,13 +16,12 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
PvaClientMultiGetDoublePtr PvaClientMultiGetDouble::create( PvaClientMultiGetDoublePtr PvaClientMultiGetDouble::create(
@@ -80,7 +79,7 @@ epics::pvData::shared_vector<double> PvaClientMultiGetDouble::get()
{ {
if(!isGetConnected) connect(); if(!isGetConnected) connect();
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
for(size_t i=0; i<nchannel; ++i) for(size_t i=0; i<nchannel; ++i)
{ {
if(isConnected[i]) { if(isConnected[i]) {
@@ -97,7 +96,7 @@ epics::pvData::shared_vector<double> PvaClientMultiGetDouble::get()
throw std::runtime_error(message); throw std::runtime_error(message);
} }
} }
for(size_t i=0; i<nchannel; ++i) for(size_t i=0; i<nchannel; ++i)
{ {
if(isConnected[i]) if(isConnected[i])
+1 -2
View File
@@ -16,13 +16,12 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
PvaClientMultiMonitorDoublePtr PvaClientMultiMonitorDouble::create( PvaClientMultiMonitorDoublePtr PvaClientMultiMonitorDouble::create(
+1 -2
View File
@@ -16,13 +16,12 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
PvaClientMultiPutDoublePtr PvaClientMultiPutDouble::create( PvaClientMultiPutDoublePtr PvaClientMultiPutDouble::create(
+34 -28
View File
@@ -15,13 +15,12 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
PvaClientNTMultiDataPtr PvaClientNTMultiData::create( PvaClientNTMultiDataPtr PvaClientNTMultiData::create(
epics::pvData::UnionConstPtr const & u, epics::pvData::UnionConstPtr const & u,
@@ -45,10 +44,6 @@ PvaClientNTMultiData::PvaClientNTMultiData(
gotTimeStamp(false) gotTimeStamp(false)
{ {
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::PvaClientNTMultiData()\n"; 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); topPVStructure.resize(nchannel);
unionValue.resize(nchannel); unionValue.resize(nchannel);
PVDataCreatePtr pvDataCreate = getPVDataCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate();
@@ -68,7 +63,7 @@ PvaClientNTMultiData::PvaClientNTMultiData(
severity.resize(nchannel); severity.resize(nchannel);
status.resize(nchannel); status.resize(nchannel);
message.resize(nchannel); message.resize(nchannel);
} }
if(pvRequest->getSubField("field.timeStamp")) { if(pvRequest->getSubField("field.timeStamp")) {
gotTimeStamp = true; gotTimeStamp = true;
@@ -89,18 +84,6 @@ PvaClientNTMultiData::~PvaClientNTMultiData()
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::~PvaClientNTMultiData()\n"; 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( void PvaClientNTMultiData::setPVStructure(
PVStructurePtr const &pvStructure,size_t index) 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) for(size_t i=0; i<nchannel; ++i)
{ {
@@ -146,20 +129,43 @@ void PvaClientNTMultiData::endDeltaTime()
if(!pvst) { if(!pvst) {
unionValue[i] = PVUnionPtr(); unionValue[i] = PVUnionPtr();
} else if(unionValue[i]) { } 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) if(gotAlarm)
{ {
severity[i] = pvst->getSubField<PVInt>("alarm.severity")->get(); PVIntPtr pvSeverity = pvst->getSubField<PVInt>("alarm.severity");
status[i] = pvst->getSubField<PVInt>("alarm.status")->get(); PVIntPtr pvStatus = pvst->getSubField<PVInt>("alarm.status");
message[i] = pvst->getSubField<PVString>("alarm.message")->get(); 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) if(gotTimeStamp)
{ {
secondsPastEpoch[i] = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch")->get(); PVLongPtr pvEpoch = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch");
nanoseconds[i] = pvst->getSubField<PVInt>("timeStamp.nanoseconds")->get(); PVIntPtr pvNano = pvst->getSubField<PVInt>("timeStamp.nanoseconds");
userTag[i] = pvst->getSubField<PVInt>("timeStamp.userTag")->get(); 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> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
PvaClientNTMultiGetPtr PvaClientNTMultiGet::create( PvaClientNTMultiGetPtr PvaClientNTMultiGet::create(
@@ -64,13 +63,10 @@ void PvaClientNTMultiGet::connect()
{ {
pvaClientGet.resize(nchannel); pvaClientGet.resize(nchannel);
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); 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) for(size_t i=0; i<nchannel; ++i)
{ {
if(isConnected[i]) { if(isConnected[i]) {
pvaClientGet[i] = pvaClientChannelArray[i]->createGet(request); pvaClientGet[i] = pvaClientChannelArray[i]->createGet(pvRequest);
pvaClientGet[i]->issueConnect(); pvaClientGet[i]->issueConnect();
} }
} }
@@ -79,7 +75,7 @@ void PvaClientNTMultiGet::connect()
if(isConnected[i]) { if(isConnected[i]) {
Status status = pvaClientGet[i]->waitConnect(); Status status = pvaClientGet[i]->waitConnect();
if(status.isOK()) continue; if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelGet::waitConnect " + status.getMessage(); + " PvaChannelGet::waitConnect " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -87,11 +83,11 @@ void PvaClientNTMultiGet::connect()
this->isConnected = true; this->isConnected = true;
} }
void PvaClientNTMultiGet::get() void PvaClientNTMultiGet::get(bool valueOnly)
{ {
if(!isConnected) connect(); if(!isConnected) connect();
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
for(size_t i=0; i<nchannel; ++i) for(size_t i=0; i<nchannel; ++i)
{ {
if(isConnected[i]) { if(isConnected[i]) {
@@ -103,7 +99,7 @@ void PvaClientNTMultiGet::get()
if(isConnected[i]) { if(isConnected[i]) {
Status status = pvaClientGet[i]->waitGet(); Status status = pvaClientGet[i]->waitGet();
if(status.isOK()) continue; if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelGet::waitGet " + status.getMessage(); + " PvaChannelGet::waitGet " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -115,7 +111,7 @@ void PvaClientNTMultiGet::get()
pvaClientNTMultiData->setPVStructure(pvaClientGet[i]->getData()->getPVStructure(),i); pvaClientNTMultiData->setPVStructure(pvaClientGet[i]->getData()->getPVStructure(),i);
} }
} }
pvaClientNTMultiData->endDeltaTime(); pvaClientNTMultiData->endDeltaTime(valueOnly);
} }
PvaClientNTMultiDataPtr PvaClientNTMultiGet::getData() PvaClientNTMultiDataPtr PvaClientNTMultiGet::getData()
+5 -9
View File
@@ -18,13 +18,12 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
PvaClientNTMultiMonitorPtr PvaClientNTMultiMonitor::create( PvaClientNTMultiMonitorPtr PvaClientNTMultiMonitor::create(
PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientMultiChannelPtr const &pvaMultiChannel,
@@ -68,13 +67,10 @@ void PvaClientNTMultiMonitor::connect()
{ {
pvaClientMonitor.resize(nchannel); pvaClientMonitor.resize(nchannel);
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); 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) for(size_t i=0; i<nchannel; ++i)
{ {
if(isConnected[i]) { if(isConnected[i]) {
pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(request); pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(pvRequest);
pvaClientMonitor[i]->issueConnect(); pvaClientMonitor[i]->issueConnect();
} }
} }
@@ -83,7 +79,7 @@ void PvaClientNTMultiMonitor::connect()
if(isConnected[i]) { if(isConnected[i]) {
Status status = pvaClientMonitor[i]->waitConnect(); Status status = pvaClientMonitor[i]->waitConnect();
if(status.isOK()) continue; if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelMonitor::waitConnect " + status.getMessage(); + " PvaChannelMonitor::waitConnect " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -95,7 +91,7 @@ void PvaClientNTMultiMonitor::connect()
this->isConnected = true; this->isConnected = true;
} }
bool PvaClientNTMultiMonitor::poll() bool PvaClientNTMultiMonitor::poll(bool valueOnly)
{ {
if(!isConnected) connect(); if(!isConnected) connect();
bool result = false; bool result = false;
@@ -112,7 +108,7 @@ bool PvaClientNTMultiMonitor::poll()
} }
} }
} }
if(result) pvaClientNTMultiData->endDeltaTime(); if(result) pvaClientNTMultiData->endDeltaTime(valueOnly);
return result; return result;
} }
+5 -6
View File
@@ -17,13 +17,12 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
PvaClientNTMultiPutPtr PvaClientNTMultiPut::create( PvaClientNTMultiPutPtr PvaClientNTMultiPut::create(
PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientMultiChannelPtr const &pvaMultiChannel,
@@ -68,7 +67,7 @@ void PvaClientNTMultiPut::connect()
if(isConnected[i]) { if(isConnected[i]) {
Status status = pvaClientPut[i]->waitConnect(); Status status = pvaClientPut[i]->waitConnect();
if(status.isOK()) continue; if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelPut::waitConnect " + status.getMessage(); + " PvaChannelPut::waitConnect " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -84,7 +83,7 @@ void PvaClientNTMultiPut::connect()
if(isConnected[i]) { if(isConnected[i]) {
Status status = pvaClientPut[i]->waitGet(); Status status = pvaClientPut[i]->waitGet();
if(status.isOK()) continue; if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelPut::waitGet " + status.getMessage(); + " PvaChannelPut::waitGet " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -122,9 +121,9 @@ void PvaClientNTMultiPut::put()
if(isConnected[i]) { if(isConnected[i]) {
Status status = pvaClientPut[i]->waitPut(); Status status = pvaClientPut[i]->waitPut();
if(status.isOK()) continue; if(status.isOK()) continue;
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName() string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
+ " PvaChannelPut::waitPut " + status.getMessage(); + " PvaChannelPut::waitPut " + status.getMessage();
throw std::runtime_error(message); throw std::runtime_error(message);
} }
} }
} }
+3 -4
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -55,7 +54,7 @@ public:
{ {
PvaClientProcessPtr clientProcess(pvaClientProcess.lock()); PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
if(!clientProcess) return; if(!clientProcess) return;
clientProcess->channelProcessConnect(status,channelProcess); clientProcess->channelProcessConnect(status,channelProcess);
} }
virtual void processDone( virtual void processDone(
@@ -157,7 +156,7 @@ void PvaClientProcess::channelProcessConnect(
req->channelProcessConnect(status,shared_from_this()); req->channelProcessConnect(status,shared_from_this());
} }
waitForConnect.signal(); waitForConnect.signal();
} }
void PvaClientProcess::processDone( void PvaClientProcess::processDone(
@@ -175,7 +174,7 @@ void PvaClientProcess::processDone(
channelProcessStatus = status; channelProcessStatus = status;
processState = processComplete; processState = processComplete;
} }
PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock()); PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
if(req) { if(req) {
req->processDone(status,shared_from_this()); req->processDone(status,shared_from_this());
+6 -7
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -56,7 +55,7 @@ public:
{ {
PvaClientPutPtr clientPut(pvaClientPut.lock()); PvaClientPutPtr clientPut(pvaClientPut.lock());
if(!clientPut) return; if(!clientPut) return;
clientPut->channelPutConnect(status,channelPut,structure); clientPut->channelPutConnect(status,channelPut,structure);
} }
virtual void getDone( virtual void getDone(
@@ -184,7 +183,7 @@ void PvaClientPut::channelPutConnect(
req->channelPutConnect(status,shared_from_this()); req->channelPutConnect(status,shared_from_this());
} }
waitForConnect.signal(); waitForConnect.signal();
} }
void PvaClientPut::getDone( void PvaClientPut::getDone(
@@ -250,7 +249,7 @@ void PvaClientPut::connect()
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::connect " + " PvaClientPut::connect "
+ status.getMessage(); + status.getMessage();
@@ -272,7 +271,7 @@ void PvaClientPut::issueConnect()
connectState = connectActive; connectState = connectActive;
channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active"); channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest); channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest);
} }
Status PvaClientPut::waitConnect() Status PvaClientPut::waitConnect()
@@ -309,7 +308,7 @@ void PvaClientPut::get()
issueGet(); issueGet();
Status status = waitGet(); Status status = waitGet();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::get " + " PvaClientPut::get "
+ status.getMessage(); + status.getMessage();
@@ -377,7 +376,7 @@ void PvaClientPut::issuePut()
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientPut::issuePut" cout << "PvaClientPut::issuePut"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " pvStructure\n" << pvaClientData->getPVStructure() << " pvStructure\n" << pvaClientData->getPVStructure()
<< " bitSet " << *pvaClientData->getChangedBitSet() << endl << " bitSet " << *pvaClientData->getChangedBitSet() << endl
<< endl; << endl;
} }
+59 -168
View File
@@ -25,6 +25,10 @@ using namespace epics::pvAccess;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { 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 class PvaClientPostHandlerPvt: public PostHandler
{ {
@@ -36,28 +40,21 @@ public:
void postPut() { putData->postPut(fieldNumber);} 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) PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) cout << "PvaClientPutData::create\n";
PvaClientPutDataPtr epv(new PvaClientPutData(structure)); PvaClientPutDataPtr epv(new PvaClientPutData(structure));
return epv; return epv;
} }
PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure)
: structure(structure), : PvaClientData(structure)
pvStructure(getPVDataCreate()->createPVStructure(structure)),
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
{ {
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(); size_t nfields = pvStructure->getNumberFields();
postHandler.resize(nfields); postHandler.resize(nfields);
PVFieldPtr pvField; PVFieldPtr pvField;
@@ -71,145 +68,18 @@ PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure)
} }
pvField->setPostHandler(postHandler[i]); 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) 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(); ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) { if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar); PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
@@ -217,47 +87,68 @@ void PvaClientPutData::putDouble(double value)
return; return;
} }
if(!ScalarTypeFunc::isNumeric(scalarType)) { 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); convert->fromDouble(pvScalar,value);
} }
void PvaClientPutData::putString(std::string const & 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); convert->fromString(pvScalar,value);
} }
void PvaClientPutData::putDoubleArray(shared_vector<const double> const & value) void PvaClientPutData::putDoubleArray(shared_vector<const double> const & value)
{ {
checkValue(); if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n";
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value"); PVFieldPtr pvField = getSinglePVField();
if(!pv) { Type type = pvField->getField()->getType();
throw std::runtime_error(messagePrefix + notDoubleArray); 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) void PvaClientPutData::putStringArray(shared_vector<const std::string> const & value)
{ {
checkValue(); if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n";
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value"); PVFieldPtr pvField = getSinglePVField();
if(!pv) { Type type = pvField->getField()->getType();
throw std::runtime_error(messagePrefix + notStringArray); 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(); size_t length = value.size();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value"); shared_vector<string> val(length);
if(!pv) { for(size_t i=0; i < length; ++i) val[i] = value[i];
throw std::runtime_error(messagePrefix + notScalarArray); putStringArray(freeze(val));
} return;
convert->fromStringArray(pv,0,value.size(),value,0);
} }
void PvaClientPutData::postPut(size_t fieldNumber)
{
if(PvaClient::getDebug()) cout << "PvaClientPutData::postPut\n";
getChangedBitSet()->set(fieldNumber);
}
}} }}
+32 -34
View File
@@ -14,7 +14,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -56,7 +55,7 @@ public:
{ {
PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
if(!clientPutGet) return; if(!clientPutGet) return;
clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure); clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
} }
virtual void putGetDone( virtual void putGetDone(
@@ -185,7 +184,7 @@ void PvaClientPutGet::channelPutGetConnect(
pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
pvaClientGetData = PvaClientGetData::create(getStructure); pvaClientGetData = PvaClientGetData::create(getStructure);
pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
} else { } else {
stringstream ss; stringstream ss;
ss << pvRequest; ss << pvRequest;
@@ -200,7 +199,7 @@ void PvaClientPutGet::channelPutGetConnect(
req->channelPutGetConnect(status,shared_from_this()); req->channelPutGetConnect(status,shared_from_this());
} }
waitForConnect.signal(); waitForConnect.signal();
} }
void PvaClientPutGet::putGetDone( void PvaClientPutGet::putGetDone(
@@ -215,14 +214,13 @@ void PvaClientPutGet::putGetDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; {
putGetState = putGetComplete; Lock xx(mutex);
if(status.isOK()) { channelPutGetStatus = status;
PVStructurePtr pvs = pvaClientGetData->getPVStructure(); putGetState = putGetComplete;
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); if(status.isOK()) {
BitSetPtr bs = pvaClientGetData->getChangedBitSet(); pvaClientGetData->setData(getPVStructure,getChangedBitSet);
bs->clear(); }
*bs |= *getChangedBitSet;
} }
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) { if(req) {
@@ -243,14 +241,17 @@ void PvaClientPutGet::getPutDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; {
putGetState = putGetComplete; Lock xx(mutex);
if(status.isOK()) { channelPutGetStatus = status;
PVStructurePtr pvs = pvaClientPutData->getPVStructure(); putGetState = putGetComplete;
pvs->copyUnchecked(*putPVStructure,*putBitSet); if(status.isOK()) {
BitSetPtr bs = pvaClientPutData->getChangedBitSet(); PVStructurePtr pvs = pvaClientPutData->getPVStructure();
bs->clear(); pvs->copyUnchecked(*putPVStructure,*putBitSet);
*bs |= *putBitSet; BitSetPtr bs = pvaClientPutData->getChangedBitSet();
bs->clear();
*bs |= *putBitSet;
}
} }
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) { if(req) {
@@ -271,14 +272,13 @@ void PvaClientPutGet::getGetDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; {
putGetState = putGetComplete; Lock xx(mutex);
if(status.isOK()) { channelPutGetStatus = status;
PVStructurePtr pvs = pvaClientGetData->getPVStructure(); putGetState = putGetComplete;
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); if(status.isOK()) {
BitSetPtr bs = pvaClientGetData->getChangedBitSet(); pvaClientGetData->setData(getPVStructure,getChangedBitSet);
bs->clear(); }
*bs |= *getChangedBitSet;
} }
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) { if(req) {
@@ -297,7 +297,7 @@ void PvaClientPutGet::connect()
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPutGet::connect " + " PvaClientPutGet::connect "
+ status.getMessage(); + status.getMessage();
@@ -358,7 +358,7 @@ void PvaClientPutGet::putGet()
issuePutGet(); issuePutGet();
Status status = waitPutGet(); Status status = waitPutGet();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::putGet " + " PvaClientPut::putGet "
+ status.getMessage(); + status.getMessage();
@@ -413,7 +413,7 @@ void PvaClientPutGet::getGet()
issueGetGet(); issueGetGet();
Status status = waitGetGet(); Status status = waitGetGet();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::getGet " + " PvaClientPut::getGet "
+ status.getMessage(); + status.getMessage();
@@ -466,7 +466,7 @@ void PvaClientPutGet::getPut()
issueGetPut(); issueGetPut();
Status status = waitGetPut(); Status status = waitGetPut();
if(status.isOK()) return; if(status.isOK()) return;
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::getPut " + " PvaClientPut::getPut "
+ status.getMessage(); + status.getMessage();
@@ -555,6 +555,4 @@ PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel()
return pvaClientChannel; return pvaClientChannel;
} }
}} }}
+20 -12
View File
@@ -12,13 +12,12 @@
#include <sstream> #include <sstream>
#include <pv/event.h> #include <pv/event.h>
#include <pv/bitSetUtil.h> #include <pv/bitSetUtil.h>
#include <pv/rpcService.h>
#define epicsExportSharedSymbols #define epicsExportSharedSymbols
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -95,7 +94,7 @@ PvaClientRPC::PvaClientRPC(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
Channel::shared_pointer const & channel, Channel::shared_pointer const & channel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
: :
connectState(connectIdle), connectState(connectIdle),
pvaClient(pvaClient), pvaClient(pvaClient),
channel(channel), channel(channel),
@@ -105,7 +104,7 @@ PvaClientRPC::PvaClientRPC(
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientRPC::PvaClientRPC()" cout<< "PvaClientRPC::PvaClientRPC()"
<< " channelName " << channel->getChannelName() << " channelName " << channel->getChannelName()
<< endl; << endl;
} }
} }
@@ -171,7 +170,7 @@ void PvaClientRPC::rpcConnect(
cout << "PvaClientRPC::rpcConnect calling waitForConnect.signal\n"; cout << "PvaClientRPC::rpcConnect calling waitForConnect.signal\n";
} }
waitForConnect.signal(); waitForConnect.signal();
} }
void PvaClientRPC::requestDone( void PvaClientRPC::requestDone(
@@ -182,6 +181,7 @@ void PvaClientRPC::requestDone(
PvaClientRPCRequesterPtr req = pvaClientRPCRequester.lock(); PvaClientRPCRequesterPtr req = pvaClientRPCRequester.lock();
{ {
Lock xx(mutex); Lock xx(mutex);
requestStatus = status;
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
string channelName("disconnected"); string channelName("disconnected");
Channel::shared_pointer chan(channel.lock()); Channel::shared_pointer chan(channel.lock());
@@ -195,7 +195,7 @@ void PvaClientRPC::requestDone(
Channel::shared_pointer chan(channel.lock()); Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName(); if(chan) channelName = chan->getChannelName();
string message = "channel " string message = "channel "
+ channelName + channelName
+" PvaClientRPC::requestDone" +" PvaClientRPC::requestDone"
+ " but not active"; + " but not active";
throw std::runtime_error(message); throw std::runtime_error(message);
@@ -222,11 +222,11 @@ void PvaClientRPC::connect()
Channel::shared_pointer chan(channel.lock()); Channel::shared_pointer chan(channel.lock());
string channelName("disconnected"); string channelName("disconnected");
if(chan) channelName = chan->getChannelName(); if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ channelName + channelName
+ " PvaClientRPC::connect " + " PvaClientRPC::connect "
+ status.getMessage(); + status.getMessage();
throw std::runtime_error(message); throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
} }
void PvaClientRPC::issueConnect() void PvaClientRPC::issueConnect()
@@ -237,7 +237,7 @@ void PvaClientRPC::issueConnect()
string channelName("disconnected"); string channelName("disconnected");
if(chan) channelName = chan->getChannelName(); if(chan) channelName = chan->getChannelName();
string message = string("channel ") string message = string("channel ")
+ channelName + channelName
+ " pvaClientRPC already connected "; + " pvaClientRPC already connected ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
@@ -307,10 +307,18 @@ PVStructure::shared_pointer PvaClientRPC::request(PVStructure::shared_pointer co
string message = "channel " string message = "channel "
+ channelName + channelName
+ " PvaClientRPC::request request timeout "; + " PvaClientRPC::request request timeout ";
throw std::runtime_error(message); throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
} }
rpcState = rpcIdle; 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, PVStructure::shared_pointer const & pvArgument,
PvaClientRPCRequesterPtr const & pvaClientRPCRequester) PvaClientRPCRequesterPtr const & pvaClientRPCRequester)
{ {
checkRPCState(); checkRPCState();
this->pvaClientRPCRequester = pvaClientRPCRequester; this->pvaClientRPCRequester = pvaClientRPCRequester;
if(responseTimeout<=0.0) { if(responseTimeout<=0.0) {
{ {