28 Commits
7.1.1 ... 8.0.0

Author SHA1 Message Date
Michael Davidsaver
6ceaa6adb0 update release notes for 8.0.0 2019-07-24 11:19:30 -07:00
Michael Davidsaver
0447826e7c minor 2019-07-14 19:09:54 -07:00
Michael Davidsaver
3ef60a61a2 always epicsThreadStackBig
On RTEMS at least, c++ code needs the largest
standard stack frame size.
2019-07-08 09:07:09 -07:00
Daniel Damiani
31802a8bde Added additional explicit template instantiations to fix build problems on macos with c+11 2019-07-04 07:09:58 -07:00
Bruno Martins
c2bc77a649 Improve and add new tests for testIntrospect 2019-05-20 16:35:59 -07:00
Bruno Martins
4dd7a18301 Improve docs. Make getFieldT(offset) use vector::at. 2019-05-20 16:35:59 -07:00
Bruno Martins
a29894ee2b getField<T>() fail to compile when T isn't Field or a sub-class 2019-05-20 16:35:59 -07:00
Bruno Martins
2f8ac7f673 Fix tests with expected exceptions for getField(size_t) 2019-05-20 16:35:59 -07:00
Bruno Martins
b050fbbcbe Revert {Structure,Union}::getField to previous behavior 2019-05-20 16:35:59 -07:00
Bruno Martins
caa11605fc Add {Structure,Union}::getFieldT, fix {Structure,Union}::getField 2019-05-20 16:35:59 -07:00
Michael Davidsaver
cfcdd1a3f9 deprecate ByteBuffer::getArray()
in favor of identical ByteBuffer::getBuffer()
2019-05-18 18:21:06 -07:00
Michael Davidsaver
95ff606ba1 quiet (un)signed comparison warning 2019-05-16 10:17:56 -07:00
Michael Davidsaver
4cc9b650c5 getSubField<T>() fail to compile when T isn't PVField or a sub-class 2019-05-16 10:17:56 -07:00
Michael Davidsaver
cd2436342d Revert "Replace display.format with .form and .precision"
This reverts commit 4ffddfa2f6.
2019-05-06 10:40:54 -07:00
Michael Davidsaver
3ae2d09fe3 bump module version after removals 2019-05-01 14:43:33 -07:00
Michael Davidsaver
35b3403de6 remove deprecated pvCopy 2019-05-01 14:18:48 -07:00
Michael Davidsaver
f780ebdf76 remove deprecated localStaticLock 2019-05-01 14:06:33 -07:00
Michael Davidsaver
93f0518b4b Merge remote-tracking branch 'md/display-format'
* md/display-format:
  Replace display.format with .form and .precision
2019-05-01 14:03:57 -07:00
Michael Davidsaver
6da871fa64 7.1.3 2019-04-17 11:48:01 -07:00
Michael Davidsaver
d53cb0cbc9 doc 2019-04-17 11:47:56 -07:00
Michael Davidsaver
8f0111e482 fix ByteBuffer::putArray() and getArray()
Erroneous mixing of byte and element indexing
introduced by a51b308cc8
2019-04-08 09:46:23 -07:00
Michael Davidsaver
5525119778 test ByteBuffer array operations 2019-04-08 09:46:20 -07:00
Michael Davidsaver
6410600205 testByteBuffer cleanup 2019-04-08 09:46:16 -07:00
Michael Davidsaver
a5d44745d1 cleanup testSharedVector
"using namespace" considered harmful...
2019-04-08 09:46:07 -07:00
Michael Davidsaver
8c275cbc1c 7.1.2 2019-03-18 11:07:20 -07:00
Michael Davidsaver
b79f69231c more doxygen 2019-03-18 10:32:50 -07:00
Michael Davidsaver
ff165595c4 minor doc 2019-03-18 09:28:00 -07:00
Michael Davidsaver
4ffddfa2f6 Replace display.format with .form and .precision
Remove instance accessors w/o replacement
as a prelude to deprecation.
2019-01-16 09:06:15 -08:00
29 changed files with 509 additions and 1726 deletions

View File

@@ -1,4 +1,4 @@
EPICS_PVD_MAJOR_VERSION = 7
EPICS_PVD_MINOR_VERSION = 1
EPICS_PVD_MAJOR_VERSION = 8
EPICS_PVD_MINOR_VERSION = 0
EPICS_PVD_MAINTENANCE_VERSION = 0
EPICS_PVD_DEVELOPMENT_FLAG = 0

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = "PVData C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 7.1.0
PROJECT_NUMBER = 8.0.0
# 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
@@ -319,7 +319,7 @@ AUTOLINK_SUPPORT = YES
# diagrams that involve STL classes more complete and accurate.
# The default value is: NO.
BUILTIN_STL_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
@@ -1001,7 +1001,7 @@ VERBATIM_HEADERS = YES
# compiled with the --with-libclang option.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
CLANG_ASSISTED_PARSING = YES
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
@@ -1948,7 +1948,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO
MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -1970,7 +1970,7 @@ SEARCH_INCLUDES = YES
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
INCLUDE_PATH = ../src/misc ../src ../../../include/
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1997,7 +1997,7 @@ PREDEFINED =
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED =
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
@@ -2007,7 +2007,7 @@ EXPAND_AS_DEFINED =
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
SKIP_FUNCTION_MACROS = YES
SKIP_FUNCTION_MACROS = NO
#---------------------------------------------------------------------------
# Configuration options related to external references
@@ -2026,7 +2026,7 @@ SKIP_FUNCTION_MACROS = YES
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
TAGFILES = ../../../base-git/documentation/epics-base.tag
TAGFILES = "libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen"
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
# tag file that is based on the input files it reads. See section "Linking to
@@ -2045,14 +2045,14 @@ ALLEXTERNALS = NO
# listed.
# The default value is: YES.
EXTERNAL_GROUPS = YES
EXTERNAL_GROUPS = NO
# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
# the related pages index. If set to NO, only the current project's pages will
# be listed.
# The default value is: YES.
EXTERNAL_PAGES = YES
EXTERNAL_PAGES = NO
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').

View File

@@ -3,11 +3,14 @@ all: gen
clean:
rm -rf doxygen_sqlite3.db html
gen:
gen: libstdc++.tag
doxygen
commit: gen
touch html/.nojekyll
./commit-gh.sh documentation/html/ html/.nojekyll html/*.* html/search/*.*
libstdc++.tag:
wget -O $@ https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag
.PHONY: all clean gen commit

View File

@@ -3,7 +3,8 @@
/**
@mainpage pvDataCPP documentation
- [Download](https://sourceforge.net/projects/epics-pvdata/files/)
- This module is included in [EPICS Base releases](https://epics-controls.org/resources-and-support/base/) beginning with 7.0.1
- It may also be [Downloaded](https://github.com/epics-base/pvDataCPP/releases) and built separately.
- @htmlonly <a href="modules.html">API components</a> @endhtmlonly
- @ref release_notes

View File

@@ -2,6 +2,28 @@
@page release_notes Release Notes
Release 8.0.0 (July 2019)
=========================
- Deprecations
- ByteBuffer::getArray()
- Removals
- pv/localStaticLock.h
- pv/pvCopy.h (see epics::pvData::PVRequestMapper)
- Additions
- Add {Structure,Union}::getFieldT
Release 7.1.3 (Apr 2019)
========================
- Fix for array serialization error to/from big endian.
https://github.com/epics-base/pvDataCPP/issues/65
Release 7.1.2 (Mar 2019)
========================
- 7.1.1 tag pushed prematurely.
Release 7.1.1 (Mar 2019)
========================

View File

@@ -3,8 +3,6 @@
SRC_DIRS += $(PVDATA_SRC)/copy
INC += pv/createRequest.h
INC += pv/pvCopy.h
LIBSRCS += createRequest.cpp
LIBSRCS += requestmapper.cpp
LIBSRCS += pvCopy.cpp

View File

@@ -1,233 +0,0 @@
/* pvCopy.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author Marty Kraimer
* @date 2013.04
*/
#ifndef PVCOPY_H
#define PVCOPY_H
#include <string>
#include <stdexcept>
#include <memory>
#include <compilerDependencies.h>
#include <shareLib.h>
#include <pv/pvData.h>
#include <pv/bitSet.h>
namespace epics { namespace pvData{
class PVCopyTraverseMasterCallback;
typedef std::tr1::shared_ptr<PVCopyTraverseMasterCallback> PVCopyTraverseMasterCallbackPtr;
/**
* @brief Callback for traversing master structure
*
* Must be implemented by code that creates pvCopy.
*/
class epicsShareClass PVCopyTraverseMasterCallback
{
public:
POINTER_DEFINITIONS(PVCopyTraverseMasterCallback);
virtual ~PVCopyTraverseMasterCallback() {}
/**
* Called once for each field in master.
* @param pvField The field in master.
*/
virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField) = 0;
};
class PVCopy;
typedef std::tr1::shared_ptr<PVCopy> PVCopyPtr;
struct CopyNode;
typedef std::tr1::shared_ptr<CopyNode> CopyNodePtr;
struct CopyMasterNode;
typedef std::tr1::shared_ptr<CopyMasterNode> CopyMasterNodePtr;
struct CopyStructureNode;
typedef std::tr1::shared_ptr<CopyStructureNode> CopyStructureNodePtr;
/**
* @brief Support for subset of fields in a pvStructure.
*
* Class that manages one or more PVStructures that holds an arbitrary subset of the fields
* in another PVStructure called master.
*/
class epicsShareClass EPICS_DEPRECATED PVCopy :
public std::tr1::enable_shared_from_this<PVCopy>
{
public:
POINTER_DEFINITIONS(PVCopy);
/**
* Create a new pvCopy
* @param pvMaster The top-level structure for which a copy of
* an arbitrary subset of the fields in master will be created and managed.
* @param pvRequest Selects the set of subfields desired and options for each field.
* @param structureName The name for the top level of any PVStructure created.
*/
static PVCopyPtr create(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvRequest,
std::string const & structureName);
virtual ~PVCopy(){}
void destroy();
/**
* Get the top-level structure of master
* @returns The master top-level structure.
* This should not be modified.
*/
PVStructurePtr getPVMaster();
/**
* Traverse all the fields in master.
* @param callback This is called for each field on master.
*/
void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback)
{
traverseMaster(headNode,callback);
}
/**
* Get the introspection interface for a PVStructure for e copy.
*/
StructureConstPtr getStructure();
/**
* Create a copy instance. Monitors keep a queue of monitor elements.
* Since each element needs a PVStructure, multiple top-level structures will be created.
*/
PVStructurePtr createPVStructure();
/**
* Given a field in pvMaster. return the offset in copy for the same field.
* A value of std::string::npos means that the copy does not have this field.
* @param masterPVField The field in master.
*/
std::size_t getCopyOffset(PVFieldPtr const &masterPVField);
/**
* Given a field in pvMaster. return the offset in copy for the same field.
* A value of std::string::npos means that the copy does not have this field.
* @param masterPVStructure A structure in master that has masterPVField.
* @param masterPVField The field in master.
*/
std::size_t getCopyOffset(
PVStructurePtr const &masterPVStructure,
PVFieldPtr const &masterPVField);
/**
* Given an offset in the copy get the corresponding field in pvMaster.
* @param structureOffset The offset in the copy.
*/
PVFieldPtr getMasterPVField(std::size_t structureOffset);
/**
* Initialize the fields in copyPVStructure by giving each field
* the value from the corresponding field in pvMaster.
* bitSet will be set to show that all fields are changed.
* @param copyPVStructure A copy top-level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void initCopy(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* Set all fields in copyPVStructure to the value of the corresponding field in pvMaster.
* Each field that is changed has it's corresponding bit set in bitSet.
* @param copyPVStructure A copy top-level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void updateCopySetBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* For each set bit in bitSet
* set the field in copyPVStructure to the value of the corresponding field in pvMaster.
* @param copyPVStructure A copy top-level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void updateCopyFromBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* For each set bit in bitSet
* set the field in pvMaster to the value of the corresponding field in copyPVStructure
* @param copyPVStructure A copy top-level structure.
* @param bitSet A bitSet for copyPVStructure.
*/
void updateMaster(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet);
/**
* Get the options for the field at the specified offset.
* @param fieldOffset the offset in copy.
* @returns A NULL is returned if no options were specified for the field.
* If options were specified,PVStructurePtr is a structures
* with a set of PVString subfields that specify name,value pairs.s
* name is the subField name and value is the subField value.
*/
PVStructurePtr getOptions(std::size_t fieldOffset);
/**
* For debugging.
*/
std::string dump();
private:
void dump(
std::string *builder,
CopyNodePtr const &node,
int indentLevel);
PVCopyPtr getPtrSelf()
{
return shared_from_this();
}
void traverseMaster(CopyNodePtr const &node, PVCopyTraverseMasterCallbackPtr const & callback);
PVStructurePtr pvMaster;
StructureConstPtr structure;
CopyNodePtr headNode;
PVStructurePtr cacheInitStructure;
PVCopy(PVStructurePtr const &pvMaster);
friend class PVCopyMonitor;
bool init(PVStructurePtr const &pvRequest);
std::string dump(
std::string const &value,
CopyNodePtr const &node,
int indentLevel);
StructureConstPtr createStructure(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvFromRequest);
CopyNodePtr createStructureNodes(
PVStructurePtr const &pvMasterStructure,
PVStructurePtr const &pvFromRequest,
PVStructurePtr const &pvFromField);
void updateStructureNodeSetBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
BitSetPtr const &bitSet);
void updateSubFieldSetBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMaster,
BitSetPtr const &bitSet);
void updateStructureNodeFromBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll);
void updateSubFieldFromBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMasterField,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll);
CopyMasterNodePtr getCopyOffset(
CopyStructureNodePtr const &structureNode,
PVFieldPtr const &masterPVField);
CopyMasterNodePtr getMasterNode(
CopyStructureNodePtr const &structureNode,
std::size_t structureOffset);
};
}}
#endif /* PVCOPY_H */

