26 Commits
4.5.0 ... 4.5.2

Author SHA1 Message Date
Andrew Johnson
3f5bfd067f Update version numbers for release 2020-05-28 16:14:30 -05:00
mrkraimer
85165e6579 get ready for next epics7 release 2020-05-20 14:03:13 -04:00
Marty Kraimer
476a8f1e32 Merge pull request #56 from dirk-zimoch/CleanupWhitespace
Cleanup whitespace
2020-05-20 08:47:32 -04:00
31e883dbbc removed empty lines at end of file 2020-04-15 18:00:08 +02:00
57cbf66833 removed spaces at end of line 2020-04-15 17:58:14 +02:00
7f31332a80 replaced tabs with spaces 2020-04-15 17:54:47 +02:00
Marty Kraimer
12015309d8 Merge pull request #55 from epics-base/arrayfilterforunion
Arrayfilterforunion
2020-04-13 06:27:41 -04:00
mrkraimer
1e62844a22 testPlugin found bug: added unionArrayTest 2020-04-12 14:01:22 -04:00
mrkraimer
ad479309b0 fix bitset bug 2020-04-08 11:06:59 -04:00
mrkraimer
2f7c82757f pvArrayPlugin now supports union scalarArray 2020-04-07 12:53:01 -04:00
Marty Kraimer
634153a28d Merge pull request #54 from epics-base/issue53
Issue53
2020-02-18 05:39:58 -05:00
Heesterman, Peter J
e664037063 static analysis during the Codathon at Diamond. 2020-02-17 12:06:08 +00:00
mrkraimer
75c16bd423 pvDatabase::removeRecord and pvRecord::remove no longer call eachother directly 2020-02-12 09:13:19 -05:00
mrkraimer
083dffac3c pvDatabase::removeRecord and pvRecord::remove changes;descructors now have at most a print statement 2020-02-10 06:15:59 -05:00
mrkraimer
42ba054e5f add createdestroy example 2020-02-07 10:58:55 -05:00
mrkraimer
3173e9aeae problems with examples 2020-02-07 09:17:08 -05:00
mrkraimer
785d654129 first attempt to fix issue 53; add example 2020-02-07 08:54:18 -05:00
Ralph Lange
22ce4440b7 Fix bug preventing "whole structure" bitset(0) copy
(fixes #52)
(this should have a test added, but I am not familiar enough with the code)
2020-01-28 15:44:27 +01:00
Andrew Johnson
80baccfd9c Incr version and set development flag after release 2019-11-01 12:52:23 -05:00
Andrew Johnson
0c92f07749 Clear development flag for 4.5.1 release 2019-11-01 12:50:11 -05:00
Andrew Johnson
73a9f1f84f Release notes for 4.5.1 2019-11-01 12:48:58 -05:00
Marty Kraimer
3c3f0ab7f1 Merge pull request #51 from mrkraimer/master
addRecord is new
2019-09-13 10:00:22 -04:00
Marty Kraimer
803098922a Update .travis.yml 2019-09-13 09:04:54 -04:00
mrkraimer
c028af8b6d addRecord is new 2019-09-11 10:17:09 -04:00
Ralph Lange
d33d03189e rtd-ci: add read-the-docs integration 2019-09-06 14:19:00 +02:00
Andrew Johnson
d7bd5628d4 Update version number to 4.5.1 DEVELOPMENT 2019-08-13 11:04:36 -05:00
56 changed files with 950 additions and 303 deletions

17
.readthedocs.yml Normal file
View File

@@ -0,0 +1,17 @@
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the documentation/ directory with Sphinx
sphinx:
configuration: documentation/conf.py
# Build documentation with MkDocs
#mkdocs:
# configuration: mkdocs.yml
# Optionally build your docs in additional formats such as PDF and ePub
formats: all

View File

@@ -28,4 +28,4 @@ env:
- BRBASE=7.0 RTEMS=4.9 TEST=NO - BRBASE=7.0 RTEMS=4.9 TEST=NO
- BRBASE=3.16 - BRBASE=3.16
- BRBASE=3.15 - BRBASE=3.15
- BRBASE=3.14

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = pvDatabaseCPP
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = PROJECT_NUMBER = 4.5.2
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a
@@ -765,7 +765,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = include INPUT = src
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -1035,7 +1035,7 @@ GENERATE_HTML = YES
# The default directory is: html. # The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES. # This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = documentation/html HTML_OUTPUT = html/doxygen
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp). # generated HTML page (for example: .htm, .php, .asp).

View File

@@ -1,3 +1,12 @@
# Version number for the PV Database API and shared library
EPICS_PVDATABASE_MAJOR_VERSION = 4 EPICS_PVDATABASE_MAJOR_VERSION = 4
EPICS_PVDATABASE_MINOR_VERSION = 5 EPICS_PVDATABASE_MINOR_VERSION = 5
EPICS_PVDATABASE_MAINTENANCE_VERSION = 0 EPICS_PVDATABASE_MAINTENANCE_VERSION = 2
# Development flag, set to zero for release versions
EPICS_PVDATABASE_DEVELOPMENT_FLAG = 0
# Immediately after a release the MAINTENANCE_VERSION
# will be incremented and the DEVELOPMENT_FLAG set to 1

View File

@@ -2,10 +2,21 @@
This document summarizes the changes to the module between releases. This document summarizes the changes to the module between releases.
## Release 4.5.2 (EPICS 7.0.3.2 May 2020)
* plugin support is new
* fixed issues #53 and #52
## Release 4.5.1 (EPICS 7.0.3.1, Nov 2019)
* addRecord is new.
* Doxygen updates and read-the-docs integration.
## Release 4.5.0 (EPICS 7.0.3, Jul 2019) ## Release 4.5.0 (EPICS 7.0.3, Jul 2019)
1) support is a new feature. * support is a new feature.
2) processRecord is new * processRecord is new.
## Release 4.4.2 (EPICS 7.0.2.2, Apr 2019) ## Release 4.4.2 (EPICS 7.0.2.2, Apr 2019)

View File

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

80
documentation/conf.py Normal file
View File

@@ -0,0 +1,80 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'normativeTypes (C++)'
copyright = '2019, EPICS Controls.'
author = 'EPICS'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.intersphinx',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# Intersphinx links to subprojects
intersphinx_mapping = {
}
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = [
'css/custom.css',
]
master_doc = 'index'
html_theme_options = {
'logo_only': True,
}
html_logo = "images/EPICS_white_logo_v02.png"
html_extra_path = [
'../html',
'pvDatabaseCPP.html',
]
# -- Run Doxygen ------------------------------------------------------------
import subprocess
subprocess.call('cd ..; mkdir -p html/doxygen; doxygen', shell=True)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

17
documentation/index.rst Normal file
View File

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

View File

@@ -37,7 +37,7 @@
<div class="head"> <div class="head">
<h1>pvDatabaseCPP</h1> <h1>pvDatabaseCPP</h1>
<h2 class="nocount">Release ? - TBD</h2> <h2 class="nocount">Release ? - TBD</h2>
Latest update 2019.06.19. Latest update 2019.09.11.
<h2 class="nocount">Abstract</h2> <h2 class="nocount">Abstract</h2>
@@ -135,6 +135,10 @@ href="./html/index.html">doxgen</a>
<dd> <dd>
This is a PVRecord that periodical processes a set of PVRecords in the local PVDatabase. This is a PVRecord that periodical processes a set of PVRecords in the local PVDatabase.
</dd> </dd>
<dt>addRecord.h</dt>
<dd>
This is a PVRecord that adds a new PVRecord to the local PVDatabase.
</dd>
<dt>removeRecord.h</dt> <dt>removeRecord.h</dt>
<dd> <dd>
This is a PVRecord that removes a PVRecord in the local PVDatabase. This is a PVRecord that removes a PVRecord in the local PVDatabase.
@@ -174,7 +178,7 @@ href="./html/index.html">doxgen</a>
<p>This has the pvSupport code.</p> <p>This has the pvSupport code.</p>
<h3>src/special</h3> <h3>src/special</h3>
<p> <p>
This has the code for processRecord, removeRecord, and traceRecord. This has the code for processRecord, addRecord, removeRecord, and traceRecord.
</p> </p>
<h3>src/copy</h3> <h3>src/copy</h3>
<p>This has the code for pvStructureCopy and all the plugin support. <p>This has the code for pvStructureCopy and all the plugin support.

25
example/createdestroy/Makefile Executable file
View File

@@ -0,0 +1,25 @@
TOP=../..
include $(TOP)/configure/CONFIG
#----------------------------------------
# ADD MACRO DEFINITIONS AFTER THIS LINE
#=============================
#=============================
# Build the application
TESTPROD_HOST = createdestroy
createdestroy_SRCS += createdestroy.cpp
# Add all the support libraries needed by this application
#pvatest_LIBS += xxx
# Finally link to the EPICS Base libraries
createdestroy_LIBS += pvDatabase pvAccess pvData
createdestroy_LIBS += $(EPICS_BASE_IOC_LIBS)
#===========================
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@@ -0,0 +1,20 @@
# pvDatabaseCPP/example/createdestroy
This is an example that:
1) Gets the master PVDatabase
2) Create ChannelProviderLocal
3) Creates a ServerContext
Then it executes a forever loop that:
1) creates a pvRecord and adds it to the pvDatabase.
2) creates a pvac::ClientProvider
3) creates a pvac::ClientChannel
4) creates a monitor on the channel
5) runs a loop 10 times that: does a put to the channel, and then gets the data for any outstanding monitors
6) removes the pvRecord from the pvDatabase
It also has options to set trace level for the pvRecord and to periodically pause by asking for input.

View File

