6 Commits
6.0.2 ... 5.0.2

Author SHA1 Message Date
Dave Hickin
892f1e2242 Merge branch 'master' into release/5.0 2015-10-17 10:36:39 +01:00
Dave Hickin
f02ac3c139 Merge branch 'master' into release/5.0 2015-10-16 23:25:24 +01:00
Ralph Lange
fc641b48c3 jenkins: fix CloudBees doc job 2015-09-28 14:59:35 +02:00
Ralph Lange
bcaac0163a jenkins: adapt doc script to new CloudBees jenkins job 2015-09-14 15:17:55 +02:00
Dave Hickin
f9d27b2d74 Merge branch 'master' into release/5.0 2015-09-05 07:38:15 +01:00
Ralph Lange
392cc7426d jenkins: update dependencies pvCommonCPP/4.1 pvDataCPP/5.0 2015-09-04 11:55:29 +02:00
89 changed files with 8164 additions and 5469 deletions

View File

@@ -1,10 +0,0 @@
#!/bin/sh
set -e -x
make -j2 $EXTRA
if [ "$TEST" != "NO" ]
then
make -j2 tapfiles
make -j2 -s test-results
fi

View File

@@ -1,107 +0,0 @@
#!/bin/sh
set -e -x
CURDIR="$PWD"
cat << EOF > $CURDIR/configure/RELEASE.local
EPICS_BASE=$HOME/.source/epics-base
EOF
install -d "$HOME/.source"
cd "$HOME/.source"
add_gh_flat() {
MODULE=$1
REPOOWNER=$2
REPONAME=$3
BRANCH=$4
MODULE_UC=$(echo $MODULE | tr 'a-z' 'A-Z')
( git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
cd $MODULE && git log -n1 )
cat < $CURDIR/configure/RELEASE.local > $MODULE/configure/RELEASE.local
cat << EOF >> $CURDIR/configure/RELEASE.local
${MODULE_UC}=$HOME/.source/$MODULE
EOF
}
# not recursive
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
(cd epics-base && git log -n1 )
add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
if [ -e $CURDIR/configure/RELEASE.local ]
then
cat $CURDIR/configure/RELEASE.local
fi
EPICS_HOST_ARCH=`sh epics-base/startup/EpicsHostArch`
# requires wine and g++-mingw-w64-i686
if [ "$WINE" = "32" ]
then
echo "Cross mingw32"
sed -i -e '/CMPLR_PREFIX/d' epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
cat << EOF >> epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
CMPLR_PREFIX=i686-w64-mingw32-
EOF
cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw
EOF
fi
if [ "$STATIC" = "YES" ]
then
echo "Build static libraries/executables"
cat << EOF >> epics-base/configure/CONFIG_SITE
SHARED_LIBRARIES=NO
STATIC_BUILD=YES
EOF
fi
case "$CMPLR" in
clang)
echo "Host compiler is clang"
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.$EPICS_HOST_ARCH
GNU = NO
CMPLR_CLASS = clang
CC = clang
CCC = clang++
EOF
# hack
sed -i -e 's/CMPLR_CLASS = gcc/CMPLR_CLASS = clang/' epics-base/configure/CONFIG.gnuCommon
clang --version
;;
*)
echo "Host compiler is default"
gcc --version
;;
esac
cat <<EOF >> epics-base/configure/CONFIG_SITE
USR_CPPFLAGS += $USR_CPPFLAGS
USR_CFLAGS += $USR_CFLAGS
USR_CXXFLAGS += $USR_CXXFLAGS
EOF
# set RTEMS to eg. "4.9" or "4.10"
# requires qemu, bison, flex, texinfo, install-info
if [ -n "$RTEMS" ]
then
echo "Cross RTEMS${RTEMS} for pc386"
curl -L "https://github.com/mdavidsaver/rsb/releases/download/20171203-${RTEMS}/i386-rtems${RTEMS}-trusty-20171203-${RTEMS}.tar.bz2" \
| tar -C / -xmj
sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' epics-base/configure/os/CONFIG_SITE.Common.RTEMS
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.RTEMS
RTEMS_VERSION=$RTEMS
RTEMS_BASE=$HOME/.rtems
EOF
cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS += RTEMS-pc386-qemu
EOF
fi
make -j2 -C epics-base $EXTRA
make -j2 -C pvData $EXTRA

23
.gitignore vendored
View File

@@ -1,14 +1,9 @@
/cfg/
/bin/
/lib/
/db/
/dbd/
/html/
/include/
/templates/
/configure/*.local
O.*/
/QtC-*
*.orig
*.log
.*.swp
bin/
include/
lib/
db/
dbd/
configure/*.local
html/
**/O.*
**/**/O.*

View File

@@ -1,17 +0,0 @@
# .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

View File

@@ -1,31 +0,0 @@
sudo: false
dist: trusty
language: c++
compiler:
- gcc
addons:
apt:
packages:
- libreadline6-dev
- libncurses5-dev
- perl
- clang
- g++-mingw-w64-i686
- qemu-system-x86
install:
- ./.ci/travis-prepare.sh
script:
- ./.ci/travis-build.sh
env:
- BRBASE=7.0
- BRBASE=7.0 CMPLR=clang
- BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++98"
- BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++11"
- BRBASE=7.0 CMPLR=clang EXTRA="CMD_CXXFLAGS=-std=c++11"
- BRBASE=7.0 WINE=32 TEST=NO STATIC=YES
- BRBASE=7.0 WINE=32 TEST=NO STATIC=NO
- BRBASE=7.0 RTEMS=4.10 TEST=NO
- BRBASE=7.0 RTEMS=4.9 TEST=NO
- BRBASE=3.16
- BRBASE=3.15
- BRBASE=3.14

31
COPYRIGHT Normal file
View File

@@ -0,0 +1,31 @@
This software is in part copyrighted by the various organizations and
individuals listed below. Permission to use it is set out in the file
LICENSE that accompanies the software.
In no event shall any copyright holder be liable to any party for
direct, indirect, special, incidental, or consequential damages arising
out of the use of this software, its documentation, or any derivatives
thereof, even if they have been advised of the possibility of such
damage.
The copyright holders specifically disclaim any warranties, including,
but not limited to, the implied warranties of merchantability, fitness
for a particular purpose, and non-infringement. This software is
provided on an "as is" basis, and the copyright holders have no
obligation either collectively or individually to provide maintenance,
support, updates, enhancements, or modifications.
Copyright (c) 2006 - 2015 All rights reserved
Martin R. Kraimer
The University of Chicago, as Operator of Argonne National Laboratory.
Deutsches Elektronen-Synchroton, Member of the Helmholtz Association,
(DESY), HAMBURG, GERMANY,
BERLINER SPEICHERRING GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H.
(BESSY), BERLIN, GERMANY.
COSYLAB (Control System Laboratory), Ljubljana, Slovenia.
Brookhaven Science Associates, as Operator of Brookhaven
National Laboratory.
Diamond Light Source Ltd., Didcot, United Kingdom.

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = normativeTypesCPP
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 6.0.2
PROJECT_NUMBER =
# 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
@@ -743,7 +743,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = src
INPUT = include
# 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
@@ -1008,7 +1008,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = html/doxygen
HTML_OUTPUT = documentation/html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).

109
LICENSE
View File

@@ -1,16 +1,14 @@
Copyright and License Terms
---------------------------
Copyright (c) 2006-2016 Martin R. Kraimer
Copyright (c) 2006-2016 UChicago Argonne LLC, as Operator of Argonne
Copyright (c) 2006-2015 Martin R. Kraimer
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
National Laboratory.
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
Copyright (c) 2007-2016 Control System Laboratory,
Copyright (c) 2007-2015 Control System Laboratory,
(COSYLAB) Ljubljana Slovenia
Copyright (c) 2010-2016 Brookhaven Science Associates, as Operator
of Brookhaven National Laboratory
Copyright (c) 2011-2016 Diamond Light Source Limited,
Copyright (c) 2010-2015 Brookhaven Science Associates, as Operator of Brookhaven
National Laboratory
Copyright (c) 2011-2015 Diamond Light Source Limited,
(DLS) Didcot, United Kingdom
Permission is hereby granted, free of charge, to any person
@@ -36,30 +34,81 @@ OTHER DEALINGS IN THE SOFTWARE.
________________________________________________________________________
Additional Disclaimers
----------------------
This software is in part copyrighted by the University of Chicago (UofC)
This software is copyright in part by these institutions:
In no event shall UofC be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
UofC has been advised of the possibility of such damage.
* Brookhaven Science Associates, as Operator of Brookhaven
National Laboratory, New York, USA
* Control System Laboratory, Ljubljana, Slovenia
* Deutsches Elektronen-Synchroton, Member of the Helmholtz
Association, Hamburg, Germany
* Diamond Light Source Limited, Didcot, United Kingdom
* Helmholtz-Zentrum Berlin fuer Materialien und Energie m.b.H.,
Berlin, Germany.
* UChicage Argonne LLC, as Operator of Argonne National Laboratory,
Illinois, USA
UofC specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and UofC has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
In no event shall these institutions be liable to any party for direct,
indirect, special, incidental, or consequential damages arising out of
the use of this software, its documentation, or any derivatives thereof,
even if advised of the possibility of such damage.
________________________________________________________________________
These institutions specifically disclaim any warranties, including, but
not limited to, the implied warranties of merchantability, fitness for a
particular purpose, and non-infringement. This software is provided on
an "as is" basis, and these institutions have no obligation to provide
maintenance, support, updates, enhancements, or modifications.
This software is in part copyrighted by the BERLINER SPEICHERRING
GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H. (BESSY), BERLIN, GERMANY.
In no event shall BESSY be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
BESSY has been advised of the possibility of such damage.
BESSY specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and BESSY has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________
This software is in part copyrighted by the Deutsches Elektronen-Synchroton,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
In no event shall DESY be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
DESY has been advised of the possibility of such damage.
DESY specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and DESY has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
______________________________________________________________________
This software is in part copyrighted by the Brookhaven
National Laboratory (BNL).
In no event shall BNL be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
BNL has been advised of the possibility of such damage.
BNL specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and BNL has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________
This software is in part copyrighted by Diamond Light Source Limited (DLS)
In no event shall DLS be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
DLS has been advised of the possibility of such damage.
DLS specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and DLS has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________

View File