View File

@@ -1,652 +0,0 @@
/* pvCopy.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author Marty Kraimer
* @date 2013.04
*/
#include <string>
#include <stdexcept>
#include <memory>
#include <sstream>
#include <epicsThread.h>
#include <compilerDependencies.h>
#undef EPICS_DEPRECATED
#define EPICS_DEPRECATED
#define epicsExportSharedSymbols
#include <pv/thread.h>
#include <pv/pvCopy.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using std::string;
using std::size_t;
using std::cout;
using std::endl;
namespace epics { namespace pvData {
/**
* Convenience method for implementing dump.
* It generates a newline and inserts blanks at the beginning of the newline.
* @param builder The std::string * being constructed.
* @param indentLevel Indent level, Each level is four spaces.
*/
static void newLine(string *buffer, int indentLevel)
{
*buffer += "\n";
*buffer += string(indentLevel*4, ' ');
}
struct CopyNode {
CopyNode()
: isStructure(false),
structureOffset(0),
nfields(0)
{}
bool isStructure;
size_t structureOffset; // In the copy
size_t nfields;
PVStructurePtr options;
};
struct CopyMasterNode : public CopyNode{
PVFieldPtr masterPVField;
};
typedef std::vector<CopyNodePtr> CopyNodePtrArray;
typedef std::tr1::shared_ptr<CopyNodePtrArray> CopyNodePtrArrayPtr;
struct CopyStructureNode : public CopyNode {
CopyNodePtrArrayPtr nodes;
};
PVCopyPtr PVCopy::create(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvRequest,
string const & structureName)
{
PVStructurePtr pvStructure(pvRequest);
if(structureName.size()>0) {
if(pvRequest->getStructure()->getNumberFields()>0) {
pvStructure = pvRequest->getSubField<PVStructure>(structureName);
if(!pvStructure) return PVCopyPtr();
}
} else if(pvStructure->getSubField<PVStructure>("field")) {
pvStructure = pvRequest->getSubField<PVStructure>("field");
}
PVCopyPtr pvCopy(new PVCopy(pvMaster));
bool result = pvCopy->init(pvStructure);
if(!result) pvCopy.reset();
return pvCopy;
}
PVCopy::PVCopy(
PVStructurePtr const &pvMaster)
: pvMaster(pvMaster)
{
}
void PVCopy::destroy()
{
headNode.reset();
}
PVStructurePtr PVCopy::getPVMaster()
{
return pvMaster;
}
void PVCopy::traverseMaster(CopyNodePtr const &innode, PVCopyTraverseMasterCallbackPtr const & callback)
{
CopyNodePtr node = innode;
if(!node->isStructure) {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(node);
callback->nextMasterPVField(masterNode->masterPVField);
return;
}
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
node = (*nodes)[i];
traverseMaster(node,callback);
}
}
StructureConstPtr PVCopy::getStructure()
{
return structure;
}
PVStructurePtr PVCopy::createPVStructure()
{
if(cacheInitStructure) {
PVStructurePtr save = cacheInitStructure;
cacheInitStructure.reset();
return save;
}
PVStructurePtr pvStructure =
getPVDataCreate()->createPVStructure(structure);
return pvStructure;
}
PVStructurePtr PVCopy::getOptions(std::size_t fieldOffset)
{
if(fieldOffset==0) return headNode->options;
CopyNodePtr node = headNode;
while(true) {
if(!node->isStructure) {
if(node->structureOffset==fieldOffset) return node->options;
return PVStructurePtr();
}
CopyStructureNodePtr structNode = static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structNode->nodes;
boolean okToContinue = false;
for(size_t i=0; i< nodes->size(); i++) {
node = (*nodes)[i];
size_t soff = node->structureOffset;
if(fieldOffset>=soff && fieldOffset<soff+node->nfields) {
if(fieldOffset==soff) return node->options;
if(!node->isStructure) {
return PVStructurePtr();
}
okToContinue = true;
break;
}
}
if(okToContinue) continue;
throw std::invalid_argument("fieldOffset not valid");
}
}
size_t PVCopy::getCopyOffset(PVFieldPtr const &masterPVField)
{
if(masterPVField->getFieldOffset()==0) return 0;
if(!headNode->isStructure) {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
if((masterNode->masterPVField.get())==masterPVField.get()) {
return headNode->structureOffset;
}
PVStructure * parent = masterPVField->getParent();
size_t offsetParent = parent->getFieldOffset();
size_t off = masterPVField->getFieldOffset();
size_t offdiff = off -offsetParent;
if(offdiff<masterNode->nfields) return headNode->structureOffset + offdiff;
return string::npos;
}
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
CopyMasterNodePtr masterNode = getCopyOffset(node,masterPVField);
if(masterNode) return masterNode->structureOffset;
return string::npos;
}
size_t PVCopy::getCopyOffset(
PVStructurePtr const &masterPVStructure,
PVFieldPtr const &masterPVField)
{
CopyMasterNodePtr masterNode;
if(!headNode->isStructure) {
masterNode = static_pointer_cast<CopyMasterNode>(headNode);
if(masterNode->masterPVField.get()!=masterPVStructure.get()) return string::npos;
} else {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
masterNode = getCopyOffset(node,masterPVField);
}
if(!masterNode) return string::npos;
size_t diff = masterPVField->getFieldOffset()
- masterPVStructure->getFieldOffset();
return masterNode->structureOffset + diff;
}
PVFieldPtr PVCopy::getMasterPVField(size_t structureOffset)
{
CopyMasterNodePtr masterNode;
if(!headNode->isStructure) {
masterNode = static_pointer_cast<CopyMasterNode>(headNode);
} else {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
masterNode = getMasterNode(node,structureOffset);
}
if(!masterNode) {
throw std::invalid_argument(
"PVCopy::getMasterPVField: setstructureOffset not valid");
}
size_t diff = structureOffset - masterNode->structureOffset;
PVFieldPtr pvMasterField = masterNode->masterPVField;
if(diff==0) return pvMasterField;
PVStructurePtr pvStructure
= static_pointer_cast<PVStructure>(pvMasterField);
return pvStructure->getSubField(
pvMasterField->getFieldOffset() + diff);
}
void PVCopy::initCopy(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bitSet->clear();
bitSet->set(0);
updateCopyFromBitSet(copyPVStructure,bitSet);
}
void PVCopy::updateCopySetBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
if(headNode->isStructure) {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeSetBitSet(copyPVStructure,node,bitSet);
} else {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
PVFieldPtr pvMasterField= masterNode->masterPVField;
PVFieldPtr copyPVField = copyPVStructure;
PVFieldPtr pvField = pvMasterField;
if(pvField->getField()->getType()==epics::pvData::structure) {
updateSubFieldSetBitSet(copyPVField,pvMasterField,bitSet);
return;
}
bool isEqual = (*copyPVField == *pvField);
if(!isEqual) {
copyPVField->copyUnchecked(*pvField);
bitSet->set(copyPVField->getFieldOffset());
}
}
}
void PVCopy::updateCopyFromBitSet(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bool doAll = bitSet->get(0);
if(headNode->isStructure) {
CopyStructureNodePtr node = static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeFromBitSet(copyPVStructure,node,bitSet,true,doAll);
} else {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(headNode);
updateSubFieldFromBitSet(copyPVStructure, masterNode->masterPVField,bitSet, true,doAll);
}
}
void PVCopy::updateMaster(
PVStructurePtr const &copyPVStructure,
BitSetPtr const &bitSet)
{
bool doAll = bitSet->get(0);
if(headNode->isStructure) {
CopyStructureNodePtr node =
static_pointer_cast<CopyStructureNode>(headNode);
updateStructureNodeFromBitSet(
copyPVStructure,node,bitSet,false,doAll);
} else {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(headNode);
updateSubFieldFromBitSet( copyPVStructure,masterNode->masterPVField,bitSet,false,doAll);
}
}
string PVCopy::dump()
{
string builder;
dump(&builder,headNode,0);
return builder;
}
void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
{
newLine(builder,indentLevel);
std::stringstream ss;
ss << (node->isStructure ? "structureNode" : "masterNode");
ss << " structureOffset " << node->structureOffset;
ss << " nfields " << node->nfields;
*builder += ss.str();
PVStructurePtr options = node->options;
if(options) {
newLine(builder,indentLevel +1);
// TODO !!! ugly
std::ostringstream oss;
oss << *options;
*builder += oss.str();
newLine(builder,indentLevel);
}
if(!node->isStructure) {
CopyMasterNodePtr masterNode = static_pointer_cast<CopyMasterNode>(node);
string name = masterNode->masterPVField->getFullName();
*builder += " masterField " + name;
return;
}
CopyStructureNodePtr structureNode =
static_pointer_cast<CopyStructureNode>(node);
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); ++i) {
if((*nodes)[i].get()==NULL) {
newLine(builder,indentLevel +1);
ss.str("");
ss << "node[" << i << "] is null";
*builder += ss.str();
continue;
}
dump(builder,(*nodes)[i],indentLevel+1);
}
}
bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
{
PVStructurePtr pvMasterStructure = pvMaster;
size_t len = pvRequest->getPVFields().size();
bool entireMaster = false;
if(len==string::npos) entireMaster = true;
if(len==0) entireMaster = true;
PVStructurePtr pvOptions;
if(len==1) {
pvOptions = pvRequest->getSubField<PVStructure>("_options");
}
if(entireMaster) {
structure = pvMasterStructure->getStructure();
CopyMasterNodePtr masterNode(new CopyMasterNode());
headNode = masterNode;
masterNode->options = pvOptions;
masterNode->isStructure = false;
masterNode->structureOffset = 0;
masterNode->masterPVField = pvMasterStructure;
masterNode->nfields = pvMasterStructure->getNumberFields();
return true;
}
structure = createStructure(pvMasterStructure,pvRequest);
if(!structure) return false;
cacheInitStructure = createPVStructure();
headNode = createStructureNodes(
pvMaster,
pvRequest,
cacheInitStructure);
return true;
}
string PVCopy::dump(
string const &value,
CopyNodePtr const &node,
int indentLevel)
{
throw std::logic_error(string("Not Implemented"));
}
StructureConstPtr PVCopy::createStructure(
PVStructurePtr const &pvMaster,
PVStructurePtr const &pvFromRequest)
{
if(pvFromRequest->getStructure()->getNumberFields()==0) {
return pvMaster->getStructure();
}
PVFieldPtrArray const &pvFromRequestFields = pvFromRequest->getPVFields();
StringArray const &fromRequestFieldNames = pvFromRequest->getStructure()->getFieldNames();
size_t length = pvFromRequestFields.size();
if(length==0) return StructureConstPtr();
FieldConstPtrArray fields; fields.reserve(length);
StringArray fieldNames; fields.reserve(length);
for(size_t i=0; i<length; ++i) {
string const &fieldName = fromRequestFieldNames[i];
PVFieldPtr pvMasterField = pvMaster->getSubField(fieldName);
if(!pvMasterField) continue;
FieldConstPtr field = pvMasterField->getField();
if(field->getType()==epics::pvData::structure) {
PVStructurePtr pvRequestStructure = static_pointer_cast<PVStructure>(
pvFromRequestFields[i]);
if(pvRequestStructure->getNumberFields()>0) {
StringArray const &names = pvRequestStructure->getStructure()->
getFieldNames();
size_t num = names.size();
if(num>0 && names[0].compare("_options")==0) --num;
if(num>0) {
if(pvMasterField->getField()->getType()!=epics::pvData::structure) continue;
fieldNames.push_back(fieldName);
fields.push_back(createStructure(
static_pointer_cast<PVStructure>(pvMasterField),
pvRequestStructure));
continue;
}
}
}
fieldNames.push_back(fieldName);
fields.push_back(field);
}
size_t numsubfields = fields.size();
if(numsubfields==0) return StructureConstPtr();
return getFieldCreate()->createStructure(fieldNames, fields);
}
CopyNodePtr PVCopy::createStructureNodes(
PVStructurePtr const &pvMasterStructure,
PVStructurePtr const &pvFromRequest,
PVStructurePtr const &pvFromCopy)
{
PVFieldPtrArray const & copyPVFields = pvFromCopy->getPVFields();
PVStructurePtr pvOptions;
PVFieldPtr pvField = pvFromRequest->getSubField("_options");
if(pvField) pvOptions = static_pointer_cast<PVStructure>(pvField);
size_t number = copyPVFields.size();
CopyNodePtrArrayPtr nodes(new CopyNodePtrArray());
nodes->reserve(number);
for(size_t i=0; i<number; i++) {
PVFieldPtr copyPVField = copyPVFields[i];
string fieldName = copyPVField->getFieldName();
PVStructurePtr requestPVStructure = pvFromRequest->getSubField<PVStructure>(fieldName);
PVStructurePtr pvSubFieldOptions = requestPVStructure->getSubField<PVStructure>("_options");
PVFieldPtr pvMasterField;
PVFieldPtrArray const & pvMasterFields = pvMasterStructure->getPVFields();
for(size_t j=0; i<pvMasterFields.size(); j++ ) {
if(pvMasterFields[j]->getFieldName().compare(fieldName)==0) {
pvMasterField = pvMasterFields[j];
break;
}
}
size_t numberRequest = requestPVStructure->getPVFields().size();
if(pvSubFieldOptions) numberRequest--;
if(numberRequest>0) {
nodes->push_back(createStructureNodes(
static_pointer_cast<PVStructure>(pvMasterField),
requestPVStructure,
static_pointer_cast<PVStructure>(copyPVField)));
continue;
}
CopyMasterNodePtr masterNode(new CopyMasterNode());
masterNode->options = pvSubFieldOptions;
masterNode->isStructure = false;
masterNode->masterPVField = pvMasterField;
masterNode->nfields = copyPVField->getNumberFields();
masterNode->structureOffset = copyPVField->getFieldOffset();
nodes->push_back(masterNode);
}
CopyStructureNodePtr structureNode(new CopyStructureNode());
structureNode->isStructure = true;
structureNode->nodes = nodes;
structureNode->structureOffset = pvFromCopy->getFieldOffset();
structureNode->nfields = pvFromCopy->getNumberFields();
structureNode->options = pvOptions;
return structureNode;
}
void PVCopy::updateStructureNodeSetBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
epics::pvData::BitSetPtr const &bitSet)
{
for(size_t i=0; i<structureNode->nodes->size(); i++) {
CopyNodePtr node = (*structureNode->nodes)[i];
PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset);
if(node->isStructure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
CopyStructureNodePtr yyy =
static_pointer_cast<CopyStructureNode>(node);
updateStructureNodeSetBitSet(xxx,yyy,bitSet);
} else {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
updateSubFieldSetBitSet(pvField,masterNode->masterPVField,bitSet);
}
}
}
void PVCopy::updateSubFieldSetBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMaster,
BitSetPtr const &bitSet)
{
FieldConstPtr field = pvCopy->getField();
Type type = field->getType();
if(type!=epics::pvData::structure) {
bool isEqual = (*pvCopy == *pvMaster);
if(isEqual) {
if(type==structureArray) {
// always act as though a change occurred.
// Note that array elements are shared.
bitSet->set(pvCopy->getFieldOffset());
}
}
if(isEqual) return;
pvCopy->copyUnchecked(*pvMaster);
bitSet->set(pvCopy->getFieldOffset());
return;
}
PVStructurePtr pvCopyStructure = static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
PVStructurePtr pvMasterStructure =
static_pointer_cast<PVStructure>(pvMaster);
PVFieldPtrArray const & pvMasterFields =
pvMasterStructure->getPVFields();
size_t length = pvCopyFields.size();
for(size_t i=0; i<length; i++) {
updateSubFieldSetBitSet(pvCopyFields[i],pvMasterFields[i],bitSet);
}
}
void PVCopy::updateStructureNodeFromBitSet(
PVStructurePtr const &pvCopy,
CopyStructureNodePtr const &structureNode,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll)
{
size_t offset = structureNode->structureOffset;
if(!doAll) {
size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==string::npos) return;
}
if(offset>=pvCopy->getNextFieldOffset()) return;
if(!doAll) doAll = bitSet->get(offset);
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i<nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
PVFieldPtr pvField = pvCopy->getSubFieldT(node->structureOffset);
if(node->isStructure) {
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
CopyStructureNodePtr subStructureNode =
static_pointer_cast<CopyStructureNode>(node);
updateStructureNodeFromBitSet(
xxx,subStructureNode,bitSet,toCopy,doAll);
} else {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
updateSubFieldFromBitSet(
pvField,masterNode->masterPVField,bitSet,toCopy,doAll);
}
}
}
void PVCopy::updateSubFieldFromBitSet(
PVFieldPtr const &pvCopy,
PVFieldPtr const &pvMasterField,
BitSetPtr const &bitSet,
bool toCopy,
bool doAll)
{
if(!doAll) {
doAll = bitSet->get(pvCopy->getFieldOffset());
}
if(!doAll) {
size_t offset = pvCopy->getFieldOffset();
size_t nextSet = bitSet->nextSetBit(offset);
if(nextSet==string::npos) return;
if(nextSet>=pvCopy->getNextFieldOffset()) return;
}
if(pvCopy->getField()->getType()==epics::pvData::structure) {
PVStructurePtr pvCopyStructure =
static_pointer_cast<PVStructure>(pvCopy);
PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields();
if(pvMasterField->getField()->getType() !=epics::pvData::structure)
{
throw std::logic_error(string("Logic error"));
}
PVStructurePtr pvMasterStructure =
static_pointer_cast<PVStructure>(pvMasterField);
PVFieldPtrArray const & pvMasterFields =
pvMasterStructure->getPVFields();
for(size_t i=0; i<pvCopyFields.size(); i++) {
updateSubFieldFromBitSet(
pvCopyFields[i],
pvMasterFields[i],
bitSet,toCopy,doAll);
}
} else {
if(toCopy) {
pvCopy->copyUnchecked(*pvMasterField);
} else {
pvMasterField->copyUnchecked(*pvCopy);
}
}
}
CopyMasterNodePtr PVCopy::getCopyOffset(
CopyStructureNodePtr const &structureNode,
PVFieldPtr const &masterPVField)
{
size_t offset = masterPVField->getFieldOffset();
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
if(!node->isStructure) {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
size_t off = masterNode->masterPVField->getFieldOffset();
size_t nextOffset = masterNode->masterPVField->getNextFieldOffset();
if(offset>= off && offset<nextOffset) return masterNode;
} else {
CopyStructureNodePtr subNode =
static_pointer_cast<CopyStructureNode>(node);
CopyMasterNodePtr masterNode =
getCopyOffset(subNode,masterPVField);
if(masterNode) return masterNode;
}
}
return CopyMasterNodePtr();
}
CopyMasterNodePtr PVCopy::getMasterNode(
CopyStructureNodePtr const &structureNode,
std::size_t structureOffset)
{
CopyNodePtrArrayPtr nodes = structureNode->nodes;
for(size_t i=0; i< nodes->size(); i++) {
CopyNodePtr node = (*nodes)[i];
if(structureOffset>=(node->structureOffset + node->nfields)) continue;
if(!node->isStructure) {
CopyMasterNodePtr masterNode =
static_pointer_cast<CopyMasterNode>(node);
return masterNode;
}
CopyStructureNodePtr subNode =
static_pointer_cast<CopyStructureNode>(node);
return getMasterNode(subNode,structureOffset);
}
return CopyMasterNodePtr();
}
}}