@@ -0,0 +1,179 @@
/******************************************************************************
* This is modeled after a test program created by Bertrand Bauvir from the ITER Organization
******************************************************************************/
#include <iostream>
#include <epicsGetopt.h>
#include <pv/pvData.h>
#include <pv/pvDatabase.h>
#include <pv/serverContext.h>
#include <pv/channelProviderLocal.h>
#include <pva/client.h>
#include <epicsEvent.h>
// Local header files
// Constants
#define DEFAULT_RECORD_NAME "examplechannel"
using std::tr1::static_pointer_cast;
class Record : public ::epics::pvDatabase::PVRecord
{
public:
std::shared_ptr<::epics::pvData::PVStructure> __pv;
static std::shared_ptr<Record> create (std::string const & name, std::shared_ptr<::epics::pvData::PVStructure> const & pvstruct);
Record (std::string const & name, std::shared_ptr<epics::pvData::PVStructure> const & pvstruct)
: epics::pvDatabase::PVRecord(name, pvstruct) { __pv = pvstruct; };
virtual void process (void);
};
std::shared_ptr<Record> Record::create (std::string const & name, std::shared_ptr<::epics::pvData::PVStructure> const & pvstruct)
{
std::shared_ptr<Record> pvrecord (new Record (name, pvstruct));
// Need to be explicitly called .. not part of the base constructor
if(!pvrecord->init()) pvrecord.reset();
return pvrecord;
}
void Record::process (void)
{
PVRecord::process();
std::string name = this->getRecordName();
std::cout << this->getRecordName()
<< " process\n";
}
class MyMonitor
{
private:
std::tr1::shared_ptr<::pvac::MonitorSync> monitor;
MyMonitor(std::tr1::shared_ptr<::pvac::ClientChannel> const &channel)
{
monitor = std::tr1::shared_ptr<::pvac::MonitorSync>(new ::pvac::MonitorSync(channel->monitor()));
}
public:
static std::tr1::shared_ptr<MyMonitor> create(std::tr1::shared_ptr<::pvac::ClientChannel> const &channel)
{
return std::tr1::shared_ptr<MyMonitor>(new MyMonitor(channel));
}
void getData();
};
void MyMonitor::getData()
{
while (true) {
if(!monitor->wait(.001)) break;
switch(monitor->event.event) {
case pvac::MonitorEvent::Fail:
std::cerr<<monitor->name()<<" : Error : "<<monitor->event.message<<"\n";
return;
case pvac::MonitorEvent::Cancel:
std::cout<<monitor->name()<<" <Cancel>\n";
return;
case pvac::MonitorEvent::Disconnect:
std::cout<<monitor->name()<<" <Disconnect>\n";
return;
case pvac::MonitorEvent::Data:
while(monitor->poll()) {
std::cout<<monitor->name()<<" : "<<monitor->root;
}
if(monitor->complete()) {
return;
}
}
}
}
int main (int argc, char** argv)
{
int verbose = 0;
unsigned loopctr = 0;
unsigned pausectr = 0;
bool allowExit = false;
bool callRecord = false;
bool callDatabase = false;
int opt;
while((opt = getopt(argc, argv, "v:ardh")) != -1) {
switch(opt) {
case 'v':
verbose = std::stoi(optarg);
break;
case 'a' :
allowExit = true;
break;
case 'r' :
callRecord = true;
break;
case 'd' :
callDatabase = true;
break;
case 'h':
std::cout << " -v level -a -r -d -h \n";
std::cout << "-r call pvRecord->remove -d call master->removeRecord\n";
std::cout << "default\n";
std::cout << "-v " << verbose
<< " -a false"
<< " -d"
<< "\n";
return 0;
default:
std::cerr<<"Unknown argument: "<<opt<<"\n";
return -1;
}
}
if(!callRecord && !callDatabase) callDatabase = true;
::epics::pvDatabase::PVDatabasePtr master = epics::pvDatabase::PVDatabase::getMaster();
::epics::pvDatabase::ChannelProviderLocalPtr channelProvider = epics::pvDatabase::getChannelProviderLocal();
epics::pvAccess::ServerContext::shared_pointer context
= epics::pvAccess::startPVAServer(epics::pvAccess::PVACCESS_ALL_PROVIDERS, 0, true, true);
std::string startset("starting set of puts valuectr = ");
while (true) {
loopctr++;
std::string name = DEFAULT_RECORD_NAME + std::to_string(loopctr);
// Create record
// Create record structure
::epics::pvData::FieldBuilderPtr builder = epics::pvData::getFieldCreate()->createFieldBuilder();
builder->add("value", ::epics::pvData::pvULong);
std::shared_ptr<::epics::pvData::PVStructure> pvstruct
= ::epics::pvData::getPVDataCreate()->createPVStructure(builder->createStructure());
std::shared_ptr<Record> pvrecord = Record::create(std::string(name), pvstruct);
master->addRecord(pvrecord);
pvrecord->setTraceLevel(verbose);
// Start PVA (local) client
std::tr1::shared_ptr<::pvac::ClientProvider> provider
= std::tr1::shared_ptr<::pvac::ClientProvider>(new ::pvac::ClientProvider ("pva"));
std::tr1::shared_ptr<::pvac::ClientChannel> channel
= std::tr1::shared_ptr<::pvac::ClientChannel>(new ::pvac::ClientChannel (provider->connect(name)));
std::tr1::shared_ptr<MyMonitor> mymonitor = MyMonitor::create(channel);
unsigned valuectr = loopctr;
std::cout << startset << loopctr << "\n";
for (int ind=0; ind<100; ind++) {
channel->put().set("value",valuectr++).exec();
mymonitor->getData();
}
pausectr++;
if(allowExit && pausectr>10) {
pausectr = 0;
std::cout << "Type exit to stop: \n";
int c = std::cin.peek(); // peek character
if ( c == EOF ) continue;
std::string str;
std::getline(std::cin,str);
if(str.compare("exit")==0) break;
}
if(callRecord) {
std::cout << "callRecord\n";
pvrecord->remove();
}
if(callDatabase) {
std::cout << "callDatabase\n";
master->removeRecord(pvrecord);
}
}
return (0);
}

View File

@@ -25,6 +25,7 @@ INC += pv/channelProviderLocal.h
INC += pv/traceRecord.h INC += pv/traceRecord.h
INC += pv/removeRecord.h INC += pv/removeRecord.h
INC += pv/addRecord.h
INC += pv/processRecord.h INC += pv/processRecord.h
INC += pv/pvSupport.h INC += pv/pvSupport.h

View File

@@ -76,9 +76,19 @@ static vector<string> split(string const & colonSeparatedList) {
PVArrayFilterPtr PVArrayFilter::create( PVArrayFilterPtr PVArrayFilter::create(
const std::string & requestValue, const std::string & requestValue,
const PVFieldPtr & master) const PVFieldPtr & masterField)
{ {
Type type = master->getField()->getType(); bool masterIsUnion = false;
PVUnionPtr pvUnion;
Type type = masterField->getField()->getType();
if(type==epics::pvData::union_) {
pvUnion = std::tr1::static_pointer_cast<PVUnion>(masterField);
PVFieldPtr pvField = pvUnion->get();
if(pvField) {
masterIsUnion = true;
type = pvField->getField()->getType();
}
}
if(type!=scalarArray) { if(type!=scalarArray) {
PVArrayFilterPtr filter = PVArrayFilterPtr(); PVArrayFilterPtr filter = PVArrayFilterPtr();
return filter; return filter;
@@ -112,60 +122,82 @@ PVArrayFilterPtr PVArrayFilter::create(
PVArrayFilterPtr filter = PVArrayFilterPtr(); PVArrayFilterPtr filter = PVArrayFilterPtr();
return filter; return filter;
} }
PVScalarArrayPtr masterArray;
if(masterIsUnion) {
masterArray = static_pointer_cast<PVScalarArray>(pvUnion->get());
} else {
masterArray = static_pointer_cast<PVScalarArray>(masterField);
}
PVArrayFilterPtr filter = PVArrayFilterPtr filter =
PVArrayFilterPtr( PVArrayFilterPtr(
new PVArrayFilter( new PVArrayFilter(start,increment,end,masterField,masterArray));
start,increment,end,static_pointer_cast<PVScalarArray>(master)));
return filter; return filter;
} }
PVArrayFilter::PVArrayFilter(long start,long increment,long end,const PVScalarArrayPtr & masterArray) PVArrayFilter::PVArrayFilter(
long start,long increment,long end,
const PVFieldPtr & masterField,
const epics::pvData::PVScalarArrayPtr masterArray)
: start(start), : start(start),
increment(increment), increment(increment),
end(end), end(end),
masterField(masterField),
masterArray(masterArray) masterArray(masterArray)
{ {
} }
bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bool toCopy) bool PVArrayFilter::filter(const PVFieldPtr & pvField,const BitSetPtr & bitSet,bool toCopy)
{ {
PVScalarArrayPtr copyArray = static_pointer_cast<PVScalarArray>(pvCopy); PVFieldPtr pvCopy = pvField;
PVScalarArrayPtr copyArray;
bool isUnion = false;
Type type = masterField->getField()->getType();
if(type==epics::pvData::union_) {
isUnion = true;
PVUnionPtr pvMasterUnion = std::tr1::static_pointer_cast<PVUnion>(masterField);
PVUnionPtr pvCopyUnion = std::tr1::static_pointer_cast<PVUnion>(pvCopy);
if(toCopy) pvCopyUnion->copy(*pvMasterUnion);
PVFieldPtr pvField = pvCopyUnion->get();
copyArray = static_pointer_cast<PVScalarArray>(pvField);
} else {
copyArray = static_pointer_cast<PVScalarArray>(pvCopy);
}
long len = 0; long len = 0;
long start = this->start; long start = this->start;
long end = this->end; long end = this->end;
long no_elements = masterArray->getLength(); long no_elements = masterArray->getLength();
if(start<0) { if(start<0) {
start = no_elements+start; start = no_elements+start;
if(start<0) start = 0; if(start<0) start = 0;
} }
if (end < 0) { if (end < 0) {
end = no_elements + end; end = no_elements + end;
if (end < 0) end = 0; if (end < 0) end = 0;
} }
if(toCopy) { if(toCopy) {
if (end >= no_elements) end = no_elements - 1; if (end >= no_elements) end = no_elements - 1;
if (end - start >= 0) len = 1 + (end - start) / increment; if (end - start >= 0) len = 1 + (end - start) / increment;
if(len<=0 || start>=no_elements) { if(len<=0 || start>=no_elements) {
copyArray->setLength(0); copyArray->setLength(0);
return true; return true;
} }
long indfrom = start; long indfrom = start;
long indto = 0; long indto = 0;
copyArray->setCapacity(len); copyArray->setCapacity(len);
if(increment==1) { if(increment==1) {
copy(*masterArray,indfrom,1,*copyArray,indto,1,len); copy(*masterArray,indfrom,1,*copyArray,indto,1,len);
} else { } else {
for(long i=0; i<len; ++i) { for(long i=0; i<len; ++i) {
copy(*masterArray,indfrom,1,*copyArray,indto,1,1); copy(*masterArray,indfrom,1,*copyArray,indto,1,1);
indfrom += increment; indfrom += increment;
indto += 1; indto += 1;
} }
} }
copyArray->setLength(len); copyArray->setLength(len);
bitSet->set(pvCopy->getFieldOffset()); bitSet->set(pvField->getFieldOffset());
return true; return true;
} }
if (end - start >= 0) len = 1 + (end - start) / increment; if (end - start >= 0) len = 1 + (end - start) / increment;
if(len<=0) return true; if(len<=0) return true;
@@ -173,21 +205,21 @@ bool PVArrayFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bo
long indfrom = 0; long indfrom = 0;
long indto = start; long indto = start;
if(increment==1) { if(increment==1) {
copy(*copyArray,indfrom,1,*masterArray,indto,1,len); copy(*copyArray,indfrom,1,*masterArray,indto,1,len);
} else { } else {
for(long i=0; i<len; ++i) { for(long i=0; i<len; ++i) {
copy(*copyArray,indfrom,1,*masterArray,indto,1,1); copy(*copyArray,indfrom,1,*masterArray,indto,1,1);
indfrom += 1; indfrom += 1;
indto += increment; indto += increment;
} }
} }
if(isUnion) masterField->postPut();
return true; return true;
} }
string PVArrayFilter::getName() string PVArrayFilter::getName()
{ {
return name; return name;
} }
}} }}

View File

