Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ceaa6adb0 | ||
|
|
0447826e7c | ||
|
|
3ef60a61a2 | ||
|
|
31802a8bde | ||
|
|
c2bc77a649 | ||
|
|
4dd7a18301 | ||
|
|
a29894ee2b | ||
|
|
2f8ac7f673 | ||
|
|
b050fbbcbe | ||
|
|
caa11605fc | ||
|
|
cfcdd1a3f9 | ||
|
|
95ff606ba1 | ||
|
|
4cc9b650c5 | ||
|
|
cd2436342d | ||
|
|
3ae2d09fe3 | ||
|
|
35b3403de6 | ||
|
|
f780ebdf76 | ||
|
|
93f0518b4b | ||
|
|
6da871fa64 | ||
|
|
d53cb0cbc9 | ||
|
|
8f0111e482 | ||
|
|
5525119778 | ||
|
|
6410600205 | ||
|
|
a5d44745d1 | ||
|
|
8c275cbc1c | ||
|
|
b79f69231c | ||
|
|
ff165595c4 | ||
|
|
4ffddfa2f6 |
@@ -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
|
||||
|
||||
@@ -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').
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
========================
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ©PVStructure,
|
||||
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 ©PVStructure,
|
||||
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 ©PVStructure,
|
||||
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 ©PVStructure,
|
||||
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 */
|
||||
@@ -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 ©PVStructure,
|
||||
BitSetPtr const &bitSet)
|
||||
{
|
||||
bitSet->clear();
|
||||
bitSet->set(0);
|
||||
updateCopyFromBitSet(copyPVStructure,bitSet);
|
||||
}
|
||||
|
||||
void PVCopy::updateCopySetBitSet(
|
||||
PVStructurePtr const ©PVStructure,
|
||||
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 ©PVStructure,
|
||||
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 ©PVStructure,
|
||||
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();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
@@ -28,7 +28,7 @@
|
||||
public:
|
||||
...
|
||||
};
|
||||
@code
|
||||
@endcode
|
||||
*
|
||||
* @note This macro contains 'private:'.
|
||||
*/
|
||||
|
||||
@@ -158,7 +158,7 @@ public:
|
||||
Thread(std::string name,
|
||||
ThreadPriority priority,
|
||||
Runnable *runnable,
|
||||
epicsThreadStackSizeClass stkcls=epicsThreadStackSmall);
|
||||
epicsThreadStackSizeClass stkcls=epicsThreadStackBig);
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user