View File

@@ -551,6 +551,21 @@ size_t Structure::getFieldIndex(string const &fieldName) const {
return -1;
}
FieldConstPtr Structure::getFieldImpl(string const & fieldName, bool throws) const {
for(size_t i=0, N=fields.size(); i<N; i++)
if(fieldName==fieldNames[i])
return fields[i];
if (throws) {
std::stringstream ss;
ss << "Failed to get field: "
<< fieldName << " (not found)";
throw std::runtime_error(ss.str());
} else {
return FieldConstPtr();
}
}
std::ostream& Structure::dump(std::ostream& o) const
{
o << format::indent() << getID() << std::endl;
@@ -750,6 +765,21 @@ size_t Union::getFieldIndex(string const &fieldName) const {
return -1;
}
FieldConstPtr Union::getFieldImpl(string const & fieldName, bool throws) const {
for(size_t i=0, N=fields.size(); i<N; i++)
if(fieldName==fieldNames[i])
return fields[i];
if (throws) {
std::stringstream ss;
ss << "Failed to get field: "
<< fieldName << " (not found)";
throw std::runtime_error(ss.str());
} else {
return FieldConstPtr();
}
}
std::ostream& Union::dump(std::ostream& o) const
{
o << format::indent() << getID() << std::endl;

View File

@@ -758,6 +758,18 @@ template class PVScalarValue<uint64>;
template class PVScalarValue<float>;
template class PVScalarValue<double>;
template class PVScalarValue<std::string>;
template class PVValueArray<boolean>;
template class PVValueArray<int8>;
template class PVValueArray<uint8>;
template class PVValueArray<int16>;
template class PVValueArray<uint16>;
template class PVValueArray<int32>;
template class PVValueArray<uint32>;
template class PVValueArray<int64>;
template class PVValueArray<uint64>;
template class PVValueArray<float>;
template class PVValueArray<double>;
template class PVValueArray<std::string>;
}} // namespace epics::pvData