@@ -29,7 +29,7 @@ using std::endl;
using std::vector; using std::vector;
using namespace epics::pvData; using namespace epics::pvData;
namespace epics { namespace pvCopy { namespace epics { namespace pvCopy {
/** /**
* Convenience method for implementing dump. * Convenience method for implementing dump.
@@ -60,19 +60,19 @@ struct CopyNode {
PVStructurePtr options; PVStructurePtr options;
vector<PVFilterPtr> pvFilters; vector<PVFilterPtr> pvFilters;
}; };
static CopyNodePtr NULLCopyNode; static CopyNodePtr NULLCopyNode;
typedef std::vector<CopyNodePtr> CopyNodePtrArray; typedef std::vector<CopyNodePtr> CopyNodePtrArray;
typedef std::tr1::shared_ptr<CopyNodePtrArray> CopyNodePtrArrayPtr; typedef std::tr1::shared_ptr<CopyNodePtrArray> CopyNodePtrArrayPtr;
struct CopyStructureNode : public CopyNode { struct CopyStructureNode : public CopyNode {
CopyNodePtrArrayPtr nodes; CopyNodePtrArrayPtr nodes;
}; };
PVCopyPtr PVCopy::create( PVCopyPtr PVCopy::create(
PVStructurePtr const &pvMaster, PVStructurePtr const &pvMaster,
PVStructurePtr const &pvRequest, PVStructurePtr const &pvRequest,
string const & structureName) string const & structureName)
{ {
PVStructurePtr pvStructure(pvRequest); PVStructurePtr pvStructure(pvRequest);
@@ -114,7 +114,7 @@ PVStructurePtr PVCopy::createPVStructure()
cacheInitStructure.reset(); cacheInitStructure.reset();
return save; return save;
} }
PVStructurePtr pvStructure = PVStructurePtr pvStructure =
getPVDataCreate()->createPVStructure(structure); getPVDataCreate()->createPVStructure(structure);
return pvStructure; return pvStructure;
} }
@@ -244,7 +244,7 @@ void PVCopy::updateMasterCheckBitSet(
bitSet->clear(nextSet); bitSet->clear(nextSet);
PVStructurePtr pv = static_pointer_cast<PVStructure>(pvField); PVStructurePtr pv = static_pointer_cast<PVStructure>(pvField);
PVFieldPtrArray pvFieldArray = pv->getPVFields(); PVFieldPtrArray pvFieldArray = pv->getPVFields();
for(size_t i=0; i>pvFieldArray.size(); ++i) { for(size_t i=0; i<pvFieldArray.size(); ++i) {
PVFieldPtr pvField = pvFieldArray[i]; PVFieldPtr pvField = pvFieldArray[i];
bitSet->set(pvField->getFieldOffset()); bitSet->set(pvField->getFieldOffset());
} }
@@ -296,7 +296,7 @@ void PVCopy::updateMaster(
bitSet->clear(nextSet); bitSet->clear(nextSet);
} }
} }
PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset) PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
{ {
if(fieldOffset==0) return headNode->options; if(fieldOffset==0) return headNode->options;
@@ -414,7 +414,7 @@ void PVCopy::updateCopyFromBitSet(
size_t offset = structureNode->structureOffset; size_t offset = structureNode->structureOffset;
size_t nextSet = bitSet->nextSetBit(offset); size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==string::npos) return; if(nextSet==string::npos) return;
if(offset>=pvCopy->getNextFieldOffset()) return; if(offset>=pvCopy->getNextFieldOffset()) return;
PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy); PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields(); PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
for(size_t i=0; i<pvCopyFields.size(); ++i) { for(size_t i=0; i<pvCopyFields.size(); ++i) {
@@ -529,9 +529,9 @@ CopyNodePtr PVCopy::createStructureNodes(
for(size_t i=0; i<number; i++) { for(size_t i=0; i<number; i++) {
PVFieldPtr copyPVField = copyPVFields[i]; PVFieldPtr copyPVField = copyPVFields[i];
string fieldName = copyPVField->getFieldName(); string fieldName = copyPVField->getFieldName();
PVStructurePtr requestPVStructure = PVStructurePtr requestPVStructure =
pvFromRequest->getSubField<PVStructure>(fieldName); pvFromRequest->getSubField<PVStructure>(fieldName);
PVStructurePtr pvSubFieldOptions = PVStructurePtr pvSubFieldOptions =
requestPVStructure->getSubField<PVStructure>("_options"); requestPVStructure->getSubField<PVStructure>("_options");
PVFieldPtr pvMasterField = pvMasterStructure->getSubField(fieldName); PVFieldPtr pvMasterField = pvMasterStructure->getSubField(fieldName);
if(!pvMasterField) { if(!pvMasterField) {
@@ -641,14 +641,14 @@ void PVCopy::initPlugin(
void PVCopy::traverseMasterInitPlugin() void PVCopy::traverseMasterInitPlugin()
{ {
traverseMasterInitPlugin(headNode); traverseMasterInitPlugin(headNode);
} }
void PVCopy::traverseMasterInitPlugin(CopyNodePtr const & node) void PVCopy::traverseMasterInitPlugin(CopyNodePtr const & node)
{ {
PVFieldPtr pvField = node->masterPVField; PVFieldPtr pvField = node->masterPVField;
PVStructurePtr pvOptions = node->options; PVStructurePtr pvOptions = node->options;
if(pvOptions) initPlugin(node,pvOptions,pvField); if(pvOptions) initPlugin(node,pvOptions,pvField);
if(!node->isStructure) return; if(!node->isStructure) return;
CopyStructureNodePtr structureNode = static_pointer_cast<CopyStructureNode>(node); CopyStructureNodePtr structureNode = static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structureNode->nodes; CopyNodePtrArrayPtr nodes = structureNode->nodes;
@@ -667,7 +667,7 @@ CopyNodePtr PVCopy::getCopyOffset(
CopyNodePtr node = (*nodes)[i]; CopyNodePtr node = (*nodes)[i];
if(!node->isStructure) { if(!node->isStructure) {
size_t off = node->masterPVField->getFieldOffset(); size_t off = node->masterPVField->getFieldOffset();
size_t nextOffset = node->masterPVField->getNextFieldOffset(); size_t nextOffset = node->masterPVField->getNextFieldOffset();
if(offset>= off && offset<nextOffset) return node; if(offset>= off && offset<nextOffset) return node;
} else { } else {
CopyStructureNodePtr subNode = CopyStructureNodePtr subNode =
@@ -710,7 +710,7 @@ void PVCopy::setIgnore(CopyNodePtr const &node) {
CopyNodePtrArrayPtr nodes = structureNode->nodes; CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); ++i) { for(size_t i=0; i<nodes->size(); ++i) {
CopyNodePtr node = (*nodes)[i]; CopyNodePtr node = (*nodes)[i];
setIgnore(node); } setIgnore(node); }
} else { } else {
size_t num = node->masterPVField->getNumberFields(); size_t num = node->masterPVField->getNumberFields();
if(num>1) { if(num>1) {

View File

@@ -82,7 +82,7 @@ PVDeadbandFilterPtr PVDeadbandFilter::create(
PVDeadbandFilterPtr filter = PVDeadbandFilterPtr filter =
PVDeadbandFilterPtr( PVDeadbandFilterPtr(
new PVDeadbandFilter( new PVDeadbandFilter(
absolute,deadband,static_pointer_cast<PVScalar>(master))); absolute,deadband,static_pointer_cast<PVScalar>(master)));
return filter; return filter;
} }
@@ -91,7 +91,7 @@ PVDeadbandFilter::PVDeadbandFilter(bool absolute,double deadband,PVScalarPtr con
deadband(deadband), deadband(deadband),
master(master), master(master),
firstTime(true), firstTime(true),
lastReportedValue(0.0) lastReportedValue(0.0)
{ {
} }
@@ -128,8 +128,7 @@ bool PVDeadbandFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet
string PVDeadbandFilter::getName() string PVDeadbandFilter::getName()
{ {
return name; return name;
} }
}} }}

View File

@@ -14,7 +14,7 @@
using namespace epics::pvData; using namespace epics::pvData;
namespace epics { namespace pvCopy{ namespace epics { namespace pvCopy{
typedef std::map<std::string,PVPluginPtr> PVPluginMap; typedef std::map<std::string,PVPluginPtr> PVPluginMap;
@@ -38,4 +38,3 @@ PVPluginPtr PVPluginRegistry::find(const std::string & name)
} }
}} }}

View File

@@ -89,7 +89,7 @@ PVTimestampFilter::PVTimestampFilter(bool current,bool copy,PVFieldPtr const & m
bool PVTimestampFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bool toCopy) bool PVTimestampFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSet,bool toCopy)
{ {
if(current) { if(current) {
timeStamp.getCurrent(); timeStamp.getCurrent();
if(toCopy) { if(toCopy) {
if(!pvTimeStamp.attach(pvCopy)) return false; if(!pvTimeStamp.attach(pvCopy)) return false;
@@ -100,7 +100,7 @@ bool PVTimestampFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSe
bitSet->set(pvCopy->getFieldOffset()); bitSet->set(pvCopy->getFieldOffset());
return true; return true;
} }
if(copy) { if(copy) {
if(toCopy) { if(toCopy) {
if(!pvTimeStamp.attach(master)) return false; if(!pvTimeStamp.attach(master)) return false;
pvTimeStamp.get(timeStamp); pvTimeStamp.get(timeStamp);
@@ -120,8 +120,7 @@ bool PVTimestampFilter::filter(const PVFieldPtr & pvCopy,const BitSetPtr & bitSe
string PVTimestampFilter::getName() string PVTimestampFilter::getName()
{ {
return name; return name;
} }
}} }}

View File

@@ -44,7 +44,7 @@ PVDatabasePtr PVDatabase::getMaster()
PVArrayPlugin::create(); PVArrayPlugin::create();
PVTimestampPlugin::create(); PVTimestampPlugin::create();
PVDeadbandPlugin::create(); PVDeadbandPlugin::create();
} }
return pvDatabaseMaster; return pvDatabaseMaster;
} }
@@ -56,14 +56,6 @@ PVDatabase::PVDatabase()
PVDatabase::~PVDatabase() PVDatabase::~PVDatabase()
{ {
if(DEBUG_LEVEL>0) cout << "PVDatabase::~PVDatabase()\n"; if(DEBUG_LEVEL>0) cout << "PVDatabase::~PVDatabase()\n";
size_t len = recordMap.size();
shared_vector<string> names(len);
PVRecordMap::iterator iter;
size_t i = 0;
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
names[i++] = (*iter).first;
}
for(size_t i=0; i<len; ++i) removeRecord(findRecord(names[i]));
} }
void PVDatabase::lock() { void PVDatabase::lock() {
@@ -100,17 +92,28 @@ bool PVDatabase::addRecord(PVRecordPtr const & record)
return true; return true;
} }
bool PVDatabase::removeRecord(PVRecordPtr const & record) PVRecordWPtr PVDatabase::removeFromMap(PVRecordPtr const & record)
{ {
if(record->getTraceLevel()>0) {
cout << "PVDatabase::removeRecord " << record->getRecordName() << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex); epicsGuard<epics::pvData::Mutex> guard(mutex);
string recordName = record->getRecordName(); string recordName = record->getRecordName();
PVRecordMap::iterator iter = recordMap.find(recordName); PVRecordMap::iterator iter = recordMap.find(recordName);
if(iter!=recordMap.end()) { if(iter!=recordMap.end()) {
PVRecordPtr pvRecord = (*iter).second; PVRecordPtr pvRecord = (*iter).second;
recordMap.erase(iter); recordMap.erase(iter);
return pvRecord->shared_from_this();
}
return PVRecordWPtr();
}
bool PVDatabase::removeRecord(PVRecordPtr const & record)
{
if(record->getTraceLevel()>0) {
cout << "PVDatabase::removeRecord " << record->getRecordName() << endl;
}
epicsGuard<epics::pvData::Mutex> guard(mutex);
PVRecordWPtr pvRecord = removeFromMap(record);
if(pvRecord.use_count()!=0) {
pvRecord.lock()->unlistenClients();
return true; return true;
} }
return false; return false;

View File

@@ -58,64 +58,16 @@ PVRecord::PVRecord(
{ {
} }
void PVRecord::notifyClients()
{
{
epicsGuard<epics::pvData::Mutex> guard(mutex);
if(traceLevel>0) {
cout << "PVRecord::notifyClients() " << recordName
<< endl;
}
}
pvTimeStamp.detach();
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
iter!=pvListenerList.end();
iter++ )
{
PVListenerPtr listener = iter->lock();
if(!listener) continue;
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling listener->unlisten "
<< recordName << endl;
}
listener->unlisten(shared_from_this());
}
pvListenerList.clear();
for (std::list<PVRecordClientWPtr>::iterator iter = clientList.begin();
iter!=clientList.end();
iter++ )
{
PVRecordClientPtr client = iter->lock();
if(!client) continue;
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling client->detach "
<< recordName << endl;
}
client->detach(shared_from_this());
}
if(traceLevel>0) {
cout << "PVRecord::notifyClients() calling clientList.clear() "
<< recordName << endl;
}
clientList.clear();
if(traceLevel>0) {
cout << "PVRecord::notifyClients() returning " << recordName << endl;
}
}
PVRecord::~PVRecord() PVRecord::~PVRecord()
{ {
if(traceLevel>0) { if(traceLevel>0) {
cout << "~PVRecord() " << recordName << endl; cout << "~PVRecord() " << recordName << endl;
} }
notifyClients();
} }
void PVRecord::remove() void PVRecord::unlistenClients()
{ {
PVDatabasePtr pvDatabase(PVDatabase::getMaster()); epicsGuard<epics::pvData::Mutex> guard(mutex);
if(pvDatabase) pvDatabase->removeRecord(shared_from_this());
pvTimeStamp.detach();
for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin(); for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
iter!=pvListenerList.end(); iter!=pvListenerList.end();
iter++ ) iter++ )
@@ -142,6 +94,19 @@ void PVRecord::remove()
clientList.clear(); clientList.clear();
} }
void PVRecord::remove()
{
if(traceLevel>0) {
cout << "PVRecord::remove() " << recordName << endl;
}
unlistenClients();
epicsGuard<epics::pvData::Mutex> guard(mutex);
PVDatabasePtr pvDatabase(PVDatabase::getMaster());
if(pvDatabase) pvDatabase->removeFromMap(shared_from_this());
pvTimeStamp.detach();
}
void PVRecord::initPVRecord() void PVRecord::initPVRecord()
{ {
PVRecordStructurePtr parent; PVRecordStructurePtr parent;
@@ -283,7 +248,7 @@ void PVRecord::nextMasterPVField(PVFieldPtr const & pvField)
PVRecordFieldPtr pvRecordField = findPVRecordField(pvField); PVRecordFieldPtr pvRecordField = findPVRecordField(pvField);
PVListenerPtr listener = pvListener.lock(); PVListenerPtr listener = pvListener.lock();
if(!listener.get()) return; if(!listener.get()) return;
if(isAddListener) { if(isAddListener) {
pvRecordField->addListener(listener); pvRecordField->addListener(listener);
} else { } else {
pvRecordField->removeListener(listener); pvRecordField->removeListener(listener);
@@ -412,7 +377,7 @@ bool PVRecordField::addListener(PVListenerPtr const & pvListener)
void PVRecordField::removeListener(PVListenerPtr const & pvListener) void PVRecordField::removeListener(PVListenerPtr const & pvListener)
{ {
PVRecordPtr pvRecord(this->pvRecord.lock()); PVRecordPtr pvRecord(this->pvRecord.lock());
if(pvRecord && pvRecord->getTraceLevel()>1) { if(pvRecord && pvRecord->getTraceLevel()>1) {
cout << "PVRecordField::removeListener() " << getFullName() << endl; cout << "PVRecordField::removeListener() " << getFullName() << endl;
} }
@@ -454,7 +419,7 @@ void PVRecordField::postSubField()
{ {
callListener(); callListener();
if(isStructure) { if(isStructure) {
PVRecordStructurePtr pvrs = PVRecordStructurePtr pvrs =
static_pointer_cast<PVRecordStructure>(shared_from_this()); static_pointer_cast<PVRecordStructure>(shared_from_this());
PVRecordFieldPtrArrayPtr pvRecordFields = pvrs->getPVRecordFields(); PVRecordFieldPtrArrayPtr pvRecordFields = pvrs->getPVRecordFields();
PVRecordFieldPtrArray::iterator iter; PVRecordFieldPtrArray::iterator iter;
@@ -494,7 +459,7 @@ void PVRecordStructure::init()
PVRecordStructurePtr self = PVRecordStructurePtr self =
static_pointer_cast<PVRecordStructure>(shared_from_this()); static_pointer_cast<PVRecordStructure>(shared_from_this());
PVRecordPtr pvRecord = getPVRecord(); PVRecordPtr pvRecord = getPVRecord();
for(size_t i=0; i<numFields; i++) { for(size_t i=0; i<numFields; i++) {
PVFieldPtr pvField = pvFields[i]; PVFieldPtr pvField = pvFields[i];
if(pvField->getField()->getType()==structure) { if(pvField->getField()->getType()==structure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField); PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);

63
src/pv/addRecord.h Normal file
View File

@@ -0,0 +1,63 @@
/* addRecord.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#ifndef ADDRECORD_H
#define ADDRECORD_H
#include <pv/channelProviderLocal.h>
#include <shareLib.h>
namespace epics { namespace pvDatabase {
class AddRecord;
typedef std::tr1::shared_ptr<AddRecord> AddRecordPtr;
/**
* @brief Add another record in the same database.
*
* A record to add another record
* It is meant to be used via a channelPutGet request.
* The argument has one field: recordName.
* The result has a field named status.
*/
class epicsShareClass AddRecord :
public PVRecord
{
public:
POINTER_DEFINITIONS(AddRecord);
/**
* Factory methods to create AddRecord.
* @param recordName The name for the AddRecord.
* @return A shared pointer to AddRecord..
*/
static AddRecordPtr create(
std::string const & recordName);
/**
* standard init method required by PVRecord
* @return true unless record name already exists.
*/
virtual bool init();
/**
* @brief Add the record specified by recordName.
*/
virtual void process();
private:
AddRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure);
epics::pvData::PVStringPtr pvRecordName;
epics::pvData::PVStringPtr pvResult;
};
}}
#endif /* ADDRECORD_H */

View File

@@ -28,7 +28,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class ChannelProviderLocal; class ChannelProviderLocal;
typedef std::tr1::shared_ptr<ChannelProviderLocal> ChannelProviderLocalPtr; typedef std::tr1::shared_ptr<ChannelProviderLocal> ChannelProviderLocalPtr;
@@ -93,7 +93,7 @@ public:
virtual epics::pvAccess::ChannelFind::shared_pointer channelFind( virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(
std::string const &channelName, std::string const &channelName,
epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester); epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
/** /**
* @brief Calls method channelListRequester::channelListResult. * @brief Calls method channelListRequester::channelListResult.
* *
* This provides the caller with a list of the record names on the PVDatabase. * This provides the caller with a list of the record names on the PVDatabase.
@@ -101,7 +101,7 @@ public:
* @param channelListRequester The client callback. * @param channelListRequester The client callback.
* @return shared pointer to ChannelFind. * @return shared pointer to ChannelFind.
* The interface for SyncChannelFind is defined by pvAccessCPP. * The interface for SyncChannelFind is defined by pvAccessCPP.
*/ */
virtual epics::pvAccess::ChannelFind::shared_pointer channelList( virtual epics::pvAccess::ChannelFind::shared_pointer channelList(
epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester); epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester);
/** /**
@@ -186,28 +186,28 @@ public:
epics::pvAccess::ChannelRequester::shared_pointer const & requester, epics::pvAccess::ChannelRequester::shared_pointer const & requester,
PVRecordPtr const & pvRecord PVRecordPtr const & pvRecord
); );
/** /**
* @brief Destructor * @brief Destructor
*/ */
virtual ~ChannelLocal(); virtual ~ChannelLocal();
/** /**
* @brief DEPRECATED * @brief DEPRECATED
* *
*/ */
virtual void destroy() {}; virtual void destroy() {};
/** /**
* @brief Detach from the record. * @brief Detach from the record.
* *
* This is called when a record is being removed from the database. * This is called when a record is being removed from the database.
* @param pvRecord The record being removed. * @param pvRecord The record being removed.
*/ */
virtual void detach(PVRecordPtr const &pvRecord); virtual void detach(PVRecordPtr const &pvRecord);
/** /**
* @brief Get the requester name. * @brief Get the requester name.
* @return returns the name of the channel requester. * @return returns the name of the channel requester.
*/ */
virtual std::string getRequesterName(); virtual std::string getRequesterName();
/** /**
* @brief Passes the message to the channel requester. * @brief Passes the message to the channel requester.
* @param message The message. * @param message The message.
* @param messageType The message type. * @param messageType The message type.
@@ -215,37 +215,37 @@ public:
virtual void message( virtual void message(
std::string const & message, std::string const & message,
epics::pvData::MessageType messageType); epics::pvData::MessageType messageType);
/** /**
* @brief Get the channel provider * @brief Get the channel provider
* @return The provider. * @return The provider.
*/ */
virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider(); virtual epics::pvAccess::ChannelProvider::shared_pointer getProvider();
/** /**
* @brief Get the remote address * @brief Get the remote address
* @return <b>local</b> * @return <b>local</b>
*/ */
virtual std::string getRemoteAddress(); virtual std::string getRemoteAddress();
/** /**
* Get the connection state. * Get the connection state.
* @return Channel::CONNECTED. * @return Channel::CONNECTED.
*/ */
virtual epics::pvAccess::Channel::ConnectionState getConnectionState(); virtual epics::pvAccess::Channel::ConnectionState getConnectionState();
/** /**
* @brief Get the channel name. * @brief Get the channel name.
* @return the record name. * @return the record name.
*/ */
virtual std::string getChannelName(); virtual std::string getChannelName();
/** /**
* @brief Get the channel requester * @brief Get the channel requester
* @return The channel requester. * @return The channel requester.
*/ */
virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester(); virtual epics::pvAccess::ChannelRequester::shared_pointer getChannelRequester();
/** /**
* @brief Is the channel connected? * @brief Is the channel connected?
* @return true. * @return true.
*/ */
virtual bool isConnected(); virtual bool isConnected();
/** /**
* @brief Get the introspection interface for subField. * @brief Get the introspection interface for subField.
* *
* The introspection interface is given via GetFieldRequester::getDone. * The introspection interface is given via GetFieldRequester::getDone.
@@ -257,14 +257,14 @@ public:
virtual void getField( virtual void getField(
epics::pvAccess::GetFieldRequester::shared_pointer const &requester, epics::pvAccess::GetFieldRequester::shared_pointer const &requester,
std::string const & subField); std::string const & subField);
/** /**
* Get the access rights for the record. * Get the access rights for the record.
* This throws an exception because it is assumed that access rights are * This throws an exception because it is assumed that access rights are
* handled by a higher level. * handled by a higher level.
*/ */
virtual epics::pvAccess::AccessRights getAccessRights( virtual epics::pvAccess::AccessRights getAccessRights(
epics::pvData::PVField::shared_pointer const &pvField); epics::pvData::PVField::shared_pointer const &pvField);
/** /**
* @brief Create a channelProcess. * @brief Create a channelProcess.
* *
* @param requester The client callback. * @param requester The client callback.
@@ -275,9 +275,9 @@ public:
virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess( virtual epics::pvAccess::ChannelProcess::shared_pointer createChannelProcess(
epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester, epics::pvAccess::ChannelProcessRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/** /**
* @brief Create a channelGet. * @brief Create a channelGet.
* *
* @param requester The client callback. * @param requester The client callback.
* @param pvRequest The options specified by the client. * @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation. * @return A shared pointer to the newly created implementation.
@@ -286,7 +286,7 @@ public:
virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet( virtual epics::pvAccess::ChannelGet::shared_pointer createChannelGet(
epics::pvAccess::ChannelGetRequester::shared_pointer const &requester, epics::pvAccess::ChannelGetRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/** /**
* @brief Create a channelPut. * @brief Create a channelPut.
* *
* @param requester The client callback. * @param requester The client callback.
@@ -297,9 +297,9 @@ public:
virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut( virtual epics::pvAccess::ChannelPut::shared_pointer createChannelPut(
epics::pvAccess::ChannelPutRequester::shared_pointer const &requester, epics::pvAccess::ChannelPutRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/** /**
* @brief Create a channelPutGet. * @brief Create a channelPutGet.
* *
* @param requester The client callback. * @param requester The client callback.
* @param pvRequest The options specified by the client. * @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation. * @return A shared pointer to the newly created implementation.
@@ -308,7 +308,7 @@ public:
virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet( virtual epics::pvAccess::ChannelPutGet::shared_pointer createChannelPutGet(
epics::pvAccess::ChannelPutGetRequester::shared_pointer const &requester, epics::pvAccess::ChannelPutGetRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/** /**
* @brief Create a channelRPC. * @brief Create a channelRPC.
* *
* The PVRecord must implement <b>getService</b> or an empty shared pointer is returned. * The PVRecord must implement <b>getService</b> or an empty shared pointer is returned.
@@ -319,9 +319,9 @@ public:
virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC( virtual epics::pvAccess::ChannelRPC::shared_pointer createChannelRPC(
epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester, epics::pvAccess::ChannelRPCRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/** /**
* @brief Create a monitor. * @brief Create a monitor.
* *
* @param requester The client callback. * @param requester The client callback.
* @param pvRequest The options specified by the client. * @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation. * @return A shared pointer to the newly created implementation.
@@ -330,9 +330,9 @@ public:
virtual epics::pvData::Monitor::shared_pointer createMonitor( virtual epics::pvData::Monitor::shared_pointer createMonitor(
epics::pvData::MonitorRequester::shared_pointer const &requester, epics::pvData::MonitorRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/** /**
* @brief Create a channelArray. * @brief Create a channelArray.
* *
* @param requester The client callback. * @param requester The client callback.
* @param pvRequest The options specified by the client. * @param pvRequest The options specified by the client.
* @return A shared pointer to the newly created implementation. * @return A shared pointer to the newly created implementation.
@@ -341,13 +341,13 @@ public:
virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray( virtual epics::pvAccess::ChannelArray::shared_pointer createChannelArray(
epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester, epics::pvAccess::ChannelArrayRequester::shared_pointer const &requester,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
/** /**
* @brief calls printInfo(std::cout); * @brief calls printInfo(std::cout);
*/ */
virtual void printInfo(); virtual void printInfo();
/** /**
* @brief displays a message * @brief displays a message
* *
* @param out the stream on which the message is displayed. * @param out the stream on which the message is displayed.
*/ */
virtual void printInfo(std::ostream& out); virtual void printInfo(std::ostream& out);

View File

@@ -16,7 +16,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class ControlSupport; class ControlSupport;
typedef std::tr1::shared_ptr<ControlSupport> ControlSupportPtr; typedef std::tr1::shared_ptr<ControlSupport> ControlSupportPtr;
@@ -57,20 +57,20 @@ public:
* @return Returns true is any fields were modified; otherwise false. * @return Returns true is any fields were modified; otherwise false.
*/ */
virtual void reset(); virtual void reset();
/** /**
* @brief create a ControlSupport * @brief create a ControlSupport
* *
* @param pvRecord - The pvRecord to which the support is attached. * @param pvRecord - The pvRecord to which the support is attached.
* @return The new ControlSupport * @return The new ControlSupport
*/ */
static ControlSupportPtr create(PVRecordPtr const & pvRecord); static ControlSupportPtr create(PVRecordPtr const & pvRecord);
/** /**
* @brief create a controlSupport required by ControlSupport * @brief create a controlSupport required by ControlSupport
* *
* @param scalarType The type for outputValue. * @param scalarType The type for outputValue.
* @return The controlField introspection structure. * @return The controlField introspection structure.
*/ */
static epics::pvData::StructureConstPtr controlField(epics::pvData::ScalarType scalarType); static epics::pvData::StructureConstPtr controlField(epics::pvData::ScalarType scalarType);
private: private:
ControlSupport(PVRecordPtr const & pvRecord); ControlSupport(PVRecordPtr const & pvRecord);
PVRecordPtr pvRecord; PVRecordPtr pvRecord;
@@ -87,4 +87,3 @@ private:
}} }}
#endif /* CONTROLSUPPORT_H */ #endif /* CONTROLSUPPORT_H */