@@ -1,17 +1,78 @@
# normativeTypesCPP
normativeTypesCPP
=================
The EPICS **Normative Types** are a set of standard high-level data types, designed to aid interoperability between EPICS PVA applications.
normativeTypesCPP is a C++ module containing helper classes which implement
and provide support for the EPICS V4 Normative Types.
This normativeTypesCPP module is a part of the EPICS software toolkit that provides C++ helper classes which implement the EPICS Normative Types.
The latter are a set of standard high-level data types to aid interoperability
of EPICS V4 applications and are specified in the
[NormativeTypes Specification](http://epics-pvdata.sourceforge.net/alpha/normativeTypes/normativeTypes.html).
## Links
- General information about EPICS can be found at the
[EPICS Controls website](https://epics-controls.org).
- API documentation for this module can be found in its
documentation directory, in particular the file
normativeTypesCPP.html
Status
------
## Building
The current release (5.0) implements fully the
[16 Mar 2015 version](http://epics-pvdata.sourceforge.net/alpha/normativeTypes/normativeTypes_20150316.html)
of the Normative Types Specification.
The module status is alpha and the API and behaviour may change in future
versions.
The previous release (4.0) supported only 6 types.
There is no documentation yet for the new types added in 5.0.
Further Info
------------
Consult the documents in the documentation directory, in particular
* normativeTypesCPP.html
* RELEASE_NOTES.md
Also see the [EPICS Version 4 website](http://epics-pvdata.sourceforge.net)
Prerequisites
-------------
normativeTypesCPP requires recent versions of the following software:
1. EPICS Base (v3.14.12.3 or later)
2. EPICS4 pvCommonCPP (4.1.0 or later)
2. pvDataCPP (5.0.0 or later)
(pvCommonCPP may not be needed depending on host/compiler.)
Building
--------
Building uses the make utility and the EPICS base build system.
The build system needs the location of the prerequisites, e.g. by placing the
lines of the form
PVDATA = /home/install/epicsV4/pvDataCPP
PVCOMMON = /home/install/epicsV4/pvCommonCPP
EPICS_BASE = /home/install/epics/base
pointing to the locations in a file called RELEASE.local
in the configure directory or the parent directory of normativeTypesCPP.
With this in place, to build type make
make
To perform a clean build type
make clean uninstall
To run the unit tests type
make runtests
For more information on the EPICS build system consult the
[Application Development guide](http://www.aps.anl.gov/epics/base/R3-14/12-docs/AppDevGuide.pdf).
This module is included as a submodule of a full EPICS 7 release and will be compiled during builds of that software.

View File

@@ -1,12 +0,0 @@
# Version number for the Normative Types API and shared library
EPICS_NTYPES_MAJOR_VERSION = 6
EPICS_NTYPES_MINOR_VERSION = 0
EPICS_NTYPES_MAINTENANCE_VERSION = 2
# Development flag, set to zero for release versions
EPICS_NTYPES_DEVELOPMENT_FLAG = 0
# Immediately after a release the MAINTENANCE_VERSION
# will be incremented and the DEVELOPMENT_FLAG set to 1

View File

@@ -29,8 +29,9 @@ USR_CPPFLAGS += --coverage
USR_LDFLAGS += --coverage
endif
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local
# MSVC - skip defining min()/max() macros
USR_CPPFLAGS_WIN32 += -DNOMINMAX

View File

@@ -10,8 +10,6 @@ include $(TOP)/configure/CONFIG
# but continue the build even if conflicts are found.
CHECK_RELEASE = YES
CFG += CONFIG_NTYPES_VERSION
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))

View File

@@ -1,40 +1,32 @@
# RELEASE - Location of external support modules
#RELEASE Location of external products
#
# IF YOU CHANGE ANY PATHS in this file or make API changes to
# any modules it refers to, you should do a "make rebuild" in
# this application's top level directory.
# IF YOU MAKE ANY CHANGES to this file you MUST at least run
# "gnumake" in this directory afterwards; you usually need
# to run "gnumake rebuild" in the application's top level
# directory each time this file is changed.
#
# The EPICS build process does not check dependencies against
# any files from outside the application, so it is safest to
# rebuild it completely if any modules it depends on change.
# NOTE: The build does not check dependencies against files
# that are outside this application, thus you should run
# "gnumake distclean install" in the top directory each time
# EPICS_BASE, SNCSEQ, or any other external module defined
# in the RELEASE file is rebuilt.
#
# Host- or target-specific settings can be given in files named
# Host/target specific settings can be specified in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
#
# This file is parsed by both GNUmake and an EPICS Perl script,
# so it may ONLY contain definititions of paths to other support
# modules, variable definitions that are used in module paths,
# and include statements that pull in other RELEASE files.
# Variables may be used before their values have been set.
# Build variables that are NOT used in paths should be set in
# the CONFIG_SITE file.
# Variables and paths to dependent modules:
#MODULES = /path/to/modules
#MYMODULE = $(MODULES)/my-module
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
# If building the EPICS modules individually, set these:
#EPICS_PVDATA = $(MODULES)/pvData-7.0.0
#EPICS_LIBCOM = $(MODULES)/libcom-3.17.0
#EPICS_BASE = $(MODULES)/core-7.0.1
#If using the sequencer, point SNCSEQ at its top directory:
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
# Set RULES here if you want to use build rules from elsewhere:
#RULES = $(MODULES)/build-rules
# EPICS_BASE usually appears last so other apps can override stuff:
#EPICS_BASE=/opt/epics/base
#Capfast users may need the following definitions
#CAPFAST_TEMPLATES=
#SCH2EDIF_PATH=
# These allow developers to override the RELEASE variable settings
# without having to modify the configure/RELEASE file itself.
-include $(TOP)/../RELEASE.local
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
-include $(TOP)/configure/RELEASE.local

View File

@@ -0,0 +1,81 @@
<h1>Release 5.0</h1>
<p>This release adds support through wrapper classes and builders for the
remaining Normative Types:</p>
<ul>
<li>NTEnum</li>
<li>NTMatrix</li>
<li>NTURI</li>
<li>NTAttribute</li>
<li>NTContinuum</li>
<li>NTHistogram</li>
<li>NTAggregate</li>
<li>NTUnion</li>
<li>NTScalarMultiChannel</li>
</ul>
<p>Release 5.0 therefore implements fully the
<a href="http://epics-pvdata.sourceforge.net/alpha/normativeTypes/normativeTypes_20150316.html">16 Mar 2015 version</a>
of the normativeTypes specification.</p>
<p>Each wrapper class has an extended API:</p>
<ul>
<li>is_a now has a convenience overload taking a PVStructure.</li>
<li>isCompatible, reporting introspection type compatibility, now has an overload
taking a Structure. The PVStructure version is retained as a convenience
method and for backwards compatibility.</li>
<li>An isValid function now reports validity of a compatible PVStructure's data
with respect to the specification.</li>
</ul>
<p>Other changes are:</p>
<ul>
<li>Support for NTAttributes extended as required by NTNDArray
(NTNDArrayAttributes).</li>
<li>A new class for parsing NT IDs (NTID).</li>
<li>Resolution of the confusion between column names and labels in NTTable and
improved API. Function for adding columns is now addColumn rather than add.
New getColumnNames function provided.</li>
<li>isConnected is treated as an optional rather than a required field in
NTMultiChannelArray. isConnected() and addIsConnected() functions added to
wrapper and builder respectively.</li>
<li>Unit tests for all new classes.</li>
</ul>
<h1>Release 4.0</h1>
<p>This is the first release of normativeTypesCPP that is part of an official
EPICS V4 release.
It is a major rewrite of the previous versions of normativeTypesCPP.</p>
<p>This release provides support through wrapper classes and builders for the
following Normative Types:</p>
<ul>
<li>NTScalar</li>
<li>NTScalarArray</li>
<li>NTNameValue</li>
<li>NTTable</li>
<li>NTMultiChannel</li>
<li>NTNDArray</li>
</ul>
<p>Each type has a wrapper class of the same name which has functions for checking
compatibility of existing PVStructures (isCompatible) and the reported types of
Structures (is_a), wraps existing PVStructures (wrap, wrapUnsafe) and provides
a convenient interface to all required and optional fields.</p>
<p>Each type has a builder which can create a Structure, a PVStructure or a
wrapper around a new PVStructure. In each case optional or extra fields can be
added and options such as choice of scalar type can be made.</p>
<p>Additional features are:</p>
<ul>
<li>Utility classes NTField and NTPVField for standard structure fields and
NTUtils for type IDs.</li>
<li>Unit tests for the implemented classes.</li>
</ul>

View File

@@ -1,135 +1,47 @@
# normativeTypes Module
This document summarizes the changes to the module between releases.
## Release 6.0.2 (EPICS 7.0.10, December 2025)
- Fix potential NULL pointer dereference in `NTNDArray::getValueSize()`
## Release 6.0.1 (EPICS 7.0.3.1, October 2019)
- Doxygen updates and read-the-docs integration.
## Release 6.0.0 (EPICS 7.0.3, July 2019)
- Reimplement `isCompatible()` methods to use a new internal validation API in
order to make the implementation uniform, less repetitive and less strict.
The new implementation is less strict in the sense that it considers types that
can be converted into one another compatible with each other.
For example, any `Scalar` is considered compatible with any other `Scalar`,
regardless of the underlying type.
Normative Types users are advised to use `getAs()` and `putFrom()` when
getting/putting data from/into `PVScalar`s and `PVScalarArray`s.
Also, `isCompatible()` methods now disregard field order and extra fields that
are not part of the specification.
This change is not expected to break any current server or client, but it will
break existing clients that rely on the previous `isCompatible()` strictness
once servers start to take advantage of `isCompatible()` now being less strict.
## Release 5.2.2
- Fix `NTTable::getColumnNames()`.
## Release 5.2.1 (EPICS 7.0.2, Dec 2018)
- No functional changes.
- Removal of declaration for unimplemented `PVNTField::createAlarmLimit()` and
elimination of unused variables.
## Release 5.2.0 (EPICS 7.0.1, Dec 2017)
This release contains bug fixes and minor source updates needed to
build against the latest version of pvData.
## Release 5.1.2 (EPICS V4.6, Aug 2016)
The main changes since release 5.1.1 are:
- NTUnionBuilder: Add missing `value()` function
- Updated document: Now document all Normative Types
## Release 5.1.1
The main changes since release 5.0 are:
- Linux shared library version added
- Headers and source locations have changed
- Missing `is_a()` implementations added
- `NTAttribute::addTags()` is now non-virtual
- New license file replaces LICENSE and COPYRIGHT
### Shared library version added
Linux shared library version numbers have been added by setting `SHRLIB_VERSION`
(to 5.1 in this case).
The shared object will be `libnt.so.5.1` instead of `libnt.so`.
### Headers and source locations have changed
Source has moved out of nt directory directly into src.
Headers have been moved into a pv directory.
This facilitates using some IDEs such as Qt Creator.
- `src/nt/ntscalar.cpp -> src/ntscalar.cpp`
- `src/nt/ntscalar.h -> src/pv/ntscalar.h`
### Missing `is_a()` implementations added
`is_a(PVStructurePtr const &)` implementation has been added for each type.
## Release 5.0 (EPICS V4.5, Oct 2015)
Release 5.0
===========
This release adds support through wrapper classes and builders for the
remaining Normative Types:
- NTEnum
- NTMatrix
- NTURI
- NTAttribute
- NTContinuum
- NTHistogram
- NTAggregate
- NTUnion
- NTScalarMultiChannel
* NTEnum
* NTMatrix
* NTURI
* NTAttribute
* NTContinuum
* NTHistogram
* NTAggregate
* NTUnion
* NTScalarMultiChannel
Release 5.0 therefore fully implements the 16 Mar 2015 version of the
normativeTypes specification.
Release 5.0 therefore implements fully the
[16 Mar 2015 version](http://epics-pvdata.sourceforge.net/alpha/normativeTypes/normativeTypes_20150316.html)
of the normativeTypes specification.
Each wrapper class has an extended API:
- `is_a()` now has a convenience overload taking a PVStructure.
- `isCompatible()`, reporting introspection type compatibility, now has an
overload taking a Structure.
The PVStructure version is retained as a convenience method and for backwards
compatibility.
- An `isValid()` function now reports validity of a compatible PVStructure's
data with respect to the specification.
* is_a now has a convenience overload taking a PVStructure.
* isCompatible, reporting introspection type compatibility, now has an overload
taking a Structure. The PVStructure version is retained as a convenience
method and for backwards compatibility.
* An isValid function now reports validity of a compatible PVStructure's data
with respect to the specification.
Other changes are:
- Support for NTAttributes extended as required by NTNDArray
* Support for NTAttributes extended as required by NTNDArray
(NTNDArrayAttributes).
- A new class for parsing NT IDs (NTID).
- Resolution of the confusion between column names and labels in NTTable and
improved API.
Function for adding columns is now `addColumn()` rather than `add()`.
A new `getColumnNames()` function provided.
- `isConnected()` is treated as an optional rather than a required field in
NTMultiChannelArray.
`isConnected()` and `addIsConnected()` functions added to wrapper and builder
respectively.
* A new class for parsing NT IDs (NTID).
* Resolution of the confusion between column names and labels in NTTable and
improved API. Function for adding columns is now addColumn rather than add.
New getColumnNames function provided.
* isConnected is treated as an optional rather than a required field in
NTMultiChannelArray. isConnected() and addIsConnected() functions added to
wrapper and builder respectively.
* Unit tests for all new classes.
- Unit tests for all new classes.
## Release 4.0 (EPICS V4.4, Dec 2014)
Release 4.0
===========
This is the first release of normativeTypesCPP that is part of an official
EPICS V4 release.
@@ -138,27 +50,26 @@ It is a major rewrite of the previous versions of normativeTypesCPP.
This release provides support through wrapper classes and builders for the
following Normative Types:
- NTScalar
- NTScalarArray
- NTNameValue
- NTTable
- NTMultiChannel
- NTNDArray
* NTScalar
* NTScalarArray
* NTNameValue
* NTTable
* NTMultiChannel
* NTNDArray
Each type has a wrapper class of the same name which has functions for checking
compatibility of existing PVStructures (`isCompatible()`) and the reported types
of Structures (`is_a()`),
wraps existing PVStructures (`wrap()`, `wrapUnsafe()`) and provides a convenient
interface to all required and optional fields.
compatibility of existing PVStructures (isCompatible) and the reported types of
Structures (is_a), wraps existing PVStructures (wrap, wrapUnsafe) and provides
a convenient interface to all required and optional fields.
Each type has a builder which can create a Structure, a PVStructure or a
wrapper around a new PVStructure.
In each case optional or extra fields can be added and options such as choice of
scalar type can be made.
wrapper around a new PVStructure. In each case optional or extra fields can be
added and options such as choice of scalar type can be made.
Additional features are:
- Utility classes NTField and NTPVField for standard structure fields and
* Utility classes NTField and NTPVField for standard structure fields and
NTUtils for type IDs.
- Unit tests for the implemented classes.
* Unit tests for the implemented classes.

View File

@@ -1,7 +0,0 @@
.wy-side-nav-search {
background-color: #18334B;
}
.wy-side-nav-search input[type="text"] {
border-color: #18334b;
}

View File

@@ -1,77 +0,0 @@
# 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']
# -- Run Doxygen ------------------------------------------------------------
import subprocess
subprocess.call('cd ..; mkdir -p html/doxygen; doxygen', shell=True)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -1,17 +0,0 @@
NormativeTypes (C++) Library
============================
.. toctree::
:hidden:
EPICS Website <https://epics-controls.org>
EPICS Documentation Home <https://docs.epics-controls.org>
.. toctree::
:maxdepth: 1
:caption: normativeTypesCPP
Reference Manual <ntCPP>
API Documentation <https://docs.epics-controls.org/projects/normativetypes-cpp/en/latest/doxygen>
Source Code Repository on GitHub <https://github.com/epics-base/normativeTypesCPP>

1516
documentation/ntCPP.html Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,289 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>EPICS pvDataCPP</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<div class="head">
<h1>EPICS pvDataCPP</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 23-July-2014</h2>
<dl>
<dt>Latest version:</dt>
<dd><a
href="ntCPP.html">ntCPP.html</a>
</dd>
<dt>This version:</dt>
<dd><a
href="ntCPP_20140723.html">ntCPP_20140723.html</a>
</dd>
<dt>Previous version:</dt>
<dd>None</dd>
<dt>Editors:</dt>
<dd>Marty Kraimer, BNL</dd>
<dd>Michael Davidsaver, BNL</dd>
<dd>Matej Sekoranja, CosyLab</dd>
</dl>
<p class="copyright">This product is made available subject to acceptance of the <a
href="http://epics-pvdata.sourceforge.net/LICENSE.html">EPICS open source
license.</a></p>
<hr />
</div>
<h2 class="nocount">Abstract</h2>
<p>EPICS Version 4 provides efficient
storage, access, and communication, of memory resident structured data.
pvData is the storage compoment.
pvDataCPP is the C++ implementation of pvData.
It is one part of the set of related products in the EPICS
V4 control system programming environment:<br />
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
</p>
<h2 class="nocount">Status of this Document</h2>
<p>For now this is a working copy so it is not the same as "This version" shown above.</p>
<p>This is the 23-July-2014 version of the C++ implementation of pvData.
</p>
<p>RELEASE_NOTES.md provides changes since the last release.
TODO.md describes things to do before the next release.
</p>
<div id="toc">
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
</div>
<div id="contents" class="contents">
<body>
<h1 style="text-align: center">EPICS normative type C++ implementation
</h1>
<h2 class="nocount" id="L50">Draft, 4-Nov-2012</h2>
<dl>
<dt>This version:</dt>
<dd><a href="http://epics-pvdata.hg.sourceforge.net/hgweb/epics-pvdata/normativeTypesCPP/raw-file/tip/documentation/ntCPP.html">ntCPP.html</a></dd>
<dt>Editors:</dt>
<dd>Matej Sekoranja, CosyLab<br>
Marty Kraimer, BNL
</dd>
</dl>
<hr />
</div>
<h2>Introduction</h2>
<p>This section describes the C++ implemmentation of normative types. Two (2) helper classes are implemented,
ntNameValue and NTTable respectively. </p>
<h3>Normative Type Fields.</h3>
<p>These are helper classes for creating standard fields for normative types.
There is a single instance of this class, which is obtained via NTField::get().
</p>
<pre>class NTField: NoDefaultMethods {
public:
static NTFieldPtr get();
~NTField() {}
PVStructurePtr createEnumerated(StringArray const &amp; choices);
PVStructurePtr createTimeStamp();
PVStructurePtr createAlarm();
PVStructurePtr createDisplay();
PVStructurePtr createAlarmLimit();
PVStructurePtr createControl();
PVStructureArrayPtr createEnumeratedArray();
PVStructureArrayPtr createTimeStampArray();
PVStructureArrayPtr createAlarmArray();
};</pre>
<p>where</p>
<dl>
<dt>createEnumerated</dt>
<dd>Create an introspection interface for an enumerated structure.</dd>
<dt>createTimeStamp</dt>
<dd>Create an interspection interface for a timeStamp structure.</dd>
<dt>createAlarm</dt>
<dd>Create an interspection interface for an alarm structure.</dd>
<dt>createDisplay</dt>
<dd>Create an introsepecion interface for a display structure.</dd>
<dt>createAlarmLimit</dt>
<dd>Create an introspection interface for an alarm limit structure.</dd>
<dt>createControl</dt>
<dd>Create an introspection interface for a control structure.</dd>
<dt>createEnumeratedArray</dt>
<dd>Create an introspection interface for an structureArray of enumerated
structures.</dd>
<dt>createTimeStampArray</dt>
<dd>Create an introspection interface for an structureArray of timeStamp
structures.</dd>
<dt>createAlarmArray</dt>
<dd>Create an introspection interface for an structureArray of alarm
structures.</dd>
</dl>
<h3>NTNameValue</h3>
<p>These are helper classes for NTNameValue</p>
<pre>class NTNameValue : private NoDefaultMethods
{
public:
static bool isNTNameValue(PVStructurePtr const & pvStructure);
static NTNameValuePtr create(
bool hasFunction,bool hasTimeStamp, bool hasAlarm);
static NTNameValuePtr create(
PVStructurePtr const & pvStructure);
~NTNameValue();
PVStringPtr getFunction();
void attachTimeStamp(PVTimeStamp &amp;pvTimeStamp);
void attachAlarm(PVAlarm &amp;pvAlarm);
PVStructurePtr getPVStructure();
PVStructurePtr getTimeStamp();
PVStructurePtr getAlarm();
PVStringArrayPtr getNames();
PVStringArrayPtr getValues();
};</pre>
<p>where</p>
<dl>
<dt>isNTNameValue</dt>
<dd>Is the structure a NTNameValue structure?</dd>
<dt>create</dt>
<dd>Create an NTNameValue that has the associated fields.</dd>
<dt>~NTNameValue</dt>
<dd>The destructor.</dd>
<dt>getFunction</dt>
<dd>Get the function field. This can be null.</dd>
<dt>attachTimeStamp</dt>
<dd>The timeStamp field of the NTNameValue is atttached to the
pvTimeStamp.</dd>
<dt>attachAlarm</dt>
<dd>The alarm field of the NTNameValue is atttached to the alarm.</dd>
<dt>getPVStructure</dt>
<dd>Get the pvStructure that this NTNameValue contains.</dd>
<dt>getTimeStamp</dt>
<dd>Get the timeStamp field.</dd>
<dt>getAlarm</dt>
<dd>Get the alarm field.</dd>
<dt>getNames</dt>
<dd>Get the names field.</dd>
<dt>getValues</dt>
<dd>Get the values field.</dd>
</dl>
<h3>NTTable</h3>
<p>These are helper classes for NTTable</p>
<pre>class NTTable: private NoDefaultMethods
{
public:
static bool isNTTable(PVStructurePtr const & pvStructure);
static PVStructure::shared_pointer create(
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
int numberValues,
FieldConstPtrArray valueFields);
static NTTablePtr create(
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
StringArray const & valueNames,
FieldConstPtrArray const &valueFields);
static NTTablePtr clone(PVStructurePtr const &);
~NTTable();
PVStringPtr getFunction();
void attachTimeStamp(PVTimeStamp &amp;pvTimeStamp);
void attachAlarm(PVAlarm &amp;pvAlarm);
PVStructurePtr getPVStructure();
PVStructurePtr getTimeStamp();
PVStructurePtr getAlarm();
PVStringArrayPtr getLabel();
size_t getNumberValues();
FieldConstPtr getField(int index);
PVFieldPtr getPVField(int index);
};</pre>
<p>where</p>
<dl>
<dt>isNTTable</dt>
<dd>y</dd>
<dt>create</dt>
<dd>Create an NTTable that has the associated fields.</dd>
<dt>~NTTable</dt>
<dd>The destructor.</dd>
<dt>getFunction</dt>
<dd>Get the function field. This can be null.</dd>
<dt>attachTimeStamp</dt>
<dd>The timeStamp field of the NTTable is atttached to the pvTimeStamp.</dd>
<dt>attachAlarm</dt>
<dd>The alarm field of the NTTable is atttached to the alarm.</dd>
<dt>getPVStructure</dt>
<dd>Get the pvStructure that this NTTable contains.</dd>
<dt>getTimeStamp</dt>
<dd>Get the timeStamp field.</dd>
<dt>getAlarm</dt>
<dd>Get the alarm field.</dd>
<dt>getLabel</dt>
<dd>Get the label field.</dd>
<dt>getNumberValues</dt>
<dd>Get the number of value fields.</dd>
<dt>getField</dt>
<dd>Get the introspection interface for the specified field.</dd>
<dt>getPVField</dt>
<dd>Get the data field for the specified field.</dd>
</dl>
<h2>MTMultiChannel</h2>
<pre>
structure NTMultiChannel
union_t[] value
string[] channelName
time_t timeStamp :opt // time when data collected
alarm_t alarm :opt // alarm associated with data collection
int[] severity :opt // alarm severity for each value
int[] status :opt // alarm status for each value
string[] message :opt // alarm message for each value
long[] secondsPastEpoch :opt // seconds for each value.
int[] nanoseconds :opt // nanoseconds for each value
string descriptor :opt // descriptor data
</pre>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,35 +6,20 @@
#
# Author: Ralph Lange <ralph.lange@gmx.de>
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
# Copyright (C) 2014-2016 ITER Organization.
# Copyright (C) 2014-2015 ITER Organization.
# All rights reserved. Use is subject to license terms.
installTool () {
local module=$1
local version=$2
wget -nv https://openepics.ci.cloudbees.com/job/${module}-${version}_Build/lastSuccessfulBuild/artifact/${module,,}-${version}.CB-dist.tar.gz
tar -xzf ${module,,}-${version}.CB-dist.tar.gz
}
installE4 () {
local module=$1
local branch=$2
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
tar -xzf ${module}.CB-dist.tar.gz
}
###########################################
# Defaults for EPICS Base
# Determine EPICS Base version
DEFAULT_BASE=3.15.4
BASE=${BASE:-${DEFAULT_BASE}}
DEFAULT_BASE=3.14.12.5
###########################################
# Dependent module branches
BASE=${1:-${DEFAULT_BASE}}
USE_MB=${2:-"MB_NO"}
PVDATA_BRANCH="master"
# Dependent module branches (empty = master)
PVCOMMON_BRANCH="Release-4.1-"
PVDATA_BRANCH="Release-5.0-"
###########################################
# Fetch and unpack dependencies
@@ -45,10 +30,15 @@ rm -fr ${STUFF}
mkdir -p ${STUFF}
cd ${STUFF}
installTool Boost 1.61.0
installTool Base ${BASE}
wget -nv https://openepics.ci.cloudbees.com/job/Base-${BASE}_Build/lastSuccessfulBuild/artifact/base-${BASE}.CB-dist.tar.gz
wget -nv https://openepics.ci.cloudbees.com/job/pvDataCPP_${PVDATA_BRANCH}Build/BASE=${BASE},USE_MB=MB_NO/lastSuccessfulBuild/artifact/pvData.CB-dist.tar.gz
tar -xzf base-${BASE}.CB-dist.tar.gz
tar -xzf pvData.CB-dist.tar.gz
installE4 pvData ${PVDATA_BRANCH}
if [ "${USE_MB}" = "MB_YES" ]; then
wget -nv https://openepics.ci.cloudbees.com/job/pvCommonCPP_${PVCOMMON_BRANCH}Build/BASE=${BASE},USE_MB=MB_YES/lastSuccessfulBuild/artifact/pvCommon.CB-dist.tar.gz
tar -xzf pvCommon.CB-dist.tar.gz
fi
###########################################
# Build
@@ -72,6 +62,6 @@ make distclean all
make runtests
###########################################
# Create cache
# Create distribution
tar --exclude=test* -czf normativeTypes.CB-dist.tar.gz lib include

View File

@@ -6,31 +6,14 @@
#
# Author: Ralph Lange <ralph.lange@gmx.de>
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
# Copyright (C) 2014-2016 ITER Organization.
# Copyright (C) 2014-2015 ITER Organization.
# All rights reserved. Use is subject to license terms.
installTool () {
local module=$1
local version=$2
wget -nv https://openepics.ci.cloudbees.com/job/${module}-${version}_Build/lastSuccessfulBuild/artifact/${module,,}-${version}.CB-dist.tar.gz
tar -xzf ${module,,}-${version}.CB-dist.tar.gz
}
installE4 () {
local module=$1
local branch=$2
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
tar -xzf ${module}.CB-dist.tar.gz
}
###########################################
# Defaults for EPICS Base and parameters
# Set EPICS Base version and upload target
BASE=3.15.4
PUBLISH=${PUBLISH:-NO}
BRANCH=${BRANCH:-master}
BASE=3.15.2
PUBLISH=${1:-DONT}
###########################################
# Fetch and unpack dependencies
@@ -41,14 +24,16 @@ rm -fr ${STUFF}
mkdir -p ${STUFF}
cd ${STUFF}
installTool Doxygen 1.8.11
wget -nv https://openepics.ci.cloudbees.com/job/Doxygen-1.8.3_Build/lastSuccessfulBuild/artifact/doxygen-1.8.3.CB-dist.tar.gz
tar -xzf doxygen-1.8.3.CB-dist.tar.gz
###########################################
# Generate
cd ${WORKSPACE}
installE4 normativeTypes ${BRANCH}
wget -nv https://openepics.ci.cloudbees.com/job/normativeTypesCPP_Build/BASE=${BASE},USE_MB=MB_NO/lastSuccessfulBuild/artifact/normativeTypes.CB-dist.tar.gz
tar -xzf normativeTypes.CB-dist.tar.gz
export PATH=${STUFF}/bin:${PATH}

View File

@@ -1,26 +1,30 @@
TOP = ..
include $(TOP)/configure/CONFIG
INC += pv/nt.h
INC += pv/ntutils.h
INC += pv/ntid.h
INC += pv/ntfield.h
INC += pv/ntscalar.h
INC += pv/ntscalarArray.h
INC += pv/ntnameValue.h
INC += pv/nttable.h
INC += pv/ntmultiChannel.h
INC += pv/ntscalarMultiChannel.h
INC += pv/ntndarray.h
INC += pv/ntmatrix.h
INC += pv/ntenum.h
INC += pv/ntunion.h
INC += pv/ntaggregate.h
INC += pv/ntattribute.h
INC += pv/ntcontinuum.h
INC += pv/nthistogram.h
INC += pv/nturi.h
INC += pv/ntndarrayAttribute.h
SRC = $(TOP)/src
SRC_DIRS += $(SRC)/nt
INC += nt.h
INC += ntutils.h
INC += ntid.h
INC += ntfield.h
INC += ntscalar.h
INC += ntscalarArray.h
INC += ntnameValue.h
INC += nttable.h
INC += ntmultiChannel.h
INC += ntscalarMultiChannel.h
INC += ntndarray.h
INC += ntmatrix.h
INC += ntenum.h
INC += ntunion.h
INC += ntaggregate.h
INC += ntattribute.h
INC += ntcontinuum.h
INC += nthistogram.h
INC += nturi.h
INC += ntndarrayAttribute.h
LIBSRCS += ntutils.cpp
LIBSRCS += ntid.cpp
@@ -46,8 +50,5 @@ LIBRARY = nt
nt_LIBS += pvData Com
# shared library ABI version.
SHRLIB_VERSION ?= $(EPICS_NTYPES_MAJOR_VERSION).$(EPICS_NTYPES_MINOR_VERSION).$(EPICS_NTYPES_MAINTENANCE_VERSION)
include $(TOP)/configure/RULES

View File

@@ -1,7 +1,8 @@
/* nt.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NT_H
#define NT_H
@@ -31,7 +32,7 @@
/** @page Overview Documentation
*
* <a href = "../ntCPP.html">Normative Types (C++) Reference</a>
* <a href = "ntCPP.html">ntCPP.html</a>
*
*/

View File

@@ -1,11 +1,10 @@
/* ntaggregate.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntaggregate.h>
#include <pv/ntutils.h>
@@ -188,34 +187,85 @@ bool NTAggregate::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTAggregate::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTAggregate::isCompatible(StructureConstPtr const &structure)
{
if (!structure)
if (structure.get() == 0) return false;
ScalarConstPtr valueField = structure->getField<Scalar>("value");
if (valueField.get() == 0 || valueField->getScalarType() != pvDouble)
return false;
Result result(structure);
ScalarConstPtr nField = structure->getField<Scalar>("N");
if (nField.get() == 0 || nField->getScalarType() != pvLong)
return false;
return result
.is<Structure>()
.has<Scalar>("value")
.has<Scalar>("N")
.maybeHas<Scalar>("dispersion")
.maybeHas<Scalar>("first")
.maybeHas<&NTField::isTimeStamp, Structure>("firstTimeStamp")
.maybeHas<Scalar>("last")
.maybeHas<&NTField::isTimeStamp, Structure>("lastTimeStamp")
.maybeHas<Scalar>("max")
.maybeHas<Scalar>("min")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
FieldConstPtr field = structure->getField("dispersion");
if (field.get())
{
ScalarConstPtr dispersionField = structure->getField<Scalar>("dispersion");
if (!dispersionField.get() || dispersionField->getScalarType() != pvDouble)
return false;
}
field = structure->getField("first");
if (field.get())
{
ScalarConstPtr firstField = structure->getField<Scalar>("first");
if (!firstField.get() || firstField->getScalarType() != pvDouble)
return false;
}
field = structure->getField("firstTimeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
field = structure->getField("last");
if (field.get())
{
ScalarConstPtr lastField = structure->getField<Scalar>("last");
if (!lastField.get() || lastField->getScalarType() != pvDouble)
return false;
}
field = structure->getField("lastTimeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
field = structure->getField("max");
if (field.get())
{
ScalarConstPtr maxField = structure->getField<Scalar>("max");
if (!maxField.get() || maxField->getScalarType() != pvDouble)
return false;
}
field = structure->getField("min");
if (field.get())
{
ScalarConstPtr minField = structure->getField<Scalar>("min");
if (!minField.get() || minField->getScalarType() != pvDouble)
return false;
}
field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTAggregate::isCompatible(PVStructurePtr const & pvStructure)

View File

@@ -1,7 +1,8 @@
/* ntaggregate.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTAGGREGATE_H
#define NTAGGREGATE_H

View File

@@ -1,11 +1,10 @@
/* ntattribute.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntattribute.h>
#include <pv/ntutils.h>
@@ -125,29 +124,48 @@ bool NTAttribute::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTAttribute::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTAttribute::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (structure.get() == 0) return false;
ScalarConstPtr nameField = structure->getField<Scalar>("name");
if (nameField.get() == 0 || nameField->getScalarType() != pvString)
return false;
Result result(structure);
UnionConstPtr valueField = structure->getField<Union>("value");
if (valueField.get() == 0 || !valueField->isVariant())
return false;
return result
.is<Structure>()
.has<Scalar>("name")
.has<Union>("value")
.maybeHas<ScalarArray>("tags")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
FieldConstPtr field = structure->getField("tags");
if (field.get())
{
ScalarArrayConstPtr tagsField = structure->getField<ScalarArray>("tags");
if (tagsField.get() == 0 || tagsField->getElementType() != pvString)
return false;
}
field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTAttribute::isCompatible(PVStructurePtr const & pvStructure)
{
if(!pvStructure) return false;

View File

@@ -1,7 +1,8 @@
/* ntattribute.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTATTRIBUTE_H
#define NTATTRIBUTE_H
@@ -44,7 +45,7 @@ namespace detail {
* Adds tags field to the NTAttribute.
* @return this instance of <b>NTAttributeBuilder</b>.
*/
shared_pointer addTags();
virtual shared_pointer addTags();
/**
* Adds descriptor field to the NTAttribute.

View File

@@ -1,11 +1,10 @@
/* ntcontinuum.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntcontinuum.h>
#include <pv/ntutils.h>
@@ -117,29 +116,44 @@ bool NTContinuum::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTContinuum::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTContinuum::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (structure.get() == 0) return false;
ScalarArrayConstPtr baseField = structure->getField<ScalarArray>("base");
if (baseField.get() == 0 || baseField->getElementType() != pvDouble)
return false;
Result result(structure);
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
if (valueField.get() == 0 || valueField->getElementType() != pvDouble)
return false;
return result
.is<Structure>()
.has<ScalarArray>("base")
.has<ScalarArray>("value")
.has<ScalarArray>("units")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
ScalarArrayConstPtr unitsField = structure->getField<ScalarArray>("units");
if (unitsField.get() == 0 || unitsField->getElementType() != pvString)
return false;
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTContinuum::isCompatible(PVStructurePtr const & pvStructure)
{
if(!pvStructure) return false;

View File

@@ -1,7 +1,8 @@
/* ntcontinuum.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTCONTINUUM_H
#define NTCONTINUUM_H
@@ -93,6 +94,7 @@ namespace detail {
void reset();
bool dim;
bool descriptor;
bool alarm;
bool timeStamp;

View File

@@ -1,11 +1,10 @@
/* ntenum.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntenum.h>
#include <pv/ntutils.h>
@@ -116,27 +115,36 @@ bool NTEnum::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTEnum::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTEnum::isCompatible(StructureConstPtr const &structure)
{
if (!structure)
if (structure.get() == 0) return false;
NTFieldPtr ntField = NTField::get();
FieldConstPtr valueField = structure->getField("value");
if (!valueField.get() || !ntField->isEnumerated(valueField))
return false;
Result result(structure);
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
return result
.is<Structure>()
.has<&NTField::isEnumerated, Structure>("value")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTEnum::isCompatible(PVStructurePtr const & pvStructure)
{
if(!pvStructure) return false;

View File

@@ -1,7 +1,8 @@
/* ntenum.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTENUM_H
#define NTENUM_H

343
src/nt/ntfield.cpp Normal file
View File

@@ -0,0 +1,343 @@
/* ntfield.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <pv/lock.h>
#define epicsExportSharedSymbols
#include <pv/ntfield.h>
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
namespace epics { namespace nt {
NTFieldPtr NTField::get()
{
static Mutex mutex;
static NTFieldPtr ntstructureField;
Lock xx(mutex);
if(ntstructureField.get()==NULL) {
ntstructureField = NTFieldPtr(new NTField());
}
return ntstructureField;
}
NTField::NTField()
: fieldCreate(getFieldCreate()),
standardField(getStandardField())
{
}
bool NTField::isEnumerated(FieldConstPtr const & field)
{
if(field->getType()!=structure) return false;
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
FieldConstPtrArray fields = structurePtr->getFields();
StringArray names = structurePtr->getFieldNames();
size_t n = structurePtr->getNumberFields();
if(n!=2) return false;
FieldConstPtr f = fields[0];
if(names[0].compare("index")!=0) return false;
if(f->getType()!=scalar) return false;
ScalarConstPtr s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[1];
if(names[1].compare("choices")!=0) return false;
if(f->getType()!=scalarArray) return false;
ScalarConstPtr sa = static_pointer_cast<const Scalar>(f);
if(sa->getScalarType()!=pvString) return false;
return true;
}
bool NTField::isTimeStamp(FieldConstPtr const & field)
{
if(field->getType()!=structure) return false;
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
FieldConstPtrArray fields = structurePtr->getFields();
StringArray names = structurePtr->getFieldNames();
size_t n = structurePtr->getNumberFields();
if(n!=3) return false;
FieldConstPtr f = fields[0];
if(names[0].compare("secondsPastEpoch")!=0) return false;
if(f->getType()!=scalar) return false;
ScalarConstPtr s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvLong) return false;
f = fields[1];
if(names[1].compare("nanoseconds")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[2];
if(names[2].compare("userTag")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
return true;
}
bool NTField::isAlarm(FieldConstPtr const & field)
{
if(field->getType()!=structure) return false;
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
FieldConstPtrArray fields = structurePtr->getFields();
StringArray names = structurePtr->getFieldNames();
size_t n = structurePtr->getNumberFields();
if(n!=3) return false;
FieldConstPtr f = fields[0];
if(names[0].compare("severity")!=0) return false;
if(f->getType()!=scalar) return false;
ScalarConstPtr s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[1];
if(names[1].compare("status")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[2];
if(names[2].compare("message")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvString) return false;
return true;
}
bool NTField::isDisplay(FieldConstPtr const & field)
{
if(field->getType()!=structure) return false;
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
FieldConstPtrArray fields = structurePtr->getFields();
StringArray names = structurePtr->getFieldNames();
size_t n = structurePtr->getNumberFields();
if(n!=5) return false;
FieldConstPtr f = fields[0];
if(names[0].compare("limitLow")!=0) return false;
if(f->getType()!=scalar) return false;
ScalarConstPtr s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[1];
if(names[1].compare("limitHigh")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[2];
if(names[2].compare("description")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvString) return false;
f = fields[3];
if(names[3].compare("format")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvString) return false;
f = fields[4];
if(names[4].compare("units")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvString) return false;
return true;
}
bool NTField::isAlarmLimit(FieldConstPtr const & field)
{
if(field->getType()!=structure) return false;
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
FieldConstPtrArray fields = structurePtr->getFields();
StringArray names = structurePtr->getFieldNames();
size_t n = structurePtr->getNumberFields();
if(n!=10) return false;
FieldConstPtr f = fields[0];
if(names[0].compare("active")!=0) return false;
if(f->getType()!=scalar) return false;
ScalarConstPtr s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvBoolean) return false;
f = fields[1];
if(names[1].compare("lowAlarmLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[2];
if(names[2].compare("lowWarningLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[3];
if(names[3].compare("highWarningLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[4];
if(names[4].compare("highAlarmLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[5];
if(names[5].compare("lowAlarmSeverity")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[6];
if(names[6].compare("lowWarningSeverity")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[7];
if(names[7].compare("highWarningSeverity")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[8];
if(names[8].compare("highAlarmSeverity")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvInt) return false;
f = fields[9];
if(names[9].compare("hysteresis")!=0) return false;
if(f->getType()!=scalar) return false;
return true;
}
bool NTField::isControl(FieldConstPtr const & field)
{
if(field->getType()!=structure) return false;
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
FieldConstPtrArray fields = structurePtr->getFields();
StringArray names = structurePtr->getFieldNames();
size_t n = structurePtr->getNumberFields();
if(n!=3) return false;
FieldConstPtr f = fields[0];
if(names[0].compare("limitLow")!=0) return false;
if(f->getType()!=scalar) return false;
ScalarConstPtr s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[1];
if(names[1].compare("limitHigh")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[2];
if(names[2].compare("minStep")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
return true;
}
StructureConstPtr NTField::createEnumerated()
{
return standardField->enumerated();
}
StructureConstPtr NTField::createTimeStamp()
{
return standardField->timeStamp();
}
StructureConstPtr NTField::createAlarm()
{
return standardField->alarm();
}
StructureConstPtr NTField::createDisplay()
{
return standardField->display();
}
StructureConstPtr NTField::createControl()
{
return standardField->control();
}
StructureArrayConstPtr NTField::createEnumeratedArray()
{
return fieldCreate->createStructureArray(createEnumerated());
}
StructureArrayConstPtr NTField::createTimeStampArray()
{
StructureConstPtr st = createTimeStamp();
return fieldCreate->createStructureArray(st);
}
StructureArrayConstPtr NTField::createAlarmArray()
{
StructureConstPtr st = createAlarm();
return fieldCreate->createStructureArray(st);
}
PVNTFieldPtr PVNTField::get()
{
static Mutex mutex;
static PVNTFieldPtr pvntstructureField;
Lock xx(mutex);
if(pvntstructureField.get()==NULL) {
pvntstructureField = PVNTFieldPtr(new PVNTField());
}
return pvntstructureField;
}
PVNTField::PVNTField()
: pvDataCreate(getPVDataCreate()),
standardField(getStandardField()),
standardPVField(getStandardPVField()),
ntstructureField(NTField::get())
{
}
PVStructurePtr PVNTField::createEnumerated(
StringArray const & choices)
{
return standardPVField->enumerated(choices);
}
PVStructurePtr PVNTField::createTimeStamp()
{
StructureConstPtr timeStamp = standardField->timeStamp();
return pvDataCreate->createPVStructure(timeStamp);
}
PVStructurePtr PVNTField::createAlarm()
{
StructureConstPtr alarm = standardField->alarm();
return pvDataCreate->createPVStructure(alarm);
}
PVStructurePtr PVNTField::createDisplay()
{
StructureConstPtr display = standardField->display();
return pvDataCreate->createPVStructure(display);
}
PVStructurePtr PVNTField::createControl()
{
StructureConstPtr control = standardField->control();
return pvDataCreate->createPVStructure(control);
}
PVStructureArrayPtr PVNTField::createEnumeratedArray()
{
StructureArrayConstPtr sa =
ntstructureField->createEnumeratedArray();
return pvDataCreate->createPVStructureArray(sa);
}
PVStructureArrayPtr PVNTField::createTimeStampArray()
{
StructureArrayConstPtr sa =
ntstructureField->createTimeStampArray();
return pvDataCreate->createPVStructureArray(sa);
}
PVStructureArrayPtr PVNTField::createAlarmArray()
{
StructureArrayConstPtr sa = ntstructureField->createAlarmArray();
return pvDataCreate->createPVStructureArray(sa);
}
}}

View File

@@ -1,7 +1,8 @@
/* ntfield.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTFIELD_H
#define NTFIELD_H
@@ -30,8 +31,6 @@
namespace epics { namespace nt {
struct Result;
class NTField;
typedef std::tr1::shared_ptr<NTField> NTFieldPtr;
@@ -151,30 +150,6 @@ private:
NTField();
epics::pvData::FieldCreatePtr fieldCreate;
epics::pvData::StandardFieldPtr standardField;
// These won't be public just yet
static Result& isEnumerated(Result&);
static Result& isTimeStamp(Result&);
static Result& isAlarm(Result&);
static Result& isDisplay(Result&);
static Result& isAlarmLimit(Result&);
static Result& isControl(Result&);
friend class NTAggregate;
friend class NTAttribute;
friend class NTContinuum;
friend class NTEnum;
friend class NTHistogram;
friend class NTMatrix;
friend class NTMultiChannel;
friend class NTNameValue;
friend class NTNDArray;
friend class NTNDArrayAttribute;
friend class NTScalar;
friend class NTScalarArray;
friend class NTScalarMultiChannel;
friend class NTTable;
friend class NTUnion;
};
/**
@@ -223,6 +198,12 @@ public:
*/
epics::pvData::PVStructurePtr createDisplay();
/**
* Creates an alarmLimit PVStructure.
* @return an alarmLimit PVStructure.
*/
epics::pvData::PVStructurePtr createAlarmLimit();
/**
* Creates a control PVStructure.
* @return a control PVStructure.

View File

@@ -1,11 +1,10 @@
/* ntcontinuum.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/nthistogram.h>
#include <pv/ntutils.h>
@@ -130,26 +129,39 @@ bool NTHistogram::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTHistogram::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTHistogram::isCompatible(StructureConstPtr const &structure)
{
if (!structure)
if(!structure.get()) return false;
ScalarArrayConstPtr rangesField = structure->getField<ScalarArray>("ranges");
if(!rangesField.get() || rangesField->getElementType() != pvDouble) return false;
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
if(!valueField.get()) return false;
ScalarType scalarType = valueField->getElementType();
if (scalarType != pvShort &&
scalarType != pvInt &&
scalarType != pvLong)
return false;
Result result(structure);
FieldConstPtr field = structure->getField("descriptor");
if(field)
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
return result
.is<Structure>()
.has<ScalarArray>("ranges")
.has<ScalarArray>("value")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTHistogram::isCompatible(PVStructurePtr const & pvStructure)

View File

@@ -1,7 +1,8 @@
/* nthistogram.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTHISTOGRAM_H
#define NTHISTOGRAM_H
@@ -103,6 +104,7 @@ namespace detail {
bool valueTypeSet;
epics::pvData::ScalarType valueType;
bool dim;
bool descriptor;
bool alarm;
bool timeStamp;

View File

@@ -1,17 +1,17 @@
/* ntid.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <pv/ntid.h>
#include <pv/typeCast.h>
namespace epics {
namespace epics {
namespace nt {
const static std::string BAD_NAME = "?";
const static std::string BAD_NAME = "?";
NTID::NTID(const std::string & id)
: fullName(id),
@@ -81,7 +81,7 @@ namespace nt {
else
{
name = fullName;
}
}
}
return name;
}
@@ -105,7 +105,7 @@ namespace nt {
{
endMajorIndex = fullName.find('.', versionSepIndex+1);
majorVersionStr = (endMajorIndex != std::string::npos)
? fullName.substr(versionSepIndex+1, endMajorIndex-(versionSepIndex+1)) :
? fullName.substr(versionSepIndex+1, endMajorIndex-(versionSepIndex+1)) :
fullName.substr(versionSepIndex+1);
}
else
@@ -150,7 +150,7 @@ namespace nt {
{
endMinorIndex = fullName.find('.', endMajorIndex+1);
minorVersionStr = (endMinorIndex != std::string::npos)
? fullName.substr(endMajorIndex+1, endMinorIndex-(endMajorIndex+1)) :
? fullName.substr(endMajorIndex+1, endMinorIndex-(endMajorIndex+1)) :
fullName.substr(endMajorIndex+1);
}
else
@@ -186,3 +186,5 @@ namespace nt {
}}

View File

@@ -1,7 +1,7 @@
/* ntid.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTID_H
#define NTID_H

View File

@@ -1,11 +1,10 @@
/* ntmatrix.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntmatrix.h>
#include <pv/ntutils.h>
@@ -134,27 +133,45 @@ bool NTMatrix::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTMatrix::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTMatrix::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (structure.get() == 0) return false;
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
if (valueField.get() == 0 || valueField->getElementType() != pvDouble)
return false;
Result result(structure);
FieldConstPtr field = structure->getField("dim");
if (field.get())
{
ScalarArrayConstPtr dimField = structure->getField<ScalarArray>("dim");
if (dimField.get() == 0 || dimField->getElementType() != pvInt)
return false;
}
return result
.is<Structure>()
.has<ScalarArray>("value")
.maybeHas<ScalarArray>("dim")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.maybeHas<&NTField::isDisplay, Structure>("display")
.valid();
field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
field = structure->getField("display");
if (field.get() && !ntField->isDisplay(field))
return false;
return true;
}
bool NTMatrix::isCompatible(PVStructurePtr const & pvStructure)

View File

@@ -1,7 +1,8 @@
/* ntmatrix.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTMATRIX_H
#define NTMATRIX_H

View File

@@ -1,13 +1,12 @@
/* ntmultiChannel.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <algorithm>
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntmultiChannel.h>
#include <pv/ntutils.h>
@@ -15,7 +14,7 @@
using namespace std;
using namespace epics::pvData;
namespace epics { namespace nt {
namespace epics { namespace nt {
static FieldCreatePtr fieldCreate = getFieldCreate();
@@ -227,34 +226,89 @@ bool NTMultiChannel::is_a(StructureConstPtr const &structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTMultiChannel::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTMultiChannel::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (!structure.get()) return false;
UnionArrayConstPtr valueField = structure->getField<UnionArray>("value");
if (!valueField.get()) return false;
ScalarArrayConstPtr channelNameField = structure->getField<ScalarArray>(
"channelName");
if (!channelNameField.get()) return false;
if (channelNameField->getElementType() != pvString) return false;
FieldConstPtr field = structure->getField("severity");
if (field.get())
{
ScalarArrayConstPtr severityField = structure->getField<ScalarArray>("severity");
if (!severityField.get() || severityField->getElementType() != pvInt)
return false;
}
field = structure->getField("status");
if (field.get())
{
ScalarArrayConstPtr statusField = structure->getField<ScalarArray>("status");
if (!statusField.get() || statusField->getElementType() != pvInt)
return false;
}
field = structure->getField("message");
if (field.get())
{
ScalarArrayConstPtr messageField = structure->getField<ScalarArray>("message");
if (!messageField.get() || messageField->getElementType() != pvString)
return false;
}
field = structure->getField("secondsPastEpoch");
if (field.get())
{
ScalarArrayConstPtr secondsPastEpochField = structure->getField<ScalarArray>("secondsPastEpoch");
if (!secondsPastEpochField.get() || secondsPastEpochField->getElementType() != pvLong)
return false;
}
field = structure->getField("nanoseconds");
if (field.get())
{
ScalarArrayConstPtr nanosecondsField = structure->getField<ScalarArray>("nanoseconds");
if (!nanosecondsField.get() || nanosecondsField->getElementType() != pvInt)
return false;
}
field = structure->getField("userTag");
if (field.get())
{
ScalarArrayConstPtr userTagField = structure->getField<ScalarArray>("userTag");
if (!userTagField.get() || userTagField->getElementType() != pvInt)
return false;
}
field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
Result result(structure);
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return result
.is<Structure>()
.has<UnionArray>("value")
.has<ScalarArray>("channelName")
.maybeHas<ScalarArray>("severity")
.maybeHas<ScalarArray>("status")
.maybeHas<ScalarArray>("message")
.maybeHas<ScalarArray>("secondsPastEpoch")
.maybeHas<ScalarArray>("nanoseconds")
.maybeHas<ScalarArray>("userTag")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
return true;
}
bool NTMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
{
if(!pvStructure.get()) return false;
@@ -269,7 +323,7 @@ bool NTMultiChannel::isValid()
if (getChannelName()->getLength() != valueLength) return false;
PVScalarArrayPtr arrayFields[] = {
getSeverity(), getStatus(), getMessage(),
getSeverity(), getStatus(), getMessage(),
getSecondsPastEpoch(), getNanoseconds(), getUserTag()
};
size_t N = sizeof(arrayFields)/sizeof(arrayFields[0]);
@@ -281,7 +335,7 @@ bool NTMultiChannel::isValid()
if (arrayField.get() && arrayField->getLength() != valueLength)
return false;
}
return true;
return true;
}

View File

@@ -1,7 +1,8 @@
/* ntmultiChannel.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTMULTICHANNEL_H
#define NTMULTICHANNEL_H

View File

@@ -1,11 +1,10 @@
/* ntnameValue.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntnameValue.h>
#include <pv/ntutils.h>
@@ -129,26 +128,37 @@ bool NTNameValue::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTNameValue::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTNameValue::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (structure.get() == 0) return false;
ScalarArrayConstPtr nameField = structure->getField<ScalarArray>("name");
if (nameField.get() == 0 || nameField->getElementType() != pvString)
return false;
Result result(structure);
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
if (valueField.get() == 0)
return false;
return result
.is<Structure>()
.has<ScalarArray>("name")
.has<ScalarArray>("value")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTNameValue::isCompatible(PVStructurePtr const & pvStructure)

View File

@@ -1,7 +1,8 @@
/* ntnameValue.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTNAMEVALUE_H
#define NTNAMEVALUE_H

View File

@@ -1,16 +1,12 @@
/* ntndarray.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <algorithm>
#include <pv/lock.h>
#include <pv/sharedPtr.h>
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntndarray.h>
#include <pv/ntndarrayAttribute.h>
@@ -21,6 +17,9 @@ using namespace epics::pvData;
namespace epics { namespace nt {
static NTFieldPtr ntField = NTField::get();
namespace detail {
static FieldCreatePtr fieldCreate = getFieldCreate();
@@ -71,7 +70,7 @@ StructureConstPtr NTNDArrayBuilder::createStructure()
ScalarType st = static_cast<ScalarType>(i);
fb->addArray(std::string(ScalarTypeFunc::name(st)) + "Value", st);
}
valueType = fb->createUnion();
valueType = fb->createUnion();
}
if (!codecStruc)
@@ -127,7 +126,7 @@ StructureConstPtr NTNDArrayBuilder::createStructure()
returnedStruc = fb->createStructure();
if (!isExtended)
ntndarrayStruc[index] = returnedStruc;
ntndarrayStruc[index] = returnedStruc;
}
else
{
@@ -192,11 +191,95 @@ NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::add(string const & name, Fiel
return shared_from_this();
}
}
const std::string NTNDArray::URI("epics:nt/NTNDArray:1.0");
const std::string ntAttrStr("epics:nt/NTAttribute:1.0");
static FieldCreatePtr fieldCreate = getFieldCreate();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
class NTValueType
{
public:
static bool isCompatible(UnionConstPtr const &u)
{
if(!u.get()) return false;
if (u->getID() != Union::defaultId()) return false;
if (u->isVariant()) return false;
for (int i = pvBoolean; i != pvString; ++i)
{
ScalarType scalarType = static_cast<ScalarType>(i);
std::string name(ScalarTypeFunc::name(scalarType));
name += "Value";
ScalarArrayConstPtr scalarField = u->getField<ScalarArray>(name);
if (scalarField.get() == 0 ||
scalarField->getElementType() != scalarType)
return false;
}
return true;
}
};
class NTCodec
{
public:
static bool isCompatible(StructureConstPtr const &structure)
{
if(!structure.get()) return false;
if (structure->getID() != "codec_t") return false;
ScalarConstPtr scalarField = structure->getField<Scalar>("name");
if (scalarField.get() == 0 || scalarField->getScalarType() != pvString)
return false;
UnionConstPtr paramField = structure->getField<Union>("parameters");
if (paramField.get() == 0 || !paramField->isVariant())
return false;
return true;
}
};
class NTDimension
{
public:
static bool isCompatible(StructureConstPtr const &structure)
{
if(!structure.get()) return false;
if (structure->getID() != "dimension_t") return false;
ScalarConstPtr scalarField = structure->getField<Scalar>("size");
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
return false;
scalarField = structure->getField<Scalar>("offset");
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
return false;
scalarField = structure->getField<Scalar>("fullSize");
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
return false;
scalarField = structure->getField<Scalar>("binning");
if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt)
return false;
scalarField = structure->getField<Scalar>("reverse");
if (scalarField.get() == 0 || scalarField->getScalarType() != pvBoolean)
return false;
return true;
}
};
NTNDArray::shared_pointer NTNDArray::wrap(PVStructurePtr const & pvStructure)
{
if(!isCompatible(pvStructure)) return shared_pointer();
@@ -213,67 +296,84 @@ bool NTNDArray::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTNDArray::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
namespace {
Result& isValue(Result& result)
{
result.is<Union>(Union::defaultId());
for (int i = pvBoolean; i < pvString; ++i) {
ScalarType type = static_cast<ScalarType>(i);
string name(ScalarTypeFunc::name(type));
result.has<ScalarArray>(name + "Value");
}
return result;
}
Result& isCodec(Result& result)
{
return result
.is<Structure>("codec_t")
.has<Scalar>("name")
.has<Union>("parameters");
}
Result& isDimension(Result& result)
{
return result
.is<StructureArray>("dimension_t[]")
.has<Scalar>("size")
.has<Scalar>("offset")
.has<Scalar>("fullSize")
.has<Scalar>("binning")
.has<Scalar>("reverse");
}
}
bool NTNDArray::isCompatible(StructureConstPtr const &structure)
{
if (!structure)
if(!structure.get()) return false;
UnionConstPtr valueField = structure->getField<Union>("value");
if(!NTValueType::isCompatible(valueField)) return false;
StructureConstPtr codecField = structure->getField<Structure>("codec");
if(!NTCodec::isCompatible(codecField)) return false;
ScalarConstPtr compressedSizeField = structure->getField<Scalar>("compressedSize");
if (compressedSizeField.get() == 0)
return false;
Result result(structure);
if (compressedSizeField->getScalarType() != pvLong)
return false;
return result
.is<Structure>()
.has<&isValue>("value")
.has<&isCodec>("codec")
.has<Scalar>("compressedSize")
.has<Scalar>("uncompressedSize")
.has<&isDimension>("dimension")
.has<Scalar>("uniqueId")
.has<&NTField::isTimeStamp, Structure>("dataTimeStamp")
.has<&NTNDArrayAttribute::isAttribute, StructureArray>("attribute")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.maybeHas<&NTField::isDisplay, Structure>("display")
.valid();
ScalarConstPtr uncompressedSizeField = structure->getField<Scalar>("uncompressedSize");
if (uncompressedSizeField.get() == 0)
return false;
if (uncompressedSizeField->getScalarType() != pvLong)
return false;
StructureArrayConstPtr dimensionField = structure->getField<StructureArray>("dimension");
if (dimensionField.get() == 0)
return false;
StructureConstPtr dimElementStruc = dimensionField->getStructure();
if(!NTDimension::isCompatible(dimElementStruc))
return false;
NTFieldPtr ntField = NTField::get();
StructureConstPtr dataTimeStampField = structure->getField<Structure>(
"dataTimeStamp");
if (dataTimeStampField.get() == 0 || !ntField->isTimeStamp(dataTimeStampField))
return false;
ScalarConstPtr uniqueIdField = structure->getField<Scalar>("uniqueId");
if (uniqueIdField.get() == 0)
return false;
if (uniqueIdField->getScalarType() != pvInt)
return false;
StructureArrayConstPtr attributeField = structure->getField<StructureArray>( "attribute");
StructureConstPtr attributeElementStruc = attributeField->getStructure();
if (!NTNDArrayAttribute::isCompatible(attributeElementStruc))
return false;
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
field = structure->getField("display");
if (field.get() && !ntField->isDisplay(field))
return false;
return true;
}
@@ -284,6 +384,7 @@ bool NTNDArray::isCompatible(PVStructurePtr const & pvStructure)
return isCompatible(pvStructure->getStructure());
}
bool NTNDArray::isValid()
{
int64 valueSize = getValueSize();
@@ -327,8 +428,10 @@ int64 NTNDArray::getValueSize()
{
int64 size = 0;
PVScalarArrayPtr storedValue = getValue()->get<PVScalarArray>();
if (storedValue.get())
if (!storedValue.get())
{
size = storedValue->getLength()*getValueTypeSize();
}
return size;
}

View File

@@ -1,7 +1,8 @@
/* ntndarray.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTNDARRAY_H
#define NTNDARRAY_H
@@ -10,16 +11,16 @@
#include <string>
#ifdef epicsExportSharedSymbols
# define ntndarrayEpicsExportSharedSymbols
# define ntscalarArrayEpicsExportSharedSymbols
# undef epicsExportSharedSymbols
#endif
#include <pv/pvDisplay.h>
#include <pv/pvControl.h>
#ifdef ntndarrayEpicsExportSharedSymbols
#ifdef ntscalarArrayEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef ntndarrayEpicsExportSharedSymbols
# undef ntscalarArrayEpicsExportSharedSymbols
#endif
#include <pv/ntfield.h>
@@ -139,7 +140,7 @@ public:
* and if so returns an NTScalarArray which wraps it.
* This method will return null if the structure is is not compatible
* or is null.
*
*
* @param pvStructure the PVStructure to be wrapped
* @return NTScalarArray instance wrapping pvStructure on success, null otherwise
*/
@@ -150,7 +151,7 @@ public:
* <p>
* No checks are made as to whether the specified PVStructure
* is compatible with NTNDArray or is non-null.
*
*
* @param pvStructure the PVStructure to be wrapped
* @return NTNDArray instance wrapping pvStructure
*/
@@ -163,7 +164,7 @@ public:
* version of NTNDArray through its type ID, including checking version numbers.
* The return value does not depend on whether the structure is actually
* compatible in terms of its introspection type.
*
*
* @param structure the pvStructure to test
* @return (false,true) if the specified Structure (is not, is) a compatible NTNDArray
*/
@@ -176,7 +177,7 @@ public:
* version of NTNDArray through its type ID, including checking version numbers.
* The return value does not depend on whether the structure is actually
* compatible in terms of its introspection type.
*
*
* @param pvStructure the PVStructure to test
* @return (false,true) if the specified PVStructure (is not, is) a compatible NTNDArray
*/
@@ -187,7 +188,7 @@ public:
* <p>
* Checks if the specified Structure is compatible with this version
* of NTNDArray through the introspection interface.
*
*
* @param structure the Structure to test
* @return (false,true) if the specified Structure (is not, is) a compatible NTNDArray
*/

View File

@@ -1,11 +1,10 @@
/* ntndarrayAttribute.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntndarrayAttribute.h>
#include <pv/ntattribute.h>
@@ -95,7 +94,6 @@ NTNDArrayAttributeBuilder::NTNDArrayAttributeBuilder()
void NTNDArrayAttributeBuilder::reset()
{
tags = false;
descriptor = false;
alarm = false;
timeStamp = false;
@@ -129,30 +127,24 @@ bool NTNDArrayAttribute::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTNDArrayAttribute::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
Result& NTNDArrayAttribute::isAttribute(Result& result) {
return result
.has<Scalar>("name")
.has<Union>("value")
.maybeHas<ScalarArray>("tags")
.has<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.has<Scalar>("sourceType")
.has<Scalar>("source");
}
bool NTNDArrayAttribute::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (!NTAttribute::isCompatible(structure)) return false;
// descriptor required field for attibute in an ndarray
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (descriptorField.get() == 0 || descriptorField->getScalarType() != pvString)
return false;
Result result(structure);
return isAttribute(result.is<Structure>()).valid();
ScalarConstPtr sourcedTypeField = structure->getField<Scalar>("sourceType");
if (sourcedTypeField.get() == 0 || sourcedTypeField->getScalarType() != pvInt)
return false;
ScalarConstPtr sourcedField = structure->getField<Scalar>("source");
if (sourcedField.get() == 0 || sourcedField->getScalarType() != pvString)
return false;
return true;
}
bool NTNDArrayAttribute::isCompatible(PVStructurePtr const & pvStructure)

View File

@@ -1,7 +1,8 @@
/* ntndarrayAttribute.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTNDARRAYATTRIBUTE_H
#define NTNDARRAYATTRIBUTE_H
@@ -22,7 +23,6 @@
namespace epics { namespace nt {
struct Result;
class NTNDArrayAttribute;
typedef std::tr1::shared_ptr<NTNDArrayAttribute> NTNDArrayAttributePtr;
@@ -45,7 +45,7 @@ namespace detail {
* Adds tags field to the NTNDArrayAttribute.
* @return this instance of <b>NTNDArrayAttributeBuilder</b>.
*/
shared_pointer addTags();
virtual shared_pointer addTags();
/**
* Adds descriptor field to the NTNDArrayAttribute.
@@ -303,13 +303,10 @@ public:
private:
NTNDArrayAttribute(epics::pvData::PVStructurePtr const & pvStructure);
static Result& isAttribute(Result& result);
epics::pvData::PVStructurePtr pvNTNDArrayAttribute;
epics::pvData::PVUnionPtr pvValue;
friend class detail::NTNDArrayAttributeBuilder;
friend class NTNDArray;
};
}}

View File

@@ -1,11 +1,10 @@
/* ntscalar.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntscalar.h>
#include <pv/ntutils.h>
@@ -147,29 +146,44 @@ bool NTScalar::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTScalar::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTScalar::isCompatible(StructureConstPtr const &structure)
{
if (!structure)
if (structure.get() == 0) return false;
ScalarConstPtr valueField = structure->getField<Scalar>("value");
if (valueField.get() == 0)
return false;
Result result(structure);
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
return result
.is<Structure>()
.has<Scalar>("value")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.maybeHas<&NTField::isDisplay, Structure>("display")
.maybeHas<&NTField::isControl, Structure>("control")
.valid();
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
field = structure->getField("display");
if (field.get() && !ntField->isDisplay(field))
return false;
field = structure->getField("control");
if (field.get() && !ntField->isControl(field))
return false;
return true;
}
bool NTScalar::isCompatible(PVStructurePtr const & pvStructure)
{
if(!pvStructure) return false;

View File

@@ -1,7 +1,8 @@
/* ntscalar.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTSCALAR_H
#define NTSCALAR_H

View File

@@ -1,11 +1,10 @@
/* ntscalarArray.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntscalarArray.h>
#include <pv/ntutils.h>
@@ -156,27 +155,41 @@ bool NTScalarArray::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTScalarArray::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTScalarArray::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (structure.get() == 0) return false;
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
if (valueField.get() == 0)
return false;
Result result(structure);
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
return result
.is<Structure>()
.has<ScalarArray>("value")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.maybeHas<&NTField::isDisplay, Structure>("display")
.maybeHas<&NTField::isControl, Structure>("control")
.valid();
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
field = structure->getField("display");
if (field.get() && !ntField->isDisplay(field))
return false;
field = structure->getField("control");
if (field.get() && !ntField->isControl(field))
return false;
return true;
}
bool NTScalarArray::isCompatible(PVStructurePtr const & pvStructure)

View File

@@ -1,7 +1,8 @@
/* ntscalarArray.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTSCALARARRAY_H
#define NTSCALARARRAY_H

View File

@@ -1,10 +1,11 @@
/* ntscalarMultiChannel.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <algorithm>
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntscalarMultiChannel.h>
@@ -13,7 +14,7 @@
using namespace std;
using namespace epics::pvData;
namespace epics { namespace nt {
namespace epics { namespace nt {
static FieldCreatePtr fieldCreate = getFieldCreate();
@@ -222,34 +223,89 @@ bool NTScalarMultiChannel::is_a(StructureConstPtr const &structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTScalarMultiChannel::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTScalarMultiChannel::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (!structure.get()) return false;
ScalarArrayConstPtr valueField = structure->getField<ScalarArray>("value");
if (!valueField.get()) return false;
ScalarArrayConstPtr channelNameField = structure->getField<ScalarArray>(
"channelName");
if (!channelNameField.get()) return false;
if (channelNameField->getElementType() != pvString) return false;
FieldConstPtr field = structure->getField("severity");
if (field.get())
{
ScalarArrayConstPtr severityField = structure->getField<ScalarArray>("severity");
if (!severityField.get() || severityField->getElementType() != pvInt)
return false;
}
field = structure->getField("status");
if (field.get())
{
ScalarArrayConstPtr statusField = structure->getField<ScalarArray>("status");
if (!statusField.get() || statusField->getElementType() != pvInt)
return false;
}
field = structure->getField("message");
if (field.get())
{
ScalarArrayConstPtr messageField = structure->getField<ScalarArray>("message");
if (!messageField.get() || messageField->getElementType() != pvString)
return false;
}
field = structure->getField("secondsPastEpoch");
if (field.get())
{
ScalarArrayConstPtr secondsPastEpochField = structure->getField<ScalarArray>("secondsPastEpoch");
if (!secondsPastEpochField.get() || secondsPastEpochField->getElementType() != pvLong)
return false;
}
field = structure->getField("nanoseconds");
if (field.get())
{
ScalarArrayConstPtr nanosecondsField = structure->getField<ScalarArray>("nanoseconds");
if (!nanosecondsField.get() || nanosecondsField->getElementType() != pvInt)
return false;
}
field = structure->getField("userTag");
if (field.get())
{
ScalarArrayConstPtr userTagField = structure->getField<ScalarArray>("userTag");
if (!userTagField.get() || userTagField->getElementType() != pvInt)
return false;
}
field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
Result result(structure);
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return result
.is<Structure>()
.has<ScalarArray>("value")
.has<ScalarArray>("channelName")
.maybeHas<ScalarArray>("severity")
.maybeHas<ScalarArray>("status")
.maybeHas<ScalarArray>("message")
.maybeHas<ScalarArray>("secondsPastEpoch")
.maybeHas<ScalarArray>("nanoseconds")
.maybeHas<ScalarArray>("userTag")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
return true;
}
bool NTScalarMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
{
if(!pvStructure.get()) return false;
@@ -263,7 +319,7 @@ bool NTScalarMultiChannel::isValid()
if (getChannelName()->getLength() != valueLength) return false;
PVScalarArrayPtr arrayFields[] = {
getSeverity(), getStatus(), getMessage(),
getSeverity(), getStatus(), getMessage(),
getSecondsPastEpoch(), getNanoseconds(), getUserTag()
};
size_t N = sizeof(arrayFields)/sizeof(arrayFields[0]);
@@ -275,7 +331,7 @@ bool NTScalarMultiChannel::isValid()
if (arrayField.get() && arrayField->getLength() != valueLength)
return false;
}
return true;
return true;
}
NTScalarMultiChannelBuilderPtr NTScalarMultiChannel::createBuilder()

View File

@@ -1,7 +1,8 @@
/* ntscalarMultiChannel.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTSCALARMULTICHANNEL_H
#define NTSCALARMULTICHANNEL_H

View File

@@ -1,11 +1,11 @@
/* nttable.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <algorithm>
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/nttable.h>
@@ -143,39 +143,44 @@ bool NTTable::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTTable::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTTable::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (!structure.get()) return false;
StructureConstPtr valueField = structure->getField<Structure>("value");
if (!valueField.get())
return false;
Result result(structure);
result
.is<Structure>()
.has<Structure>("value")
.has<ScalarArray>("labels")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp");
StructureConstPtr value(structure->getField<Structure>("value"));
if (value) {
Result r(value);
StringArray const & names(value->getFieldNames());
StringArray::const_iterator it;
for (it = names.begin(); it != names.end(); ++it)
r.has<ScalarArray>(*it);
result |= r;
FieldConstPtrArray const & fields = valueField->getFields();
for (FieldConstPtrArray::const_iterator it = fields.begin();
it != fields.end(); ++it)
{
if ((*it)->getType() != scalarArray) return false;
}
return result.valid();
ScalarArrayConstPtr labelsField = structure->getField<ScalarArray>("labels");
if (!labelsField.get() || labelsField->getElementType() != pvString)
return false;
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTTable::isCompatible(PVStructurePtr const & pvStructure)
@@ -188,7 +193,7 @@ bool NTTable::isCompatible(PVStructurePtr const & pvStructure)
bool NTTable::isValid()
{
PVFieldPtrArray const & columns = pvValue->getPVFields();
if (getLabels()->getLength() != columns.size()) return false;
bool first = true;
int length = 0;
@@ -261,7 +266,7 @@ PVStringArrayPtr NTTable::getLabels() const
StringArray const & NTTable::getColumnNames() const
{
return pvValue->getStructure()->getFieldNames();
return pvNTTable->getStructure()->getFieldNames();
}
PVFieldPtr NTTable::getColumn(std::string const & columnName) const

View File

@@ -1,7 +1,8 @@
/* nttable.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTTABLE_H
#define NTTABLE_H

View File

@@ -1,11 +1,10 @@
/* ntunion.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntunion.h>
#include <pv/ntutils.h>
@@ -20,12 +19,6 @@ static NTFieldPtr ntField = NTField::get();
namespace detail {
NTUnionBuilder::shared_pointer NTUnionBuilder::value(UnionConstPtr unionType)
{
valueType = unionType;
return shared_from_this();
}
StructureConstPtr NTUnionBuilder::createStructure()
{
FieldBuilderPtr builder =
@@ -123,25 +116,33 @@ bool NTUnion::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTUnion::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTUnion::isCompatible(StructureConstPtr const &structure)
{
if (!structure)
if (structure.get() == 0) return false;
UnionConstPtr valueField = structure->getField<Union>("value");
if (valueField.get() == 0)
return false;
Result result(structure);
FieldConstPtr field = structure->getField("descriptor");
if (field.get())
{
ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor");
if (!descriptorField.get() || descriptorField->getScalarType() != pvString)
return false;
}
return result
.is<Structure>()
.has<Union>("value")
.maybeHas<Scalar>("descriptor")
.maybeHas<&NTField::isAlarm, Structure>("alarm")
.maybeHas<&NTField::isTimeStamp, Structure>("timeStamp")
.valid();
NTFieldPtr ntField = NTField::get();
field = structure->getField("alarm");
if (field.get() && !ntField->isAlarm(field))
return false;
field = structure->getField("timeStamp");
if (field.get() && !ntField->isTimeStamp(field))
return false;
return true;
}
bool NTUnion::isCompatible(PVStructurePtr const & pvStructure)

View File

@@ -1,7 +1,8 @@
/* ntunion.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTUNION_H
#define NTUNION_H
@@ -40,14 +41,6 @@ namespace detail {
public:
POINTER_DEFINITIONS(NTUnionBuilder);
/**
* Specifies the union for the value field.
* If this is not called then a variant union is the default.
* @param unionType the introspection object for the union value field
* @return this instance of NTUnionBuilder
*/
shared_pointer value(epics::pvData::UnionConstPtr unionType);
/**
* Adds descriptor field to the NTUnion.
* @return this instance of <b>NTUnionBuilder</b>.

View File

@@ -1,11 +1,11 @@
/* nturi.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <algorithm>
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/nturi.h>
@@ -143,38 +143,47 @@ bool NTURI::is_a(StructureConstPtr const & structure)
return NTUtils::is_a(structure->getID(), URI);
}
bool NTURI::is_a(PVStructurePtr const & pvStructure)
{
return is_a(pvStructure->getStructure());
}
bool NTURI::isCompatible(StructureConstPtr const & structure)
{
if (!structure)
if (!structure.get()) return false;
ScalarConstPtr schemeField = structure->getField<Scalar>("scheme");
if (schemeField.get() == 0 || schemeField->getScalarType() != pvString)
return false;
Result result(structure);
ScalarConstPtr pathField = structure->getField<Scalar>("path");
if (pathField.get() == 0 || pathField->getScalarType() != pvString)
return false;
result
.is<Structure>()
.has<Scalar>("scheme")
.has<Scalar>("path")
.maybeHas<Scalar>("authority")
.maybeHas<Structure>("query");
StructureConstPtr query(structure->getField<Structure>("query"));
if (query) {
Result r(query);
StringArray const & names(query->getFieldNames());
StringArray::const_iterator it;
for (it = names.begin(); it != names.end(); ++it)
r.has<ScalarArray>(*it);
result |= r;
FieldConstPtr field = structure->getField("authority");
if (field.get())
{
ScalarConstPtr authorityField = structure->getField<Scalar>("authority");
if (!authorityField.get() || authorityField->getScalarType() != pvString)
return false;
}
return result.valid();
field = structure->getField("query");
if (field.get())
{
StructureConstPtr queryField = structure->getField<Structure>("query");
if (!queryField.get())
return false;
FieldConstPtrArray const & fields = queryField->getFields();
for (FieldConstPtrArray::const_iterator it = fields.begin();
it != fields.end(); ++it)
{
if ((*it)->getType() != scalar) return false;
ScalarType scalarType = std::tr1::dynamic_pointer_cast<const Scalar>(
(*it))->getScalarType();
if (scalarType != pvString &&
scalarType != pvInt &&
scalarType != pvDouble) return false;
}
}
return true;
}

View File

@@ -1,7 +1,8 @@
/* nturi.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTURI_H
#define NTURI_H

View File

@@ -1,7 +1,8 @@
/* ntutils.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#define epicsExportSharedSymbols

View File

@@ -1,7 +1,8 @@
/* ntutils.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTUTILS_H
#define NTUTILS_H

View File

@@ -1,241 +0,0 @@
/* ntfield.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
#include <pv/lock.h>
#include "validator.h"
#define epicsExportSharedSymbols
#include <pv/ntfield.h>
using namespace epics::pvData;
using std::tr1::static_pointer_cast;
namespace epics { namespace nt {
NTFieldPtr NTField::get()
{
static Mutex mutex;
static NTFieldPtr ntstructureField;
Lock xx(mutex);
if(ntstructureField.get()==NULL) {
ntstructureField = NTFieldPtr(new NTField());
}
return ntstructureField;
}
NTField::NTField()
: fieldCreate(getFieldCreate()),
standardField(getStandardField())
{
}
Result& NTField::isEnumerated(Result& result)
{
return result
.has<Scalar>("index")
.has<ScalarArray>("choices");
}
bool NTField::isEnumerated(FieldConstPtr const & field)
{
Result result(field);
return isEnumerated(result.is<Structure>()).valid();
}
Result& NTField::isTimeStamp(Result& result)
{
return result
.has<Scalar>("secondsPastEpoch")
.has<Scalar>("nanoseconds")
.has<Scalar>("userTag");
}
bool NTField::isTimeStamp(FieldConstPtr const & field)
{
Result result(field);
return isTimeStamp(result.is<Structure>()).valid();
}
Result& NTField::isAlarm(Result& result)
{
return result
.has<Scalar>("severity")
.has<Scalar>("status")
.has<Scalar>("message");
}
bool NTField::isAlarm(FieldConstPtr const & field)
{
Result result(field);
return isAlarm(result.is<Structure>()).valid();
}
Result& NTField::isDisplay(Result& result)
{
return result
.has<Scalar>("limitLow")
.has<Scalar>("limitHigh")
.has<Scalar>("description")
.has<Scalar>("format")
.has<Scalar>("units");
}
bool NTField::isDisplay(FieldConstPtr const & field)
{
Result result(field);
return isDisplay(result.is<Structure>()).valid();
}
Result& NTField::isAlarmLimit(Result& result)
{
return result
.has<Scalar>("active")
.has<Scalar>("lowAlarmLimit")
.has<Scalar>("lowWarningLimit")
.has<Scalar>("highWarningLimit")
.has<Scalar>("highAlarmLimit")
.has<Scalar>("lowAlarmSeverity")
.has<Scalar>("lowWarningSeverity")
.has<Scalar>("highWarningSeverity")
.has<Scalar>("highAlarmSeverity")
.has<Scalar>("hysteresis");
}
bool NTField::isAlarmLimit(FieldConstPtr const & field)
{
Result result(field);
return isAlarmLimit(result.is<Structure>()).valid();
}
Result& NTField::isControl(Result& result)
{
return result
.has<Scalar>("limitLow")
.has<Scalar>("limitHigh")
.has<Scalar>("minStep");
}
bool NTField::isControl(FieldConstPtr const & field)
{
Result result(field);
return isControl(result.is<Structure>()).valid();
}
StructureConstPtr NTField::createEnumerated()
{
return standardField->enumerated();
}
StructureConstPtr NTField::createTimeStamp()
{
return standardField->timeStamp();
}
StructureConstPtr NTField::createAlarm()
{
return standardField->alarm();
}
StructureConstPtr NTField::createDisplay()
{
return standardField->display();
}
StructureConstPtr NTField::createControl()
{
return standardField->control();
}
StructureArrayConstPtr NTField::createEnumeratedArray()
{
return fieldCreate->createStructureArray(createEnumerated());
}
StructureArrayConstPtr NTField::createTimeStampArray()
{
StructureConstPtr st = createTimeStamp();
return fieldCreate->createStructureArray(st);
}
StructureArrayConstPtr NTField::createAlarmArray()
{
StructureConstPtr st = createAlarm();
return fieldCreate->createStructureArray(st);
}
PVNTFieldPtr PVNTField::get()
{
static Mutex mutex;
static PVNTFieldPtr pvntstructureField;
Lock xx(mutex);
if(pvntstructureField.get()==NULL) {
pvntstructureField = PVNTFieldPtr(new PVNTField());
}
return pvntstructureField;
}
PVNTField::PVNTField()
: pvDataCreate(getPVDataCreate()),
standardField(getStandardField()),
standardPVField(getStandardPVField()),
ntstructureField(NTField::get())
{
}
PVStructurePtr PVNTField::createEnumerated(
StringArray const & choices)
{
return standardPVField->enumerated(choices);
}
PVStructurePtr PVNTField::createTimeStamp()
{
StructureConstPtr timeStamp = standardField->timeStamp();
return pvDataCreate->createPVStructure(timeStamp);
}
PVStructurePtr PVNTField::createAlarm()
{
StructureConstPtr alarm = standardField->alarm();
return pvDataCreate->createPVStructure(alarm);
}
PVStructurePtr PVNTField::createDisplay()
{
StructureConstPtr display = standardField->display();
return pvDataCreate->createPVStructure(display);
}
PVStructurePtr PVNTField::createControl()
{
StructureConstPtr control = standardField->control();
return pvDataCreate->createPVStructure(control);
}
PVStructureArrayPtr PVNTField::createEnumeratedArray()
{
StructureArrayConstPtr sa =
ntstructureField->createEnumeratedArray();
return pvDataCreate->createPVStructureArray(sa);
}
PVStructureArrayPtr PVNTField::createTimeStampArray()
{
StructureArrayConstPtr sa =
ntstructureField->createTimeStampArray();
return pvDataCreate->createPVStructureArray(sa);
}
PVStructureArrayPtr PVNTField::createAlarmArray()
{
StructureArrayConstPtr sa = ntstructureField->createAlarmArray();
return pvDataCreate->createPVStructureArray(sa);
}
}}

View File

@@ -1,277 +0,0 @@
/* validator.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
#ifndef VALIDATOR_H
#define VALIDATOR_H
#include <string>
#include <set>
#include <algorithm>
#include <pv/pvIntrospect.h>
namespace epics { namespace nt {
/**
* @brief Validation methods for NT types.
*
* @author bsm
*/
struct Result {
struct Error {
std::string path;
enum Type {
MissingField,
IncorrectType,
IncorrectId,
} type;
Error(std::string const & path, Type type)
: path(path), type(type) {}
bool operator==(const Error& other) const {
return type == other.type && path == other.path;
}
std::ostream& dump(std::ostream& os) const {
os << "Error(path=" << (path.empty() ? "<root>" : path) << ": ";
switch(type) {
case MissingField: os << "missing"; break;
case IncorrectType: os << "incorrect type"; break;
case IncorrectId: os << "incorrect ID"; break;
}
os << ")";
return os;
}
};
epics::pvData::FieldConstPtr field;
std::string path;
std::vector<Error> errors;
enum result_t {
Pass,
Fail,
} result;
Result(const epics::pvData::FieldConstPtr& field, const std::string& path = std::string())
: field(field), path(path), errors(), result(Pass) {}
Result() {}
Result& operator|=(const Result& other) {
result = std::max(result, other.result);
errors.insert(errors.end(), other.errors.begin(), other.errors.end());
return *this;
}
/**
* Returns whether this Result is valid.
*
* @return true if all tests passed, false otherwise.
*/
inline bool valid(void) const {
return result == Pass;
}
/**
* Test that this Result's field is of a particular type 'T'.
*
* Appends an Error::Type::IncorrectType if the field is not of type 'T'.
*
* @return itself
*/
template<typename T>
Result& is(void) {
if (!dynamic_cast<T const *>(field.get())) {
result = Fail;
errors.push_back(Error(path, Error::IncorrectType));
}
return *this;
}
/**
* Test that this Result's field is of a particular type 'T' and has
* an ID equal to 'id'.
*
* Appends an Error::Type::IncorrectType if the field is not of type 'T'.
* Appends an Error::Type::IncorrectId if the field does not have an ID
* equal to 'id'.
*
* @return itself
*/
template<typename T>
Result& is(const std::string& id) {
T const *s = dynamic_cast<T const *>(field.get());
if (!s) {
result = Fail;
errors.push_back(Error(path, Error::IncorrectType));
} else if (s->getID() != id) {
result = Fail;
errors.push_back(Error(path, Error::IncorrectId));
}
return *this;
}
/**
* Test that this Result's field has a subfield with name 'name' and
* apply the function 'fn' to the subfield.
*
* Appends an Error::Type::IncorrectType if the field is not one of
* Structure, StructureArray, Union, UnionArray.
* Appends an Error::Type::MissingField if the subfield is not
* present.
*
* @return itself
*/
template<Result& (*fn)(Result&)>
Result& has(const std::string& name) {
return has<epics::pvData::Field>(name, false, fn);
}
/**
* Test that this Result's field has an optional subfield with name
* 'name' and, if it has, apply the function 'fn' to the subfield.
*
* Appends an Error::Type::IncorrectType if the field is not one of
* Structure, StructureArray, Union, UnionArray.
*
* @return itself
*/
template<Result& (*fn)(Result&)>
Result& maybeHas(const std::string& name) {
return has<epics::pvData::Field>(name, true, fn);
}
/**
* Test that this Result's field has a subfield with name 'name',
* apply the function 'fn' to the subfield and
* test that the subfield is of type 'T'.
*
* Appends an Error::Type::IncorrectType if the field is not one of
* Structure, StructureArray, Union, UnionArray.
* Appends an Error::Type::IncorrectType if the subfield is not of
* type 'T'.
* Appends an Error::Type::MissingField if the subfield is not
* present.
*
* @return itself
*/
template<Result& (*fn)(Result&), typename T>
Result& has(const std::string& name) {
return has<T>(name, false, fn);
}
/**
* Test that this Result's field has an optional subfield with name
* 'name' and, if it has, apply the function 'fn' to the subfield and
* test that the subfield is of type 'T'.
*
* Appends an Error::Type::IncorrectType if the field is not one of
* Structure, StructureArray, Union, UnionArray.
* Appends an Error::Type::IncorrectType if the subfield exists and
* is not of type 'T'.
*
* @return itself
*/
template<Result& (*fn)(Result&), typename T>
Result& maybeHas(const std::string& name) {
return has<T>(name, true, fn);
}
/**
* Test that this Result's field has a subfield with name 'name' and
* test that the subfield is of type 'T'.
*
* Appends an Error::Type::IncorrectType if the field is not one of
* Structure, StructureArray, Union, UnionArray.
* Appends an Error::Type::IncorrectType if the subfield is not of
* type 'T'.
* Appends an Error::Type::MissingField if the subfield is not
* present.
*
* @return itself
*/
template<typename T>
Result& has(const std::string& name) {
return has<T>(name, false, NULL);
}
/**
* Test that this Result's field has an optional subfield with name
* 'name' and, if it has, test that the subfield is of type 'T'.
*
* Appends an Error::Type::IncorrectType if the field is not one of
* Structure, StructureArray, Union, UnionArray.
* Appends an Error::Type::IncorrectType if the subfield exists and
* is not of type 'T'.
*
* @return itself
*/
template<typename T>
Result& maybeHas(const std::string& name) {
return has<T>(name, true, NULL);
}
std::ostream& dump(std::ostream& os) const {
os << "Result(valid=" << (result == Pass) << ", errors=[ ";
std::vector<Error>::const_iterator it;
for (it = errors.begin(); it != errors.end(); ++it) {
(*it).dump(os);
os << " ";
}
os << "])";
return os;
}
private:
template<typename T>
Result& has(const std::string& name, bool optional, Result& (*check)(Result&) = NULL) {
epics::pvData::FieldConstPtr subField;
switch(field->getType()) {
case epics::pvData::structure:
subField = static_cast<epics::pvData::Structure const *>(field.get())->getField(name);
break;
case epics::pvData::structureArray:
subField = static_cast<epics::pvData::StructureArray const *>(field.get())->getStructure()->getField(name);
break;
case epics::pvData::union_:
subField = static_cast<epics::pvData::Union const *>(field.get())->getField(name);
break;
case epics::pvData::unionArray:
subField = static_cast<epics::pvData::UnionArray const *>(field.get())->getUnion()->getField(name);
break;
default:
// Expected a structure-like Field
result = Fail;
errors.push_back(Error(path, Error::IncorrectType));
return *this;
}
std::string subFieldPath(path.empty() ? name : path + "." + name);
if (!subField) {
if (!optional) {
result = Fail;
errors.push_back(Error(subFieldPath, Error::MissingField));
}
} else if (!dynamic_cast<T const *>(subField.get())) {
result = Fail;
errors.push_back(Error(subFieldPath, Error::IncorrectType));
} else if (check) {
Result r(subField, subFieldPath);
*this |= check(r);
}
return *this;
}
};
}}
#endif

View File

@@ -1,84 +1,5 @@
TOP=..
TOP = ..
include $(TOP)/configure/CONFIG
PROD_LIBS += nt pvData Com
TESTPROD_HOST += ntfieldTest
ntfieldTest_SRCS += ntfieldTest.cpp
TESTS += ntfieldTest
TESTPROD_HOST += ntscalarTest
ntscalarTest_SRCS += ntscalarTest.cpp
TESTS += ntscalarTest
TESTPROD_HOST += ntscalarArrayTest
ntscalarArrayTest_SRCS += ntscalarArrayTest.cpp
TESTS += ntscalarArrayTest
TESTPROD_HOST += ntnameValueTest
ntnameValueTest_SRCS += ntnameValueTest.cpp
TESTS += ntnameValueTest
TESTPROD_HOST += ntmultiChannelTest
ntmultiChannelTest_SRCS += ntmultiChannelTest.cpp
TESTS += ntmultiChannelTest
TESTPROD_HOST += ntscalarMultiChannelTest
ntscalarMultiChannelTest_SRCS += ntscalarMultiChannelTest.cpp
TESTS += ntscalarMultiChannelTest
TESTPROD_HOST += nttableTest
nttableTest_SRCS = nttableTest.cpp
TESTS += nttableTest
TESTPROD_HOST += ntndarrayTest
ntndarrayTest_SRCS = ntndarrayTest.cpp
TESTS += ntndarrayTest
TESTPROD_HOST += ntmatrixTest
ntmatrixTest_SRCS = ntmatrixTest.cpp
TESTS += ntmatrixTest
TESTPROD_HOST += ntenumTest
ntenumTest_SRCS = ntenumTest.cpp
TESTS += ntenumTest
TESTPROD_HOST += ntunionTest
ntunionTest_SRCS = ntunionTest.cpp
TESTS += ntunionTest
TESTPROD_HOST += ntaggregateTest
ntaggregateTest_SRCS = ntaggregateTest.cpp
TESTS += ntaggregateTest
TESTPROD_HOST += ntattributeTest
ntattributeTest_SRCS = ntattributeTest.cpp
TESTS += ntattributeTest
TESTPROD_HOST += ntndarrayAttributeTest
ntndarrayAttributeTest_SRCS = ntndarrayAttributeTest.cpp
TESTS += ntndarrayAttributeTest
TESTPROD_HOST += ntcontinuumTest
ntcontinuumTest = ntcontinuumTest.cpp
TESTS += ntcontinuumTest
TESTPROD_HOST += nthistogramTest
nthistogramTest_SRCS = nthistogramTest.cpp
TESTS += nthistogramTest
TESTPROD_HOST += ntutilsTest
ntutilsTest_SRCS = ntutilsTest.cpp
TESTS += ntutilsTest
TESTPROD_HOST += validatorTest
validatorTest_SRCS = validatorTest.cpp
TESTS += validatorTest
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE
DIRS += nt
include $(TOP)/configure/RULES_DIRS

80
test/nt/Makefile Normal file
View File

@@ -0,0 +1,80 @@
TOP=../..
include $(TOP)/configure/CONFIG
PROD_LIBS += nt pvData Com
TESTPROD_HOST += ntfieldTest
ntfieldTest_SRCS += ntfieldTest.cpp
TESTS += ntfieldTest
TESTPROD_HOST += ntscalarTest
ntscalarTest_SRCS += ntscalarTest.cpp
TESTS += ntscalarTest
TESTPROD_HOST += ntscalarArrayTest
ntscalarArrayTest_SRCS += ntscalarArrayTest.cpp
TESTS += ntscalarArrayTest
TESTPROD_HOST += ntnameValueTest
ntnameValueTest_SRCS += ntnameValueTest.cpp
TESTS += ntnameValueTest
TESTPROD_HOST += ntmultiChannelTest
ntmultiChannelTest_SRCS += ntmultiChannelTest.cpp
TESTS += ntmultiChannelTest
TESTPROD_HOST += ntscalarMultiChannelTest
ntscalarMultiChannelTest_SRCS += ntscalarMultiChannelTest.cpp
TESTS += ntscalarMultiChannelTest
TESTPROD_HOST += nttableTest
nttableTest_SRCS = nttableTest.cpp
TESTS += nttableTest
TESTPROD_HOST += ntndarrayTest
ntndarrayTest_SRCS = ntndarrayTest.cpp
TESTS += ntndarrayTest
TESTPROD_HOST += ntmatrixTest
ntmatrixTest_SRCS = ntmatrixTest.cpp
TESTS += ntmatrixTest
TESTPROD_HOST += ntenumTest
ntenumTest_SRCS = ntenumTest.cpp
TESTS += ntenumTest
TESTPROD_HOST += ntunionTest
ntunionTest_SRCS = ntunionTest.cpp
TESTS += ntunionTest
TESTPROD_HOST += ntaggregateTest
ntaggregateTest_SRCS = ntaggregateTest.cpp
TESTS += ntaggregateTest
TESTPROD_HOST += ntattributeTest
ntattributeTest_SRCS = ntattributeTest.cpp
TESTS += ntattributeTest
TESTPROD_HOST += ntndarrayAttributeTest
ntndarrayAttributeTest_SRCS = ntndarrayAttributeTest.cpp
TESTS += ntndarrayAttributeTest
TESTPROD_HOST += ntcontinuumTest
ntattributeTest_SRCS = ntcontinuumTest.cpp
TESTS += ntcontinuumTest
TESTPROD_HOST += nthistogramTest
ntattributeTest_SRCS = nthistogramTest.cpp
TESTS += nthistogramTest
TESTPROD_HOST += ntutilsTest
ntutilsTest_SRCS = ntutilsTest.cpp
TESTS += ntutilsTest
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -65,9 +66,6 @@ void test_ntaggregate()
create();
testOk1(ntAggregate.get() != 0);
testOk1(NTAggregate::is_a(ntAggregate->getPVStructure()));
testOk1(NTAggregate::isCompatible(ntAggregate->getPVStructure()));
testOk1(ntAggregate->getPVStructure().get() != 0);
testOk1(ntAggregate->getValue().get() != 0);
testOk1(ntAggregate->getDescriptor().get() != 0);
@@ -78,7 +76,7 @@ void test_ntaggregate()
// example how to set a value
//
ntAggregate->getValue()->put(1.0);
//
// example how to get a value
//
@@ -167,9 +165,11 @@ void test_wrap()
}
MAIN(testNTAggregate) {
testPlan(30);
testPlan(28);
test_builder();
test_ntaggregate();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,8 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*
*/
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -74,9 +76,6 @@ void test_ntattribute()
create();
testOk1(ntAttribute.get() != 0);
testOk1(NTAttribute::is_a(ntAttribute->getPVStructure()));
testOk1(NTAttribute::isCompatible(ntAttribute->getPVStructure()));
testOk1(ntAttribute->getPVStructure().get() != 0);
testOk1(ntAttribute->getName().get() != 0);
testOk1(ntAttribute->getValue().get() != 0);
@@ -167,9 +166,11 @@ void test_wrap()
}
MAIN(testNTAttribute) {
testPlan(35);
testPlan(33);
test_builder();
test_ntattribute();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -71,9 +72,6 @@ void test_ntcontinuum()
create();
testOk1(ntContinuum.get() != 0);
testOk1(NTContinuum::is_a(ntContinuum->getPVStructure()));
testOk1(NTContinuum::isCompatible(ntContinuum->getPVStructure()));
testOk1(ntContinuum->getPVStructure().get() != 0);
testOk1(ntContinuum->getDescriptor().get() != 0);
testOk1(ntContinuum->getAlarm().get() != 0);
@@ -267,10 +265,12 @@ void test_extra()
MAIN(testNTContinuum) {
testPlan(61);
testPlan(59);
test_builder();
test_ntcontinuum();
test_wrap();
test_extra();
return testDone();
}

View File

@@ -1,7 +1,9 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -65,9 +67,6 @@ void test_ntenum()
create();
testOk1(ntEnum.get() != 0);
testOk1(NTEnum::is_a(ntEnum->getPVStructure()));
testOk1(NTEnum::isCompatible(ntEnum->getPVStructure()));
testOk1(ntEnum->getPVStructure().get() != 0);
testOk1(ntEnum->getValue().get() != 0);
testOk1(ntEnum->getDescriptor().get() != 0);
@@ -84,7 +83,7 @@ void test_ntenum()
choices[1] = "On";
pvValue->getSubField<PVStringArray>("choices")->replace(freeze(choices));
pvValue->getSubField<PVInt>("index")->put(1);
//
// example how to get a value
//
@@ -179,9 +178,11 @@ void test_wrap()
}
MAIN(testNTEnum) {
testPlan(32);
testPlan(30);
test_builder();
test_ntenum();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/*
* ntfieldTest.cpp

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -83,9 +84,6 @@ void test_nthistogram()
create();
testOk1(ntHistogram.get() != 0);
testOk1(NTHistogram::is_a(ntHistogram->getPVStructure()));
testOk1(NTHistogram::isCompatible(ntHistogram->getPVStructure()));
testOk1(ntHistogram->getPVStructure().get() != 0);
testOk1(ntHistogram->getDescriptor().get() != 0);
testOk1(ntHistogram->getAlarm().get() != 0);
@@ -252,10 +250,12 @@ void test_extra()
MAIN(testNTHistogram) {
testPlan(52);
testPlan(50);
test_builder();
test_nthistogram();
test_wrap();
test_extra();
return testDone();
}

View File

@@ -1,7 +1,9 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -57,7 +59,7 @@ void test_ntmatrix()
NTMatrixBuilderPtr builder = NTMatrix::createBuilder();
testOk(builder.get() != 0, "Got builder");
NTMatrixPtr ntMatrix = builder->
NTMatrixPtr ntScalarArray = builder->
//arrayValue(pvInt)->
addDim()->
addDescriptor()->
@@ -65,18 +67,15 @@ void test_ntmatrix()
addTimeStamp()->
addDisplay()->
create();
testOk1(ntMatrix.get() != 0);
testOk1(ntScalarArray.get() != 0);
testOk1(NTMatrix::is_a(ntMatrix->getPVStructure()));
testOk1(NTMatrix::isCompatible(ntMatrix->getPVStructure()));
testOk1(ntMatrix->getPVStructure().get() != 0);
testOk1(ntMatrix->getValue().get() != 0);
testOk1(ntMatrix->getDim().get() != 0);
testOk1(ntMatrix->getDescriptor().get() != 0);
testOk1(ntMatrix->getAlarm().get() != 0);
testOk1(ntMatrix->getTimeStamp().get() != 0);
testOk1(ntMatrix->getDisplay().get() != 0);
testOk1(ntScalarArray->getPVStructure().get() != 0);
testOk1(ntScalarArray->getValue().get() != 0);
testOk1(ntScalarArray->getDim().get() != 0);
testOk1(ntScalarArray->getDescriptor().get() != 0);
testOk1(ntScalarArray->getAlarm().get() != 0);
testOk1(ntScalarArray->getTimeStamp().get() != 0);
testOk1(ntScalarArray->getDisplay().get() != 0);
//
// example how to set values
@@ -86,7 +85,7 @@ void test_ntmatrix()
newValues.push_back(2.0);
newValues.push_back(8.0);
PVDoubleArrayPtr pvValueField = ntMatrix->getValue();
PVDoubleArrayPtr pvValueField = ntScalarArray->getValue();
pvValueField->replace(freeze(newValues));
//
@@ -103,7 +102,7 @@ void test_ntmatrix()
// timeStamp ops
//
PVTimeStamp pvTimeStamp;
if (ntMatrix->attachTimeStamp(pvTimeStamp))
if (ntScalarArray->attachTimeStamp(pvTimeStamp))
{
testPass("timeStamp attach");
@@ -124,7 +123,7 @@ void test_ntmatrix()
// alarm ops
//
PVAlarm pvAlarm;
if (ntMatrix->attachAlarm(pvAlarm))
if (ntScalarArray->attachAlarm(pvAlarm))
{
testPass("alarm attach");
@@ -142,7 +141,7 @@ void test_ntmatrix()
// display ops
//
PVDisplay pvDisplay;
if (ntMatrix->attachDisplay(pvDisplay))
if (ntScalarArray->attachDisplay(pvDisplay))
{
testPass("display attach");
@@ -151,6 +150,7 @@ void test_ntmatrix()
display.setLow(-15);
display.setHigh(15);
display.setDescription("This is a test scalar array");
display.setFormat("%d");
display.setUnits("A");
pvDisplay.set(display);
}
@@ -160,10 +160,10 @@ void test_ntmatrix()
//
// set descriptor
//
ntMatrix->getDescriptor()->put("This is a test NTMatrix");
ntScalarArray->getDescriptor()->put("This is a test NTMatrix");
// dump ntMatrix
std::cout << *ntMatrix->getPVStructure() << std::endl;
// dump ntScalarArray
std::cout << *ntScalarArray->getPVStructure() << std::endl;
}
@@ -201,9 +201,11 @@ void test_wrap()
}
MAIN(testNTMatrix) {
testPlan(38);
testPlan(36);
test_builder();
test_ntmatrix();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/*
* ntmutiChannelTest.cpp
@@ -53,9 +54,6 @@ static void test()
create();
testOk1(multiChannel.get() != 0);
testOk1(NTMultiChannel::is_a(multiChannel->getPVStructure()));
testOk1(NTMultiChannel::isCompatible(multiChannel->getPVStructure()));
PVStructurePtr pvStructure = multiChannel->getPVStructure();
testOk1(pvStructure.get()!=NULL);
testOk1(NTMultiChannel::is_a(pvStructure->getStructure()));
@@ -188,8 +186,9 @@ void test_wrap()
MAIN(testCreateRequest)
{
testPlan(27);
testPlan(25);
test();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -80,9 +81,6 @@ void test_ntnameValue()
create();
testOk1(ntNameValue.get() != 0);
testOk1(NTNameValue::is_a(ntNameValue->getPVStructure()));
testOk1(NTNameValue::isCompatible(ntNameValue->getPVStructure()));
testOk1(ntNameValue->getPVStructure().get() != 0);
testOk1(ntNameValue->getDescriptor().get() != 0);
testOk1(ntNameValue->getAlarm().get() != 0);
@@ -247,10 +245,12 @@ void test_extra()
MAIN(testNTNameValue) {
testPlan(50);
testPlan(48);
test_builder();
test_ntnameValue();
test_wrap();
test_extra();
return testDone();
}

View File

@@ -1,6 +1,8 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*
*/
#include <epicsUnitTest.h>
#include <testMain.h>
@@ -74,9 +76,6 @@ void test_ntndarrayAttribute()
create();
testOk1(ntNDArrayAttribute.get() != 0);
testOk1(NTNDArrayAttribute::is_a(ntNDArrayAttribute->getPVStructure()));
testOk1(NTNDArrayAttribute::isCompatible(ntNDArrayAttribute->getPVStructure()));
testOk1(ntNDArrayAttribute->getPVStructure().get() != 0);
testOk1(ntNDArrayAttribute->getName().get() != 0);
testOk1(ntNDArrayAttribute->getValue().get() != 0);
@@ -169,9 +168,11 @@ void test_wrap()
}
MAIN(testNTNDArrayAttribute) {
testPlan(39);
testPlan(37);
test_builder();
test_ntndarrayAttribute();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -21,8 +22,8 @@ void test_builder(bool extraFields)
testOk(builder.get() != 0, "Got builder");
builder->addDescriptor()->
addTimeStamp()->
addAlarm()->
addTimeStamp()->
addAlarm()->
addDisplay();
if (extraFields)
@@ -68,13 +69,13 @@ void test_all()
PVStructurePtr pvStructure = builder->
addDescriptor()->
addTimeStamp()->
addAlarm()->
addDisplay()->
addTimeStamp()->
addAlarm()->
addDisplay()->
add("extra1",fieldCreate->createScalar(pvString)) ->
add("extra2",fieldCreate->createScalarArray(pvString)) ->
createPVStructure();
testOk1(NTNDArray::is_a(pvStructure)==true);
std::cout << *pvStructure << std::endl;
testOk1(NTNDArray::isCompatible(pvStructure)==true);
}
@@ -112,7 +113,7 @@ void test_wrap()
}
MAIN(testNTNDArray) {
testPlan(60);
testPlan(59);
test_builder(true);
test_builder(false);
test_builder(false); // called twice to test caching
@@ -120,3 +121,5 @@ MAIN(testNTNDArray) {
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -83,9 +84,6 @@ void test_ntscalarArray()
create();
testOk1(ntScalarArray.get() != 0);
testOk1(NTScalarArray::is_a(ntScalarArray->getPVStructure()));
testOk1(NTScalarArray::isCompatible(ntScalarArray->getPVStructure()));
testOk1(ntScalarArray->getPVStructure().get() != 0);
testOk1(ntScalarArray->getValue().get() != 0);
testOk1(ntScalarArray->getDescriptor().get() != 0);
@@ -167,6 +165,7 @@ void test_ntscalarArray()
display.setLow(-15);
display.setHigh(15);
display.setDescription("This is a test scalar array");
display.setFormat("%d");
display.setUnits("A");
pvDisplay.set(display);
}
@@ -236,9 +235,11 @@ void test_wrap()
}
MAIN(testNTScalarArray) {
testPlan(40);
testPlan(38);
test_builder();
test_ntscalarArray();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/*
* ntscalarMultiChannelTest.cpp
@@ -53,9 +54,6 @@ static void test()
create();
testOk1(multiChannel.get() != 0);
testOk1(NTScalarMultiChannel::is_a(multiChannel->getPVStructure()));
testOk1(NTScalarMultiChannel::isCompatible(multiChannel->getPVStructure()));
PVStructurePtr pvStructure = multiChannel->getPVStructure();
testOk1(pvStructure.get()!=NULL);
testOk1(NTScalarMultiChannel::is_a(pvStructure->getStructure()));
@@ -175,8 +173,9 @@ void test_wrap()
MAIN(testCreateRequest)
{
testPlan(27);
testPlan(25);
test();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -85,9 +86,6 @@ void test_ntscalar()
create();
testOk1(ntScalar.get() != 0);
testOk1(NTScalar::is_a(ntScalar->getPVStructure()));
testOk1(NTScalar::isCompatible(ntScalar->getPVStructure()));
testOk1(ntScalar->getPVStructure().get() != 0);
testOk1(ntScalar->getValue().get() != 0);
testOk1(ntScalar->getDescriptor().get() != 0);
@@ -159,6 +157,7 @@ void test_ntscalar()
display.setLow(-15);
display.setHigh(15);
display.setDescription("This is a test scalar");
display.setFormat("%d");
display.setUnits("A");
pvDisplay.set(display);
}
@@ -227,9 +226,11 @@ void test_wrap()
}
MAIN(testNTScalar) {
testPlan(37);
testPlan(35);
test_builder();
test_ntscalar();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -118,9 +119,6 @@ void test_nttable()
create();
testOk1(ntTable.get() != 0);
testOk1(NTTable::is_a(ntTable->getPVStructure()));
testOk1(NTTable::isCompatible(ntTable->getPVStructure()));
testOk1(ntTable->getPVStructure().get() != 0);
testOk1(ntTable->getDescriptor().get() != 0);
testOk1(ntTable->getAlarm().get() != 0);
@@ -238,10 +236,12 @@ void test_wrap()
}
MAIN(testNTTable) {
testPlan(50);
testPlan(48);
test_builder();
test_labels();
test_nttable();
test_wrap();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -47,6 +48,7 @@ void test_builder()
testOk(valueField.get() != 0, "value is enum");
std::cout << *structure << std::endl;
}
void test_ntunion()
@@ -63,9 +65,6 @@ void test_ntunion()
create();
testOk1(ntUnion.get() != 0);
testOk1(NTUnion::is_a(ntUnion->getPVStructure()));
testOk1(NTUnion::isCompatible(ntUnion->getPVStructure()));
testOk1(ntUnion->getPVStructure().get() != 0);
testOk1(ntUnion->getValue().get() != 0);
testOk1(ntUnion->getDescriptor().get() != 0);
@@ -157,42 +156,12 @@ void test_wrap()
testOk(ptr.get() != 0, "wrapUnsafe OK");
}
void test_variant_union()
{
StructureConstPtr structure = NTUnion::createBuilder()->
addDescriptor()->
addAlarm()->
addTimeStamp()->
createStructure();
testOk1(structure->getField<Union>("value")->isVariant());
}
void test_regular_union()
{
UnionConstPtr u = getFieldCreate()->createFieldBuilder()->
add("x", pvDouble)->
add("i", pvInt)->
createUnion();
StructureConstPtr structure = NTUnion::createBuilder()->
value(u)->
addDescriptor()->
addAlarm()->
addTimeStamp()->
createStructure();
testOk1(!structure->getField<Union>("value")->isVariant());
testOk1(structure->getField<Union>("value") == u);
}
MAIN(testNTUnion) {
testPlan(32);
testPlan(27);
test_builder();
test_ntunion();
test_wrap();
test_variant_union();
test_regular_union();
return testDone();
}

View File

@@ -1,6 +1,7 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* This software is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <epicsUnitTest.h>
@@ -33,3 +34,5 @@ MAIN(testNTUtils) {
test_is_a();
return testDone();
}

View File

@@ -1,311 +0,0 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
#include <epicsUnitTest.h>
#include <testMain.h>
#include "../src/validator.h"
#include <pv/ntndarray.h>
#include <pv/pvIntrospect.h>
using namespace epics::nt;
using namespace epics::pvData;
static epics::pvData::FieldCreatePtr FC;
void test_is()
{
testDiag("test_is");
// Result::is<Scalar> must be valid for Scalars of any type
for(int i = pvBoolean; i <= pvString; ++i) {
ScalarType t = static_cast<ScalarType>(i);
testOk(Result(FC->createScalar(t)).is<Scalar>().valid(),
"Result(Scalar<%s>).is<Scalar>().valid()", ScalarTypeFunc::name(t));
}
// Result::is<ScalarArray> must be valid for ScalarArray of any type
for(int i = pvBoolean; i <= pvString; ++i) {
ScalarType t = static_cast<ScalarType>(i);
testOk(Result(FC->createScalarArray(t)).is<ScalarArray>().valid(),
"Result(ScalarArray<%s>).is<ScalarArray>().valid()", ScalarTypeFunc::name(t));
}
{
// Result::is<Scalar> must be invalid for non-Scalar
Result result(FC->createScalarArray(pvInt));
result.is<Scalar>();
testOk(!result.valid(), "!Result(ScalarArray<pvInt>).is<Scalar>.valid()");
testOk1(result.errors.at(0) == Result::Error("", Result::Error::IncorrectType));
}
{
// Result::is<ScalarArray> must be invalid for non-ScalarArray
Result result(FC->createScalar(pvInt));
result.is<ScalarArray>();
testOk(!result.valid(), "!Result(ScalarArray<pvInt>).is<Scalar>.valid()");
testOk1(result.errors.at(0) == Result::Error("", Result::Error::IncorrectType));
}
}
void test_is_id()
{
testDiag("test_is_id");
FieldBuilderPtr FB(FieldBuilder::begin());
{
// Both type and ID match for Structure
Result result(FB->setId("TEST_ID")->createStructure());
result.is<Structure>("TEST_ID");
testOk(result.valid(), "Result(Structure['TEST_ID']).is<Structure>('TEST_ID').valid()");
}
{
// Both type and ID match for Union
UnionConstPtr un(FB->
setId("TEST_ID")->
add("A", pvInt)->
add("B", pvString)->
createUnion()
);
Result result(un);
result.is<Union>("TEST_ID");
testOk(result.valid(), "Result(Union{A:int,B:string}['TEST_ID']).is<Union>('TEST_ID').valid()");
}
{
// Both type and ID match for Variant Union
Result result(FB-> createUnion());
result.is<Union>(Union::ANY_ID);
testOk(result.valid(), "Result(Union).is<Union>('%s').valid()", Union::ANY_ID.c_str());
}
{
// ID matches, type doesn't
Result result(FB->setId("TEST_ID")->createStructure());
result.is<Union>("TEST_ID");
testOk(!result.valid(), "!Result(Union['TEST_ID']).is<Structure>('TEST_ID').valid()");
testOk1(result.errors.at(0) == Result::Error("", Result::Error::IncorrectType));
}
{
// Type matches, ID doesn't
Result result(FB->setId("WRONG_ID")->createStructure());
result.is<Structure>("TEST_ID");
testOk(!result.valid(), "!Result(Structure['WRONG_ID']).is<Structure>('TEST_ID').valid()");
testOk1(result.errors.at(0) == Result::Error("", Result::Error::IncorrectId));
}
{
// Neither type nor ID match (ID is not even checked in this case since it doesn't exist)
Result result(FC->createScalar(pvDouble));
result.is<Structure>("SOME_ID");
testOk(!result.valid(), "!Result(Scalar).is<Structure>('SOME_ID').valid()");
testOk1(result.errors.at(0) == Result::Error("", Result::Error::IncorrectType));
}
}
void test_has()
{
testDiag("test_has");
FieldBuilderPtr FB(FieldBuilder::begin());
StructureConstPtr struc(FB->
add("A", pvInt)->
add("B", pvString)->
createStructure()
);
std::string strucRepr("Structure{A:int,B:String}");
{
// Test that struc has both A and B, both being Scalars
Result result(struc);
result
.has<Scalar>("A")
.has<Scalar>("B");
testOk(result.valid(),
"Result(%s).has<Scalar>('A').has<Scalar>('B').valid()",
strucRepr.c_str());
}
{
// Test that struc does not have a field B of type ScalarArray
Result result(struc);
result
.has<Scalar>("A")
.has<ScalarArray>("B");
testOk(!result.valid(),
"!Result(%s).has<Scalar>('A').has<ScalarArray>('B').valid()",
strucRepr.c_str());
testOk1(result.errors.at(0) == Result::Error("B", Result::Error::IncorrectType));
}
{
// Test that struc does not have a field C
Result result(struc);
result
.has<Scalar>("A")
.has<Scalar>("C");
testOk(!result.valid(),
"!Result(%s).has<Scalar>('A').has<Scalar>('C').valid()",
strucRepr.c_str());
testOk1(result.errors.at(0) == Result::Error("C", Result::Error::MissingField));
}
{
// Test that 'has' fails for non-structure-like Fields
Result result(FC->createScalar(pvByte));
result.has<Scalar>("X");
testOk(!result.valid(), "!Result(Scalar<pvByte>).has<Scalar>('X').valid()");
testOk1(result.errors.at(0) == Result::Error("", Result::Error::IncorrectType));
}
}
void test_maybe_has()
{
testDiag("test_maybe_has");
FieldBuilderPtr FB(FieldBuilder::begin());
StructureConstPtr struc(FB->
add("A", pvInt)->
add("B", pvString)->
createStructure()
);
std::string strucRepr("Structure{A:int,B:String}");
{
// Test that struc maybe has A and B, both being Scalars
Result result(struc);
result
.maybeHas<Scalar>("A")
.maybeHas<Scalar>("B");
testOk(result.valid(),
"Result(%s).maybeHas<Scalar>('A').maybeHas<Scalar>('B').valid()",
strucRepr.c_str());
}
{
// Test that if struc has a field B, it must be of type ScalarArray
Result result(struc);
result
.maybeHas<Scalar>("A")
.maybeHas<ScalarArray>("B");
testOk(!result.valid(),
"!Result(%s).maybeHas<Scalar>('A').maybeHas<ScalarArray>('B').valid()",
strucRepr.c_str());
testOk1(result.errors.at(0) == Result::Error("B", Result::Error::IncorrectType));
}
{
// Test that struc maybe has A (which it does) and B (which it doesn't)
Result result(struc);
result
.maybeHas<Scalar>("A")
.maybeHas<Scalar>("C");
testOk(result.valid(),
"Result(%s).maybeHas<Scalar>('A').maybeHas<Scalar>('C').valid()",
strucRepr.c_str());
}
{
// Test that 'maybeHas' fails for non-structure-like Fields
Result result(FC->createScalar(pvByte));
result.maybeHas<Scalar>("X");
testOk(!result.valid(), "!Result(Scalar<pvByte>).maybeHas<Scalar>('X').valid()");
testOk1(result.errors.at(0) == Result::Error("", Result::Error::IncorrectType));
}
}
Result& isStructABC(Result& result)
{
return result
.is<Structure>("ABC")
.has<Scalar>("A")
.has<ScalarArray>("B")
.maybeHas<Scalar>("C");
}
void test_has_fn()
{
testDiag("test_has_fn");
FieldBuilderPtr FB(FieldBuilder::begin());
{
StructureConstPtr inner(FB->
setId("ABC")->
add("A", pvInt)->
addArray("B", pvDouble)->
add("C", pvString)->
createStructure()
);
Result result(FB->add("inner", inner)->createStructure());
result.has<&isStructABC>("inner");
testOk(result.valid(), "Result({inner:<valid structABC>}).has<&isStructAbc>('inner').valid()");
}
{
StructureConstPtr inner(FB->
setId("ABC")->
add("A", pvInt)->
addArray("B", pvDouble)->
createStructure()
);
Result result(FB->add("inner", inner)->createStructure());
result.has<&isStructABC>("inner");
testOk(result.valid(), "Result({inner:<valid structABC w/o C>}).has<&isStructAbc>('inner').valid()");
}
{
StructureConstPtr inner(FB->
setId("XYZ")->
add("A", pvInt)->
addArray("B", pvDouble)->
createStructure()
);
Result result(FB->add("inner", inner)->createStructure());
result.has<&isStructABC>("inner");
testOk(!result.valid(), "!Result({inner:<structABC wrong id>}).has<&isStructAbc>('inner').valid()");
testOk1(result.errors.at(0) == Result::Error("inner", Result::Error::IncorrectId));
}
{
StructureConstPtr inner(FB->
setId("XYZ")->
add("A", pvInt)->
add("B", pvDouble)->
createStructure()
);
Result result(FB->add("inner", inner)->createStructure());
result.has<&isStructABC>("inner");
testOk(!result.valid(), "!Result({inner:<structABC wrong id and fields>}).has<&isStructAbc>('inner').valid()");
testOk1(result.errors.size() == 2);
}
}
MAIN(testValidator) {
testPlan(56);
FC = epics::pvData::getFieldCreate();
test_is();
test_is_id();
test_has();
test_maybe_has();
test_has_fn();
return testDone();
}