View File

@@ -15,7 +15,6 @@ INC += pv/timer.h
INC += pv/status.h
INC += pv/sharedPtr.h
INC += pv/debugPtr.h
INC += pv/localStaticLock.h
INC += pv/typeCast.h
INC += pv/sharedVector.h
INC += pv/templateMeta.h
@@ -31,7 +30,6 @@ LIBSRCS += serializeHelper.cpp
LIBSRCS += event.cpp
LIBSRCS += timer.cpp
LIBSRCS += status.cpp
LIBSRCS += localStaticLock.cpp
LIBSRCS += typeCast.cpp
LIBSRCS += thread.cpp
LIBSRCS += parseToPOD.cpp

View File

@@ -1,39 +0,0 @@
/* localStaticLock.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mse
*/
#define epicsExportSharedSymbols
#include <pv/localStaticLock.h>
static int nifty_counter;
static epics::pvData::Mutex* g_localStaticInitMutex;
epics::pvData::Mutex& getLocalStaticInitMutex()
{
return *g_localStaticInitMutex;
}
// The counter is initialized at load-time, i.e., before any of the static objects are initialized.
MutexInitializer::MutexInitializer ()
{
if (0 == nifty_counter++)
{
// Initialize static members.
g_localStaticInitMutex = new epics::pvData::Mutex();
}
}
MutexInitializer::~MutexInitializer ()
{
if (0 == --nifty_counter)
{
// Clean-up.
delete g_localStaticInitMutex;
}
}

View File