View File

@@ -18,7 +18,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
typedef std::tr1::shared_ptr<epicsThread> EpicsThreadPtr; typedef std::tr1::shared_ptr<epicsThread> EpicsThreadPtr;

View File

@@ -63,9 +63,13 @@ private:
long start; long start;
long increment; long increment;
long end; long end;
epics::pvData::PVFieldPtr masterField;
epics::pvData::PVScalarArrayPtr masterArray; epics::pvData::PVScalarArrayPtr masterArray;
PVArrayFilter(long start,long increment,long end,const epics::pvData::PVScalarArrayPtr & masterArray); PVArrayFilter(
long start,long increment,long end,
const epics::pvData::PVFieldPtr & masterField,
const epics::pvData::PVScalarArrayPtr masterArray);
public: public:
POINTER_DEFINITIONS(PVArrayFilter); POINTER_DEFINITIONS(PVArrayFilter);
virtual ~PVArrayFilter(); virtual ~PVArrayFilter();
@@ -95,4 +99,3 @@ public:
}} }}
#endif /* PVARRAYPLUGIN_H */ #endif /* PVARRAYPLUGIN_H */

View File

@@ -16,7 +16,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class PVRecord; class PVRecord;
typedef std::tr1::shared_ptr<PVRecord> PVRecordPtr; typedef std::tr1::shared_ptr<PVRecord> PVRecordPtr;
@@ -93,7 +93,7 @@ public:
/** /**
* @brief remove record from database. * @brief remove record from database.
* *
* Remove the PVRecord. Release any resources used and * Remove the PVRecord. Release any resources used and
* get rid of listeners and requesters. * get rid of listeners and requesters.
* If derived class overrides this then it must call PVRecord::remove() * If derived class overrides this then it must call PVRecord::remove()
* after it has destroyed any resorces it uses. * after it has destroyed any resorces it uses.
@@ -103,7 +103,7 @@ public:
* @brief Optional method for derived class. * @brief Optional method for derived class.
* *
* Return a service corresponding to the specified request PVStructure. * Return a service corresponding to the specified request PVStructure.
* @param pvRequest The request PVStructure * @param pvRequest The request PVStructure
* @return The corresponding service * @return The corresponding service
*/ */
virtual epics::pvAccess::RPCServiceAsync::shared_pointer getService( virtual epics::pvAccess::RPCServiceAsync::shared_pointer getService(
@@ -112,7 +112,7 @@ public:
return epics::pvAccess::RPCServiceAsync::shared_pointer(); return epics::pvAccess::RPCServiceAsync::shared_pointer();
} }
/** /**
* @brief Creates a <b>soft</b> record. * @brief Creates a <b>soft</b> record.
* *
* @param recordName The name of the record, which is also the channelName. * @param recordName The name of the record, which is also the channelName.
* @param pvStructure The top level structure. * @param pvStructure The top level structure.
@@ -247,15 +247,17 @@ protected:
epics::pvData::PVStructurePtr const & pvStructure); epics::pvData::PVStructurePtr const & pvStructure);
/** /**
* @brief Initializes the base class. * @brief Initializes the base class.
* *
* Must be called by derived classes. * Must be called by derived classes.
*/ */
void initPVRecord(); void initPVRecord();
private: private:
friend class PVDatabase;
void unlistenClients();
PVRecordFieldPtr findPVRecordField( PVRecordFieldPtr findPVRecordField(
PVRecordStructurePtr const & pvrs, PVRecordStructurePtr const & pvrs,
epics::pvData::PVFieldPtr const & pvField); epics::pvData::PVFieldPtr const & pvField);
void notifyClients();
std::string recordName; std::string recordName;
epics::pvData::PVStructurePtr pvStructure; epics::pvData::PVStructurePtr pvStructure;
@@ -499,6 +501,7 @@ public:
/** /**
* @brief Remove a record. * @brief Remove a record.
* @param record The record to remove. * @param record The record to remove.
*
* @return <b>true</b> if record was removed. * @return <b>true</b> if record was removed.
*/ */
bool removeRecord(PVRecordPtr const & record); bool removeRecord(PVRecordPtr const & record);
@@ -508,6 +511,9 @@ public:
*/ */
epics::pvData::PVStringArrayPtr getRecordNames(); epics::pvData::PVStringArrayPtr getRecordNames();
private: private:
friend class PVRecord;
PVRecordWPtr removeFromMap(PVRecordPtr const & record);
PVDatabase(); PVDatabase();
void lock(); void lock();
void unlock(); void unlock();
@@ -519,4 +525,3 @@ private:
}} }}
#endif /* PVDATABASE_H */ #endif /* PVDATABASE_H */

