30 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
31 changed files with 581 additions and 395 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)))
+20 -1
View File
@@ -1,7 +1,26 @@
# 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) ## 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. Changes have been made for getDouble, putDouble, getDoubleArray, putDoubleArray, getString, putString, getStringArray, and putStringArray.
+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>
+1 -1
View File
@@ -6,7 +6,7 @@ include $(TOP)/configure/CONFIG
LIBRARY += pvaClient LIBRARY += pvaClient
# shared library ABI version. # shared library ABI version.
SHRLIB_VERSION ?= 4.5.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
+36 -3
View File
@@ -17,6 +17,7 @@
#include <list> #include <list>
#include <iostream> #include <iostream>
#include <ostream>
#include <sstream> #include <sstream>
#include <pv/requester.h> #include <pv/requester.h>
#include <pv/status.h> #include <pv/status.h>
@@ -35,7 +36,7 @@
#ifdef pvaClientEpicsExportSharedSymbols #ifdef pvaClientEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef pvaClientEpicsExportSharedSymbols # undef pvaClientEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>
@@ -613,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.
*/ */
@@ -679,6 +681,29 @@ 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. /** @brief Factory method for creating an instance of PvaClientData.
* *
* NOTE: Not normally called by clients * NOTE: Not normally called by clients
@@ -688,15 +713,23 @@ public:
static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure); static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure);
protected: protected:
PvaClientData(epics::pvData::StructureConstPtr const & structure); PvaClientData(epics::pvData::StructureConstPtr const & structure);
epics::pvData::PVFieldPtr getSinglePVField();
void checkValue(); void checkValue();
std::string messagePrefix; std::string messagePrefix;
private: 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::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure; epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet; epics::pvData::BitSetPtr bitSet;
epics::pvData::PVFieldPtr pvValue; epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm; epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp; epics::pvData::PVTimeStamp pvTimeStamp;
@@ -1813,6 +1846,7 @@ private:
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;
}; };
@@ -1826,4 +1860,3 @@ private:
* <a href = "../pvaClientCPP.html">pvaClientCPP.html</a> * <a href = "../pvaClientCPP.html">pvaClientCPP.html</a>
* *
*/ */
+9 -7
View File
@@ -21,7 +21,7 @@
#ifdef pvaClientMultiChannelEpicsExportSharedSymbols #ifdef pvaClientMultiChannelEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef pvaClientMultiChannelEpicsExportSharedSymbols # undef pvaClientMultiChannelEpicsExportSharedSymbols
#endif #endif
@@ -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.
@@ -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.
@@ -551,11 +554,12 @@ public:
* @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.
@@ -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);
@@ -612,4 +615,3 @@ private:
}} }}
#endif /* PVACLIENTMULTICHANNEL_H */ #endif /* PVACLIENTMULTICHANNEL_H */
-1
View File
@@ -231,4 +231,3 @@ size_t PvaClient::cacheSize()
} }
}} }}
+191 -112
View File
@@ -11,9 +11,17 @@
#include <typeinfo> #include <typeinfo>
#include <sstream> #include <sstream>
#include <istream>
#include <ostream>
#include <pv/createRequest.h> #include <pv/createRequest.h>
#include <pv/convert.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 #define epicsExportSharedSymbols
@@ -49,6 +57,30 @@ PvaClientData::PvaClientData(StructureConstPtr const & 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() void PvaClientData::checkValue()
{ {
if(PvaClient::getDebug()) cout << "PvaClientData::checkValue\n"; if(PvaClient::getDebug()) cout << "PvaClientData::checkValue\n";
@@ -106,6 +138,7 @@ void PvaClientData::setData(
pvValue = pvStructure->getSubField("value"); pvValue = pvStructure->getSubField("value");
} }
bool PvaClientData::hasValue() bool PvaClientData::hasValue()
{ {
if(PvaClient::getDebug()) cout << "PvaClientData::hasValue\n"; if(PvaClient::getDebug()) cout << "PvaClientData::hasValue\n";
@@ -171,34 +204,12 @@ PVScalarArrayPtr PvaClientData::getScalarArrayValue()
double PvaClientData::getDouble() double PvaClientData::getDouble()
{ {
if(PvaClient::getDebug()) cout << "PvaClientData::getDouble\n"; if(PvaClient::getDebug()) cout << "PvaClientData::getDouble\n";
PVScalarPtr pvScalar; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalar) {
if(pvValue) { throw std::logic_error("PvaClientData::getDouble() did not find a scalar field");
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getDouble() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
throw std::logic_error(
"PvaClientData::getDouble() 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);
@@ -214,70 +225,24 @@ double PvaClientData::getDouble()
string PvaClientData::getString() string PvaClientData::getString()
{ {
if(PvaClient::getDebug()) cout << "PvaClientData::getString\n"; if(PvaClient::getDebug()) cout << "PvaClientData::getString\n";
PVScalarPtr pvScalar; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalar) {
if(pvValue) { throw std::logic_error("PvaClientData::getString() did not find a scalar field");
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getString() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
throw std::logic_error(
"PvaClientData::getString() did not find a scalar field");
} }
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
return convert->toString(pvScalar); return convert->toString(pvScalar);
} }
shared_vector<const double> PvaClientData::getDoubleArray() shared_vector<const double> PvaClientData::getDoubleArray()
{ {
if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n"; if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n";
PVScalarArrayPtr pvScalarArray; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalarArray) {
if(pvValue) { throw std::logic_error("PvaClientData::getDoubleArray() did not find a scalarArray field");
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
}
if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getDoubleArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::getDoubleArray() did not find a scalarArray field");
} }
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType(); ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(!ScalarTypeFunc::isNumeric(scalarType)) { if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error( throw std::logic_error(
@@ -291,36 +256,12 @@ shared_vector<const double> PvaClientData::getDoubleArray()
shared_vector<const string> PvaClientData::getStringArray() shared_vector<const string> PvaClientData::getStringArray()
{ {
if(PvaClient::getDebug()) cout << "PvaClientData::getStringArray\n"; if(PvaClient::getDebug()) cout << "PvaClientData::getStringArray\n";
PVScalarArrayPtr pvScalarArray; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalarArray) {
if(pvValue) { throw std::logic_error("PvaClientData::getStringArray() did not find a scalarArray field");
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
}
if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getStringArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::getStringArray() did not find a scalarArray field");
} }
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
shared_vector<const string> retValue; shared_vector<const string> retValue;
pvScalarArray->getAs<const string>(retValue); pvScalarArray->getAs<const string>(retValue);
return retValue; return retValue;
@@ -358,4 +299,142 @@ TimeStamp PvaClientData::getTimeStamp()
throw std::runtime_error(messagePrefix + noTimeStamp); 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;
}
}
}
}} }}
+1 -1
View File
@@ -80,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);
+31 -24
View File
@@ -44,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();
@@ -88,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)
{ {
@@ -137,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)
{ {
@@ -145,18 +129,41 @@ 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();
}
} }
} }
} }
+3 -6
View File
@@ -63,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();
} }
} }
@@ -86,7 +83,7 @@ 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();
@@ -114,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()
+3 -6
View File
@@ -67,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();
} }
} }
@@ -94,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;
@@ -111,7 +108,7 @@ bool PvaClientNTMultiMonitor::poll()
} }
} }
} }
if(result) pvaClientNTMultiData->endDeltaTime(); if(result) pvaClientNTMultiData->endDeltaTime(valueOnly);
return result; return result;
} }
+20 -112
View File
@@ -74,34 +74,12 @@ PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure)
void PvaClientPutData::putDouble(double value) void PvaClientPutData::putDouble(double value)
{ {
if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\n"; if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\n";
PVScalarPtr pvScalar; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalar) {
if(pvValue) { throw std::logic_error("PvaClientData::putDouble() did not find a scalar field");
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putDouble() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
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);
@@ -118,70 +96,24 @@ void PvaClientPutData::putDouble(double value)
void PvaClientPutData::putString(std::string const & value) void PvaClientPutData::putString(std::string const & value)
{ {
if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\n"; if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\n";
PVScalarPtr pvScalar; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalar) {
if(pvValue) { throw std::logic_error("PvaClientData::putString() did not find a scalar field");
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putString() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
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)
{ {
if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n"; if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n";
PVScalarArrayPtr pvScalarArray; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalarArray) {
if(pvValue) { throw std::logic_error("PvaClientData::putDoubleArray() did not find a scalarArray field");
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
}
if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putDoubleArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::putDoubleArray() did not find a scalarArray field");
} }
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType(); ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(!ScalarTypeFunc::isNumeric(scalarType)) { if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error( throw std::logic_error(
@@ -193,36 +125,12 @@ void PvaClientPutData::putDoubleArray(shared_vector<const double> const & value)
void PvaClientPutData::putStringArray(shared_vector<const std::string> const & value) void PvaClientPutData::putStringArray(shared_vector<const std::string> const & value)
{ {
if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n"; if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n";
PVScalarArrayPtr pvScalarArray; PVFieldPtr pvField = getSinglePVField();
PVStructurePtr pvStructure = getPVStructure(); Type type = pvField->getField()->getType();
PVFieldPtr pvValue = pvStructure->getSubField("value"); if(type!=scalarArray) {
if(pvValue) { throw std::logic_error("PvaClientData::putStringArray() did not find a scalarArray field");
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
}
if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putStringArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::putStringArray() did not find a scalarArray field");
} }
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
pvScalarArray->putFrom<const string>(value); pvScalarArray->putFrom<const string>(value);
return; return;
} }
+13 -3
View File
@@ -12,6 +12,7 @@
#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
@@ -180,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());
@@ -224,7 +226,7 @@ void PvaClientRPC::connect()
+ 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()
@@ -305,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);
} }