@@ -16,6 +16,7 @@
#include <epicsEndian.h>
#include <shareLib.h>
#include <epicsAssert.h>
#include <compilerDependencies.h>
#include <pv/templateMeta.h>
#include <pv/pvType.h>
@@ -695,7 +696,7 @@ public:
EPICS_ALWAYS_INLINE double getDouble (std::size_t index) { return get<double>(index); }
// TODO remove
EPICS_ALWAYS_INLINE const char* getArray() const
EPICS_ALWAYS_INLINE const char* getArray() const EPICS_DEPRECATED
{
return _buffer;
}
@@ -803,8 +804,8 @@ private:
assert(n<=getRemaining());
if (reverse<T>()) {
for(std::size_t i=0; i<n; i+=sizeof(T)) {
detail::store_unaligned(_position+i, swap<T>(values[i]));
for(std::size_t i=0; i<count; i++) {
detail::store_unaligned(_position+i*sizeof(T), swap<T>(values[i]));
}
} else {
memcpy(_position, values, n);
@@ -819,8 +820,8 @@ private:
assert(n<=getRemaining());
if (reverse<T>()) {
for(std::size_t i=0; i<n; i+=sizeof(T)) {
values[i] = swap<T>(detail::load_unaligned<T>(_position+i));
for(std::size_t i=0; i<count; i++) {
values[i] = swap<T>(detail::load_unaligned<T>(_position+i*sizeof(T)));
}
} else {
memcpy(values, _position, n);

View File

@@ -1,34 +0,0 @@
/* localStaticLock.h */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mse
*/
#ifndef LOCALSTATICLOCK_H
#define LOCALSTATICLOCK_H
#include <compilerDependencies.h>
#include <pv/lock.h>
#include <shareLib.h>
epicsShareExtern epics::pvData::Mutex& getLocalStaticInitMutex() EPICS_DEPRECATED;
#if defined(__GNUC__) && __GNUC__ >= 4
// noop
#define LOCAL_STATIC_LOCK
#else
#define LOCAL_STATIC_LOCK epics::pvData::Lock localStaticInitMutexLock(getLocalStaticInitMutex());
#endif
static class epicsShareClass MutexInitializer {
public:
MutexInitializer ();
~MutexInitializer ();
} localStaticMutexInitializer; // Note object here in the header.
#endif /* LOCALSTATICLOCK_H */

View File

@@ -28,7 +28,7 @@
public:
...
};
@code
@endcode
*
* @note This macro contains 'private:'.
*/

View File

@@ -158,7 +158,7 @@ public:
Thread(std::string name,
ThreadPriority priority,
Runnable *runnable,
epicsThreadStackSizeClass stkcls=epicsThreadStackSmall);
epicsThreadStackSizeClass stkcls=epicsThreadStackBig);
/**
*

View File

@@ -223,7 +223,7 @@ void RefMonitor::start(double period)
impl->period = period;
impl->worker.reset(new epicsThread(*impl,
"RefMonitor",
epicsThreadGetStackSize(epicsThreadStackSmall),
epicsThreadGetStackSize(epicsThreadStackBig),
epicsThreadPriorityMin));
impl->worker->start();
}

View File

@@ -109,7 +109,7 @@ namespace epics {
{
// entire string is in buffer, simply create a string out of it (copy)
std::size_t pos = buffer->getPosition();
string str(buffer->getArray()+pos, size);
string str(buffer->getBuffer()+pos, size);
buffer->setPosition(pos+size);
return str;
}
@@ -122,7 +122,7 @@ namespace epics {
while(true) {
std::size_t toRead = min(size-i, buffer->getRemaining());
std::size_t pos = buffer->getPosition();
str.append(buffer->getArray()+pos, toRead);
str.append(buffer->getBuffer()+pos, toRead);
buffer->setPosition(pos+toRead);
i += toRead;
if(i<size)

View File

@@ -52,7 +52,7 @@ void Thread::Config::x_setdefault()
this->p_prio = epicsThreadPriorityLow;
this->p_autostart = true;
this->p_runner = NULL;
(*this).stack(epicsThreadStackSmall);
(*this).stack(epicsThreadStackBig);
}
size_t Thread::num_instances;

View File

@@ -17,6 +17,8 @@
#include <iostream>
#include <iomanip>
#include <epicsAssert.h>
#include <pv/pvIntrospect.h>
#include <pv/typeCast.h>
#include <pv/anyscalar.h>
@@ -237,6 +239,7 @@ public:
void copyUnchecked(const PVField& from);
static size_t num_instances; // use atomic::get() or volatile* access
enum {isPVField=1};
protected:
PVField::shared_pointer getPtrSelf()
{
@@ -762,12 +765,14 @@ public:
template<typename PVD, typename A>
inline std::tr1::shared_ptr<PVD> getSubField(A a)
{
STATIC_ASSERT(PVD::isPVField); // only allow cast from PVField sub-class
return std::tr1::dynamic_pointer_cast<PVD>(getSubFieldImpl(a, false));
}
template<typename PVD, typename A>
inline std::tr1::shared_ptr<const PVD> getSubField(A a) const
{
STATIC_ASSERT(PVD::isPVField); // only allow cast from PVField sub-class
return std::tr1::dynamic_pointer_cast<const PVD>(getSubFieldImpl(a, false));
}
@@ -800,6 +805,7 @@ public:
template<typename PVD, typename A>
inline std::tr1::shared_ptr<PVD> getSubFieldT(A a)
{
STATIC_ASSERT(PVD::isPVField); // only allow cast from PVField sub-class
std::tr1::shared_ptr<PVD> ret(std::tr1::dynamic_pointer_cast<PVD>(getSubFieldImpl(a, true)));
if(!ret)
throwBadFieldType(a);
@@ -809,6 +815,7 @@ public:
template<typename PVD, typename A>
inline std::tr1::shared_ptr<const PVD> getSubFieldT(A a) const
{
STATIC_ASSERT(PVD::isPVField); // only allow cast from PVField sub-class
std::tr1::shared_ptr<const PVD> ret(std::tr1::dynamic_pointer_cast<const PVD>(getSubFieldImpl(a, true)));
if(!ret)
throwBadFieldType(a);
@@ -963,11 +970,13 @@ public:
template<typename PVT>
inline std::tr1::shared_ptr<PVT> get() {
STATIC_ASSERT(PVT::isPVField); // only allow cast from PVField sub-class
return std::tr1::dynamic_pointer_cast<PVT>(get());
}
template<typename PVT>
inline std::tr1::shared_ptr<const PVT> get() const {
STATIC_ASSERT(PVT::isPVField); // only allow cast from PVField sub-class
return std::tr1::dynamic_pointer_cast<const PVT>(get());
}
@@ -981,6 +990,7 @@ public:
template<typename PVT>
inline std::tr1::shared_ptr<PVT> select(int32 index) {
STATIC_ASSERT(PVT::isPVField); // only allow cast from PVField sub-class
return std::tr1::dynamic_pointer_cast<PVT>(select(index));
}

View File

@@ -14,6 +14,8 @@
#include <iostream>
#include <map>
#include <epicsAssert.h>
#include <pv/lock.h>
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
@@ -361,6 +363,8 @@ public:
//! @version Added after 7.0.0
std::tr1::shared_ptr<PVField> build() const;
enum {isField=1};
protected:
/**
* Constructor
@@ -713,40 +717,96 @@ public:
* @return The number of fields.
*/
std::size_t getNumberFields() const {return fieldNames.size();}
/**
* Get the field for the specified fieldName.
* @param fieldName The name of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
* Lookup Field by name
* @param fieldName Member field name. May not contain '.'
* @return NULL if no member by this name.
*/
FieldConstPtr getField(std::string const &fieldName) const;
/** Lookup Field by name and cast to Field sub-class.
* @param fieldName Member field name. May not contain '.'
* @return NULL If no member by this name, or member exists, but has type other than FT.
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getField(std::string const &fieldName) const
{
FieldConstPtr field(getField(fieldName));
if (field)
return std::tr1::dynamic_pointer_cast<const FT>(field);
else
return std::tr1::shared_ptr<const FT>();
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
return std::tr1::dynamic_pointer_cast<const FT>(getField(fieldName));
}
/**
* Get the field for the specified fieldName.
* @param index The index of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
* Lookup Field by name
* @param fieldName Member field name. May not contain '.'
* @return Field pointer (never NULL)
* @throws std::runtime_error If no member by this name
*/
FieldConstPtr getFieldT(std::string const &fieldName) const {return getFieldImpl(fieldName, true);};
/** Lookup Field by name and cast to Field sub-class.
* @param fieldName Member field name. May not contain '.'
* @return Field pointer (never NULL)
* @throws std::runtime_error If no member by this name, or member exists, but has type other than FT.
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getFieldT(std::string const &fieldName) const
{
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
std::tr1::shared_ptr<const FT> result(
std::tr1::dynamic_pointer_cast<const FT>(getFieldT(fieldName))
);
if (!result)
throw std::runtime_error("Wrong Field type");
return result;
}
/** Lookup Field by index, within this Structure.
* @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
* @return Field pointer (never NULL)
* @throws std::out_of_range If index >= getNumberFields()
*/
const FieldConstPtr& getField(std::size_t index) const {return fields.at(index);}
/** Lookup Field by index, within this Structure.
* @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
* @return NULL if member is not a sub-class of FT
* @throws std::out_of_range If index >= getNumberFields()
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getField(std::size_t index) const
{
const FieldConstPtr& field(getField(index));
if (field)
return std::tr1::dynamic_pointer_cast<const FT>(field);
else
return std::tr1::shared_ptr<const FT>();
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
return std::tr1::dynamic_pointer_cast<const FT>(getField(index));
}
/** Lookup Field by index, within this Structure.
* @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
* @return Field pointer (never NULL)
* @throws std::out_of_range If index >= getNumberFields()
*/
FieldConstPtr getFieldT(std::size_t index) const {return fields.at(index);}
/** Lookup Field by index, within this Structure.
* @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
* @return Field pointer (never NULL)
* @throws std::out_of_range If index >= getNumberFields()
* @throws std::runtime_error If member is not a sub-class of FT
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getFieldT(std::size_t index) const
{
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
std::tr1::shared_ptr<const FT> result(
std::tr1::dynamic_pointer_cast<const FT>(getFieldT(index))
);
if (!result)
throw std::runtime_error("Wrong Field type");
return result;
}
/**
@@ -790,6 +850,7 @@ private:
FieldConstPtrArray fields;
std::string id;
FieldConstPtr getFieldImpl(const std::string& fieldName, bool throws) const;
void dumpFields(std::ostream& o) const;
friend class FieldCreate;
@@ -836,40 +897,96 @@ public:
* @return The number of fields.
*/
std::size_t getNumberFields() const {return fieldNames.size();}
/**
* Get the field for the specified fieldName.
* @param fieldName The name of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the union.
* Lookup Field by name
* @param fieldName Member field name. May not contain '.'
* @return NULL if no member by this name.
*/
FieldConstPtr getField(std::string const &fieldName) const;
/** Lookup Field by name and cast to Field sub-class.
* @param fieldName Member field name. May not contain '.'
* @return NULL If no member by this name, or member exists, but has type other than FT.
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getField(std::string const &fieldName) const
{
FieldConstPtr field = getField(fieldName);
if (field)
return std::tr1::dynamic_pointer_cast<const FT>(field);
else
return std::tr1::shared_ptr<const FT>();
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
return std::tr1::dynamic_pointer_cast<const FT>(getField(fieldName));
}
/**
* Get the field for the specified fieldName.
* @param index The index of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the union.
* Lookup Field by name
* @param fieldName Member field name. May not contain '.'
* @return Field pointer (never NULL)
* @throws std::runtime_error If no member by this name
*/
FieldConstPtr getFieldT(std::string const &fieldName) const {return getFieldImpl(fieldName, true);};
/** Lookup Field by name and cast to Field sub-class.
* @param fieldName Member field name. May not contain '.'
* @return Field pointer (never NULL)
* @throws std::runtime_error If no member by this name, or member exists, but has type other than FT.
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getFieldT(std::string const &fieldName) const
{
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
std::tr1::shared_ptr<const FT> result(
std::tr1::dynamic_pointer_cast<const FT>(getFieldT(fieldName))
);
if (!result)
throw std::runtime_error("Wrong Field type");
return result;
}
/** Lookup Field by index, within this Union.
* @param index Index of member in this union. @code index>=0 && index<getNumberFields() @endcode
* @return Field pointer (never NULL)
* @throws std::out_of_range If index >= getNumberFields()
*/
FieldConstPtr getField(std::size_t index) const {return fields.at(index);}
/** Lookup Field by index, within this Union.
* @param index Index of member in this union. @code index>=0 && index<getNumberFields() @endcode
* @return NULL if member is not a sub-class of FT
* @throws std::out_of_range If index >= getNumberFields()
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getField(std::size_t index) const
{
FieldConstPtr field = getField(index);
if (field)
return std::tr1::dynamic_pointer_cast<const FT>(field);
else
return std::tr1::shared_ptr<const FT>();
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
return std::tr1::dynamic_pointer_cast<const FT>(getField(index));
}
/** Lookup Field by index, within this Union.
* @param index Index of member in this union. @code index>=0 && index<getNumberFields() @endcode
* @return Field pointer (never NULL)
* @throws std::out_of_range If index >= getNumberFields()
*/
FieldConstPtr getFieldT(std::size_t index) const {return fields.at(index);}
/** Lookup Field by index, within this Structure.
* @param index Index of member in this structure. @code index>=0 && index<getNumberFields() @endcode
* @return Field pointer (never NULL)
* @throws std::out_of_range If index >= getNumberFields()
* @throws std::runtime_error If member is not a sub-class of FT
*/
template<typename FT>
std::tr1::shared_ptr<const FT> getFieldT(std::size_t index) const
{
STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class
std::tr1::shared_ptr<const FT> result(
std::tr1::dynamic_pointer_cast<const FT>(getFieldT(index))
);
if (!result)
throw std::runtime_error("Wrong Field type");
return result;
}
/**
@@ -929,7 +1046,8 @@ private:
StringArray fieldNames;
FieldConstPtrArray fields;
std::string id;
FieldConstPtr getFieldImpl(const std::string& fieldName, bool throws) const;
void dumpFields(std::ostream& o) const;
friend class FieldCreate;

View File

@@ -74,7 +74,7 @@ struct ValueBuilder::child_scalar_array : public ValueBuilder::child
{
builder->addArray(name, array.original_type());
}
virtual void store(const PVFieldPtr& val)
virtual void store(const PVFieldPtr& val) OVERRIDE FINAL
{
if(val->getField()->getType()!=scalarArray)
THROW_EXCEPTION2(std::logic_error, "Scalar Array type mis-match");

View File

@@ -6,8 +6,3 @@ TESTPROD_HOST += testCreateRequest
testCreateRequest_SRCS = testCreateRequest.cpp
testHarness_SRCS += testCreateRequest.cpp
TESTS += testCreateRequest
TESTPROD_HOST += testPVCopy
testPVCopy_SRCS += testPVCopy.cpp
testHarness_SRCS += testPVCopy.cpp
TESTS += testPVCopy

View File

@@ -1,299 +0,0 @@
/*testPVCopyMain.cpp */
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/**
* @author mrk
*/
/* Author: Marty Kraimer */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <iostream>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <compilerDependencies.h>
#undef EPICS_DEPRECATED
#define EPICS_DEPRECATED
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/convert.h>
#include <pv/pvCopy.h>
#include <pv/createRequest.h>
using namespace std;
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
static void testPVScalar(
string const & valueNameMaster,
string const & valueNameCopy,
PVStructurePtr const & pvMaster,
PVCopyPtr const & pvCopy)
{
PVStructurePtr pvStructureCopy;
PVScalarPtr pvValueMaster;
PVScalarPtr pvValueCopy;
BitSetPtr bitSet;
ConvertPtr convert = getConvert();
pvValueMaster = pvMaster->getSubField<PVScalar>(valueNameMaster);
convert->fromDouble(pvValueMaster,.04);
StructureConstPtr structure = pvCopy->getStructure();
pvStructureCopy = pvCopy->createPVStructure();
pvValueCopy = pvStructureCopy->getSubField<PVScalar>(valueNameCopy);
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
pvCopy->initCopy(pvStructureCopy, bitSet);
convert->fromDouble(pvValueMaster,.06);
testOk1(convert->toDouble(pvValueCopy)==.04);
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
testOk1(convert->toDouble(pvValueCopy)==.06);
testOk1(bitSet->get(pvValueCopy->getFieldOffset()));
pvCopy->getCopyOffset(pvValueMaster);
bitSet->clear();
convert->fromDouble(pvValueMaster,1.0);
bitSet->set(0);
testOk1(convert->toDouble(pvValueCopy)==0.06);
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet);
testOk1(convert->toDouble(pvValueCopy)==1.0);
convert->fromDouble(pvValueCopy,2.0);
bitSet->set(0);
testOk1(convert->toDouble(pvValueMaster)==1.0);
pvCopy->updateMaster(pvStructureCopy,bitSet);
testOk1(convert->toDouble(pvValueMaster)==2.0);
}
static void testPVScalarArray(
string const & valueNameMaster,
string const & valueNameCopy,
PVStructurePtr const & pvMaster,
PVCopyPtr const & pvCopy)
{
PVStructurePtr pvStructureCopy;
PVScalarArrayPtr pvValueMaster;
PVScalarArrayPtr pvValueCopy;
BitSetPtr bitSet;
size_t n = 5;
shared_vector<double> values(n);
shared_vector<const double> cvalues;
pvValueMaster = pvMaster->getSubField<PVScalarArray>(valueNameMaster);
for(size_t i=0; i<n; i++) values[i] = i;
const shared_vector<const double> xxx(freeze(values));
pvValueMaster->putFrom(xxx);
StructureConstPtr structure = pvCopy->getStructure();
pvStructureCopy = pvCopy->createPVStructure();
pvValueCopy = pvStructureCopy->getSubField<PVScalarArray>(valueNameCopy);
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
pvCopy->initCopy(pvStructureCopy, bitSet);
values.resize(n);
for(size_t i=0; i<n; i++) values[i] = i + .06;
const shared_vector<const double> yyy(freeze(values));
pvValueMaster->putFrom(yyy);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==0.0);
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==0.06);
pvCopy->getCopyOffset(pvValueMaster);
bitSet->clear();
values.resize(n);
for(size_t i=0; i<n; i++) values[i] = i + 1.0;
const shared_vector<const double> zzz(freeze(values));
pvValueMaster->putFrom(zzz);
bitSet->set(0);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==0.06);
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet);
pvValueCopy->getAs(cvalues);
testOk1(cvalues[0]==1.0);
values.resize(n);
for(size_t i=0; i<n; i++) values[i] = i + 2.0;
const shared_vector<const double> ttt(freeze(values));
pvValueMaster->putFrom(ttt);
bitSet->set(0);
pvValueMaster->getAs(cvalues);
testOk1(cvalues[0]==2.0);
pvCopy->updateMaster(pvStructureCopy,bitSet);
pvValueMaster->getAs(cvalues);
testOk1(cvalues[0]==1.0);
}
static void scalarTest()
{
testDiag("scalarTest()");
PVStructurePtr pvMaster;
string request;
PVStructurePtr pvRequest;
PVFieldPtr pvMasterField;
PVCopyPtr pvCopy;
string valueNameMaster;
string valueNameCopy;
StandardPVFieldPtr standardPVField = getStandardPVField();
pvMaster = standardPVField->scalar(pvDouble,"alarm,timeStamp,display");
valueNameMaster = request = "value";
CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,value";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
}
static void arrayTest()
{
testDiag("arrayTest");
PVStructurePtr pvMaster;
string request;
PVStructurePtr pvRequest;
PVFieldPtr pvMasterField;
PVCopyPtr pvCopy;
string valueNameMaster;
string valueNameCopy;
CreateRequest::shared_pointer createRequest = CreateRequest::create();
StandardPVFieldPtr standardPVField = getStandardPVField();
pvMaster = standardPVField->scalarArray(pvDouble,"alarm,timeStamp");
valueNameMaster = request = "value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalarArray(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalarArray(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,value";
valueNameMaster = "value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "value";
testPVScalarArray(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
}
static PVStructurePtr createPowerSupply()
{
FieldCreatePtr fieldCreate = getFieldCreate();
StandardFieldPtr standardField = getStandardField();
PVDataCreatePtr pvDataCreate = getPVDataCreate();
size_t nfields = 5;
StringArray names;
names.reserve(nfields);
FieldConstPtrArray powerSupply;
powerSupply.reserve(nfields);
names.push_back("alarm");
powerSupply.push_back(standardField->alarm());
names.push_back("timeStamp");
powerSupply.push_back(standardField->timeStamp());
string properties("alarm,display");
names.push_back("voltage");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
names.push_back("power");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
names.push_back("current");
powerSupply.push_back(standardField->scalar(pvDouble,properties));
return pvDataCreate->createPVStructure(
fieldCreate->createStructure(names,powerSupply));
}
static void powerSupplyTest()
{
testDiag("powerSupplyTest");
PVStructurePtr pvMaster;
string request;
PVStructurePtr pvRequest;
PVFieldPtr pvMasterField;
PVCopyPtr pvCopy;
string builder;
string valueNameMaster;
string valueNameCopy;
CreateRequest::shared_pointer createRequest = CreateRequest::create();
pvMaster = createPowerSupply();
valueNameMaster = request = "power.value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "";
valueNameMaster = "power.value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,voltage.value,power.value,current.value";
valueNameMaster = "power.value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value";
valueNameMaster = "power.value";
pvRequest = createRequest->createRequest(request);
pvCopy = PVCopy::create(pvMaster,pvRequest,"");
valueNameCopy = "power.value";
testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy);
}
MAIN(testPVCopy)
{
testPlan(67);
scalarTest();
arrayTest();
powerSupplyTest();
return testDone();
}