View File

@@ -66,7 +66,7 @@ private:
epics::pvData::PVScalarPtr master; epics::pvData::PVScalarPtr master;
bool firstTime; bool firstTime;
double lastReportedValue; double lastReportedValue;
PVDeadbandFilter(bool absolute,double deadband,epics::pvData::PVScalarPtr const & master); PVDeadbandFilter(bool absolute,double deadband,epics::pvData::PVScalarPtr const & master);
public: public:
@@ -100,4 +100,3 @@ public:
}} }}
#endif /* PVDEADBANDPLUGIN_H */ #endif /* PVDEADBANDPLUGIN_H */

View File

@@ -16,7 +16,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvCopy{ namespace epics { namespace pvCopy{
class PVPlugin; class PVPlugin;
class PVFilter; class PVFilter;
@@ -36,7 +36,7 @@ typedef std::map<std::string,PVPluginPtr> PVPluginMap;
* PVCopy looks for plugins defined in pvRequest and calls the filter when a pvCopy is updated. * PVCopy looks for plugins defined in pvRequest and calls the filter when a pvCopy is updated.
* @author mrk * @author mrk
* @since 2017.03.17 * @since 2017.03.17
* *
* Interface for a filter plugin for PVCopy. * Interface for a filter plugin for PVCopy.
* *
*/ */

View File

@@ -18,7 +18,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvCopy{ namespace epics { namespace pvCopy{
class PVCopyTraverseMasterCallback; class PVCopyTraverseMasterCallback;
typedef std::tr1::shared_ptr<PVCopyTraverseMasterCallback> PVCopyTraverseMasterCallbackPtr; typedef std::tr1::shared_ptr<PVCopyTraverseMasterCallback> PVCopyTraverseMasterCallbackPtr;
@@ -62,7 +62,7 @@ typedef std::tr1::shared_ptr<CopyStructureNode> CopyStructureNodePtr;
* Class that manages one or more PVStructures that holds an arbitrary subset of the fields * Class that manages one or more PVStructures that holds an arbitrary subset of the fields
* in another PVStructure called master. * in another PVStructure called master.
*/ */
class epicsShareClass PVCopy : class epicsShareClass PVCopy :
public std::tr1::enable_shared_from_this<PVCopy> public std::tr1::enable_shared_from_this<PVCopy>
{ {
public: public:
@@ -173,12 +173,12 @@ public:
*/ */
std::string dump(); std::string dump();
private: private:
PVCopyPtr getPtrSelf() PVCopyPtr getPtrSelf()
{ {
return shared_from_this(); return shared_from_this();
} }
epics::pvData::PVStructurePtr pvMaster; epics::pvData::PVStructurePtr pvMaster;
epics::pvData::StructureConstPtr structure; epics::pvData::StructureConstPtr structure;
CopyNodePtr headNode; CopyNodePtr headNode;

View File

@@ -20,7 +20,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class PVSupport; class PVSupport;
typedef std::tr1::shared_ptr<PVSupport> PVSupportPtr; typedef std::tr1::shared_ptr<PVSupport> PVSupportPtr;
@@ -29,7 +29,7 @@ typedef std::tr1::shared_ptr<PVSupport> PVSupportPtr;
* @brief Base interface for a PVSupport. * @brief Base interface for a PVSupport.
* *
*/ */
class epicsShareClass PVSupport class epicsShareClass PVSupport
{ {
public: public:
POINTER_DEFINITIONS(PVSupport); POINTER_DEFINITIONS(PVSupport);
@@ -75,4 +75,3 @@ public:
}} }}
#endif /* PVSUPPORT_H */ #endif /* PVSUPPORT_H */

View File

@@ -66,7 +66,7 @@ private:
bool current; bool current;
bool copy; bool copy;
epics::pvData::PVFieldPtr master; epics::pvData::PVFieldPtr master;
PVTimestampFilter(bool current,bool copy,epics::pvData::PVFieldPtr const & pvField); PVTimestampFilter(bool current,bool copy,epics::pvData::PVFieldPtr const & pvField);
public: public:
@@ -98,4 +98,3 @@ public:
}} }}
#endif /* PVTIMESTAMPPLUGIN_H */ #endif /* PVTIMESTAMPPLUGIN_H */

View File

@@ -15,7 +15,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class RemoveRecord; class RemoveRecord;

View File

@@ -19,7 +19,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class ScalarAlarmSupport; class ScalarAlarmSupport;
typedef std::tr1::shared_ptr<ScalarAlarmSupport> ScalarAlarmSupportPtr; typedef std::tr1::shared_ptr<ScalarAlarmSupport> ScalarAlarmSupportPtr;
@@ -61,19 +61,19 @@ public:
* *
*/ */
virtual void reset(); virtual void reset();
/** /**
* @brief create a ScalarAlarm * @brief create a ScalarAlarm
* *
* @param pvRecord - The pvRecord to which the support is attached. * @param pvRecord - The pvRecord to which the support is attached.
* @return The new ScalarAlarm * @return The new ScalarAlarm
*/ */
static ScalarAlarmSupportPtr create(PVRecordPtr const & pvRecord); static ScalarAlarmSupportPtr create(PVRecordPtr const & pvRecord);
/** /**
* @brief create a scalarAlarm required by ScalarAlarm * @brief create a scalarAlarm required by ScalarAlarm
* *
* @return The scalarAlarmField introspection structure. * @return The scalarAlarmField introspection structure.
*/ */
static epics::pvData::StructureConstPtr scalarAlarmField(); static epics::pvData::StructureConstPtr scalarAlarmField();
private: private:
ScalarAlarmSupport(PVRecordPtr const & pvRecord); ScalarAlarmSupport(PVRecordPtr const & pvRecord);
@@ -108,4 +108,3 @@ private:
}} }}
#endif /* SCALARALARMSUPPORT_H */ #endif /* SCALARALARMSUPPORT_H */

View File

@@ -16,7 +16,7 @@
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class TraceRecord; class TraceRecord;

View File

@@ -38,7 +38,7 @@ using std::cout;
using std::endl; using std::endl;
using std::string; using std::string;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
static StructureConstPtr nullStructure; static StructureConstPtr nullStructure;
@@ -68,7 +68,7 @@ static bool getProcess(PVStructurePtr pvRequest,bool processDefault)
return pvString->get().compare("true")==0 ? true : false; return pvString->get().compare("true")==0 ? true : false;
} else if(scalar->getScalarType()==pvBoolean) { } else if(scalar->getScalarType()==pvBoolean) {
PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField); PVBooleanPtr pvBoolean = static_pointer_cast<PVBoolean>(pvField);
return pvBoolean->get(); return pvBoolean->get();
} }
return processDefault; return processDefault;
} }
@@ -102,7 +102,7 @@ private:
ChannelProcessRequester::shared_pointer const & channelProcessRequester, ChannelProcessRequester::shared_pointer const & channelProcessRequester,
PVRecordPtr const &pvRecord, PVRecordPtr const &pvRecord,
int nProcess) int nProcess)
: :
channelLocal(channelLocal), channelLocal(channelLocal),
channelProcessRequester(channelProcessRequester), channelProcessRequester(channelProcessRequester),
pvRecord(pvRecord), pvRecord(pvRecord),
@@ -132,7 +132,7 @@ ChannelProcessLocalPtr ChannelProcessLocal::create(
if(pvField) { if(pvField) {
PVStringPtr pvString = pvOptions->getSubField<PVString>("nProcess"); PVStringPtr pvString = pvOptions->getSubField<PVString>("nProcess");
if(pvString) { if(pvString) {
int size; int size=0;
std::stringstream ss; std::stringstream ss;
ss << pvString->get(); ss << pvString->get();
ss >> size; ss >> size;
@@ -156,10 +156,7 @@ ChannelProcessLocalPtr ChannelProcessLocal::create(
ChannelProcessLocal::~ChannelProcessLocal() ChannelProcessLocal::~ChannelProcessLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelProcessLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelProcessLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelProcessLocal::getChannel()
@@ -238,7 +235,7 @@ private:
PVStructurePtr const&pvStructure, PVStructurePtr const&pvStructure,
BitSetPtr const & bitSet, BitSetPtr const & bitSet,
PVRecordPtr const &pvRecord) PVRecordPtr const &pvRecord)
: :
firstTime(true), firstTime(true),
callProcess(callProcess), callProcess(callProcess),
channelLocal(channelLocal), channelLocal(channelLocal),
@@ -304,10 +301,7 @@ ChannelGetLocalPtr ChannelGetLocal::create(
ChannelGetLocal::~ChannelGetLocal() ChannelGetLocal::~ChannelGetLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelGetLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelGetLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelGetLocal::getChannel()
@@ -469,10 +463,7 @@ ChannelPutLocalPtr ChannelPutLocal::create(
ChannelPutLocal::~ChannelPutLocal() ChannelPutLocal::~ChannelPutLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelPutLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelPutLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelPutLocal::getChannel()
@@ -532,7 +523,7 @@ void ChannelPutLocal::put(
PVRecordPtr pvr(pvRecord.lock()); PVRecordPtr pvr(pvRecord.lock());
if(!pvr) throw std::logic_error("pvRecord is deleted"); if(!pvr) throw std::logic_error("pvRecord is deleted");
try { try {
{ {
epicsGuard <PVRecord> guard(*pvr); epicsGuard <PVRecord> guard(*pvr);
pvr->beginGroupPut(); pvr->beginGroupPut();
pvCopy->updateMaster(pvStructure, bitSet); pvCopy->updateMaster(pvStructure, bitSet);
@@ -543,7 +534,7 @@ void ChannelPutLocal::put(
} }
requester->putDone(Status::Ok,getPtrSelf()); requester->putDone(Status::Ok,getPtrSelf());
if(pvr->getTraceLevel()>1) if(pvr->getTraceLevel()>1)
{ {
cout << "ChannelPutLocal::put" << endl; cout << "ChannelPutLocal::put" << endl;
} }
} catch(std::exception& ex) { } catch(std::exception& ex) {
@@ -590,7 +581,7 @@ private:
PVStructurePtr const&pvGetStructure, PVStructurePtr const&pvGetStructure,
BitSetPtr const & getBitSet, BitSetPtr const & getBitSet,
PVRecordPtr const &pvRecord) PVRecordPtr const &pvRecord)
: :
callProcess(callProcess), callProcess(callProcess),
channelLocal(channelLocal), channelLocal(channelLocal),
channelPutGetRequester(channelPutGetRequester), channelPutGetRequester(channelPutGetRequester),
@@ -662,10 +653,7 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create(
ChannelPutGetLocal::~ChannelPutGetLocal() ChannelPutGetLocal::~ChannelPutGetLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelPutGetLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelPutGetLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelPutGetLocal::getChannel()
@@ -862,10 +850,7 @@ ChannelRPCLocalPtr ChannelRPCLocal::create(
ChannelRPCLocal::~ChannelRPCLocal() ChannelRPCLocal::~ChannelRPCLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelRPCLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelRPCLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelRPCLocal::getChannel()
@@ -902,7 +887,7 @@ void ChannelRPCLocal::processRequest(
status = Status(Status::STATUSTYPE_FATAL, "Unexpected exception caught while calling RPCService.request(PVStructure)."); status = Status(Status::STATUSTYPE_FATAL, "Unexpected exception caught while calling RPCService.request(PVStructure).");
ok = false; ok = false;
} }
// check null result // check null result
if (ok && !result) if (ok && !result)
{ {
@@ -1001,7 +986,7 @@ private:
PVArrayPtr const &pvArray, PVArrayPtr const &pvArray,
PVArrayPtr const &pvCopy, PVArrayPtr const &pvCopy,
PVRecordPtr const &pvRecord) PVRecordPtr const &pvRecord)
: :
channelLocal(channelLocal), channelLocal(channelLocal),
channelArrayRequester(channelArrayRequester), channelArrayRequester(channelArrayRequester),
pvArray(pvArray), pvArray(pvArray),
@@ -1104,10 +1089,7 @@ ChannelArrayLocalPtr ChannelArrayLocal::create(
ChannelArrayLocal::~ChannelArrayLocal() ChannelArrayLocal::~ChannelArrayLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); //cout << "~ChannelArrayLocal()\n";
if(pvr && pvr->getTraceLevel()>0) {
cout << "~ChannelArrayLocal() " << pvr->getRecordName() << endl;
}
} }
std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel() std::tr1::shared_ptr<Channel> ChannelArrayLocal::getChannel()
@@ -1246,7 +1228,7 @@ ChannelLocal::ChannelLocal(
ChannelProviderLocalPtr const & provider, ChannelProviderLocalPtr const & provider,
ChannelRequester::shared_pointer const & requester, ChannelRequester::shared_pointer const & requester,
PVRecordPtr const & pvRecord) PVRecordPtr const & pvRecord)
: :
requester(requester), requester(requester),
provider(provider), provider(provider),
pvRecord(pvRecord) pvRecord(pvRecord)
@@ -1261,12 +1243,7 @@ ChannelLocal::ChannelLocal(
ChannelLocal::~ChannelLocal() ChannelLocal::~ChannelLocal()
{ {
PVRecordPtr pvr(pvRecord.lock()); // cout << "~ChannelLocal()" << endl;
if(!pvr) return;
if(pvr->getTraceLevel()>0)
{
cout << "~ChannelLocal()" << endl;
}
} }
ChannelProvider::shared_pointer ChannelLocal::getProvider() ChannelProvider::shared_pointer ChannelLocal::getProvider()
@@ -1296,7 +1273,7 @@ string ChannelLocal::getRequesterName()
<< " requester exists " << (requester ? "true" : "false") << " requester exists " << (requester ? "true" : "false")
<< endl; << endl;
} }
if(!requester) return string(); if(!requester) return string();
return requester->getRequesterName(); return requester->getRequesterName();
} }
@@ -1319,7 +1296,7 @@ void ChannelLocal::message(
string recordName("record deleted"); string recordName("record deleted");
if(pvr) recordName = pvr->getRecordName(); if(pvr) recordName = pvr->getRecordName();
cout << recordName cout << recordName
<< " message " << message << " message " << message
<< " messageType " << getMessageTypeName(messageType) << " messageType " << getMessageTypeName(messageType)
<< endl; << endl;
} }
@@ -1362,8 +1339,8 @@ void ChannelLocal::getField(GetFieldRequester::shared_pointer const &requester,
pvr->getPVRecordStructure()->getPVStructure()->getStructure(); pvr->getPVRecordStructure()->getPVStructure()->getStructure();
requester->getDone(Status::Ok,structure); requester->getDone(Status::Ok,structure);
return; return;
} }
PVFieldPtr pvField = PVFieldPtr pvField =
pvr->getPVRecordStructure()->getPVStructure()->getSubField(subField); pvr->getPVRecordStructure()->getPVStructure()->getSubField(subField);
if(pvField) { if(pvField) {
requester->getDone(Status::Ok,pvField->getField()); requester->getDone(Status::Ok,pvField->getField());
@@ -1479,7 +1456,7 @@ ChannelRPC::shared_pointer ChannelLocal::createChannelRPC(
<< endl; << endl;
} }
ChannelRPCLocalPtr channelRPC = ChannelRPCLocalPtr channelRPC =
ChannelRPCLocal::create( ChannelRPCLocal::create(
getPtrSelf(), getPtrSelf(),
channelRPCRequester, channelRPCRequester,

View File

@@ -30,13 +30,13 @@ using std::cout;
using std::endl; using std::endl;
using std::string; using std::string;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
static string providerName("local"); static string providerName("local");
static ChannelProviderLocalPtr channelProvider; static ChannelProviderLocalPtr channelProvider;
class LocalChannelProviderFactory : public ChannelProviderFactory class LocalChannelProviderFactory : public ChannelProviderFactory
{ {
public: public:
POINTER_DEFINITIONS(LocalChannelProviderFactory); POINTER_DEFINITIONS(LocalChannelProviderFactory);
virtual string getFactoryName() { return providerName;} virtual string getFactoryName() { return providerName;}
@@ -114,7 +114,7 @@ ChannelFind::shared_pointer ChannelProviderLocal::channelFind(
Status::Ok, Status::Ok,
shared_from_this(), shared_from_this(),
true); true);
} else { } else {
Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found"); Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found");
channelFindRequester->channelFindResult( channelFindRequester->channelFindResult(

View File

@@ -34,7 +34,7 @@ using std::cout;
using std::endl; using std::endl;
using std::string; using std::string;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class MonitorLocal; class MonitorLocal;
typedef std::tr1::shared_ptr<MonitorLocal> MonitorLocalPtr; typedef std::tr1::shared_ptr<MonitorLocal> MonitorLocalPtr;
@@ -88,7 +88,7 @@ public:
nextGetUsed = 0; nextGetUsed = 0;
nextReleaseUsed = 0; nextReleaseUsed = 0;
} }
MonitorElementPtr getFree() MonitorElementPtr getFree()
{ {
if(numberFree==0) return MonitorElementPtr(); if(numberFree==0) return MonitorElementPtr();
@@ -98,7 +98,7 @@ public:
if(nextGetFree>=size) nextGetFree = 0; if(nextGetFree>=size) nextGetFree = 0;
return elements[ind]; return elements[ind];
} }
void setUsed(MonitorElementPtr const &element) void setUsed(MonitorElementPtr const &element)
{ {
if(element!=elements[nextSetUsed++]) { if(element!=elements[nextSetUsed++]) {
@@ -107,7 +107,7 @@ public:
numberUsed++; numberUsed++;
if(nextSetUsed>=size) nextSetUsed = 0; if(nextSetUsed>=size) nextSetUsed = 0;
} }
MonitorElementPtr getUsed() MonitorElementPtr getUsed()
{ {
if(numberUsed==0) return MonitorElementPtr(); if(numberUsed==0) return MonitorElementPtr();
@@ -131,7 +131,7 @@ public:
typedef std::tr1::shared_ptr<MonitorRequester> MonitorRequesterPtr; typedef std::tr1::shared_ptr<MonitorRequester> MonitorRequesterPtr;
class MonitorLocal : class MonitorLocal :
public Monitor, public Monitor,
public PVListener, public PVListener,
@@ -191,10 +191,7 @@ MonitorLocal::MonitorLocal(
MonitorLocal::~MonitorLocal() MonitorLocal::~MonitorLocal()
{ {
if(pvRecord->getTraceLevel()>0) //cout << "MonitorLocal::~MonitorLocal()" << endl;
{
cout << "MonitorLocal::~MonitorLocal()" << endl;
}
} }
@@ -294,7 +291,7 @@ void MonitorLocal::dataPut(PVRecordFieldPtr const & pvRecordField)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::dataPut(pvRecordField)" << endl; cout << "MonitorLocal::dataPut(pvRecordField)" << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -319,7 +316,7 @@ void MonitorLocal::dataPut(
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::dataPut(requested,pvRecordField)" << endl; cout << "MonitorLocal::dataPut(requested,pvRecordField)" << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -346,7 +343,7 @@ void MonitorLocal::beginGroupPut(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::beginGroupPut()" << endl; cout << "MonitorLocal::beginGroupPut()" << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -360,7 +357,7 @@ void MonitorLocal::endGroupPut(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::endGroupPut dataChanged " << dataChanged << endl; cout << "MonitorLocal::endGroupPut dataChanged " << dataChanged << endl;
} }
if(state!=active) return; if(state!=active) return;
{ {
@@ -377,7 +374,7 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
{ {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::unlisten\n"; cout << "MonitorLocal::unlisten\n";
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -387,7 +384,7 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord)
if(requester) { if(requester) {
if(pvRecord->getTraceLevel()>1) if(pvRecord->getTraceLevel()>1)
{ {
cout << "PVCopyMonitor::unlisten calling requester->unlisten\n"; cout << "MonitorLocal::unlisten calling requester->unlisten\n";
} }
requester->unlisten(getPtrSelf()); requester->unlisten(getPtrSelf());
} }

View File

@@ -4,12 +4,15 @@ SRC_DIRS += $(PVDATABASE_SRC)/special
LIBSRCS += traceRecord.cpp LIBSRCS += traceRecord.cpp
LIBSRCS += removeRecord.cpp LIBSRCS += removeRecord.cpp
LIBSRCS += addRecord.cpp
LIBSRCS += processRecord.cpp LIBSRCS += processRecord.cpp
DBD += traceRecordRegister.dbd DBD += traceRecordRegister.dbd
DBD += removeRecordRegister.dbd DBD += removeRecordRegister.dbd
DBD += addRecordRegister.dbd
DBD += processRecordRegister.dbd DBD += processRecordRegister.dbd
LIBSRCS += traceRecordRegister.cpp LIBSRCS += traceRecordRegister.cpp
LIBSRCS += removeRecordRegister.cpp LIBSRCS += removeRecordRegister.cpp
LIBSRCS += addRecordRegister.cpp
LIBSRCS += processRecordRegister.cpp LIBSRCS += processRecordRegister.cpp

117
src/special/addRecord.cpp Normal file
View File

@@ -0,0 +1,117 @@
/* addRecord.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
* @date 2013.04.18
*/
#include <string>
#include <cstring>
#include <stdexcept>
#include <memory>
#include <set>
#include <pv/lock.h>
#include <pv/pvType.h>
#include <pv/pvData.h>
#include <pv/standardField.h>
#include <pv/pvTimeStamp.h>
#include <pv/timeStamp.h>
#include <pv/rpcService.h>
#include <pv/pvAccess.h>
#include <pv/status.h>
#include <pv/serverContext.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/pvDatabase.h"
#include "pv/addRecord.h"
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvDatabase {
AddRecordPtr AddRecord::create(
std::string const & recordName)
{
FieldCreatePtr fieldCreate = getFieldCreate();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
addNestedStructure("argument")->
add("recordName",pvString)->
addNestedUnion("union") ->
endNested()->
endNested()->
addNestedStructure("result") ->
add("status",pvString) ->
endNested()->
createStructure();
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
AddRecordPtr pvRecord(
new AddRecord(recordName,pvStructure));
if(!pvRecord->init()) pvRecord.reset();
return pvRecord;
}
AddRecord::AddRecord(
std::string const & recordName,
epics::pvData::PVStructurePtr const & pvStructure)
: PVRecord(recordName,pvStructure)
{
}
bool AddRecord::init()
{
initPVRecord();
PVStructurePtr pvStructure = getPVStructure();
pvRecordName = pvStructure->getSubField<PVString>("argument.recordName");
if(!pvRecordName) return false;
pvResult = pvStructure->getSubField<PVString>("result.status");
if(!pvResult) return false;
return true;
}
void AddRecord::process()
{
PVDataCreatePtr pvDataCreate = getPVDataCreate();
string name = pvRecordName->get();
PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name);
if(pvRecord) {
pvResult->put(name + " already exists");
return;
}
PVUnionPtr pvUnion = getPVStructure()->getSubField<PVUnion>("argument.union");
if(!pvUnion) {
pvResult->put(name + " argument.union is NULL");
return;
}
PVFieldPtr pvField(pvUnion->get());
if(!pvField) {
pvResult->put(name + " union has no value");
return;
}
if(pvField->getField()->getType()!=epics::pvData::structure) {
pvResult->put(name + " union most be a structure");
return;
}
StructureConstPtr st = static_pointer_cast<const Structure>(pvField->getField());
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(st);
PVRecordPtr pvRec = PVRecord::create(name,pvStructure);
bool result = PVDatabase::getMaster()->addRecord(pvRec);
if(result) {
pvResult->put("success");
} else {
pvResult->put("failure");
}
}
}}

View File

@@ -0,0 +1,62 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
* @date 2013.07.24
*/
/* Author: Marty Kraimer */
#include <epicsThread.h>
#include <iocsh.h>
#include <pv/event.h>
#include <pv/pvAccess.h>
#include <pv/serverContext.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
#include <pv/rpcService.h>
// The following must be the last include for code pvDatabase uses
#include <epicsExport.h>
#define epicsExportSharedSymbols
#include "pv/pvStructureCopy.h"
#include "pv/pvDatabase.h"
#include "pv/addRecord.h"
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace epics::pvDatabase;
using namespace std;
static const iocshArg testArg0 = { "recordName", iocshArgString };
static const iocshArg *testArgs[] = {
&testArg0};
static const iocshFuncDef addRecordFuncDef = {"addRecordCreate", 1,testArgs};
static void addRecordCallFunc(const iocshArgBuf *args)
{
char *recordName = args[0].sval;
if(!recordName) {
throw std::runtime_error("addRecordCreate invalid number of arguments");
}
AddRecordPtr record = AddRecord::create(recordName);
bool result = PVDatabase::getMaster()->addRecord(record);
if(!result) cout << "recordname" << " not added" << endl;
}
static void addRecordRegister(void)
{
static int firstTime = 1;
if (firstTime) {
firstTime = 0;
iocshRegister(&addRecordFuncDef, addRecordCallFunc);
}
}
extern "C" {
epicsExportRegistrar(addRecordRegister);
}

View File

@@ -0,0 +1 @@
registrar("addRecordRegister")

View File

@@ -38,7 +38,7 @@ using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
ProcessRecordPtr ProcessRecord::create( ProcessRecordPtr ProcessRecord::create(
std::string const & recordName,double delay) std::string const & recordName,double delay)
@@ -141,7 +141,7 @@ void ProcessRecord::run()
if(runStop.tryWait()) { if(runStop.tryWait()) {
runReturn.signal(); runReturn.signal();
return; return;
} }
if(delay>0.0) epicsThreadSleep(delay); if(delay>0.0) epicsThreadSleep(delay);
epicsGuard<epics::pvData::Mutex> guard(mutex); epicsGuard<epics::pvData::Mutex> guard(mutex);
PVRecordMap::iterator iter; PVRecordMap::iterator iter;
@@ -164,4 +164,3 @@ void ProcessRecord::run()
}} }}

View File

@@ -36,7 +36,7 @@ using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
RemoveRecordPtr RemoveRecord::create( RemoveRecordPtr RemoveRecord::create(
std::string const & recordName) std::string const & recordName)
@@ -90,4 +90,3 @@ void RemoveRecord::process()
}} }}

View File

@@ -35,7 +35,7 @@ using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
TraceRecordPtr TraceRecord::create( TraceRecordPtr TraceRecord::create(
std::string const & recordName) std::string const & recordName)
@@ -93,4 +93,3 @@ void TraceRecord::process()
}} }}