View File

@@ -14,15 +14,13 @@
#include <cstring>
#include <memory>
#include <epicsUnitTest.h>
#include <testMain.h>
#include <pv/pvUnitTest.h>
#include <pv/byteBuffer.h>
#include <pv/pvIntrospect.h>
using namespace epics::pvData;
using std::string;
using std::cout;
static
void testBasicOperations() {
@@ -175,7 +173,7 @@ void testBasicOperations() {
testOk1(buff->getPosition()==6);
testOk1(strncmp(&src[2],&dst[2],6)==0);
cout<<"# First 10 characters of destination: >>"<<string(dst, 10)<<"<<\n";
testShow()<<"First 10 characters of destination: >>"<<std::string(dst, 10)<<"<<\n";
}
static const char expect_be[] = "abcdef";
@@ -253,14 +251,68 @@ void testUnaligned()
testOk1(memcmp(buf.getBuffer(), "\x42\x12\x34\x56\x78\x90\xab\xcd\xef\x41\x41\x41", 8)==0);
}
static
void testArrayLE()
{
testDiag("testArray() LE");
ByteBuffer buf(8, EPICS_ENDIAN_LITTLE);
std::vector<uint32> vals;
vals.push_back(0x12345678);
vals.push_back(0x01020304);
buf.putArray(&vals[0], vals.size());
testEqual(buf.getPosition(), 8u);
testOk1(memcmp(buf.getBuffer(), "\x78\x56\x34\x12\x04\x03\x02\x01", 8)==0);
buf.clear();
buf.put("\x40\x30\x20\x10\xa4\xa3\xa2\xa1", 0, 8);
buf.flip();
buf.getArray(&vals[0], 2);
testEqual(vals[0], 0x10203040u);
testEqual(vals[1], 0xa1a2a3a4u);
}
static
void testArrayBE()
{
testDiag("testArray() BE");
ByteBuffer buf(8, EPICS_ENDIAN_BIG);
std::vector<uint32> vals;
vals.push_back(0x12345678u);
vals.push_back(0x01020304u);
buf.putArray(&vals[0], vals.size());
testEqual(buf.getPosition(), 8u);
testOk1(memcmp(buf.getBuffer(), "\x12\x34\x56\x78\x01\x02\x03\x04", 8)==0);
buf.clear();
buf.put("\x10\x20\x30\x40\xa1\xa2\xa3\xa4", 0, 8);
buf.flip();
buf.getArray(&vals[0], 2);
testEqual(vals[0], 0x10203040u);
testEqual(vals[1], 0xa1a2a3a4u);
}
MAIN(testByteBuffer)
{
testPlan(96);
testPlan(104);
testDiag("Tests byteBuffer");
testBasicOperations();
testInverseEndianness(EPICS_ENDIAN_BIG, expect_be);
testInverseEndianness(EPICS_ENDIAN_LITTLE, expect_le);
testSwap();
testUnaligned();
testArrayLE();
testArrayBE();
return testDone();
}

View File