View File

@@ -25,11 +25,11 @@ using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
ControlSupport::~ControlSupport() ControlSupport::~ControlSupport()
{ {
cout << "ControlSupport::~ControlSupport()\n"; //cout << "ControlSupport::~ControlSupport()\n";
} }
epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType) epics::pvData::StructureConstPtr ControlSupport::controlField(ScalarType scalarType)
@@ -135,4 +135,3 @@ void ControlSupport::reset()
}} }}

View File

@@ -26,11 +26,11 @@ using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
ScalarAlarmSupport::~ScalarAlarmSupport() ScalarAlarmSupport::~ScalarAlarmSupport()
{ {
cout << "ScalarAlarmSupport::~ScalarAlarmSupport()\n"; //cout << "ScalarAlarmSupport::~ScalarAlarmSupport()\n";
} }
@@ -83,7 +83,7 @@ bool ScalarAlarmSupport::init(
pvHysteresis = pvScalarAlarm->getSubField<PVDouble>("hysteresis"); pvHysteresis = pvScalarAlarm->getSubField<PVDouble>("hysteresis");
} }
if(!pvScalarAlarm if(!pvScalarAlarm
|| !pvLowAlarmLimit || !pvLowWarningLimit || !pvLowAlarmLimit || !pvLowWarningLimit
|| !pvLowWarningLimit || !pvHighAlarmLimit || !pvLowWarningLimit || !pvHighAlarmLimit
|| !pvHysteresis) || !pvHysteresis)
{ {
@@ -216,4 +216,3 @@ void ScalarAlarmSupport::setAlarm(
}} }}