@@ -17,15 +17,14 @@
#include "pv/sharedVector.h"
using std::string;
using namespace epics::pvData;
namespace {
namespace pvd = epics::pvData;
void testEmpty()
{
testDiag("Test empty vector");
epics::pvData::shared_vector<int32> empty, empty2, empty3(0u);
pvd::shared_vector<pvd::int32> empty, empty2, empty3(0u);
testOk1(empty.size()==0);
testOk1(empty.empty());
@@ -47,7 +46,7 @@ void testInternalAlloc()
{
testDiag("Test vector alloc w/ new[]");
epics::pvData::shared_vector<int32> internal(5);
pvd::shared_vector<pvd::int32> internal(5);
testOk1(internal.size()==5);
testOk1(!internal.empty());
@@ -62,7 +61,7 @@ void testInternalAlloc()
internal[2] = 42;
testOk1(internal[2]==42);
epics::pvData::shared_vector<int32> internal2(15, 500);
pvd::shared_vector<pvd::int32> internal2(15, 500);
testOk1(internal2.size()==15);
testOk1(internal2[1]==500);
@@ -83,8 +82,8 @@ void testInternalAlloc()
//Note: STL shared_ptr requires that deletors be copy constructable
template<typename E>
struct callCounter {
std::tr1::shared_ptr<int32> count;
callCounter():count(new int32){*count=0;}
std::tr1::shared_ptr<pvd::int32> count;
callCounter():count(new pvd::int32){*count=0;}
callCounter(const callCounter& o):count(o.count) {}
callCounter& operator=(const callCounter& o){count=o.count;}
void operator()(E){(*count)++;}
@@ -95,8 +94,8 @@ void testExternalAlloc()
testDiag("Test vector external alloc");
// Simulate a failed malloc() or similar
int32 *oops=0;
epics::pvData::shared_vector<int32> nullPtr(oops, 42, 100);
pvd::int32 *oops=0;
pvd::shared_vector<pvd::int32> nullPtr(oops, 42, 100);
testOk1(nullPtr.size()==0);
testOk1(nullPtr.empty());
@@ -105,8 +104,8 @@ void testExternalAlloc()
testOk1(nullPtr.data()==NULL);
int32 *raw=new int32[5];
epics::pvData::shared_vector<int32> newData(raw, 1, 4);
pvd::int32 *raw=new pvd::int32[5];
pvd::shared_vector<pvd::int32> newData(raw, 1, 4);
testOk1(newData.size()==4);
testOk1(!newData.empty());
@@ -116,11 +115,11 @@ void testExternalAlloc()
testOk1(newData[0]==14);
// Check use of custom deleter
int32 localVar[4] = {1,2,3,4};
callCounter<int32*> tracker;
pvd::int32 localVar[4] = {1,2,3,4};
callCounter<pvd::int32*> tracker;
testOk1(*tracker.count==0);
epics::pvData::shared_vector<int32> locvar(localVar,
pvd::shared_vector<pvd::int32> locvar(localVar,
tracker,
0, 4);
@@ -140,8 +139,8 @@ void testShare()
{
testDiag("Test vector Sharing");
epics::pvData::shared_vector<int32> one, two(15);
epics::pvData::shared_vector<int32> three(two);
pvd::shared_vector<pvd::int32> one, two(15);
pvd::shared_vector<pvd::int32> three(two);
testOk1(one.unique());
testOk1(!two.unique());
@@ -202,22 +201,22 @@ void testConst()
{
testDiag("Test constant vector");
epics::pvData::shared_vector<int32> writable(15, 100);
pvd::shared_vector<pvd::int32> writable(15, 100);
epics::pvData::shared_vector<int32>::reference wr = writable[0];
epics::pvData::shared_vector<int32>::const_reference ror = writable[0];
pvd::shared_vector<pvd::int32>::reference wr = writable[0];
pvd::shared_vector<pvd::int32>::const_reference ror = writable[0];
testOk1(wr==ror);
int32 *compare = writable.data();
pvd::int32 *compare = writable.data();
testOk1(writable.unique());
// can re-target container, but data is R/O
epics::pvData::shared_vector<const int32> rodata(freeze(writable));
pvd::shared_vector<const pvd::int32> rodata(freeze(writable));
epics::pvData::shared_vector<const int32>::reference wcr = rodata[0];
epics::pvData::shared_vector<const int32>::const_reference rocr = rodata[0];
pvd::shared_vector<const pvd::int32>::reference wcr = rodata[0];
pvd::shared_vector<const pvd::int32>::const_reference rocr = rodata[0];
testOk1(wcr==rocr);
@@ -230,7 +229,7 @@ void testConst()
testOk1(rodata.data()==compare);
epics::pvData::shared_vector<const int32> rodata2(rodata);
pvd::shared_vector<const pvd::int32> rodata2(rodata);
testOk1(rodata.data()==rodata2.data());
@@ -243,9 +242,9 @@ void testSlice()
{
testDiag("Test vector slicing");
epics::pvData::shared_vector<int32> original(10, 100);
pvd::shared_vector<pvd::int32> original(10, 100);
epics::pvData::shared_vector<int32> half1(original), half2(original), half2a(original);
pvd::shared_vector<pvd::int32> half1(original), half2(original), half2a(original);
half1.slice(0, 5);
half2.slice(5, 5);
@@ -293,9 +292,9 @@ void testCapacity()
{
testDiag("Test vector capacity");
epics::pvData::shared_vector<int32> vect(10, 100);
pvd::shared_vector<pvd::int32> vect(10, 100);
int32 *peek = vect.dataPtr().get();
pvd::int32 *peek = vect.dataPtr().get();
vect.slice(0, 5);
@@ -333,7 +332,7 @@ void testCapacity()
void testPush()
{
epics::pvData::shared_vector<int32> vect;
pvd::shared_vector<pvd::int32> vect;
testDiag("Test push_back optimizations");
@@ -360,16 +359,16 @@ void testVoid()
{
testDiag("Test vector cast to/from void");
epics::pvData::shared_vector<int32> IV(4);
pvd::shared_vector<pvd::int32> IV(4);
epics::pvData::shared_vector<void> VV(epics::pvData::static_shared_vector_cast<void>(IV));
pvd::shared_vector<void> VV(pvd::static_shared_vector_cast<void>(IV));
testOk1(IV.dataPtr().get()==VV.dataPtr().get());
testOk1(IV.size()*sizeof(int)==VV.size());
testOk1(IV.size()*sizeof(pvd::int32)==VV.size());
VV.slice(sizeof(int), 2*sizeof(int));
VV.slice(sizeof(pvd::int32), 2*sizeof(pvd::int32));
IV = epics::pvData::static_shared_vector_cast<int32>(VV);
IV = pvd::static_shared_vector_cast<pvd::int32>(VV);
testOk1(IV.dataOffset()==1);
testOk1(IV.size()==2);
@@ -380,23 +379,23 @@ void testConstVoid()
{
testDiag("Test vector cast to/from const void");
epics::pvData::shared_vector<const int32> CIV(4);
pvd::shared_vector<const pvd::int32> CIV(4);
epics::pvData::shared_vector<const void> CVV(epics::pvData::static_shared_vector_cast<const void>(CIV));
pvd::shared_vector<const void> CVV(pvd::static_shared_vector_cast<const void>(CIV));
// case const void to const void
epics::pvData::shared_vector<const void> CVV2(epics::pvData::static_shared_vector_cast<const void>(CVV));
pvd::shared_vector<const void> CVV2(pvd::static_shared_vector_cast<const void>(CVV));
testOk1(CIV.dataPtr().get()==CVV2.dataPtr().get());
testOk1(CIV.size()*sizeof(int)==CVV2.size());
CVV2.slice(sizeof(int), 2*sizeof(int));
CIV = epics::pvData::static_shared_vector_cast<const int32>(CVV2);
CIV = pvd::static_shared_vector_cast<const pvd::int32>(CVV2);
testOk1(CIV.dataOffset()==1);
testOk1(CIV.size()==2);
epics::pvData::shared_vector<void> VV;
pvd::shared_vector<void> VV;
// not possible to thaw() void as shared_vector<void> has no make_unique()
//VV = thaw(CVV);
CVV = freeze(VV);
@@ -408,8 +407,8 @@ void testNonPOD()
{
testDiag("Test vector of non-POD types");
epics::pvData::shared_vector<string> strings(6);
epics::pvData::shared_vector<std::tr1::shared_ptr<dummyStruct> > structs(5);
pvd::shared_vector<std::string> strings(6);
pvd::shared_vector<std::tr1::shared_ptr<dummyStruct> > structs(5);
testOk1(strings[0].empty());
testOk1(structs[0].get()==NULL);
@@ -417,7 +416,7 @@ void testNonPOD()
structs[1].reset(new dummyStruct);
dummyStruct *temp = structs[1].get();
epics::pvData::shared_vector<std::tr1::shared_ptr<dummyStruct> > structs2(structs);
pvd::shared_vector<std::tr1::shared_ptr<dummyStruct> > structs2(structs);
testOk1(!structs.unique());
testOk1(structs[1].unique());
@@ -436,22 +435,22 @@ void testVectorConvert()
{
testDiag("Test shared_vector_convert");
epics::pvData::shared_vector<int32> ints(6, 42), moreints;
epics::pvData::shared_vector<float> floats;
epics::pvData::shared_vector<string> strings;
epics::pvData::shared_vector<void> voids;
pvd::shared_vector<pvd::int32> ints(6, 42), moreints;
pvd::shared_vector<float> floats;
pvd::shared_vector<std::string> strings;
pvd::shared_vector<void> voids;
testOk1(ints.unique());
// no-op convert. Just returns another reference
moreints = epics::pvData::shared_vector_convert<int32>(ints);
moreints = pvd::shared_vector_convert<pvd::int32>(ints);
testOk1(!ints.unique());
moreints.clear();
// conversion when both types are known.
// returns a new vector
floats = epics::pvData::shared_vector_convert<float>(ints);
floats = pvd::shared_vector_convert<float>(ints);
testOk1(ints.unique());
testOk1(floats.size()==ints.size());
@@ -459,16 +458,16 @@ void testVectorConvert()
// convert to void is static_shared_vector_cast<void>()
// returns a reference
voids = epics::pvData::shared_vector_convert<void>(ints);
voids = pvd::shared_vector_convert<void>(ints);
testOk1(!ints.unique());
testOk1(voids.size()==ints.size()*sizeof(int32));
testOk1(voids.size()==ints.size()*sizeof(pvd::int32));
// convert from void uses shared_vector<void>::original_type()
// to find that the actual type is 'int32'.
// returns a new vector
testOk1(voids.original_type()==epics::pvData::pvInt);
strings = epics::pvData::shared_vector_convert<string>(voids);
testOk1(voids.original_type()==pvd::pvInt);
strings = pvd::shared_vector_convert<std::string>(voids);
voids.clear();
@@ -481,11 +480,11 @@ void testWeak()
{
testDiag("Test weak_ptr counting");
epics::pvData::shared_vector<int32> data(6);
pvd::shared_vector<pvd::int32> data(6);
testOk1(data.unique());
std::tr1::shared_ptr<int32> pdata(data.dataPtr());
std::tr1::shared_ptr<pvd::int32> pdata(data.dataPtr());
testOk1(!data.unique());
@@ -493,7 +492,7 @@ void testWeak()
testOk1(data.unique());
std::tr1::weak_ptr<int32> wdata(data.dataPtr());
std::tr1::weak_ptr<pvd::int32> wdata(data.dataPtr());
testOk1(data.unique()); // True, but I wish it wasn't!!!
@@ -506,16 +505,16 @@ void testICE()
{
testDiag("Test freeze and thaw");
epics::pvData::shared_vector<int32> A(6, 42), C;
epics::pvData::shared_vector<const int32> B, D;
pvd::shared_vector<pvd::int32> A(6, 42), C;
pvd::shared_vector<const pvd::int32> B, D;
int32 *check = A.data();
pvd::int32 *check = A.data();
// check freeze w/ unique reference
// clears A and moves reference to B
// no copy
B = epics::pvData::freeze(A);
B = pvd::freeze(A);
testOk1(A.unique());
testOk1(B.unique());
@@ -528,7 +527,7 @@ void testICE()
// clears D, but reference to B
// remains, so a copy is made
C = epics::pvData::thaw(D);
C = pvd::thaw(D);
testOk1(B.unique());
testOk1(C.unique());
@@ -542,7 +541,7 @@ void testICE()
// clears B and moves reference to A
// no copy
A = epics::pvData::thaw(B);
A = pvd::thaw(B);
testOk1(A.unique());
testOk1(B.unique());
@@ -559,7 +558,7 @@ void testICE()
// would clear A, but remaining reference C
// fails operation. A not cleared
// and exception thrown
B = epics::pvData::freeze(A);
B = pvd::freeze(A);
testFail("Froze non-unique vector!");
} catch(std::runtime_error& e) {
testPass("freeze of non-unique throws runtime_error as expected");
@@ -568,12 +567,12 @@ void testICE()
void testBad()
{
epics::pvData::shared_vector<int> I;
epics::pvData::shared_vector<const int> CI;
epics::pvData::shared_vector<float> F;
epics::pvData::shared_vector<const float> CF;
epics::pvData::shared_vector<void> V;
epics::pvData::shared_vector<const void> CV;
pvd::shared_vector<int> I;
pvd::shared_vector<const int> CI;
pvd::shared_vector<float> F;
pvd::shared_vector<const float> CF;
pvd::shared_vector<void> V;
pvd::shared_vector<const void> CV;
(void)I;
(void)CI;
(void)F;
@@ -588,38 +587,38 @@ void testBad()
// No copy from const to non-const
//CI = I;
//I = CI;
//epics::pvData::shared_vector<const int> CI2(I);
//epics::pvData::shared_vector<int> I2(CI);
//pvd::shared_vector<const int> CI2(I);
//pvd::shared_vector<int> I2(CI);
// shared_vector_convert can't thaw()
//I = epics::pvData::shared_vector_convert<int>(CI);
//V = epics::pvData::shared_vector_convert<void>(CV);
//I = pvd::shared_vector_convert<int>(CI);
//V = pvd::shared_vector_convert<void>(CV);
// shared_vector_convert can't freeze()
//CI = epics::pvData::shared_vector_convert<const int>(I);
//CV = epics::pvData::shared_vector_convert<const void>(V);
//CI = pvd::shared_vector_convert<const int>(I);
//CV = pvd::shared_vector_convert<const void>(V);
// static_shared_vector_cast can't thaw()
//I = epics::pvData::static_shared_vector_cast<int>(CI);
//V = epics::pvData::static_shared_vector_cast<void>(CV);
//I = pvd::static_shared_vector_cast<int>(CI);
//V = pvd::static_shared_vector_cast<void>(CV);
// static_shared_vector_cast can't freeze()
//CI = epics::pvData::static_shared_vector_cast<const int>(I);
//CV = epics::pvData::static_shared_vector_cast<const void>(V);
//CI = pvd::static_shared_vector_cast<const int>(I);
//CV = pvd::static_shared_vector_cast<const void>(V);
// freeze() can't change type.
// the error here will be with the assignment
//I = epics::pvData::freeze(CV);
//I = epics::pvData::freeze(CF);
//CI = epics::pvData::freeze(V);
//CI = epics::pvData::freeze(F);
//I = pvd::freeze(CV);
//I = pvd::freeze(CF);
//CI = pvd::freeze(V);
//CI = pvd::freeze(F);
// that() can't change type.
// the error here will be with the assignment
//CI = epics::pvData::thaw(V);
//CI = epics::pvData::thaw(F);
//I = epics::pvData::thaw(CV);
//I = epics::pvData::that(CF);
//CI = pvd::thaw(V);
//CI = pvd::thaw(F);
//I = pvd::thaw(CV);
//I = pvd::that(CF);
}
void testAutoSwap()
@@ -636,8 +635,8 @@ void testCXX11Move()
{
#if __cplusplus>=201103L
testDiag("Check std::move()");
shared_vector<int32> A(4, 42),
B(std::move(A));
pvd::shared_vector<pvd::int32> A(4, 42),
B(std::move(A));
testOk1(A.unique());
testOk1(B.unique());
@@ -653,8 +652,8 @@ void testCXX11Move()
testOk1(A.size()==4);
testOk1(!A.empty() && A[0]==42);
shared_vector<void> C(shared_vector_convert<void>(A)),
D(std::move(C));
pvd::shared_vector<void> C(pvd::shared_vector_convert<void>(A)),
D(std::move(C));
A.clear();
testOk1(C.unique());
@@ -678,11 +677,11 @@ void testCXX11Init()
#if __cplusplus>=201103L
testDiag("Check c++11 style array initialization");
shared_vector<const int32> A = {1.0, 2.0, 3.0};
pvd::shared_vector<const pvd::int32> A = {1.0, 2.0, 3.0};
testOk1(A.size()==3);
int32 sum = 0;
pvd::int32 sum = 0;
for (auto V: A) {
sum += V;
}
@@ -699,8 +698,8 @@ MAIN(testSharedVector)
testPlan(191);
testDiag("Tests for shared_vector");
testDiag("sizeof(shared_vector<int32>)=%lu",
(unsigned long)sizeof(epics::pvData::shared_vector<int32>));
testDiag("sizeof(shared_vector<pvd::int32>)=%lu",
(unsigned long)sizeof(pvd::shared_vector<pvd::int32>));
testEmpty();
testInternalAlloc();

View File

@@ -1,294 +0,0 @@
/*
* Network configuration -- QEMU NOT using DHCP
*
************************************************************
* EDIT THIS FILE TO REFLECT YOUR NETWORK CONFIGURATION *
* BEFORE RUNNING ANY RTEMS PROGRAMS WHICH USE THE NETWORK! *
************************************************************
*
* The dynamic probing is based upon the EPICS network
* configuration file written by:
* W. Eric Norum
* eric.norum@usask.ca
* (306) 966-5394
*/
#ifndef _RTEMS_NETWORKCONFIG_H_
#define _RTEMS_NETWORKCONFIG_H_
/* #define USE_LIBBSDPORT */
#if defined(USE_LIBBSDPORT)
#include <bsp/libbsdport_api.h>
#define CONFIGURE_MAXIMUM_TIMERS 10
#endif
/*
* For TFTP test application
*/
#if (defined (RTEMS_USE_BOOTP))
#define RTEMS_TFTP_TEST_HOST_NAME "BOOTP_HOST"
#define RTEMS_TFTP_TEST_FILE_NAME "BOOTP_FILE"
#else
#define RTEMS_TFTP_TEST_HOST_NAME "XXX.YYY.ZZZ.XYZ"
#define RTEMS_TFTP_TEST_FILE_NAME "tftptest"
#endif
/*
* For NFS test application
*
* NFS mount and a directory to ls once mounted
*/
#define RTEMS_NFS_SERVER "192.168.1.210"
#define RTEMS_NFS_SERVER_PATH "/home"
#define RTEMS_NFS_LS_PATH "/mnt/nfstest"
/*
* This file can be copied to an application source directory
* and modified to override the values shown below.
*
* The following CPP symbols may be passed from the Makefile:
*
* symbol default description
*
* NETWORK_TASK_PRIORITY 150 can be read by app from public
* var 'gesysNetworkTaskPriority'
* FIXED_IP_ADDR <undefined> hardcoded IP address (e.g.,
* "192.168.0.10"); disables BOOTP;
* must also define FIXED_NETMASK
* FIXED_NETMASK <undefined> IP netmask string
* (e.g. "255.255.255.0")
* MULTI_NETDRIVER <undefined> ugly hack; if defined try to probe
* a variety of PCI and ISA drivers
* (i386 ONLY) use is discouraged!
* NIC_NAME <undefined> Ethernet driver name (e.g. "pcn1");
* must also define NIC_ATTACH
* NIC_ATTACH <undefined> Ethernet driver attach function
* (e.g., rtems_fxp_attach).
* If these are undefined then
* a) MULTI_NETDRIVER is used
* (if defined)
* b) RTEMS_BSP_NETWORK_DRIVER_NAME/
* RTEMS_BSP_NETWORK_DRIVER_ATTACH
* are tried
* MEMORY_CUSTOM <undefined> Allocate the defined amount of
* memory for mbufs and mbuf clusters,
* respectively. Define to a comma ','
* separated pair of two numerical
* values, e.g: 100*1024,200*1024
* MEMORY_SCARCE <undefined> Allocate few memory for mbufs
* (hint for how much memory the
* board has)
* MEMORY_HUGE <undefined> Allocate a lot of memory for mbufs
* (hint for how much memory the
* board has)
* If none of MEMORY_CUSTOM/
* MEMORY_SCARCE/MEMORY_HUGE are
* defined then a medium amount of
* memory is allocated for mbufs.
*/
#include <rtems/bspIo.h>
#include <bsp.h>
#include <rtems/rtems_bsdnet.h>
#if 0
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#include "verscheck.h"
#endif
#endif
//#define MULTI_NETDRIVER
//#define RTEMS_BSP_NETWORK_DRIVER_NAME 1
#define FIXED_IP_ADDR "192.168.1.249"
#define FIXED_NETMASK "255.255.255.0"
#ifndef NETWORK_TASK_PRIORITY
#define NETWORK_TASK_PRIORITY 150 /* within EPICS' range */
#endif
/* make publicly available for startup scripts... */
const int gesysNetworkTaskPriority = NETWORK_TASK_PRIORITY;
#ifdef FIXED_IP_ADDR
#define RTEMS_DO_BOOTP 0
#else
#define RTEMS_DO_BOOTP rtems_bsdnet_do_bootp
#define FIXED_IP_ADDR 0
#undef FIXED_NETMASK
#define FIXED_NETMASK 0
#endif
#if !defined(NIC_NAME)
#ifdef MULTI_NETDRIVER
#if 0
#if RTEMS_VERSION_ATLEAST(4,6,99)
#define pcib_init pci_initialize
#endif
#endif
extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int);
extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int);
extern int rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *, int);
extern int rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *, int);
/* these don't probe and will be used even if there's no device :-( */
extern int rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *, int);
extern int rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *, int);
static struct rtems_bsdnet_ifconfig isa_netdriver_config[] = {
{
"ep0", rtems_3c509_driver_attach, isa_netdriver_config + 1,
},
{
"ne1", rtems_ne_driver_attach, 0, irno: 9 /* qemu cannot configure irq-no :-(; has it hardwired to 9 */
},
};
static struct rtems_bsdnet_ifconfig pci_netdriver_config[]={
{
"dc1", rtems_dec21140_driver_attach, pci_netdriver_config+1,
},
#if !defined(USE_LIBBSDPORT)
{
"fxp1", rtems_fxp_attach, pci_netdriver_config+2,
},
#else
{
"", libbsdport_netdriver_attach, pci_netdriver_config+2,
},
#endif
{
"elnk1", rtems_elnk_driver_attach, isa_netdriver_config,
},
};
static int pci_check(struct rtems_bsdnet_ifconfig *ocfg, int attaching)
{
struct rtems_bsdnet_ifconfig *cfg;
int if_index_pre;
extern int if_index;
if ( attaching ) {
cfg = pci_initialize() ?
isa_netdriver_config : pci_netdriver_config;
}
while ( cfg ) {
printk("Probing '%s'", cfg->name);
/* unfortunately, the return value is unreliable - some drivers report
* success even if they fail.
* Check if they chained an interface (ifnet) structure instead
*/
if_index_pre = if_index;
cfg->attach(cfg, attaching);
if ( if_index > if_index_pre ) {
/* assume success */
printk(" .. seemed to work\n");
ocfg->name = cfg->name;
ocfg->attach = cfg->attach;
return 0;
}
printk(" .. failed\n");
cfg = cfg->next;
}
return -1;
}
#define NIC_NAME "dummy"
#define NIC_ATTACH pci_check
#else
#if defined(RTEMS_BSP_NETWORK_DRIVER_NAME) /* Use NIC provided by BSP */
/* force ne2k_isa on i386 for qemu */
#if defined(__i386__)
# define NIC_NAME BSP_NE2000_NETWORK_DRIVER_NAME
# define NIC_ATTACH BSP_NE2000_NETWORK_DRIVER_ATTACH
#else
# define NIC_NAME RTEMS_BSP_NETWORK_DRIVER_NAME
# define NIC_ATTACH RTEMS_BSP_NETWORK_DRIVER_ATTACH
#endif
#endif
#endif /* ifdef MULTI_NETDRIVER */
#endif
#ifdef NIC_NAME
extern int NIC_ATTACH();
#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH
static char ethernet_address[6] = { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x34 };
#endif
static struct rtems_bsdnet_ifconfig netdriver_config[1] = {{
NIC_NAME, /* name */
(int (*)(struct rtems_bsdnet_ifconfig*,int))NIC_ATTACH, /* attach function */
0, /* link to next interface */
FIXED_IP_ADDR,
FIXED_NETMASK
#if RTEMS_BSP_NETWORK_DRIVER_ATTACH == BSP_NE2000_NETWORK_DRIVER_ATTACH
,
ethernet_address,
irno:9,
port:0xc100
#endif
}};
#else
#warning "NO KNOWN NETWORK DRIVER FOR THIS BSP -- YOU MAY HAVE TO EDIT networkconfig.h"
#endif
struct rtems_bsdnet_config rtems_bsdnet_config = {
#ifdef NIC_NAME
netdriver_config, /* link to next interface */
RTEMS_DO_BOOTP, /* Use BOOTP to get network configuration */
#else
0,
0,
#endif
NETWORK_TASK_PRIORITY, /* Network task priority */
#if defined(MEMORY_CUSTOM)
MEMORY_CUSTOM,
#elif defined(MEMORY_SCARCE)
100*1024, /* MBUF space */
200*1024, /* MBUF cluster space */
#elif defined(MEMORY_HUGE)
2*1024*1024, /* MBUF space */
5*1024*1024, /* MBUF cluster space */
#else
180*1024, /* MBUF space */
350*1024, /* MBUF cluster space */
#endif
#if (!defined (RTEMS_USE_BOOTP)) && defined(ON_RTEMS_LAB_WINSYSTEMS)
"rtems", /* Host name */
"nodomain.com", /* Domain name */
"192.168.1.14", /* Gateway */
"192.168.1.1", /* Log host */
{"89.212.75.6" }, /* Name server(s) */
{"192.168.1.1" }, /* NTP server(s) */
#else
NULL, /* Host name */
NULL, /* Domain name */
NULL, /* Gateway */
NULL, /* Log host */
{ NULL }, /* Name server(s) */
{ NULL }, /* NTP server(s) */
#endif /* !RTEMS_USE_BOOTP */
0, /* efficiency */
0, /* udp TX buffer */
0, /* udp RX buffer */
0, /* tcp TX buffer */
0, /* tcp RX buffer */
};
#endif /* _RTEMS_NETWORKCONFIG_H_ */

View File

@@ -146,6 +146,54 @@ static void testStructure()
testOk1(struct1->getFieldName(0)==names1[0]);
testOk1(struct1->getFieldName(1)==names1[1]);
testOk1(struct1->getField("nonexistent").get()==NULL);
try {
FieldConstPtr field(struct1->getField(9999));
testFail("struct1->getField(9999): missing expected exception");
} catch (std::out_of_range& e) {
testPass("struct1->getField(9999): caught expected exception: %s", e.what());
}
testOk1(struct1->getFieldT("innerA")==fields1[0]);
testOk1(struct1->getFieldT("innerB")==fields1[1]);
testOk1(struct1->getFieldT(0)==fields1[0]);
testOk1(struct1->getFieldT(1)==fields1[1]);
try {
FieldConstPtr field(struct1->getFieldT("nonexistent"));
testFail("struct1->getFieldT('nonexistent'): missing required exception");
} catch (std::runtime_error& e) {
testPass("struct1->getFieldT('nonexistent'): caught expected exception: %s", e.what());
}
try {
FieldConstPtr field(struct1->getFieldT(9999));
testFail("struct1->getFieldT(9999): missing required exception");
} catch (std::out_of_range& e) {
testPass("struct1->getFieldT(9999): caught expected exception: %s", e.what());
}
testOk1(struct1->getField<Scalar>("innerA").get()!=NULL);
testOk1(struct1->getField<Structure>("innerA").get()==NULL);
testOk1(struct1->getField<ScalarArray>(1).get()!=NULL);
testOk1(struct1->getField<Structure>(1).get()==NULL);
testOk1(struct1->getFieldT<Scalar>("innerA").get()!=NULL);
try {
StructureConstPtr s(struct1->getFieldT<Structure>("innerA"));
testFail("struct1->getFieldT<Structure>('innnerA'): missing required exception");
} catch (std::runtime_error& e) {
testPass("struct1->getFieldT<Structure>('innnerA'): caught expected exception: %s", e.what());
}
testOk1(struct1->getFieldT<ScalarArray>(1).get()!=NULL);
try {
StructureConstPtr s(struct1->getFieldT<Structure>(1));
testFail("struct1->getFieldT<Structure>(1): missing required exception");
} catch (std::runtime_error& e) {
testPass("struct1->getFieldT<Structure>(1): caught expected exception: %s", e.what());
}
testOk1(struct1->getID() == Structure::DEFAULT_ID);
testOk1(fields1 == struct1->getFields()); // vector equality
@@ -190,6 +238,55 @@ static void testUnion()
testOk1(union1->getFieldName(0)==names1[0]);
testOk1(union1->getFieldName(1)==names1[1]);
testOk1(union1->getField("nonexistent").get()==NULL);
try {
FieldConstPtr field(union1->getField(9999).get());
testFail("union1->getField(9999): missing expected exception");
} catch (std::out_of_range& e) {
testPass("union1->getField(9999): caught expected exception: %s", e.what());
}
testOk1(union1->getFieldT("innerA")==fields1[0]);
testOk1(union1->getFieldT("innerB")==fields1[1]);
testOk1(union1->getFieldT(0)==fields1[0]);
testOk1(union1->getFieldT(1)==fields1[1]);
try {
FieldConstPtr field(union1->getFieldT("nonexistent"));
testFail("union1->getFieldT('nonexistent'): missing required exception");
} catch (std::runtime_error& e) {
testPass("union1->getFieldT('nonexistent'): caught expected exception: %s", e.what());
}
try {
FieldConstPtr field(union1->getFieldT(9999));
testFail("union1->getFieldT(9999): missing required exception");
} catch (std::out_of_range& e) {
testPass("union1->getFieldT(9999): caught expected exception: %s", e.what());
}
testOk1(union1->getField<Scalar>("innerA").get()!=NULL);
testOk1(union1->getField<Structure>("innerA").get()==NULL);
testOk1(union1->getField<ScalarArray>(1).get()!=NULL);
testOk1(union1->getField<Structure>(1).get()==NULL);
testOk1(union1->getFieldT<Scalar>("innerA").get()!=NULL);
try {
StructureConstPtr s(union1->getFieldT<Structure>("innerA"));
testFail("union1->getFieldT<Structure>('innnerA'): missing required exception");
} catch (std::runtime_error& e) {
testPass("union1->getFieldT<Structure>('innnerA'): caught expected exception: %s", e.what());
}
testOk1(union1->getFieldT<ScalarArray>(1).get()!=NULL);
try {
StructureConstPtr s(union1->getFieldT<Structure>(1));
testFail("union1->getFieldT<Structure>(1): missing required exception");
} catch (std::runtime_error& e) {
testPass("union1->getFieldT<Structure>(1): caught expected exception: %s", e.what());
}
testOk1(union1->getID() == Union::DEFAULT_ID);
testOk1(fields1 == union1->getFields()); // vector equality
@@ -311,7 +408,7 @@ static void testMapping()
MAIN(testIntrospect)
{
testPlan(326);
testPlan(358);
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();

View File

@@ -16,7 +16,6 @@
/* copy */
int testCreateRequest(void);
int testPVCopy(void);
/* misc */
int testBaseException(void);
@@ -81,7 +80,6 @@ void pvDataAllTests(void)
/* copy */
runTest(testCreateRequest);
runTest(testPVCopy);
/* property */
runTest(testCreateRequest);