View File

@@ -26,14 +26,14 @@
#ifdef listenerEpicsExportSharedSymbols #ifdef listenerEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef listenerEpicsExportSharedSymbols # undef listenerEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>
//epicsShareFunc epics::pvData::PVStructurePtr createListener(); //epicsShareFunc epics::pvData::PVStructurePtr createListener();
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
using namespace epics::pvData; using namespace epics::pvData;
using namespace std; using namespace std;
@@ -59,7 +59,7 @@ public:
} }
virtual void dataPut(PVRecordFieldPtr const & pvRecordField) virtual void dataPut(PVRecordFieldPtr const & pvRecordField)
{ {
cout << "Listener::dataPut record " << recordName cout << "Listener::dataPut record " << recordName
<< " pvRecordField " << pvRecordField->getPVField()->getFullName() << " pvRecordField " << pvRecordField->getPVField()->getFullName()
<< endl; << endl;
} }
@@ -67,7 +67,7 @@ public:
PVRecordStructurePtr const & requested, PVRecordStructurePtr const & requested,
PVRecordFieldPtr const & pvRecordField) PVRecordFieldPtr const & pvRecordField)
{ {
cout << "Listener::dataPut record " << recordName cout << "Listener::dataPut record " << recordName
<< " requested " << requested->getPVStructure()->getFullName() << " requested " << requested->getPVStructure()->getFullName()
<< " pvRecordField " << pvRecordField->getPVField()->getFullName() << " pvRecordField " << pvRecordField->getPVField()->getFullName()
<< endl; << endl;
@@ -84,7 +84,7 @@ public:
{ {
cout << "Listener::unlisten record " << recordName << endl; cout << "Listener::unlisten record " << recordName << endl;
} }
private: private:
Listener(PVRecordPtr const & pvRecord) Listener(PVRecordPtr const & pvRecord)
: pvCopy( : pvCopy(

View File

@@ -25,14 +25,14 @@
#ifdef powerSupplyEpicsExportSharedSymbols #ifdef powerSupplyEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef powerSupplyEpicsExportSharedSymbols # undef powerSupplyEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>
//epicsShareFunc epics::pvData::PVStructurePtr createPowerSupply(); //epicsShareFunc epics::pvData::PVStructurePtr createPowerSupply();
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class PowerSupply; class PowerSupply;
typedef std::tr1::shared_ptr<PowerSupply> PowerSupplyPtr; typedef std::tr1::shared_ptr<PowerSupply> PowerSupplyPtr;

View File

@@ -25,12 +25,12 @@
#ifdef pvRecordClientEpicsExportSharedSymbols #ifdef pvRecordClientEpicsExportSharedSymbols
# define epicsExportSharedSymbols # define epicsExportSharedSymbols
# undef pvRecordClientEpicsExportSharedSymbols # undef pvRecordClientEpicsExportSharedSymbols
#endif #endif
#include <shareLib.h> #include <shareLib.h>
namespace epics { namespace pvDatabase { namespace epics { namespace pvDatabase {
class RecordClient; class RecordClient;
typedef std::tr1::shared_ptr<RecordClient> RecordClientPtr; typedef std::tr1::shared_ptr<RecordClient> RecordClientPtr;
@@ -59,7 +59,7 @@ public:
std::cout << "RecordClient::detach record " << pvRecord->getRecordName() << std::endl; std::cout << "RecordClient::detach record " << pvRecord->getRecordName() << std::endl;
this->pvRecord.reset(); this->pvRecord.reset();
} }
private: private:
RecordClient(PVRecordPtr const & pvRecord) RecordClient(PVRecordPtr const & pvRecord)
: pvRecord(pvRecord) : pvRecord(pvRecord)

View File

@@ -134,4 +134,3 @@ MAIN(testExampleRecord)
test(); test();
return 0; return 0;
} }

View File

@@ -79,4 +79,3 @@ MAIN(testLocalProvider)
test(); test();
return 0; return 0;
} }

View File

@@ -75,4 +75,3 @@ MAIN(testPVAServer)
test(); test();
return 0; return 0;
} }

View File

@@ -273,7 +273,7 @@ static void testPVScalarArray(
cout << endl; cout << endl;
} }
} }
static void scalarTest() static void scalarTest()
{ {
if(debug) {cout << endl << endl << "****scalarTest****" << endl;} if(debug) {cout << endl << endl << "****scalarTest****" << endl;}
@@ -401,4 +401,3 @@ MAIN(testPVCopy)
powerSupplyTest(); powerSupplyTest();
return 0; return 0;
} }

View File

@@ -103,4 +103,3 @@ MAIN(testPVRecord)
powerSupplyTest(); powerSupplyTest();
return 0; return 0;
} }

View File

@@ -107,7 +107,7 @@ static void arrayTest()
uint32 nset = 0; uint32 nset = 0;
size_t n = 10; size_t n = 10;
shared_vector<double> values(n); shared_vector<double> values(n);
PVStructurePtr pvRecordStructure(getStandardPVField()->scalarArray(pvDouble,"")); PVStructurePtr pvRecordStructure(getStandardPVField()->scalarArray(pvDouble,""));
PVRecordPtr pvRecord(PVRecord::create("doubleArrayRecord",pvRecordStructure)); PVRecordPtr pvRecord(PVRecord::create("doubleArrayRecord",pvRecordStructure));
PVStructurePtr pvRequest(CreateRequest::create()->createRequest("value[array=1:3]")); PVStructurePtr pvRequest(CreateRequest::create()->createRequest("value[array=1:3]"));
@@ -145,6 +145,73 @@ static void arrayTest()
testOk1(nset==1); testOk1(nset==1);
} }
static void unionArrayTest()
{
if(debug) {cout << endl << endl << "****unionArrayTest****" << endl;}
bool result = false;
uint32 nset = 0;
size_t n = 10;
shared_vector<double> values(n);
for(size_t i=0; i<n; i++) values[i] = i + .06;
PVDoubleArrayPtr pvDoubleArray =
static_pointer_cast<PVDoubleArray>(PVDataCreate::getPVDataCreate()->createPVScalarArray(pvDouble));
const shared_vector<const double> yyy(freeze(values));
pvDoubleArray->putFrom(yyy);
StandardFieldPtr standardField = getStandardField();
FieldCreatePtr fieldCreate = getFieldCreate();
StructureConstPtr top = fieldCreate->createFieldBuilder()->
add("value",fieldCreate->createVariantUnion()) ->
add("timeStamp", standardField->timeStamp()) ->
addNestedStructure("subfield") ->
add("value",fieldCreate->createVariantUnion()) ->
endNested()->
createStructure();
PVStructurePtr pvRecordStructure(PVDataCreate::getPVDataCreate()->createPVStructure(top));
PVRecordPtr pvRecord(PVRecord::create("unionArrayRecord",pvRecordStructure));
PVUnionPtr pvUnion = pvRecord->getPVStructure()->getSubField<PVUnion>("value");
pvUnion->set(pvDoubleArray);
pvUnion = pvRecord->getPVStructure()->getSubField<PVUnion>("subfield.value");
pvUnion->set(pvDoubleArray);
if(debug) { cout << "initial\n" << pvRecordStructure << "\n";}
PVStructurePtr pvRequest(CreateRequest::create()->createRequest("value[array=1:3]"));
PVCopyPtr pvCopy(PVCopy::create(pvRecordStructure,pvRequest,""));
PVStructurePtr pvStructureCopy(pvCopy->createPVStructure());
BitSetPtr bitSet(new BitSet(pvStructureCopy->getNumberFields()));
PVDoubleArrayPtr pvValue(pvRecordStructure->getSubField<PVDoubleArray>("value"));
result = pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
nset = bitSet->cardinality();
if(debug) {
cout << "after get value"
<< " result " << (result ? "true" : "false")
<< " nset " << nset
<< " bitSet " << *bitSet
<< " pvStructureCopy\n" << pvStructureCopy
<< "\n";
}
testOk1(result==true);
testOk1(nset==1);
pvRequest = CreateRequest::create()->createRequest("subfield.value[array=1:3]");
pvCopy = PVCopy::create(pvRecordStructure,pvRequest,"");
pvStructureCopy = pvCopy->createPVStructure();
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
pvValue = pvRecordStructure->getSubField<PVDoubleArray>("subfield.value");
result = pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
nset = bitSet->cardinality();
if(debug) {
cout << "after get subfield.value"
<< " result " << (result ? "true" : "false")
<< " nset " << nset
<< " bitSet " << *bitSet
<< " pvStructureCopy\n" << pvStructureCopy
<< "\n";
}
testOk1(result==true);
testOk1(nset==1);
}
static void timeStampTest() static void timeStampTest()
{ {
if(debug) {cout << endl << endl << "****timeStampTest****" << endl;} if(debug) {cout << endl << endl << "****timeStampTest****" << endl;}
@@ -267,12 +334,12 @@ static void ignoreTest()
MAIN(testPlugin) MAIN(testPlugin)
{ {
testPlan(22); testPlan(26);
PVDatabasePtr pvDatabase(PVDatabase::getMaster()); PVDatabasePtr pvDatabase(PVDatabase::getMaster());
deadbandTest(); deadbandTest();
arrayTest(); arrayTest();
unionArrayTest();
timeStampTest(); timeStampTest();
ignoreTest(); ignoreTest();
return 0; return 0;
} }