Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d3c4d1762 | ||
|
|
51abc5032c | ||
|
|
69b3692841 | ||
|
|
d627e08419 | ||
|
|
bd9f1d1949 | ||
|
|
04db13d00e | ||
|
|
f88f0b4a76 | ||
|
|
07f9a8c0f6 | ||
|
|
5ba0209f39 | ||
|
|
ced439f4c4 | ||
|
|
cf44ec1191 | ||
|
|
e7458fad01 | ||
|
|
52dfdace88 | ||
|
|
a23631a8ca | ||
|
|
6a378dae0d | ||
|
|
0b4a8550e5 | ||
|
|
519601595c | ||
|
|
8dfd8ec02e | ||
|
|
4cef1135a3 | ||
|
|
a7bd52bd48 | ||
|
|
55df2e06e2 | ||
|
|
cfc9ebefb0 | ||
|
|
516518529c | ||
|
|
6b4eb1a1b0 | ||
|
|
5e3311a024 | ||
|
|
233a90e608 | ||
|
|
4b26e1c442 | ||
|
|
b216a62d1e | ||
|
|
978cb937c4 | ||
|
|
86adfc091b | ||
|
|
8f3a1dde34 | ||
|
|
9061e8f731 | ||
|
|
05be6e6729 | ||
|
|
156a05079e | ||
|
|
0e48497cd4 | ||
|
|
fbfed5bab1 | ||
|
|
66fb300873 | ||
|
|
6a86496385 | ||
|
|
ac10b73e69 | ||
|
|
689d0875b7 | ||
|
|
d9465b0954 | ||
|
|
25b9e5fa5a | ||
|
|
31922eac32 | ||
|
|
60d3467b1b | ||
|
|
ec1b5860fd | ||
|
|
00196cb7e2 | ||
|
|
92c68dfcbc | ||
|
|
1db56f4b29 | ||
|
|
038567280b | ||
|
|
022e6304a3 | ||
|
|
5dcd864c58 | ||
|
|
32790674d6 | ||
|
|
5d6205cb44 | ||
|
|
27c4da5b73 | ||
|
|
5d57e9bbcf | ||
|
|
9775fd4707 | ||
|
|
12d13bc2c0 | ||
|
|
3991a51fd6 | ||
|
|
90960d370d | ||
|
|
126fe9c711 | ||
|
|
770e63b8da | ||
|
|
e9b0dcd9f4 | ||
|
|
8040ad5fc7 | ||
|
|
24a08fe348 | ||
|
|
198eb453be | ||
|
|
e6a97e83ab | ||
|
|
9ab2262e86 | ||
|
|
29593a6eda | ||
|
|
27ce426f46 | ||
|
|
ca195b44cf | ||
|
|
a396d8e6ac | ||
|
|
d320f00e96 | ||
|
|
7a60e02d5c | ||
|
|
fb453ea9e5 | ||
|
|
87bff33c30 | ||
|
|
2693201cfd | ||
|
|
2dba4aab2b | ||
|
|
6caa725f5a | ||
|
|
198562c36c | ||
|
|
686a46f24c | ||
|
|
c6debc3208 |
3
.hgtags
3
.hgtags
@@ -1,3 +1,6 @@
|
||||
459f10877e5628241704f31437b4cbd342df0798 test1
|
||||
6e8a22d01e824702088195c08bf50bfb6f293de5 1.0-BETA
|
||||
d29d84f4c3f389f2accd497185b106c8541f95c9 1.1-SNAPSHOT
|
||||
a29729ca0ecd60b66f2d997031d97911377e44a7 marchtest
|
||||
9c59737f56e71aef641b70d0f72aa768fd7f8414 1.0.1-BETA
|
||||
4559c3de0cb4e3420e26272817f58bab005063ec 1.1-BETA
|
||||
|
||||
12
COPYRIGHT
Normal file
12
COPYRIGHT
Normal file
@@ -0,0 +1,12 @@
|
||||
/****************************************************
|
||||
Copyright (c) 2008 All rights reserved
|
||||
Copyright (c) 2008 Martin R. Kraimer
|
||||
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
National Laboratory.
|
||||
Deutsches Elektronen-Synchroton, Member of the Helmholtz Association,
|
||||
(DESY), HAMBURG, GERMANY,
|
||||
BERLINER SPEICHERRING GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H.
|
||||
(BESSY), BERLIN, GERMANY.
|
||||
COSYLAB (Control System Laboratory)
|
||||
(Cosylab) Ljubljana Slovenia
|
||||
*************************************************** */
|
||||
78
LICENSE
Normal file
78
LICENSE
Normal file
@@ -0,0 +1,78 @@
|
||||
|
||||
Copyright (c) 2008 Martin R. Kraimer
|
||||
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
|
||||
National Laboratory.
|
||||
Copyright (c) 2006 Deutsches Elektronen-Synchroton,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
Copyright (c) 2007 Control System Laboratory,
|
||||
(COSYLAB) Ljubljana Slovenia
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the University of Chicago (UofC)
|
||||
|
||||
In no event shall UofC be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
UofC has been advised of the possibility of such damage.
|
||||
|
||||
UofC specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and UofC has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the BERLINER SPEICHERRING
|
||||
GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H. (BESSY), BERLIN, GERMANY.
|
||||
|
||||
In no event shall BESSY be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
BESSY has been advised of the possibility of such damage.
|
||||
|
||||
BESSY specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and BESSY has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
This software is in part copyrighted by the Deutsches Elektronen-Synchroton,
|
||||
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
|
||||
|
||||
In no event shall DESY be liable to any party for direct, indirect,
|
||||
special, incidental, or consequential damages arising out of the use of
|
||||
this software, its documentation, or any derivatives thereof, even if
|
||||
DESY has been advised of the possibility of such damage.
|
||||
|
||||
DESY specifically disclaims any warranties, including, but not limited
|
||||
to, the implied warranties of merchantability, fitness for a particular
|
||||
purpose, and non-infringement. This software is provided on an "as is"
|
||||
basis, and DESY has no obligation to provide maintenance, support,
|
||||
updates, enhancements, or modifications.
|
||||
________________________________________________________________________
|
||||
@@ -1 +0,0 @@
|
||||
// ADD PREDEFINED MACROS HERE!
|
||||
@@ -1 +0,0 @@
|
||||
[General]
|
||||
@@ -1,66 +0,0 @@
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>GenericProjectManager.GenericProject.Toolchain</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value key="EditorConfiguration.Codec" type="QByteArray">System</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Desktop</value>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">GenericProjectManager.GenericTarget</value>
|
||||
<value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">0</value>
|
||||
<value key="ProjectExplorer.Target.ActiveRunConfiguration" type="int">0</value>
|
||||
<valuemap key="ProjectExplorer.Target.BuildConfiguration.0" type="QVariantMap">
|
||||
<value key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory" type="QString">/home/mrk/hgwork/pvDataCPP</value>
|
||||
<valuemap key="ProjectExplorer.BuildConfiguration.BuildStep.0" type="QVariantMap">
|
||||
<valuelist key="GenericProjectManager.GenericMakeStep.BuildTargets" type="QVariantList">
|
||||
<value type="QString">all</value>
|
||||
</valuelist>
|
||||
<valuelist key="GenericProjectManager.GenericMakeStep.MakeArguments" type="QVariantList"/>
|
||||
<value key="GenericProjectManager.GenericMakeStep.MakeCommand" type="QString"></value>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Make</value>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">GenericProjectManager.GenericMakeStep</value>
|
||||
</valuemap>
|
||||
<value key="ProjectExplorer.BuildConfiguration.BuildStepsCount" type="int">1</value>
|
||||
<value key="ProjectExplorer.BuildConfiguration.CleanStepsCount" type="int">0</value>
|
||||
<value key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment" type="bool">false</value>
|
||||
<valuelist key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges" type="QVariantList"/>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">all</value>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">GenericProjectManager.GenericBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<value key="ProjectExplorer.Target.BuildConfigurationCount" type="int">1</value>
|
||||
<valuemap key="ProjectExplorer.Target.RunConfiguration.0" type="QVariantMap">
|
||||
<valuelist key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments" type="QVariantList"/>
|
||||
<value key="ProjectExplorer.CustomExecutableRunConfiguration.BaseEnvironmentBase" type="int">2</value>
|
||||
<value key="ProjectExplorer.CustomExecutableRunConfiguration.Executable" type="QString">/home/mrk/hgwork/pvDataCPP/bin/linux-x86/testIntrospect</value>
|
||||
<value key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal" type="bool">false</value>
|
||||
<valuelist key="ProjectExplorer.CustomExecutableRunConfiguration.UserEnvironmentChanges" type="QVariantList"/>
|
||||
<value key="ProjectExplorer.CustomExecutableRunConfiguration.UserName" type="QString">testIntrospect</value>
|
||||
<value key="ProjectExplorer.CustomExecutableRunConfiguration.UserSetName" type="bool">true</value>
|
||||
<value key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory" type="QString">$BUILDDIR</value>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">testIntrospect</value>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
</valuemap>
|
||||
<value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">4</value>
|
||||
</data>
|
||||
</qtcreator>
|
||||
@@ -1,85 +0,0 @@
|
||||
include/AbstractPVArray.h
|
||||
include/AbstractPVField.h
|
||||
include/AbstractPVScalar.h
|
||||
include/AbstractPVScalarArray.h
|
||||
include/BasePVBoolean.h
|
||||
include/BasePVBooleanArray.h
|
||||
include/BasePVByte.h
|
||||
include/BasePVByteArray.h
|
||||
include/BasePVDouble.h
|
||||
include/BasePVDoubleArray.h
|
||||
include/BasePVFloat.h
|
||||
include/BasePVFloatArray.h
|
||||
include/BasePVInt.h
|
||||
include/BasePVIntArray.h
|
||||
include/BasePVLong.h
|
||||
include/BasePVLongArray.h
|
||||
include/BasePVShort.h
|
||||
include/BasePVShortArray.h
|
||||
include/BasePVString.h
|
||||
include/BasePVStructure.h
|
||||
include/BasePVStructureArray.h
|
||||
include/bitSet.h
|
||||
include/byteBuffer.h
|
||||
include/convert.h
|
||||
include/factory.h
|
||||
include/lock.h
|
||||
include/noDefaultMethods.h
|
||||
include/pvData.h
|
||||
include/pvIntrospect.h
|
||||
include/requester.h
|
||||
include/serialize.h
|
||||
include/standardField.h
|
||||
pvDataApp/factory/AbstractPVArray.h
|
||||
pvDataApp/factory/AbstractPVField.h
|
||||
pvDataApp/factory/AbstractPVScalar.h
|
||||
pvDataApp/factory/AbstractPVScalarArray.h
|
||||
pvDataApp/factory/BasePVBoolean.h
|
||||
pvDataApp/factory/BasePVBooleanArray.h
|
||||
pvDataApp/factory/BasePVByte.h
|
||||
pvDataApp/factory/BasePVByteArray.h
|
||||
pvDataApp/factory/BasePVDouble.h
|
||||
pvDataApp/factory/BasePVDoubleArray.h
|
||||
pvDataApp/factory/BasePVFloat.h
|
||||
pvDataApp/factory/BasePVFloatArray.h
|
||||
pvDataApp/factory/BasePVInt.h
|
||||
pvDataApp/factory/BasePVIntArray.h
|
||||
pvDataApp/factory/BasePVLong.h
|
||||
pvDataApp/factory/BasePVLongArray.h
|
||||
pvDataApp/factory/BasePVShort.h
|
||||
pvDataApp/factory/BasePVShortArray.h
|
||||
pvDataApp/factory/BasePVString.h
|
||||
pvDataApp/factory/BasePVStringArray.h
|
||||
pvDataApp/factory/BasePVStructure.h
|
||||
pvDataApp/factory/BasePVStructureArray.h
|
||||
pvDataApp/factory/Convert.cpp
|
||||
pvDataApp/factory/factory.h
|
||||
pvDataApp/factory/FieldCreateFactory.cpp
|
||||
pvDataApp/factory/PVAuxInfoImpl.cpp
|
||||
pvDataApp/factory/PVDataCreateFactory.cpp
|
||||
pvDataApp/factory/StandardField.cpp
|
||||
pvDataApp/factory/TypeFunc.cpp
|
||||
pvDataApp/misc/bitSet.h
|
||||
pvDataApp/misc/byteBuffer.h
|
||||
pvDataApp/misc/lock.h
|
||||
pvDataApp/misc/noDefaultMethods.h
|
||||
pvDataApp/misc/requester.h
|
||||
pvDataApp/misc/serialize.h
|
||||
pvDataApp/pv/convert.h
|
||||
pvDataApp/pv/pvData.h
|
||||
pvDataApp/pv/pvIntrospect.h
|
||||
pvDataApp/pv/standardField.h
|
||||
pvDataApp/test/testIntrospect.cpp
|
||||
pvDataApp/test/testPVAuxInfo.cpp
|
||||
pvDataApp/test/testPVScalar.cpp
|
||||
pvDataApp/test/testPVScalarArray.cpp
|
||||
pvDataApp/test/testSimpleStructure.cpp
|
||||
pvDataApp/misc/epicsException.h
|
||||
pvDataApp/misc/byteBuffer.cpp
|
||||
pvDataApp/misc/bitSet.cpp
|
||||
pvDataApp/miscTest/testByteBuffer.cpp
|
||||
pvDataApp/miscTest/testBitSet.cpp
|
||||
pvDataApp/miscTest/testBaseException.cpp
|
||||
pvDataApp/misc/serializeHelper.h
|
||||
pvDataApp/misc/serializeHelper.cpp
|
||||
pvDataApp/pvTest/testIntrospect.cpp
|
||||
@@ -1,4 +0,0 @@
|
||||
include
|
||||
pvDataApp/factory
|
||||
pvDataApp/misc
|
||||
pvDataApp/pv
|
||||
@@ -33,3 +33,4 @@ INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/configure/CONFIG_SITE.local
|
||||
-include $(TOP)/../CONFIG.local
|
||||
|
||||
@@ -24,3 +24,4 @@ EPICS_BASE=/home/install/epics/base
|
||||
# EPICS_BASE=/home/install/epics/base
|
||||
|
||||
-include $(TOP)/configure/RELEASE.local
|
||||
-include $(TOP)/../RELEASE.local
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
3608
documentation/pvDataCPP_20120927.html
Normal file
3608
documentation/pvDataCPP_20120927.html
Normal file
File diff suppressed because it is too large
Load Diff
3646
documentation/pvDataCPP_20121001.html
Normal file
3646
documentation/pvDataCPP_20121001.html
Normal file
File diff suppressed because it is too large
Load Diff
3646
documentation/pvDataCPP_20121026.html
Normal file
3646
documentation/pvDataCPP_20121026.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,6 @@ PVDATA = $(TOP)/pvDataApp/
|
||||
SRC_DIRS += $(PVDATA)/misc
|
||||
|
||||
INC += noDefaultMethods.h
|
||||
INC += linkedListVoid.h
|
||||
INC += linkedList.h
|
||||
INC += lock.h
|
||||
INC += requester.h
|
||||
INC += serialize.h
|
||||
@@ -18,30 +16,27 @@ INC += serializeHelper.h
|
||||
INC += event.h
|
||||
INC += thread.h
|
||||
INC += executor.h
|
||||
INC += CDRMonitor.h
|
||||
INC += timeFunction.h
|
||||
INC += timer.h
|
||||
INC += queueVoid.h
|
||||
INC += queue.h
|
||||
INC += messageQueue.h
|
||||
INC += destroyable.h
|
||||
INC += status.h
|
||||
INC += sharedPtr.h
|
||||
INC += localStaticLock.h
|
||||
|
||||
LIBSRCS += CDRMonitor.cpp
|
||||
#LIBSRCS += byteBuffer.cpp
|
||||
LIBSRCS += byteBuffer.cpp
|
||||
LIBSRCS += bitSet.cpp
|
||||
LIBSRCS += epicsException.cpp
|
||||
LIBSRCS += requester.cpp
|
||||
LIBSRCS += serializeHelper.cpp
|
||||
LIBSRCS += linkedListVoid.cpp
|
||||
LIBSRCS += event.cpp
|
||||
LIBSRCS += executor.cpp
|
||||
LIBSRCS += timeFunction.cpp
|
||||
LIBSRCS += timer.cpp
|
||||
LIBSRCS += queueVoid.cpp
|
||||
LIBSRCS += messageQueue.cpp
|
||||
LIBSRCS += status.cpp
|
||||
LIBSRCS += messageQueue.cpp
|
||||
LIBSRCS += localStaticLock.cpp
|
||||
|
||||
SRC_DIRS += $(PVDATA)/pv
|
||||
|
||||
@@ -56,14 +51,14 @@ SRC_DIRS += $(PVDATA)/factory
|
||||
|
||||
INC += factory.h
|
||||
LIBSRCS += TypeFunc.cpp
|
||||
LIBSRCS += PVAuxInfoImpl.cpp
|
||||
LIBSRCS += FieldCreateFactory.cpp
|
||||
LIBSRCS += PVAuxInfoImpl.cpp
|
||||
LIBSRCS += PVField.cpp
|
||||
LIBSRCS += PVScalar.cpp
|
||||
LIBSRCS += PVArray.cpp
|
||||
LIBSRCS += PVScalarArray.cpp
|
||||
LIBSRCS += PVStructure.cpp
|
||||
LIBSRCS += DefaultPVStructureArray.cpp
|
||||
LIBSRCS += PVStructureArray.cpp
|
||||
LIBSRCS += PVDataCreateFactory.cpp
|
||||
LIBSRCS += Convert.cpp
|
||||
LIBSRCS += Compare.cpp
|
||||
@@ -96,8 +91,6 @@ LIBSRCS += bitSetUtil.cpp
|
||||
|
||||
SRC_DIRS += $(PVDATA)/monitor
|
||||
INC += monitor.h
|
||||
INC += monitorQueue.h
|
||||
LIBSRCS += monitorQueue.cpp
|
||||
|
||||
|
||||
LIBRARY=pvData
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mes
|
||||
*/
|
||||
|
||||
#include <pv/convert.h>
|
||||
|
||||
@@ -56,38 +64,41 @@ bool operator==(const Scalar& a, const Scalar& b)
|
||||
{
|
||||
if(&a==&b)
|
||||
return true;
|
||||
return a.getScalarType()==b.getScalarType() && a.getFieldName()==b.getFieldName();
|
||||
return a.getScalarType()==b.getScalarType();
|
||||
}
|
||||
|
||||
bool operator==(const ScalarArray& a, const ScalarArray& b)
|
||||
{
|
||||
if(&a==&b)
|
||||
return true;
|
||||
return a.getElementType()==b.getElementType() && a.getFieldName()==b.getFieldName();
|
||||
return a.getElementType()==b.getElementType();
|
||||
}
|
||||
|
||||
bool operator==(const Structure& a, const Structure& b)
|
||||
{
|
||||
if(&a==&b)
|
||||
return true;
|
||||
int nflds=a.getNumberFields();
|
||||
if (a.getID()!=b.getID())
|
||||
return false;
|
||||
size_t nflds=a.getNumberFields();
|
||||
if (b.getNumberFields()!=nflds)
|
||||
return false;
|
||||
if (a.getFieldName()!=b.getFieldName())
|
||||
return false;
|
||||
|
||||
// std::equals does not work, since FieldConstPtrArray is an array of shared_pointers
|
||||
FieldConstPtrArray af = a.getFields();
|
||||
FieldConstPtrArray bf = b.getFields();
|
||||
for (int i = 0; i < nflds; i++)
|
||||
for (size_t i = 0; i < nflds; i++)
|
||||
if (*(af[i].get()) != *(bf[i].get()))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
StringArray an = a.getFieldNames();
|
||||
StringArray bn = b.getFieldNames();
|
||||
return std::equal( an.begin(), an.end(), bn.begin() );
|
||||
}
|
||||
|
||||
bool operator==(const StructureArray& a, const StructureArray& b)
|
||||
{
|
||||
return a.structure() == b.structure();
|
||||
return *(a.getStructure().get())==*(b.getStructure().get());
|
||||
}
|
||||
|
||||
namespace nconvert {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,251 +0,0 @@
|
||||
/*PVStructureArray.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
#include "DefaultPVStructureArray.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::const_pointer_cast;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
BasePVStructureArray::BasePVStructureArray(
|
||||
PVStructure *parent,StructureArrayConstPtr structureArray)
|
||||
: PVStructureArray(parent,structureArray),
|
||||
structureArray(structureArray),
|
||||
structureArrayData(new StructureArrayData()),
|
||||
value(new PVStructurePtr[0])
|
||||
{
|
||||
}
|
||||
|
||||
BasePVStructureArray::~BasePVStructureArray()
|
||||
{
|
||||
delete structureArrayData;
|
||||
int number = getCapacity();
|
||||
for(int i=0; i<number; i++) {
|
||||
if(value[i]!=0) {
|
||||
delete value[i];
|
||||
}
|
||||
}
|
||||
delete[] value;
|
||||
}
|
||||
|
||||
int BasePVStructureArray::append(int number)
|
||||
{
|
||||
int currentLength = getCapacity();
|
||||
int newLength = currentLength + number;
|
||||
setCapacity(newLength);
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
for(int i=currentLength; i<newLength; i++) {
|
||||
value[i] = getPVDataCreate()->createPVStructure(0,structure);
|
||||
}
|
||||
return newLength;
|
||||
}
|
||||
|
||||
bool BasePVStructureArray::remove(int offset,int number)
|
||||
{
|
||||
int length = getCapacity();
|
||||
if(offset+number>length) return false;
|
||||
for(int i=offset;i<offset+number;i++) {
|
||||
if(value[i]!=0) {
|
||||
delete value[i];
|
||||
value[i] = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BasePVStructureArray::compress() {
|
||||
int length = getCapacity();
|
||||
int newLength = 0;
|
||||
for(int i=0; i<length; i++) {
|
||||
if(value[i]!=0) {
|
||||
newLength++;
|
||||
continue;
|
||||
}
|
||||
// find first non 0
|
||||
int notNull = 0;
|
||||
for(int j=i+1;j<length;j++) {
|
||||
if(value[j]!=0) {
|
||||
notNull = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(notNull!=0) {
|
||||
value[i] = value[notNull];
|
||||
value[notNull] = 0;
|
||||
newLength++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
setCapacity(newLength);
|
||||
}
|
||||
|
||||
void BasePVStructureArray::setCapacity(int capacity) {
|
||||
if(getCapacity()==capacity) return;
|
||||
if(!isCapacityMutable()) {
|
||||
std::string message("not capacityMutable");
|
||||
PVField::message(message, errorMessage);
|
||||
return;
|
||||
}
|
||||
int length = getCapacity();
|
||||
int numRemove = length - capacity;
|
||||
if(numRemove>0) remove(length,numRemove);
|
||||
PVStructurePtrArray newValue = new PVStructurePtr[capacity];
|
||||
int limit = length;
|
||||
if(length>capacity) limit = capacity;
|
||||
for(int i=0; i<limit; i++) newValue[i] = value[i];
|
||||
for(int i=limit; i<capacity; i++) newValue[i] = 0;
|
||||
if(length>capacity) length = capacity;
|
||||
delete[] value;
|
||||
value = newValue;
|
||||
setCapacityLength(capacity,length);
|
||||
}
|
||||
|
||||
|
||||
StructureArrayConstPtr BasePVStructureArray::getStructureArray()
|
||||
{
|
||||
return structureArray;
|
||||
}
|
||||
|
||||
int BasePVStructureArray::get(
|
||||
int offset, int len, StructureArrayData *data)
|
||||
{
|
||||
int n = len;
|
||||
int length = getLength();
|
||||
if(offset+len > length) {
|
||||
n = length - offset;
|
||||
if(n<0) n = 0;
|
||||
}
|
||||
data->data = value;
|
||||
data->offset = offset;
|
||||
return n;
|
||||
}
|
||||
|
||||
int BasePVStructureArray::put(int offset,int len,
|
||||
PVStructurePtrArray from, int fromOffset)
|
||||
{
|
||||
if(isImmutable()) {
|
||||
message(String("field is immutable"), errorMessage);
|
||||
return 0;
|
||||
}
|
||||
if(from==value) return len;
|
||||
if(len<1) return 0;
|
||||
int length = getLength();
|
||||
int capacity = getCapacity();
|
||||
if(offset+len > length) {
|
||||
int newlength = offset + len;
|
||||
if(newlength>capacity) {
|
||||
setCapacity(newlength);
|
||||
capacity = getCapacity();
|
||||
newlength = capacity;
|
||||
len = newlength - offset;
|
||||
if(len<=0) return 0;
|
||||
}
|
||||
length = newlength;
|
||||
setLength(length);
|
||||
}
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
for(int i=0; i<len; i++) {
|
||||
if(value[i+offset]!=0) delete value[i+offset];
|
||||
PVStructurePtr frompv = from[i+fromOffset];
|
||||
if(frompv==0) {
|
||||
value[i+offset] = 0;
|
||||
continue;
|
||||
}
|
||||
if(frompv->getStructure()!=structure) {
|
||||
throw std::invalid_argument(String(
|
||||
"Element is not a compatible structure"));
|
||||
}
|
||||
value[i+offset] = frompv;
|
||||
}
|
||||
postPut();
|
||||
return len;
|
||||
}
|
||||
|
||||
void BasePVStructureArray::shareData(
|
||||
PVStructurePtrArray newValue,int capacity,int length)
|
||||
{
|
||||
for(int i=0; i<getLength(); i++) {
|
||||
if(value[i]!=0) delete value[i];
|
||||
}
|
||||
delete[] value;
|
||||
value = newValue;
|
||||
setCapacity(capacity);
|
||||
setLength(length);
|
||||
}
|
||||
|
||||
void BasePVStructureArray::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const {
|
||||
serialize(pbuffer, pflusher, 0, getLength());
|
||||
}
|
||||
|
||||
void BasePVStructureArray::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
int size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
if(size>=0) {
|
||||
// prepare array, if necessary
|
||||
if(size>getCapacity()) setCapacity(size);
|
||||
for(int i = 0; i<size; i++) {
|
||||
pcontrol->ensureData(1);
|
||||
int8 temp = pbuffer->getByte();
|
||||
if(temp==0) {
|
||||
if (value[i]) {
|
||||
delete value[i];
|
||||
value[i] = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(value[i]==NULL) {
|
||||
value[i] = getPVDataCreate()->createPVStructure(
|
||||
NULL, structureArray->getStructure());
|
||||
}
|
||||
value[i]->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
}
|
||||
setLength(size);
|
||||
postPut();
|
||||
}
|
||||
}
|
||||
|
||||
void BasePVStructureArray::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, int offset, int count) const {
|
||||
// cache
|
||||
int length = getLength();
|
||||
|
||||
// check bounds
|
||||
if(offset<0)
|
||||
offset = 0;
|
||||
else if(offset>length) offset = length;
|
||||
if(count<0) count = length;
|
||||
|
||||
int maxCount = length-offset;
|
||||
if(count>maxCount) count = maxCount;
|
||||
|
||||
// write
|
||||
SerializeHelper::writeSize(count, pbuffer, pflusher);
|
||||
for(int i = 0; i<count; i++) {
|
||||
if(pbuffer->getRemaining()<1) pflusher->flushSerializeBuffer();
|
||||
PVStructure* pvStructure = value[i+offset];
|
||||
if(pvStructure==NULL) {
|
||||
pbuffer->putByte(0);
|
||||
}
|
||||
else {
|
||||
pbuffer->putByte(1);
|
||||
pvStructure->serialize(pbuffer, pflusher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*DefaultPVStructureArray.h*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef DEFAULTPVSTRUCTUREARRAY_H
|
||||
#define DEFAULTPVSTRUCTUREARRAY_H
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class BasePVStructureArray : public PVStructureArray {
|
||||
public:
|
||||
BasePVStructureArray(PVStructure *parent,
|
||||
StructureArrayConstPtr structureArray);
|
||||
virtual ~BasePVStructureArray();
|
||||
virtual StructureArrayConstPtr getStructureArray();
|
||||
virtual int append(int number);
|
||||
virtual bool remove(int offset,int number);
|
||||
virtual void compress();
|
||||
virtual void setCapacity(int capacity);
|
||||
virtual int get(int offset, int length,
|
||||
StructureArrayData *data);
|
||||
virtual int put(int offset,int length,
|
||||
PVStructurePtrArray from, int fromOffset);
|
||||
virtual void shareData( PVStructurePtrArray value,int capacity,int length);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const;
|
||||
virtual void deserialize(ByteBuffer *buffer,
|
||||
DeserializableControl *pflusher);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, int offset, int count) const;
|
||||
private:
|
||||
StructureArrayConstPtr structureArray;
|
||||
StructureArrayData *structureArrayData;
|
||||
PVStructurePtrArray value;
|
||||
};
|
||||
}}
|
||||
|
||||
#endif /*DEFAULTPVSTRUCTUREARRAY_H*/
|
||||
@@ -1,9 +1,12 @@
|
||||
/*FieldCreateFactory.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
@@ -12,9 +15,10 @@
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::size_t;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -26,55 +30,204 @@ static void newLine(StringBuilder buffer, int indentLevel)
|
||||
for(int i=0; i<indentLevel; i++) *buffer += " ";
|
||||
}
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(field);
|
||||
|
||||
Field::Field(String fieldName,Type type)
|
||||
:m_fieldName(fieldName)
|
||||
,m_type(type)
|
||||
Field::Field(Type type)
|
||||
: m_fieldType(type)
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(field);
|
||||
}
|
||||
|
||||
Field::~Field() {
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(field);
|
||||
// note that compiler automatically calls destructor for fieldName
|
||||
if(debugLevel==highDebug) printf("~Field %s\n",m_fieldName.c_str());
|
||||
}
|
||||
|
||||
void Field::renameField(String newName)
|
||||
{
|
||||
m_fieldName = newName;
|
||||
}
|
||||
|
||||
void Field::toString(StringBuilder buffer,int indentLevel) const{
|
||||
*buffer += " ";
|
||||
*buffer += m_fieldName.c_str();
|
||||
}
|
||||
|
||||
Scalar::Scalar(String fieldName,ScalarType scalarType)
|
||||
: Field(fieldName,scalar),scalarType(scalarType){}
|
||||
|
||||
// TODO move all these to a header file
|
||||
|
||||
struct ScalarHashFunction {
|
||||
size_t operator() (const Scalar& scalar) const { return scalar.getScalarType(); }
|
||||
};
|
||||
|
||||
struct ScalarArrayHashFunction {
|
||||
size_t operator() (const ScalarArray& scalarArray) const { return 0x10 | scalarArray.getElementType(); }
|
||||
};
|
||||
|
||||
struct StructureHashFunction {
|
||||
size_t operator() (const Structure& structure) const { return 0; }
|
||||
// TODO
|
||||
// final int PRIME = 31;
|
||||
// return PRIME * Arrays.hashCode(fieldNames) + Arrays.hashCode(fields);
|
||||
};
|
||||
|
||||
struct StructureArrayHashFunction {
|
||||
size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); }
|
||||
};
|
||||
|
||||
|
||||
Scalar::Scalar(ScalarType scalarType)
|
||||
: Field(scalar),scalarType(scalarType){}
|
||||
|
||||
Scalar::~Scalar(){}
|
||||
|
||||
void Scalar::toString(StringBuilder buffer,int indentLevel) const{
|
||||
ScalarTypeFunc::toString(buffer,scalarType);
|
||||
Field::toString(buffer,indentLevel);
|
||||
*buffer += getID();
|
||||
}
|
||||
|
||||
|
||||
ScalarArray::ScalarArray(String fieldName,ScalarType elementType)
|
||||
: Field(fieldName,scalarArray),elementType(elementType){}
|
||||
String Scalar::getID() const
|
||||
{
|
||||
static const String idScalarLUT[] = {
|
||||
"boolean", // pvBoolean
|
||||
"byte", // pvByte
|
||||
"short", // pvShort
|
||||
"int", // pvInt
|
||||
"long", // pvLong
|
||||
"ubyte", // pvUByte
|
||||
"ushort", // pvUShort
|
||||
"uint", // pvUInt
|
||||
"ulong", // pvULong
|
||||
"float", // pvFloat
|
||||
"double", // pvDouble
|
||||
"string" // pvString
|
||||
};
|
||||
return idScalarLUT[scalarType];
|
||||
}
|
||||
|
||||
const int8 Scalar::getTypeCodeLUT() const
|
||||
{
|
||||
static const int8 typeCodeLUT[] = {
|
||||
0x00, // pvBoolean
|
||||
0x20, // pvByte
|
||||
0x21, // pvShort
|
||||
0x22, // pvInt
|
||||
0x23, // pvLong
|
||||
0x28, // pvUByte
|
||||
0x29, // pvUShort
|
||||
0x2A, // pvUInt
|
||||
0x2B, // pvULong
|
||||
0x42, // pvFloat
|
||||
0x43, // pvDouble
|
||||
0x60 // pvString
|
||||
};
|
||||
return typeCodeLUT[scalarType];
|
||||
}
|
||||
|
||||
|
||||
void Scalar::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte(getTypeCodeLUT());
|
||||
}
|
||||
|
||||
void Scalar::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
// must be done via FieldCreate
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
static String emptyString;
|
||||
|
||||
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
|
||||
{
|
||||
// to optimize default (non-empty) IDs optimization
|
||||
// empty IDs are not allowed
|
||||
String id = structure->getID();
|
||||
if (id == Structure::DEFAULT_ID) // TODO slow comparison
|
||||
SerializeHelper::serializeString(emptyString, buffer, control);
|
||||
else
|
||||
SerializeHelper::serializeString(id, buffer, control);
|
||||
|
||||
FieldConstPtrArray const & fields = structure->getFields();
|
||||
StringArray const & fieldNames = structure->getFieldNames();
|
||||
std::size_t len = fields.size();
|
||||
SerializeHelper::writeSize(len, buffer, control);
|
||||
for (std::size_t i = 0; i < len; i++)
|
||||
{
|
||||
SerializeHelper::serializeString(fieldNames[i], buffer, control);
|
||||
control->cachedSerialize(fields[i], buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static StructureConstPtr deserializeStructureField(const FieldCreate* fieldCreate, ByteBuffer* buffer, DeserializableControl* control)
|
||||
{
|
||||
String id = SerializeHelper::deserializeString(buffer, control);
|
||||
const std::size_t size = SerializeHelper::readSize(buffer, control);
|
||||
FieldConstPtrArray fields; fields.reserve(size);
|
||||
StringArray fieldNames; fieldNames.reserve(size);
|
||||
for (std::size_t i = 0; i < size; i++)
|
||||
{
|
||||
fieldNames.push_back(SerializeHelper::deserializeString(buffer, control));
|
||||
fields.push_back(control->cachedDeserialize(buffer));
|
||||
}
|
||||
|
||||
if (id.empty())
|
||||
return fieldCreate->createStructure(fieldNames, fields);
|
||||
else
|
||||
return fieldCreate->createStructure(id, fieldNames, fields);
|
||||
}
|
||||
|
||||
ScalarArray::ScalarArray(ScalarType elementType)
|
||||
: Field(scalarArray),elementType(elementType){}
|
||||
|
||||
ScalarArray::~ScalarArray() {}
|
||||
|
||||
void ScalarArray::toString(StringBuilder buffer,int indentLevel) const{
|
||||
ScalarTypeFunc::toString(buffer,elementType);
|
||||
*buffer += "[]";
|
||||
Field::toString(buffer,indentLevel);
|
||||
const int8 ScalarArray::getTypeCodeLUT() const
|
||||
{
|
||||
static const int8 typeCodeLUT[] = {
|
||||
0x00, // pvBoolean
|
||||
0x20, // pvByte
|
||||
0x21, // pvShort
|
||||
0x22, // pvInt
|
||||
0x23, // pvLong
|
||||
0x28, // pvUByte
|
||||
0x29, // pvUShort
|
||||
0x2A, // pvUInt
|
||||
0x2B, // pvULong
|
||||
0x42, // pvFloat
|
||||
0x43, // pvDouble
|
||||
0x60 // pvString
|
||||
};
|
||||
return typeCodeLUT[elementType];
|
||||
}
|
||||
|
||||
StructureArray::StructureArray(String fieldName,StructureConstPtr structure)
|
||||
: Field(fieldName,structureArray),pstructure(structure)
|
||||
const String ScalarArray::getIDScalarArrayLUT() const
|
||||
{
|
||||
static const String idScalarArrayLUT[] = {
|
||||
"boolean[]", // pvBoolean
|
||||
"byte[]", // pvByte
|
||||
"short[]", // pvShort
|
||||
"int[]", // pvInt
|
||||
"long[]", // pvLong
|
||||
"ubyte[]", // pvUByte
|
||||
"ushort[]", // pvUShort
|
||||
"uint[]", // pvUInt
|
||||
"ulong[]", // pvULong
|
||||
"float[]", // pvFloat
|
||||
"double[]", // pvDouble
|
||||
"string[]" // pvString
|
||||
};
|
||||
return idScalarArrayLUT[elementType];
|
||||
}
|
||||
|
||||
String ScalarArray::getID() const
|
||||
{
|
||||
return getIDScalarArrayLUT();
|
||||
}
|
||||
|
||||
void ScalarArray::toString(StringBuilder buffer,int indentLevel) const{
|
||||
*buffer += getID();
|
||||
}
|
||||
|
||||
void ScalarArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte(0x10 | getTypeCodeLUT());
|
||||
}
|
||||
|
||||
void ScalarArray::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
StructureArray::StructureArray(StructureConstPtr const & structure)
|
||||
: Field(structureArray),pstructure(structure)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -82,179 +235,329 @@ StructureArray::~StructureArray() {
|
||||
if(debugLevel==highDebug) printf("~StructureArray\n");
|
||||
}
|
||||
|
||||
String StructureArray::getID() const
|
||||
{
|
||||
return pstructure->getID() + "[]";
|
||||
}
|
||||
|
||||
void StructureArray::toString(StringBuilder buffer,int indentLevel) const {
|
||||
*buffer += "structure[]";
|
||||
Field::toString(buffer,indentLevel);
|
||||
*buffer += getID();
|
||||
newLine(buffer,indentLevel + 1);
|
||||
pstructure->toString(buffer,indentLevel + 1);
|
||||
}
|
||||
|
||||
void StructureArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte(0x90);
|
||||
control->cachedSerialize(pstructure, buffer);
|
||||
}
|
||||
|
||||
Structure::Structure (String fieldName,
|
||||
int numberFields, FieldConstPtrArray infields)
|
||||
: Field(fieldName,structure),
|
||||
numberFields(numberFields),
|
||||
fields(infields)
|
||||
void StructureArray::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
String Structure::DEFAULT_ID = "structure";
|
||||
|
||||
Structure::Structure (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & infields,
|
||||
String const & inid)
|
||||
: Field(structure),
|
||||
fieldNames(fieldNames),
|
||||
fields(infields),
|
||||
id(inid)
|
||||
{
|
||||
for(int i=0; i<numberFields; i++) {
|
||||
String name = fields[i]->getFieldName();
|
||||
if(inid.empty()) {
|
||||
throw std::invalid_argument("id is empty");
|
||||
}
|
||||
if(fieldNames.size()!=fields.size()) {
|
||||
throw std::invalid_argument("fieldNames.size()!=fields.size()");
|
||||
}
|
||||
size_t number = fields.size();
|
||||
for(size_t i=0; i<number; i++) {
|
||||
String name = fieldNames[i];
|
||||
if(name.size()<1) {
|
||||
throw std::invalid_argument("fieldNames has a zero length string");
|
||||
}
|
||||
// look for duplicates
|
||||
for(int j=i+1; j<numberFields; j++) {
|
||||
String otherName = fields[j]->getFieldName();
|
||||
for(size_t j=i+1; j<number; j++) {
|
||||
String otherName = fieldNames[j];
|
||||
int result = name.compare(otherName);
|
||||
if(result==0) {
|
||||
String message("duplicate fieldName ");
|
||||
message += name;
|
||||
delete[] fields;
|
||||
throw std::invalid_argument(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Structure::~Structure() {
|
||||
if(debugLevel==highDebug)
|
||||
printf("~Structure %s\n",Field::getFieldName().c_str());
|
||||
Structure::~Structure() { }
|
||||
|
||||
delete[] fields;
|
||||
|
||||
String Structure::getID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
FieldConstPtr Structure::getField(String fieldName) const {
|
||||
for(int i=0; i<numberFields; i++) {
|
||||
FieldConstPtr Structure::getField(String const & fieldName) const {
|
||||
size_t numberFields = fields.size();
|
||||
for(size_t i=0; i<numberFields; i++) {
|
||||
FieldConstPtr pfield = fields[i];
|
||||
int result = fieldName.compare(pfield->getFieldName());
|
||||
int result = fieldName.compare(fieldNames[i]);
|
||||
if(result==0) return pfield;
|
||||
}
|
||||
return FieldConstPtr();
|
||||
}
|
||||
|
||||
int Structure::getFieldIndex(String fieldName) const {
|
||||
for(int i=0; i<numberFields; i++) {
|
||||
size_t Structure::getFieldIndex(String const &fieldName) const {
|
||||
size_t numberFields = fields.size();
|
||||
for(size_t i=0; i<numberFields; i++) {
|
||||
FieldConstPtr pfield = fields[i];
|
||||
int result = fieldName.compare(pfield->getFieldName());
|
||||
int result = fieldName.compare(fieldNames[i]);
|
||||
if(result==0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Structure::appendField(FieldConstPtr field)
|
||||
{
|
||||
FieldConstPtr *newFields = new FieldConstPtr[numberFields+1];
|
||||
for(int i=0; i<numberFields; i++) newFields[i] = fields[i];
|
||||
newFields[numberFields] = field;
|
||||
delete[] fields;
|
||||
fields = newFields;
|
||||
numberFields++;
|
||||
}
|
||||
|
||||
void Structure::appendFields(int numberNew,FieldConstPtrArray nfields)
|
||||
{
|
||||
FieldConstPtr *newFields = new FieldConstPtr[numberFields+numberNew];
|
||||
for(int i=0; i<numberFields; i++) newFields[i] = fields[i];
|
||||
for(int i=0; i<numberNew; i++) newFields[numberFields+i] = nfields[i];
|
||||
delete[] fields;
|
||||
fields = newFields;
|
||||
numberFields += numberNew;
|
||||
}
|
||||
|
||||
void Structure::removeField(int index)
|
||||
{
|
||||
if(index<0 || index>=numberFields) {
|
||||
throw std::invalid_argument(
|
||||
String("Structure::removeField index out of bounds"));
|
||||
}
|
||||
FieldConstPtr *newFields = new FieldConstPtr[numberFields-1];
|
||||
|
||||
int ind=0;
|
||||
for(int i=0; i<numberFields; i++) {
|
||||
if(i==index) continue;
|
||||
newFields[ind++] = fields[i];
|
||||
}
|
||||
delete[] fields;
|
||||
fields = newFields;
|
||||
--numberFields;
|
||||
}
|
||||
|
||||
void Structure::toString(StringBuilder buffer,int indentLevel) const{
|
||||
*buffer += "structure";
|
||||
Field::toString(buffer,indentLevel);
|
||||
newLine(buffer,indentLevel+1);
|
||||
for(int i=0; i<numberFields; i++) {
|
||||
*buffer += getID();
|
||||
toStringCommon(buffer,indentLevel+1);
|
||||
}
|
||||
|
||||
void Structure::toStringCommon(StringBuilder buffer,int indentLevel) const{
|
||||
newLine(buffer,indentLevel);
|
||||
size_t numberFields = fields.size();
|
||||
for(size_t i=0; i<numberFields; i++) {
|
||||
FieldConstPtr pfield = fields[i];
|
||||
pfield->toString(buffer,indentLevel+1);
|
||||
if(i<numberFields-1) newLine(buffer,indentLevel+1);
|
||||
*buffer += pfield->getID() + " " + fieldNames[i];
|
||||
switch(pfield->getType()) {
|
||||
case scalar:
|
||||
case scalarArray:
|
||||
break;
|
||||
case structure:
|
||||
{
|
||||
Field const *xxx = pfield.get();
|
||||
Structure const *pstruct = static_cast<Structure const*>(xxx);
|
||||
pstruct->toStringCommon(buffer,indentLevel + 1);
|
||||
break;
|
||||
}
|
||||
case structureArray:
|
||||
newLine(buffer,indentLevel +1);
|
||||
pfield->toString(buffer,indentLevel +1);
|
||||
break;
|
||||
}
|
||||
if(i<numberFields-1) newLine(buffer,indentLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void Structure::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte(0x80);
|
||||
serializeStructureField(this, buffer, control);
|
||||
}
|
||||
|
||||
ScalarConstPtr FieldCreate::createScalar(String fieldName,
|
||||
ScalarType scalarType) const
|
||||
void Structure::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
ScalarConstPtr FieldCreate::createScalar(ScalarType scalarType) const
|
||||
{
|
||||
ScalarConstPtr scalar(new Scalar(fieldName,scalarType), Field::Deleter());
|
||||
return scalar;
|
||||
// TODO use singleton instance
|
||||
ScalarConstPtr scalar(new Scalar(scalarType), Field::Deleter());
|
||||
return scalar;
|
||||
}
|
||||
|
||||
ScalarArrayConstPtr FieldCreate::createScalarArray(
|
||||
String fieldName,ScalarType elementType) const
|
||||
ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
|
||||
{
|
||||
ScalarArrayConstPtr scalarArray(new ScalarArray(fieldName,elementType), Field::Deleter());
|
||||
return scalarArray;
|
||||
// TODO use singleton instance
|
||||
ScalarArrayConstPtr scalarArray(new ScalarArray(elementType), Field::Deleter());
|
||||
return scalarArray;
|
||||
}
|
||||
|
||||
StructureConstPtr FieldCreate::createStructure (
|
||||
String fieldName,int numberFields,
|
||||
FieldConstPtr fields[]) const
|
||||
StringArray const & fieldNames,FieldConstPtrArray const & fields) const
|
||||
{
|
||||
StructureConstPtr structure(new Structure(
|
||||
fieldName,numberFields,fields), Field::Deleter());
|
||||
StructureConstPtr structure(
|
||||
new Structure(fieldNames,fields), Field::Deleter());
|
||||
return structure;
|
||||
}
|
||||
StructureArrayConstPtr FieldCreate::createStructureArray(
|
||||
String fieldName,StructureConstPtr structure) const
|
||||
|
||||
StructureConstPtr FieldCreate::createStructure (
|
||||
String const & id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const
|
||||
{
|
||||
StructureArrayConstPtr structureArray(new StructureArray(fieldName,structure), Field::Deleter());
|
||||
StructureConstPtr structure(
|
||||
new Structure(fieldNames,fields,id), Field::Deleter());
|
||||
return structure;
|
||||
}
|
||||
|
||||
StructureArrayConstPtr FieldCreate::createStructureArray(
|
||||
StructureConstPtr const & structure) const
|
||||
{
|
||||
StructureArrayConstPtr structureArray(
|
||||
new StructureArray(structure), Field::Deleter());
|
||||
return structureArray;
|
||||
}
|
||||
|
||||
FieldConstPtr FieldCreate::create(String fieldName,
|
||||
FieldConstPtr pfield) const
|
||||
StructureConstPtr FieldCreate::appendField(
|
||||
StructureConstPtr const & structure,
|
||||
String const & fieldName,
|
||||
FieldConstPtr const & field) const
|
||||
{
|
||||
FieldConstPtr ret;
|
||||
Type type = pfield->getType();
|
||||
switch(type) {
|
||||
case scalar: {
|
||||
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(pfield);
|
||||
return createScalar(fieldName,pscalar->getScalarType());
|
||||
StringArray oldNames = structure->getFieldNames();
|
||||
FieldConstPtrArray oldFields = structure->getFields();
|
||||
size_t oldLen = oldNames.size();
|
||||
StringArray newNames(oldLen+1);
|
||||
FieldConstPtrArray newFields(oldLen+1);
|
||||
for(size_t i = 0; i<oldLen; i++) {
|
||||
newNames[i] = oldNames[i];
|
||||
newFields[i] = oldFields[i];
|
||||
}
|
||||
case scalarArray: {
|
||||
ScalarArrayConstPtr pscalarArray = static_pointer_cast<const ScalarArray>(pfield);
|
||||
return createScalarArray(fieldName,pscalarArray->getElementType());
|
||||
}
|
||||
case structure: {
|
||||
StructureConstPtr pstructure = static_pointer_cast<const Structure>(pfield);
|
||||
return createStructure(fieldName,pstructure->getNumberFields(),pstructure->getFields());
|
||||
}
|
||||
case structureArray: {
|
||||
StructureArrayConstPtr pstructureArray = static_pointer_cast<const StructureArray>(pfield);
|
||||
return createStructureArray(fieldName,pstructureArray->getStructure());
|
||||
}
|
||||
}
|
||||
String message("field ");
|
||||
message += fieldName;
|
||||
THROW_EXCEPTION2(std::logic_error, message);
|
||||
newNames[oldLen] = fieldName;
|
||||
newFields[oldLen] = field;
|
||||
return createStructure(structure->getID(),newNames,newFields);
|
||||
}
|
||||
|
||||
static FieldCreate* fieldCreate = 0;
|
||||
|
||||
FieldCreate::FieldCreate()
|
||||
StructureConstPtr FieldCreate::appendFields(
|
||||
StructureConstPtr const & structure,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const
|
||||
{
|
||||
StringArray oldNames = structure->getFieldNames();
|
||||
FieldConstPtrArray oldFields = structure->getFields();
|
||||
size_t oldLen = oldNames.size();
|
||||
size_t extra = fieldNames.size();
|
||||
StringArray newNames(oldLen+extra);
|
||||
FieldConstPtrArray newFields(oldLen+extra);
|
||||
for(size_t i = 0; i<oldLen; i++) {
|
||||
newNames[i] = oldNames[i];
|
||||
newFields[i] = oldFields[i];
|
||||
}
|
||||
for(size_t i = 0; i<extra; i++) {
|
||||
newNames[oldLen +i] = fieldNames[i];
|
||||
newFields[oldLen +i] = fields[i];
|
||||
}
|
||||
return createStructure(structure->getID(),newNames,newFields);
|
||||
}
|
||||
|
||||
FieldCreate * getFieldCreate() {
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
|
||||
if(fieldCreate==0) fieldCreate = new FieldCreate();
|
||||
static int decodeScalar(int8 code)
|
||||
{
|
||||
static const int integerLUT[] =
|
||||
{
|
||||
pvByte, // 8-bits
|
||||
pvShort, // 16-bits
|
||||
pvInt, // 32-bits
|
||||
pvLong, // 64-bits
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
pvUByte, // unsigned 8-bits
|
||||
pvUShort, // unsigned 16-bits
|
||||
pvUInt, // unsigned 32-bits
|
||||
pvULong, // unsigned 64-bits
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
static const int floatLUT[] =
|
||||
{
|
||||
-1, // reserved
|
||||
-1, // 16-bits
|
||||
pvFloat, // 32-bits
|
||||
pvDouble, // 64-bits
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
// bits 7-5
|
||||
switch (code >> 5)
|
||||
{
|
||||
case 0: return pvBoolean;
|
||||
case 1: return integerLUT[code & 0x0F];
|
||||
case 2: return floatLUT[code & 0x0F];
|
||||
case 3: return pvString;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl* control) const
|
||||
{
|
||||
control->ensureData(1);
|
||||
int8 code = buffer->getByte();
|
||||
if (code == -1)
|
||||
return FieldConstPtr();
|
||||
|
||||
int typeCode = code & 0xE0;
|
||||
bool notArray = ((code & 0x10) == 0);
|
||||
if (notArray)
|
||||
{
|
||||
if (typeCode < 0x80)
|
||||
{
|
||||
// Type type = Type.scalar;
|
||||
int scalarType = decodeScalar(code);
|
||||
if (scalarType == -1)
|
||||
throw std::invalid_argument("invalid scalar type encoding");
|
||||
return FieldConstPtr(new Scalar(static_cast<ScalarType>(scalarType)), Field::Deleter());
|
||||
}
|
||||
else if (typeCode == 0x80)
|
||||
{
|
||||
// Type type = Type.structure;
|
||||
return deserializeStructureField(this, buffer, control);
|
||||
}
|
||||
else
|
||||
throw std::invalid_argument("invalid type encoding");
|
||||
}
|
||||
else // array
|
||||
{
|
||||
if (typeCode < 0x80)
|
||||
{
|
||||
// Type type = Type.scalarArray;
|
||||
int scalarType = decodeScalar(code);
|
||||
if (scalarType == -1)
|
||||
throw std::invalid_argument("invalid scalarArray type encoding");
|
||||
return FieldConstPtr(new ScalarArray(static_cast<ScalarType>(scalarType)), Field::Deleter());
|
||||
}
|
||||
else if (typeCode == 0x80)
|
||||
{
|
||||
// Type type = Type.structureArray;
|
||||
StructureConstPtr elementStructure = std::tr1::static_pointer_cast<const Structure>(control->cachedDeserialize(buffer));
|
||||
return FieldConstPtr(new StructureArray(elementStructure), Field::Deleter());
|
||||
}
|
||||
else
|
||||
throw std::invalid_argument("invalid type encoding");
|
||||
}
|
||||
}
|
||||
|
||||
FieldCreatePtr FieldCreate::getFieldCreate()
|
||||
{
|
||||
LOCAL_STATIC_LOCK;
|
||||
static FieldCreatePtr fieldCreate;
|
||||
static Mutex mutex;
|
||||
|
||||
Lock xx(mutex);
|
||||
if(fieldCreate.get()==0) fieldCreate = FieldCreatePtr(new FieldCreate());
|
||||
return fieldCreate;
|
||||
}
|
||||
|
||||
FieldCreate::FieldCreate(){}
|
||||
|
||||
FieldCreatePtr getFieldCreate() {
|
||||
return FieldCreate::getFieldCreate();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*PVArray.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
@@ -12,78 +15,86 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/factory.h>
|
||||
|
||||
using std::size_t;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class PVArrayPvt {
|
||||
public:
|
||||
PVArrayPvt() : length(0),capacity(0),capacityMutable(true)
|
||||
{}
|
||||
int length;
|
||||
int capacity;
|
||||
bool capacityMutable;
|
||||
};
|
||||
class PVArrayPvt {
|
||||
public:
|
||||
PVArrayPvt() : length(0),capacity(0),capacityMutable(true)
|
||||
{}
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
bool capacityMutable;
|
||||
};
|
||||
|
||||
PVArray::PVArray(PVStructure *parent,FieldConstPtr field)
|
||||
: PVField(parent,field),pImpl(new PVArrayPvt())
|
||||
{ }
|
||||
PVArray::PVArray(FieldConstPtr const & field)
|
||||
: PVField(field),pImpl(new PVArrayPvt())
|
||||
{ }
|
||||
|
||||
PVArray::~PVArray()
|
||||
{
|
||||
delete pImpl;
|
||||
PVArray::~PVArray()
|
||||
{
|
||||
delete pImpl;
|
||||
}
|
||||
|
||||
void PVArray::setImmutable()
|
||||
{
|
||||
pImpl->capacityMutable = false;
|
||||
PVField::setImmutable();
|
||||
}
|
||||
|
||||
size_t PVArray::getLength() const {return pImpl->length;}
|
||||
|
||||
size_t PVArray::getCapacity() const {return pImpl->capacity;}
|
||||
|
||||
static String fieldImmutable("field is immutable");
|
||||
|
||||
void PVArray::setLength(size_t length) {
|
||||
if(length==pImpl->length) return;
|
||||
if(PVField::isImmutable()) {
|
||||
PVField::message(fieldImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
if(length>pImpl->capacity) this->setCapacity(length);
|
||||
if(length>pImpl->capacity) length = pImpl->capacity;
|
||||
pImpl->length = length;
|
||||
}
|
||||
|
||||
int PVArray::getLength() const {return pImpl->length;}
|
||||
|
||||
int PVArray::getCapacity() const {return pImpl->capacity;}
|
||||
|
||||
static String fieldImmutable("field is immutable");
|
||||
|
||||
void PVArray::setLength(int length) {
|
||||
if(length==pImpl->length) return;
|
||||
if(PVField::isImmutable()) {
|
||||
PVField::message(fieldImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
if(length>pImpl->capacity) this->setCapacity(length);
|
||||
if(length>pImpl->capacity) length = pImpl->capacity;
|
||||
pImpl->length = length;
|
||||
}
|
||||
|
||||
void PVArray::setCapacityLength(int capacity,int length) {
|
||||
pImpl->capacity = capacity;
|
||||
pImpl->length = length;
|
||||
}
|
||||
void PVArray::setCapacityLength(size_t capacity,size_t length) {
|
||||
pImpl->capacity = capacity;
|
||||
pImpl->length = length;
|
||||
}
|
||||
|
||||
|
||||
bool PVArray::isCapacityMutable()
|
||||
{
|
||||
if(PVField::isImmutable()) {
|
||||
return false;
|
||||
}
|
||||
return pImpl->capacityMutable;
|
||||
}
|
||||
bool PVArray::isCapacityMutable() const
|
||||
{
|
||||
if(PVField::isImmutable()) {
|
||||
return false;
|
||||
}
|
||||
return pImpl->capacityMutable;
|
||||
}
|
||||
|
||||
void PVArray::setCapacityMutable(bool isMutable)
|
||||
{
|
||||
if(isMutable && PVField::isImmutable()) {
|
||||
PVField::message(fieldImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
pImpl->capacityMutable = isMutable;
|
||||
}
|
||||
void PVArray::setCapacityMutable(bool isMutable)
|
||||
{
|
||||
if(isMutable && PVField::isImmutable()) {
|
||||
PVField::message(fieldImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
pImpl->capacityMutable = isMutable;
|
||||
}
|
||||
|
||||
static String capacityImmutable("capacity is immutable");
|
||||
static String capacityImmutable("capacity is immutable");
|
||||
|
||||
void PVArray::setCapacity(int capacity) {
|
||||
if(PVField::isImmutable()) {
|
||||
PVField::message(fieldImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
if(pImpl->capacityMutable==false) {
|
||||
PVField::message(capacityImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
pImpl->capacity = capacity;
|
||||
}
|
||||
void PVArray::setCapacity(size_t capacity) {
|
||||
if(PVField::isImmutable()) {
|
||||
PVField::message(fieldImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
if(pImpl->capacityMutable==false) {
|
||||
PVField::message(capacityImmutable,errorMessage);
|
||||
return;
|
||||
}
|
||||
pImpl->capacity = capacity;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*PVAuxInfo.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
@@ -13,24 +16,18 @@
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(pvAuxInfo);
|
||||
|
||||
PVAuxInfo::PVAuxInfo(PVField *pvField)
|
||||
: pvField(pvField),lengthInfo(1),numberInfo(0),
|
||||
pvInfos(new PVScalar *[1])
|
||||
PVAuxInfo::PVAuxInfo(PVField * pvField)
|
||||
: pvField(pvField),
|
||||
pvInfos(std::map<String,std::tr1::shared_ptr<PVScalar> > ())
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(pvAuxInfo);
|
||||
}
|
||||
|
||||
PVAuxInfo::~PVAuxInfo()
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(pvAuxInfo);
|
||||
for(int i=0; i<numberInfo; i++) delete pvInfos[i];
|
||||
delete[] pvInfos;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,49 +35,34 @@ PVField * PVAuxInfo::getPVField() {
|
||||
return pvField;
|
||||
}
|
||||
|
||||
PVScalar * PVAuxInfo::createInfo(String key,ScalarType scalarType)
|
||||
|
||||
PVScalarPtr PVAuxInfo::createInfo(String const & key,ScalarType scalarType)
|
||||
{
|
||||
for(int i=0; i<numberInfo; i++) {
|
||||
PVScalar *pvScalar = pvInfos[i];
|
||||
if(key.compare(pvScalar->getField()->getFieldName())==0) {
|
||||
String message("AuxoInfo:create key ");
|
||||
message += key.c_str();
|
||||
message += " already exists with scalarType ";
|
||||
ScalarTypeFunc::toString(&message,scalarType);
|
||||
pvField->message(message,errorMessage);
|
||||
return 0;
|
||||
}
|
||||
PVInfoIter iter = pvInfos.find(key);
|
||||
if(iter!=pvInfos.end()) {
|
||||
String message = key.c_str();
|
||||
message += " already exists ";
|
||||
pvField->message(message,errorMessage);
|
||||
return nullPVScalar;
|
||||
}
|
||||
if(lengthInfo==numberInfo) {
|
||||
int newLength = lengthInfo+4;
|
||||
PVScalar ** newInfos = new PVScalar *[newLength];
|
||||
lengthInfo = newLength;
|
||||
for(int i=0; i<numberInfo; i++) newInfos[i] = pvInfos[i];
|
||||
for(int i= numberInfo; i<lengthInfo; i++) newInfos[i] = 0;
|
||||
delete[] pvInfos;
|
||||
pvInfos = newInfos;
|
||||
}
|
||||
PVScalar *pvScalar = getPVDataCreate()->createPVScalar(0,key,scalarType);
|
||||
pvInfos[numberInfo++] = pvScalar;
|
||||
PVScalarPtr pvScalar = getPVDataCreate()->createPVScalar(scalarType);
|
||||
pvInfos.insert(PVInfoPair(key,pvScalar));
|
||||
return pvScalar;
|
||||
}
|
||||
|
||||
PVScalar * PVAuxInfo::getInfo(String key)
|
||||
PVScalarPtr PVAuxInfo::getInfo(String const & key)
|
||||
{
|
||||
for(int i=0; i<numberInfo; i++) {
|
||||
PVScalar *pvScalar = pvInfos[i];
|
||||
if(key.compare(pvScalar->getField()->getFieldName())==0) return pvScalar;
|
||||
}
|
||||
return 0;
|
||||
PVInfoIter iter;
|
||||
iter = pvInfos.find(key);
|
||||
if(iter==pvInfos.end()) return nullPVScalar;
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
PVScalar * PVAuxInfo::getInfo(int index)
|
||||
PVAuxInfo::PVInfoMap & PVAuxInfo::getInfoMap()
|
||||
{
|
||||
if(index<0 || index>=numberInfo) return 0;
|
||||
return pvInfos[index];
|
||||
return pvInfos;
|
||||
}
|
||||
|
||||
int PVAuxInfo::getNumberInfo() { return numberInfo;}
|
||||
|
||||
void PVAuxInfo::toString(StringBuilder buf)
|
||||
{
|
||||
@@ -89,13 +71,13 @@ void PVAuxInfo::toString(StringBuilder buf)
|
||||
|
||||
void PVAuxInfo::toString(StringBuilder buf,int indentLevel)
|
||||
{
|
||||
if(numberInfo==0) return;
|
||||
Convert *convert = getConvert();
|
||||
if(pvInfos.size()<=0) return;
|
||||
ConvertPtr convert = getConvert();
|
||||
convert->newLine(buf,indentLevel);
|
||||
*buf += "auxInfo";
|
||||
for(int i=0; i<numberInfo; i++) {
|
||||
for(PVInfoIter iter = pvInfos.begin(); iter!= pvInfos.end(); ++iter) {
|
||||
convert->newLine(buf,indentLevel+1);
|
||||
PVScalar *value = pvInfos[i];
|
||||
PVFieldPtr value = iter->second;
|
||||
value->toString(buf,indentLevel + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*PVDataCreateFactory.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
@@ -17,16 +20,13 @@
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
#include "DefaultPVStructureArray.h"
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::const_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::min;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static Convert* convert = 0;
|
||||
static FieldCreate * fieldCreate = 0;
|
||||
static PVDataCreate* pvDataCreate = 0;
|
||||
|
||||
/** Default storage for scalar values
|
||||
*/
|
||||
@@ -37,9 +37,9 @@ public:
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
BasePVScalar(PVStructure *parent,ScalarConstPtr scalar);
|
||||
BasePVScalar(ScalarConstPtr const & scalar);
|
||||
virtual ~BasePVScalar();
|
||||
virtual T get();
|
||||
virtual T get() const ;
|
||||
virtual void put(T val);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const;
|
||||
@@ -50,8 +50,8 @@ private:
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
BasePVScalar<T>::BasePVScalar(PVStructure *parent,ScalarConstPtr scalar)
|
||||
: PVScalarValue<T>(parent,scalar),value(0)
|
||||
BasePVScalar<T>::BasePVScalar(ScalarConstPtr const & scalar)
|
||||
: PVScalarValue<T>(scalar),value(0)
|
||||
{}
|
||||
//Note: '0' is a suitable default for all POD types (not String)
|
||||
|
||||
@@ -59,7 +59,7 @@ template<typename T>
|
||||
BasePVScalar<T>::~BasePVScalar() {}
|
||||
|
||||
template<typename T>
|
||||
T BasePVScalar<T>::get() { return value;}
|
||||
T BasePVScalar<T>::get() const { return value;}
|
||||
|
||||
template<typename T>
|
||||
void BasePVScalar<T>::put(T val){value = val;}
|
||||
@@ -68,7 +68,7 @@ template<typename T>
|
||||
void BasePVScalar<T>::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const {
|
||||
pflusher->ensureBuffer(sizeof(T));
|
||||
pbuffer->put<T>(value);
|
||||
pbuffer->put(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -76,14 +76,18 @@ void BasePVScalar<T>::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pflusher)
|
||||
{
|
||||
pflusher->ensureData(sizeof(T));
|
||||
value = pbuffer->get<T>();
|
||||
value = pbuffer->GET(T);
|
||||
}
|
||||
|
||||
typedef BasePVScalar<bool> BasePVBoolean;
|
||||
typedef BasePVScalar<boolean> BasePVBoolean;
|
||||
typedef BasePVScalar<int8> BasePVByte;
|
||||
typedef BasePVScalar<int16> BasePVShort;
|
||||
typedef BasePVScalar<int32> BasePVInt;
|
||||
typedef BasePVScalar<int64> BasePVLong;
|
||||
typedef BasePVScalar<uint8> BasePVUByte;
|
||||
typedef BasePVScalar<uint16> BasePVUShort;
|
||||
typedef BasePVScalar<uint32> BasePVUInt;
|
||||
typedef BasePVScalar<uint64> BasePVULong;
|
||||
typedef BasePVScalar<float> BasePVFloat;
|
||||
typedef BasePVScalar<double> BasePVDouble;
|
||||
|
||||
@@ -94,27 +98,27 @@ public:
|
||||
typedef String* pointer;
|
||||
typedef const String* const_pointer;
|
||||
|
||||
BasePVString(PVStructure *parent,ScalarConstPtr scalar);
|
||||
BasePVString(ScalarConstPtr const & scalar);
|
||||
virtual ~BasePVString();
|
||||
virtual String get();
|
||||
virtual String get() const ;
|
||||
virtual void put(String val);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const;
|
||||
virtual void deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pflusher);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, int offset, int count) const;
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const;
|
||||
private:
|
||||
String value;
|
||||
};
|
||||
|
||||
BasePVString::BasePVString(PVStructure *parent,ScalarConstPtr scalar)
|
||||
: PVString(parent,scalar),value()
|
||||
BasePVString::BasePVString(ScalarConstPtr const & scalar)
|
||||
: PVString(scalar),value()
|
||||
{}
|
||||
|
||||
BasePVString::~BasePVString() {}
|
||||
|
||||
String BasePVString::get() { return value;}
|
||||
String BasePVString::get() const { return value;}
|
||||
|
||||
void BasePVString::put(String val){value = val;}
|
||||
|
||||
@@ -131,15 +135,15 @@ void BasePVString::deserialize(ByteBuffer *pbuffer,
|
||||
}
|
||||
|
||||
void BasePVString::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, int offset, int count) const
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const
|
||||
{
|
||||
// check bounds
|
||||
const int length = /*(value == null) ? 0 :*/ value.length();
|
||||
const size_t length = /*(value == null) ? 0 :*/ value.length();
|
||||
if (offset < 0) offset = 0;
|
||||
else if (offset > length) offset = length;
|
||||
if (count < 0) count = length;
|
||||
|
||||
const int maxCount = length - offset;
|
||||
const size_t maxCount = length - offset;
|
||||
if (count > maxCount)
|
||||
count = maxCount;
|
||||
|
||||
@@ -152,40 +156,66 @@ void BasePVString::serialize(ByteBuffer *pbuffer,
|
||||
template<typename T>
|
||||
class DefaultPVArray : public PVValueArray<T> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef std::vector<T> vector;
|
||||
typedef const std::vector<T> const_vector;
|
||||
typedef std::tr1::shared_ptr<vector> shared_vector;
|
||||
|
||||
DefaultPVArray(PVStructure *parent,ScalarArrayConstPtr scalarArray);
|
||||
DefaultPVArray(ScalarArrayConstPtr const & scalarArray);
|
||||
virtual ~DefaultPVArray();
|
||||
virtual void setCapacity(int capacity);
|
||||
virtual int get(int offset, int length, PVArrayData<T> *data) ;
|
||||
virtual int put(int offset,int length, pointer from,
|
||||
int fromOffset);
|
||||
virtual void shareData(pointer value,int capacity,int length);
|
||||
virtual void setCapacity(size_t capacity);
|
||||
virtual void setLength(size_t length);
|
||||
virtual size_t get(size_t offset, size_t length, PVArrayData<T> &data) ;
|
||||
virtual size_t put(size_t offset,size_t length, const_pointer from,
|
||||
size_t fromOffset);
|
||||
virtual void shareData(
|
||||
std::tr1::shared_ptr<std::vector<T> > const & value,
|
||||
std::size_t capacity,
|
||||
std::size_t length);
|
||||
virtual pointer get() ;
|
||||
virtual pointer get() const ;
|
||||
virtual vector const & getVector() { return *value.get(); }
|
||||
virtual shared_vector const & getSharedVector(){return value;};
|
||||
// from Serializable
|
||||
virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) const;
|
||||
virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher);
|
||||
virtual void serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, int offset, int count) const;
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const;
|
||||
private:
|
||||
pointer value;
|
||||
shared_vector value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
DefaultPVArray<T>::DefaultPVArray(PVStructure *parent,
|
||||
ScalarArrayConstPtr scalarArray)
|
||||
: PVValueArray<T>(parent,scalarArray),value(new T[0])
|
||||
T *DefaultPVArray<T>::get()
|
||||
{
|
||||
std::vector<T> *vec = value.get();
|
||||
T *praw = &((*vec)[0]);
|
||||
return praw;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *DefaultPVArray<T>::get() const
|
||||
{
|
||||
std::vector<T> *vec = value.get();
|
||||
T *praw = &((*vec)[0]);
|
||||
return praw;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
DefaultPVArray<T>::DefaultPVArray(ScalarArrayConstPtr const & scalarArray)
|
||||
: PVValueArray<T>(scalarArray),
|
||||
value(std::tr1::shared_ptr<std::vector<T> >(new std::vector<T>()))
|
||||
|
||||
{ }
|
||||
|
||||
template<typename T>
|
||||
DefaultPVArray<T>::~DefaultPVArray()
|
||||
{
|
||||
delete[] value;
|
||||
}
|
||||
{ }
|
||||
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::setCapacity(int capacity)
|
||||
void DefaultPVArray<T>::setCapacity(size_t capacity)
|
||||
{
|
||||
if(PVArray::getCapacity()==capacity) return;
|
||||
if(!PVArray::isCapacityMutable()) {
|
||||
@@ -193,43 +223,68 @@ void DefaultPVArray<T>::setCapacity(int capacity)
|
||||
PVField::message(message, errorMessage);
|
||||
return;
|
||||
}
|
||||
int length = PVArray::getLength();
|
||||
size_t length = PVArray::getLength();
|
||||
if(length>capacity) length = capacity;
|
||||
T *newValue = new T[capacity];
|
||||
for(int i=0; i<length; i++) newValue[i] = value[i];
|
||||
delete[]value;
|
||||
value = newValue;
|
||||
size_t oldCapacity = PVArray::getCapacity();
|
||||
if(oldCapacity>capacity) {
|
||||
std::vector<T> array;
|
||||
array.reserve(capacity);
|
||||
array.resize(length);
|
||||
T * from = get();
|
||||
for (size_t i=0; i<length; i++) array[i] = from[i];
|
||||
value->swap(array);
|
||||
} else {
|
||||
value->reserve(capacity);
|
||||
}
|
||||
PVArray::setCapacityLength(capacity,length);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int DefaultPVArray<T>::get(int offset, int len, PVArrayData<T> *data)
|
||||
void DefaultPVArray<T>::setLength(size_t length)
|
||||
{
|
||||
int n = len;
|
||||
int length = this->getLength();
|
||||
if(PVArray::getLength()==length) return;
|
||||
size_t capacity = PVArray::getCapacity();
|
||||
if(length>capacity) {
|
||||
if(!PVArray::isCapacityMutable()) {
|
||||
std::string message("not capacityMutable");
|
||||
PVField::message(message, errorMessage);
|
||||
return;
|
||||
}
|
||||
setCapacity(length);
|
||||
}
|
||||
value->resize(length);
|
||||
PVArray::setCapacityLength(capacity,length);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
size_t DefaultPVArray<T>::get(size_t offset, size_t len, PVArrayData<T> &data)
|
||||
{
|
||||
size_t n = len;
|
||||
size_t length = this->getLength();
|
||||
if(offset+len > length) {
|
||||
n = length-offset;
|
||||
if(n<0) n = 0;
|
||||
}
|
||||
data->data = value;
|
||||
data->offset = offset;
|
||||
data.data = *value.get();
|
||||
data.offset = offset;
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int DefaultPVArray<T>::put(int offset,int len,
|
||||
pointer from,int fromOffset)
|
||||
size_t DefaultPVArray<T>::put(size_t offset,size_t len,
|
||||
const_pointer from,size_t fromOffset)
|
||||
{
|
||||
if(PVField::isImmutable()) {
|
||||
PVField::message("field is immutable",errorMessage);
|
||||
return 0;
|
||||
}
|
||||
if(from==value) return len;
|
||||
T * pvalue = get();
|
||||
if(from==pvalue) return len;
|
||||
if(len<1) return 0;
|
||||
int length = this->getLength();
|
||||
int capacity = this->getCapacity();
|
||||
size_t length = this->getLength();
|
||||
size_t capacity = this->getCapacity();
|
||||
if(offset+len > length) {
|
||||
int newlength = offset + len;
|
||||
size_t newlength = offset + len;
|
||||
if(newlength>capacity) {
|
||||
setCapacity(newlength);
|
||||
newlength = this->getCapacity();
|
||||
@@ -237,9 +292,11 @@ int DefaultPVArray<T>::put(int offset,int len,
|
||||
if(len<=0) return 0;
|
||||
}
|
||||
length = newlength;
|
||||
setLength(length);
|
||||
}
|
||||
for(int i=0;i<len;i++) {
|
||||
value[i+offset] = from[i+fromOffset];
|
||||
pvalue = get();
|
||||
for(size_t i=0;i<len;i++) {
|
||||
pvalue[i+offset] = from[i+fromOffset];
|
||||
}
|
||||
this->setLength(length);
|
||||
this->postPut();
|
||||
@@ -247,10 +304,12 @@ int DefaultPVArray<T>::put(int offset,int len,
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::shareData(pointer shareValue,int capacity,int length)
|
||||
void DefaultPVArray<T>::shareData(
|
||||
std::tr1::shared_ptr<std::vector<T> > const & sharedValue,
|
||||
std::size_t capacity,
|
||||
std::size_t length)
|
||||
{
|
||||
delete[] value;
|
||||
value = shareValue;
|
||||
value = sharedValue;
|
||||
PVArray::setCapacityLength(capacity,length);
|
||||
}
|
||||
|
||||
@@ -263,21 +322,23 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
int size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
// if (size>0) { pcontrol->ensureData(sizeof(T)-1); pbuffer->align(sizeof(T)); }
|
||||
if(size>=0) {
|
||||
// prepare array, if necessary
|
||||
if(size>this->getCapacity()) this->setCapacity(size);
|
||||
// set new length
|
||||
this->setLength(size);
|
||||
// retrieve value from the buffer
|
||||
int i = 0;
|
||||
size_t i = 0;
|
||||
while(true) {
|
||||
/*
|
||||
int maxIndex = std::min(size-i, (int)(pbuffer->getRemaining()/sizeof(T)))+i;
|
||||
size_t maxIndex = min(size-i, (int)(pbuffer->getRemaining()/sizeof(T)))+i;
|
||||
for(; i<maxIndex; i++)
|
||||
value[i] = pbuffer->get<T>();
|
||||
*/
|
||||
int maxCount = std::min(size-i, (int)(pbuffer->getRemaining()/sizeof(T)));
|
||||
pbuffer->getArray<T>(&value[i], maxCount);
|
||||
size_t maxCount = min(size-i, (pbuffer->getRemaining()/sizeof(T)));
|
||||
pbuffer->getArray(get()+i, maxCount);
|
||||
i += maxCount;
|
||||
|
||||
if(i<size)
|
||||
@@ -285,8 +346,7 @@ void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
|
||||
else
|
||||
break;
|
||||
}
|
||||
// set new length
|
||||
this->setLength(size);
|
||||
// inform about the change?
|
||||
PVField::postPut();
|
||||
}
|
||||
// TODO null arrays (size == -1) not supported
|
||||
@@ -294,9 +354,9 @@ void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
|
||||
|
||||
template<typename T>
|
||||
void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, int offset, int count) const {
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const {
|
||||
// cache
|
||||
int length = this->getLength();
|
||||
size_t length = this->getLength();
|
||||
|
||||
// check bounds
|
||||
if(offset<0)
|
||||
@@ -304,24 +364,25 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
else if(offset>length) offset = length;
|
||||
if(count<0) count = length;
|
||||
|
||||
int maxCount = length-offset;
|
||||
size_t maxCount = length-offset;
|
||||
if(count>maxCount) count = maxCount;
|
||||
|
||||
// write
|
||||
SerializeHelper::writeSize(count, pbuffer, pflusher);
|
||||
//if (count == 0) return; pcontrol->ensureData(sizeof(T)-1); pbuffer->align(sizeof(T));
|
||||
int end = offset+count;
|
||||
int i = offset;
|
||||
size_t end = offset+count;
|
||||
size_t i = offset;
|
||||
while(true) {
|
||||
|
||||
/*
|
||||
int maxIndex = std::min<int>(end-i, (int)(pbuffer->getRemaining()/sizeof(T)))+i;
|
||||
size_t maxIndex = min<int>(end-i, (int)(pbuffer->getRemaining()/sizeof(T)))+i;
|
||||
for(; i<maxIndex; i++)
|
||||
pbuffer->put<T>(value[i]);
|
||||
*/
|
||||
|
||||
int maxCount = std::min<int>(end-i, (int)(pbuffer->getRemaining()/sizeof(T)));
|
||||
pbuffer->putArray<T>(&value[i], maxCount);
|
||||
size_t maxCount = min<int>(end-i, (int)(pbuffer->getRemaining()/sizeof(T)));
|
||||
T * pvalue = const_cast<T *>(get());
|
||||
pbuffer->putArray(pvalue+i, maxCount);
|
||||
i += maxCount;
|
||||
|
||||
if(i<end)
|
||||
@@ -336,16 +397,19 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
|
||||
template<>
|
||||
void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
int size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
if(size>=0) {
|
||||
// prepare array, if necessary
|
||||
if(size>getCapacity()) setCapacity(size);
|
||||
// retrieve value from the buffer
|
||||
for(int i = 0; i<size; i++)
|
||||
value[i] = SerializeHelper::deserializeString(pbuffer,
|
||||
pcontrol);
|
||||
// set new length
|
||||
setLength(size);
|
||||
// retrieve value from the buffer
|
||||
String * pvalue = get();
|
||||
for(size_t i = 0; i<size; i++) {
|
||||
pvalue[i] = SerializeHelper::deserializeString(pbuffer,
|
||||
pcontrol);
|
||||
}
|
||||
// inform about the change?
|
||||
postPut();
|
||||
}
|
||||
// TODO null arrays (size == -1) not supported
|
||||
@@ -353,8 +417,8 @@ void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
|
||||
|
||||
template<>
|
||||
void DefaultPVArray<String>::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, int offset, int count) const {
|
||||
int length = getLength();
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const {
|
||||
size_t length = getLength();
|
||||
|
||||
// check bounds
|
||||
if(offset<0)
|
||||
@@ -362,240 +426,262 @@ void DefaultPVArray<String>::serialize(ByteBuffer *pbuffer,
|
||||
else if(offset>length) offset = length;
|
||||
if(count<0) count = length;
|
||||
|
||||
int maxCount = length-offset;
|
||||
size_t maxCount = length-offset;
|
||||
if(count>maxCount) count = maxCount;
|
||||
|
||||
// write
|
||||
SerializeHelper::writeSize(count, pbuffer, pflusher);
|
||||
int end = offset+count;
|
||||
for(int i = offset; i<end; i++)
|
||||
SerializeHelper::serializeString(value[i], pbuffer, pflusher);
|
||||
size_t end = offset+count;
|
||||
String * pvalue = get();
|
||||
for(size_t i = offset; i<end; i++) {
|
||||
SerializeHelper::serializeString(pvalue[i], pbuffer, pflusher);
|
||||
}
|
||||
}
|
||||
|
||||
typedef DefaultPVArray<bool> DefaultPVBooleanArray;
|
||||
typedef DefaultPVArray<boolean> DefaultPVBooleanArray;
|
||||
typedef DefaultPVArray<int8> BasePVByteArray;
|
||||
typedef DefaultPVArray<int16> BasePVShortArray;
|
||||
typedef DefaultPVArray<int32> BasePVIntArray;
|
||||
typedef DefaultPVArray<int64> BasePVLongArray;
|
||||
typedef DefaultPVArray<uint8> BasePVUByteArray;
|
||||
typedef DefaultPVArray<uint16> BasePVUShortArray;
|
||||
typedef DefaultPVArray<uint32> BasePVUIntArray;
|
||||
typedef DefaultPVArray<uint64> BasePVULongArray;
|
||||
typedef DefaultPVArray<float> BasePVFloatArray;
|
||||
typedef DefaultPVArray<double> BasePVDoubleArray;
|
||||
typedef DefaultPVArray<String> BasePVStringArray;
|
||||
|
||||
// Factory
|
||||
|
||||
PVDataCreate::PVDataCreate(){ }
|
||||
PVDataCreate::PVDataCreate()
|
||||
: fieldCreate(getFieldCreate())
|
||||
{ }
|
||||
|
||||
PVField *PVDataCreate::createPVField(PVStructure *parent,
|
||||
FieldConstPtr field)
|
||||
PVFieldPtr PVDataCreate::createPVField(FieldConstPtr const & field)
|
||||
{
|
||||
switch(field->getType()) {
|
||||
case scalar: {
|
||||
ScalarConstPtr xx = static_pointer_cast<const Scalar>(field);
|
||||
return createPVScalar(parent,xx);
|
||||
return createPVScalar(xx);
|
||||
}
|
||||
case scalarArray: {
|
||||
ScalarArrayConstPtr xx = static_pointer_cast<const ScalarArray>(field);
|
||||
return (PVField *)createPVScalarArray(parent,xx);
|
||||
return createPVScalarArray(xx);
|
||||
}
|
||||
case structure: {
|
||||
StructureConstPtr xx = static_pointer_cast<const Structure>(field);
|
||||
return (PVField *)createPVStructure(parent,xx);
|
||||
return createPVStructure(xx);
|
||||
}
|
||||
case structureArray: {
|
||||
StructureArrayConstPtr xx = static_pointer_cast<const StructureArray>(field);
|
||||
return createPVStructureArray(parent,xx);
|
||||
return createPVStructureArray(xx);
|
||||
}
|
||||
}
|
||||
String message("PVDataCreate::createPVField should never get here");
|
||||
throw std::logic_error(message);
|
||||
throw std::logic_error("PVDataCreate::createPVField should never get here");
|
||||
}
|
||||
|
||||
PVField *PVDataCreate::createPVField(PVStructure *parent,
|
||||
String fieldName,PVField * fieldToClone)
|
||||
PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone)
|
||||
{
|
||||
switch(fieldToClone->getField()->getType()) {
|
||||
case scalar:
|
||||
return createPVScalar(parent,fieldName,(PVScalar*)fieldToClone);
|
||||
{
|
||||
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(fieldToClone);
|
||||
return createPVScalar(pvScalar);
|
||||
}
|
||||
case scalarArray:
|
||||
return (PVField *)createPVScalarArray(parent,fieldName,
|
||||
(PVScalarArray *)fieldToClone);
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray
|
||||
= static_pointer_cast<PVScalarArray>(fieldToClone);
|
||||
return createPVScalarArray(pvScalarArray);
|
||||
}
|
||||
case structure:
|
||||
return (PVField *)createPVStructure(parent,fieldName,
|
||||
(PVStructure *)fieldToClone);
|
||||
{
|
||||
PVStructurePtr pvStructure
|
||||
= static_pointer_cast<PVStructure>(fieldToClone);
|
||||
StringArray const & fieldNames = pvStructure->getStructure()->getFieldNames();
|
||||
PVFieldPtrArray pvFieldPtrArray = pvStructure->getPVFields();
|
||||
return createPVStructure(fieldNames,pvFieldPtrArray);
|
||||
}
|
||||
case structureArray:
|
||||
String message(
|
||||
"PVDataCreate::createPVField structureArray not valid fieldToClone");
|
||||
throw std::invalid_argument(message);
|
||||
{
|
||||
PVStructureArrayPtr from
|
||||
= static_pointer_cast<PVStructureArray>(fieldToClone);
|
||||
StructureArrayConstPtr structureArray = from->getStructureArray();
|
||||
PVStructureArrayPtr to = createPVStructureArray(
|
||||
structureArray);
|
||||
getConvert()->copyStructureArray(from, to);
|
||||
return to;
|
||||
}
|
||||
}
|
||||
String message("PVDataCreate::createPVField should never get here");
|
||||
throw std::logic_error(message);
|
||||
throw std::logic_error("PVDataCreate::createPVField should never get here");
|
||||
}
|
||||
|
||||
PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,ScalarConstPtr scalar)
|
||||
PVScalarPtr PVDataCreate::createPVScalar(ScalarConstPtr const & scalar)
|
||||
{
|
||||
ScalarType scalarType = scalar->getScalarType();
|
||||
switch(scalarType) {
|
||||
case pvBoolean:
|
||||
return new BasePVBoolean(parent,scalar);
|
||||
return PVScalarPtr(new BasePVBoolean(scalar));
|
||||
case pvByte:
|
||||
return new BasePVByte(parent,scalar);
|
||||
return PVScalarPtr(new BasePVByte(scalar));
|
||||
case pvShort:
|
||||
return new BasePVShort(parent,scalar);
|
||||
return PVScalarPtr(new BasePVShort(scalar));
|
||||
case pvInt:
|
||||
return new BasePVInt(parent,scalar);
|
||||
return PVScalarPtr(new BasePVInt(scalar));
|
||||
case pvLong:
|
||||
return new BasePVLong(parent,scalar);
|
||||
return PVScalarPtr(new BasePVLong(scalar));
|
||||
case pvUByte:
|
||||
return PVScalarPtr(new BasePVUByte(scalar));
|
||||
case pvUShort:
|
||||
return PVScalarPtr(new BasePVUShort(scalar));
|
||||
case pvUInt:
|
||||
return PVScalarPtr(new BasePVUInt(scalar));
|
||||
case pvULong:
|
||||
return PVScalarPtr(new BasePVULong(scalar));
|
||||
case pvFloat:
|
||||
return new BasePVFloat(parent,scalar);
|
||||
return PVScalarPtr(new BasePVFloat(scalar));
|
||||
case pvDouble:
|
||||
return new BasePVDouble(parent,scalar);
|
||||
return PVScalarPtr(new BasePVDouble(scalar));
|
||||
case pvString:
|
||||
return new BasePVString(parent,scalar);
|
||||
return PVScalarPtr(new BasePVString(scalar));
|
||||
}
|
||||
String message("PVDataCreate::createPVScalar should never get here");
|
||||
throw std::logic_error(message);
|
||||
throw std::logic_error("PVDataCreate::createPVScalar should never get here");
|
||||
}
|
||||
|
||||
PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,
|
||||
String fieldName,ScalarType scalarType)
|
||||
PVScalarPtr PVDataCreate::createPVScalar(ScalarType scalarType)
|
||||
{
|
||||
ScalarConstPtr scalar = fieldCreate->createScalar(fieldName,scalarType);
|
||||
return createPVScalar(parent,scalar);
|
||||
ScalarConstPtr scalar = fieldCreate->createScalar(scalarType);
|
||||
return createPVScalar(scalar);
|
||||
}
|
||||
|
||||
|
||||
PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,
|
||||
String fieldName,PVScalar * scalarToClone)
|
||||
PVScalarPtr PVDataCreate::createPVScalar(PVScalarPtr const & scalarToClone)
|
||||
{
|
||||
PVScalar *pvScalar = createPVScalar(parent,fieldName,
|
||||
scalarToClone->getScalar()->getScalarType());
|
||||
convert->copyScalar(scalarToClone, pvScalar);
|
||||
PVAuxInfo *from = scalarToClone->getPVAuxInfo();
|
||||
PVAuxInfo *to = pvScalar->getPVAuxInfo();
|
||||
int numberInfo = from->getNumberInfo();
|
||||
for(int i=0; i<numberInfo; i++) {
|
||||
PVScalar *pvFrom = from->getInfo(i);
|
||||
ScalarConstPtr scalar = pvFrom->getScalar();
|
||||
PVScalar *pvTo = to->createInfo(scalar->getFieldName(),scalar->getScalarType());
|
||||
convert->copyScalar(pvFrom,pvTo);
|
||||
ScalarType scalarType = scalarToClone->getScalar()->getScalarType();
|
||||
PVScalarPtr pvScalar = createPVScalar(scalarType);
|
||||
getConvert()->copyScalar(scalarToClone, pvScalar);
|
||||
PVAuxInfoPtr from = scalarToClone->getPVAuxInfo();
|
||||
PVAuxInfoPtr to = pvScalar->getPVAuxInfo();
|
||||
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
|
||||
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
|
||||
String key = iter->first;
|
||||
PVScalarPtr pvFrom = iter->second;
|
||||
ScalarConstPtr scalar = pvFrom->getScalar();
|
||||
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
|
||||
getConvert()->copyScalar(pvFrom,pvTo);
|
||||
}
|
||||
return pvScalar;
|
||||
}
|
||||
|
||||
PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent,
|
||||
ScalarArrayConstPtr scalarArray)
|
||||
PVScalarArrayPtr PVDataCreate::createPVScalarArray(
|
||||
ScalarArrayConstPtr const & scalarArray)
|
||||
{
|
||||
switch(scalarArray->getElementType()) {
|
||||
case pvBoolean:
|
||||
return new DefaultPVBooleanArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new DefaultPVBooleanArray(scalarArray));
|
||||
case pvByte:
|
||||
return new BasePVByteArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new BasePVByteArray(scalarArray));
|
||||
case pvShort:
|
||||
return new BasePVShortArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new BasePVShortArray(scalarArray));
|
||||
case pvInt:
|
||||
return new BasePVIntArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new BasePVIntArray(scalarArray));
|
||||
case pvLong:
|
||||
return new BasePVLongArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new BasePVLongArray(scalarArray));
|
||||
case pvUByte:
|
||||
return PVScalarArrayPtr(new BasePVUByteArray(scalarArray));
|
||||
case pvUShort:
|
||||
return PVScalarArrayPtr(new BasePVUShortArray(scalarArray));
|
||||
case pvUInt:
|
||||
return PVScalarArrayPtr(new BasePVUIntArray(scalarArray));
|
||||
case pvULong:
|
||||
return PVScalarArrayPtr(new BasePVULongArray(scalarArray));
|
||||
case pvFloat:
|
||||
return new BasePVFloatArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new BasePVFloatArray(scalarArray));
|
||||
case pvDouble:
|
||||
return new BasePVDoubleArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new BasePVDoubleArray(scalarArray));
|
||||
case pvString:
|
||||
return new BasePVStringArray(parent,scalarArray);
|
||||
return PVScalarArrayPtr(new BasePVStringArray(scalarArray));
|
||||
}
|
||||
String message("PVDataCreate::createPVScalarArray should never get here");
|
||||
throw std::logic_error(message);
|
||||
throw std::logic_error("PVDataCreate::createPVScalarArray should never get here");
|
||||
|
||||
}
|
||||
|
||||
PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent,
|
||||
String fieldName,ScalarType elementType)
|
||||
PVScalarArrayPtr PVDataCreate::createPVScalarArray(
|
||||
ScalarType elementType)
|
||||
{
|
||||
return createPVScalarArray(parent,
|
||||
fieldCreate->createScalarArray(fieldName, elementType));
|
||||
ScalarArrayConstPtr scalarArray = fieldCreate->createScalarArray(elementType);
|
||||
return createPVScalarArray(scalarArray);
|
||||
}
|
||||
|
||||
PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent,
|
||||
String fieldName,PVScalarArray * arrayToClone)
|
||||
PVScalarArrayPtr PVDataCreate::createPVScalarArray(
|
||||
PVScalarArrayPtr const & arrayToClone)
|
||||
{
|
||||
PVScalarArray *pvArray = createPVScalarArray(parent,fieldName,
|
||||
PVScalarArrayPtr pvArray = createPVScalarArray(
|
||||
arrayToClone->getScalarArray()->getElementType());
|
||||
convert->copyScalarArray(arrayToClone,0, pvArray,0,arrayToClone->getLength());
|
||||
PVAuxInfo *from = arrayToClone->getPVAuxInfo();
|
||||
PVAuxInfo *to = pvArray->getPVAuxInfo();
|
||||
int numberInfo = from->getNumberInfo();
|
||||
for(int i=0; i<numberInfo; i++) {
|
||||
PVScalar *pvFrom = from->getInfo(i);
|
||||
ScalarConstPtr scalar = pvFrom->getScalar();
|
||||
PVScalar *pvTo = to->createInfo(scalar->getFieldName(),scalar->getScalarType());
|
||||
convert->copyScalar(pvFrom,pvTo);
|
||||
getConvert()->copyScalarArray(arrayToClone,0, pvArray,0,arrayToClone->getLength());
|
||||
PVAuxInfoPtr from = arrayToClone->getPVAuxInfo();
|
||||
PVAuxInfoPtr to = pvArray->getPVAuxInfo();
|
||||
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
|
||||
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
|
||||
String key = iter->first;
|
||||
PVScalarPtr pvFrom = iter->second;
|
||||
ScalarConstPtr scalar = pvFrom->getScalar();
|
||||
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
|
||||
getConvert()->copyScalar(pvFrom,pvTo);
|
||||
}
|
||||
return pvArray;
|
||||
}
|
||||
|
||||
PVStructureArray *PVDataCreate::createPVStructureArray(PVStructure *parent,
|
||||
StructureArrayConstPtr structureArray)
|
||||
PVStructureArrayPtr PVDataCreate::createPVStructureArray(
|
||||
StructureArrayConstPtr const & structureArray)
|
||||
{
|
||||
return new BasePVStructureArray(parent,structureArray);
|
||||
return PVStructureArrayPtr(new PVStructureArray(structureArray));
|
||||
}
|
||||
|
||||
PVStructure *PVDataCreate::createPVStructure(PVStructure *parent,
|
||||
StructureConstPtr structure)
|
||||
PVStructurePtr PVDataCreate::createPVStructure(
|
||||
StructureConstPtr const & structure)
|
||||
{
|
||||
PVStructure *pvStructure = new PVStructure(parent,structure);
|
||||
return PVStructurePtr(new PVStructure(structure));
|
||||
}
|
||||
|
||||
PVStructurePtr PVDataCreate::createPVStructure(
|
||||
StringArray const & fieldNames,PVFieldPtrArray const & pvFields)
|
||||
{
|
||||
size_t num = fieldNames.size();
|
||||
FieldConstPtrArray fields(num);
|
||||
for (size_t i=0;i<num;i++) fields[i] = pvFields[i]->getField();
|
||||
StructureConstPtr structure = fieldCreate->createStructure(fieldNames,fields);
|
||||
PVStructurePtr pvStructure(new PVStructure(structure,pvFields));
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructure *PVDataCreate::createPVStructure(PVStructure *parent,
|
||||
String fieldName,int numberFields,FieldConstPtrArray fields)
|
||||
PVStructurePtr PVDataCreate::createPVStructure(PVStructurePtr const & structToClone)
|
||||
{
|
||||
StructureConstPtr structure = fieldCreate->createStructure(
|
||||
fieldName,numberFields, fields);
|
||||
return new PVStructure(parent,structure);
|
||||
}
|
||||
|
||||
PVStructure *PVDataCreate::createPVStructure(PVStructure *parent,
|
||||
String fieldName,int numberFields,PVFieldPtrArray pvFields)
|
||||
{
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numberFields];
|
||||
for(int i=0; i<numberFields;i++) {
|
||||
fields[i] = pvFields[i]->getField();
|
||||
}
|
||||
StructureConstPtr structure = fieldCreate->createStructure(
|
||||
fieldName,numberFields,fields);
|
||||
PVStructure *pvStructure = new PVStructure(parent,structure,pvFields);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructure *PVDataCreate::createPVStructure(PVStructure *parent,
|
||||
String fieldName,PVStructure *structToClone)
|
||||
{
|
||||
FieldConstPtrArray fields = 0;
|
||||
int numberFields = 0;
|
||||
PVStructure *pvStructure = 0;;
|
||||
FieldConstPtrArray field;
|
||||
if(structToClone==0) {
|
||||
fields = new FieldConstPtr[0];
|
||||
StructureConstPtr structure = fieldCreate->createStructure(
|
||||
fieldName,numberFields,fields);
|
||||
pvStructure = new PVStructure(parent,structure);
|
||||
} else {
|
||||
StructureConstPtr structure = structToClone->getStructure();
|
||||
pvStructure = new PVStructure(parent,structure);
|
||||
convert->copyStructure(structToClone,pvStructure);
|
||||
FieldConstPtrArray fields(0);
|
||||
StringArray fieldNames(0);
|
||||
StructureConstPtr structure = fieldCreate->createStructure(fieldNames,fields);
|
||||
return PVStructurePtr(new PVStructure(structure));
|
||||
}
|
||||
StructureConstPtr structure = structToClone->getStructure();
|
||||
PVStructurePtr pvStructure(new PVStructure(structure));
|
||||
getConvert()->copyStructure(structToClone,pvStructure);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVDataCreate * getPVDataCreate() {
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
PVDataCreatePtr PVDataCreate::getPVDataCreate()
|
||||
{
|
||||
static PVDataCreatePtr pvDataCreate;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
|
||||
if(pvDataCreate==0){
|
||||
pvDataCreate = new PVDataCreate();
|
||||
convert = getConvert();
|
||||
fieldCreate = getFieldCreate();
|
||||
}
|
||||
return pvDataCreate;
|
||||
}
|
||||
if(pvDataCreate.get()==0) pvDataCreate = PVDataCreatePtr(new PVDataCreate());
|
||||
return pvDataCreate;
|
||||
}
|
||||
|
||||
PVDataCreatePtr getPVDataCreate() {
|
||||
return PVDataCreate::getPVDataCreate();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*PVField.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
@@ -12,75 +15,45 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
using std::tr1::const_pointer_cast;
|
||||
using std::size_t;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static String notImplemented("not implemented");
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(pvField);
|
||||
|
||||
class PVFieldPvt {
|
||||
public:
|
||||
PVFieldPvt(PVStructure *parent,FieldConstPtr field);
|
||||
~PVFieldPvt();
|
||||
PVStructure *parent;
|
||||
FieldConstPtr field;
|
||||
int fieldOffset;
|
||||
int nextFieldOffset;
|
||||
PVAuxInfo *pvAuxInfo;
|
||||
bool immutable;
|
||||
Requester *requester;
|
||||
PostHandler *postHandler;
|
||||
Convert *convert;
|
||||
};
|
||||
|
||||
PVFieldPvt::PVFieldPvt(PVStructure *parent,FieldConstPtr field)
|
||||
: parent(parent),field(field),
|
||||
fieldOffset(0), nextFieldOffset(0),
|
||||
pvAuxInfo(0),
|
||||
immutable(false),requester(0),postHandler(0),
|
||||
convert(getConvert())
|
||||
PVField::PVField(FieldConstPtr field)
|
||||
: notImplemented("not implemented"),
|
||||
parent(NULL),field(field),
|
||||
fieldOffset(0), nextFieldOffset(0),
|
||||
immutable(false),
|
||||
convert(getConvert())
|
||||
{
|
||||
}
|
||||
|
||||
PVFieldPvt::~PVFieldPvt()
|
||||
{
|
||||
if(pvAuxInfo!=0) delete pvAuxInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PVField::PVField(PVStructure *parent,FieldConstPtr field)
|
||||
: pImpl(new PVFieldPvt(parent,field))
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(pvField);
|
||||
}
|
||||
|
||||
PVField::~PVField()
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(pvField);
|
||||
delete pImpl;
|
||||
}
|
||||
{ }
|
||||
|
||||
void PVField::message(String fieldName,String message,MessageType messageType)
|
||||
void PVField::message(
|
||||
String message,
|
||||
MessageType messageType,
|
||||
String fullFieldName)
|
||||
{
|
||||
if(pImpl->parent!=0) {
|
||||
String parentName = pImpl->parent->getField()->getFieldName();
|
||||
if(parentName.length()>0) {
|
||||
fieldName = parentName + "." + fieldName;
|
||||
if(parent!=NULL) {
|
||||
if(fullFieldName.length()>0) {
|
||||
fullFieldName = fieldName + '.' + fullFieldName;
|
||||
} else {
|
||||
fullFieldName = fieldName;
|
||||
}
|
||||
pImpl->parent->message(fieldName,message,messageType);
|
||||
parent->message(message,messageType,fullFieldName);
|
||||
return;
|
||||
}
|
||||
if(pImpl->requester) {
|
||||
String mess = fieldName + " " + message;
|
||||
pImpl->requester->message(mess,messageType);
|
||||
message = fullFieldName + " " + message;
|
||||
if(requester) {
|
||||
requester->message(message,messageType);
|
||||
} else {
|
||||
printf("%s %s %s\n",
|
||||
messageTypeName[messageType].c_str(),
|
||||
getMessageTypeName(messageType).c_str(),
|
||||
fieldName.c_str(),
|
||||
message.c_str());
|
||||
}
|
||||
@@ -88,129 +61,178 @@ void PVField::message(String fieldName,String message,MessageType messageType)
|
||||
|
||||
void PVField::message(String message,MessageType messageType)
|
||||
{
|
||||
PVField::message(pImpl->field->getFieldName(),message,messageType);
|
||||
PVField::message(message,messageType,"");
|
||||
}
|
||||
void PVField::setRequester(Requester *requester)
|
||||
|
||||
String PVField::getFieldName() const
|
||||
{
|
||||
if(pImpl->parent!=0) {
|
||||
throw std::logic_error(String(
|
||||
"PVField::setRequester only legal for top level structure"));
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
void PVField::setRequester(RequesterPtr const &req)
|
||||
{
|
||||
if(parent!=NULL) {
|
||||
throw std::logic_error(
|
||||
"PVField::setRequester only legal for top level structure");
|
||||
}
|
||||
if(pImpl->requester!=0) {
|
||||
if(pImpl->requester==requester) return;
|
||||
throw std::logic_error(String(
|
||||
"PVField::setRequester requester is already present"));
|
||||
if(requester.get()!=NULL) {
|
||||
if(requester.get()==req.get()) return;
|
||||
throw std::logic_error(
|
||||
"PVField::setRequester requester is already present");
|
||||
}
|
||||
pImpl->requester = requester;
|
||||
requester = req;
|
||||
}
|
||||
|
||||
int PVField::getFieldOffset()
|
||||
size_t PVField::getFieldOffset() const
|
||||
{
|
||||
if(pImpl->nextFieldOffset==0) computeOffset(this);
|
||||
return pImpl->fieldOffset;
|
||||
if(nextFieldOffset==0) computeOffset(this);
|
||||
return fieldOffset;
|
||||
}
|
||||
|
||||
int PVField::getNextFieldOffset()
|
||||
size_t PVField::getNextFieldOffset() const
|
||||
{
|
||||
if(pImpl->nextFieldOffset==0) computeOffset(this);
|
||||
return pImpl->nextFieldOffset;
|
||||
if(nextFieldOffset==0) computeOffset(this);
|
||||
return nextFieldOffset;
|
||||
}
|
||||
|
||||
int PVField::getNumberFields()
|
||||
size_t PVField::getNumberFields() const
|
||||
{
|
||||
if(pImpl->nextFieldOffset==0) computeOffset(this);
|
||||
return (pImpl->nextFieldOffset - pImpl->fieldOffset);
|
||||
if(nextFieldOffset==0) computeOffset(this);
|
||||
return (nextFieldOffset - fieldOffset);
|
||||
}
|
||||
|
||||
PVAuxInfo * PVField::getPVAuxInfo(){
|
||||
if(pImpl->pvAuxInfo==0) {
|
||||
pImpl->pvAuxInfo = new PVAuxInfo(this);
|
||||
PVAuxInfoPtr & PVField::getPVAuxInfo(){
|
||||
if(pvAuxInfo.get()==NULL) {
|
||||
pvAuxInfo = PVAuxInfoPtr(new PVAuxInfo(this));
|
||||
}
|
||||
return pImpl->pvAuxInfo;
|
||||
return pvAuxInfo;
|
||||
}
|
||||
|
||||
bool PVField::isImmutable() {return pImpl->immutable;}
|
||||
bool PVField::isImmutable() const {return immutable;}
|
||||
|
||||
void PVField::setImmutable() {pImpl->immutable = true;}
|
||||
void PVField::setImmutable() {immutable = true;}
|
||||
|
||||
FieldConstPtr PVField::getField() {return pImpl->field;}
|
||||
const FieldConstPtr & PVField::getField() const {return field;}
|
||||
|
||||
PVStructure * PVField::getParent() {return pImpl->parent;}
|
||||
PVStructure *PVField::getParent() const {return parent;}
|
||||
|
||||
|
||||
bool PVField::renameField(String newName)
|
||||
void PVField::replacePVField(const PVFieldPtr & newPVField)
|
||||
{
|
||||
if(pImpl->parent!=0) {
|
||||
StructureConstPtr structure = pImpl->parent->getStructure();
|
||||
int index = structure->getFieldIndex(newName);
|
||||
if(index>=0) return false;
|
||||
if(parent==NULL) {
|
||||
throw std::logic_error("no parent");
|
||||
}
|
||||
Field::shared_pointer field(const_pointer_cast<Field>(pImpl->field));
|
||||
field->renameField(newName);
|
||||
return true;
|
||||
PVFieldPtrArray pvFields = parent->getPVFields();
|
||||
StructureConstPtr structure = parent->getStructure();
|
||||
StringArray fieldNames = structure->getFieldNames();
|
||||
for(size_t i=0; i<fieldNames.size(); i++) {
|
||||
if(newPVField->getFieldName().compare(fieldNames[i]) == 0) {
|
||||
pvFields[i] = newPVField;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::logic_error("Did not find field in parent");
|
||||
}
|
||||
|
||||
void PVField::replaceField(FieldConstPtr &xxx)
|
||||
{
|
||||
field = xxx;
|
||||
}
|
||||
|
||||
void PVField::renameField(String const & newName)
|
||||
{
|
||||
if(parent==NULL) {
|
||||
throw std::logic_error("no parent");
|
||||
}
|
||||
std::tr1::shared_ptr<Structure> parentStructure = const_pointer_cast<Structure>(
|
||||
parent->getStructure());
|
||||
PVFieldPtrArray pvFields = parent->getPVFields();
|
||||
for(size_t i=0; i<pvFields.size(); i++) {
|
||||
if(pvFields[i].get()==this) {
|
||||
parentStructure->renameField(i,newName);
|
||||
fieldName = newName;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::logic_error("Did not find field in parent");
|
||||
}
|
||||
|
||||
void PVField::postPut()
|
||||
{
|
||||
if(pImpl->postHandler!=0) pImpl->postHandler->postPut();
|
||||
if(postHandler!=NULL) postHandler->postPut();
|
||||
}
|
||||
|
||||
void PVField::setPostHandler(PostHandler *postHandler)
|
||||
void PVField::setPostHandler(PostHandlerPtr const &handler)
|
||||
{
|
||||
if(pImpl->postHandler!=0) {
|
||||
if(postHandler==pImpl->postHandler) return;
|
||||
String message(
|
||||
if(postHandler.get()!=NULL) {
|
||||
if(postHandler.get()==handler.get()) return;
|
||||
throw std::logic_error(
|
||||
"PVField::setPostHandler a postHandler is already registered");
|
||||
throw std::logic_error(message);
|
||||
|
||||
}
|
||||
pImpl->postHandler = postHandler;
|
||||
postHandler = handler;
|
||||
}
|
||||
|
||||
void PVField::setParent(PVStructure * parent)
|
||||
void PVField::setParentAndName(PVStructure * xxx,String const & name)
|
||||
{
|
||||
pImpl->parent = parent;
|
||||
parent = xxx;
|
||||
fieldName = name;
|
||||
}
|
||||
|
||||
bool PVField::equals(PVField &pv)
|
||||
{
|
||||
return pImpl->convert->equals(*this,pv);
|
||||
return convert->equals(*this,pv);
|
||||
}
|
||||
|
||||
void PVField::toString(StringBuilder buf) {toString(buf,0);}
|
||||
void PVField::toString(StringBuilder buf)
|
||||
{
|
||||
toString(buf,0);
|
||||
}
|
||||
|
||||
void PVField::toString(StringBuilder buf,int indentLevel)
|
||||
{
|
||||
pImpl->convert->getString(buf,this,indentLevel);
|
||||
if(pImpl->pvAuxInfo==0) return;
|
||||
pImpl->pvAuxInfo->toString(buf,indentLevel);
|
||||
convert->getString(buf,this,indentLevel);
|
||||
if(pvAuxInfo.get()!=NULL) pvAuxInfo->toString(buf,indentLevel);
|
||||
}
|
||||
|
||||
void PVField::computeOffset(PVField * pvField) {
|
||||
PVStructure *pvTop = pvField->getParent();
|
||||
if(pvTop==0) {
|
||||
std::ostream& PVField::dumpValue(std::ostream& o) const
|
||||
{
|
||||
// default implementation
|
||||
// each PVField class should implement it to avoid switch statement
|
||||
// and string reallocation
|
||||
String tmp;
|
||||
convert->getString(&tmp,this,0);
|
||||
return o << tmp;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const PVField& f) { return f.dumpValue(o); };
|
||||
|
||||
void PVField::computeOffset(const PVField * pvField) {
|
||||
const PVStructure * pvTop = pvField->getParent();
|
||||
if(pvTop==NULL) {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->pImpl->fieldOffset = 0;
|
||||
pvField->pImpl->nextFieldOffset = 1;
|
||||
PVField *xxx = const_cast<PVField *>(pvField);
|
||||
xxx->fieldOffset = 0;
|
||||
xxx->nextFieldOffset = 1;
|
||||
return;
|
||||
}
|
||||
pvTop = static_cast<PVStructure *>(pvField);
|
||||
pvTop = static_cast<const PVStructure *>(pvField);
|
||||
} else {
|
||||
while(pvTop->getParent()!=0) pvTop = pvTop->getParent();
|
||||
while(pvTop->getParent()!=NULL) pvTop = pvTop->getParent();
|
||||
}
|
||||
int offset = 0;
|
||||
int nextOffset = 1;
|
||||
PVFieldPtrArray pvFields = pvTop->getPVFields();
|
||||
for(int i=0; i < pvTop->getStructure()->getNumberFields(); i++) {
|
||||
PVFieldPtrArray pvFields = pvTop->getPVFields();
|
||||
for(size_t i=0; i < pvTop->getStructure()->getNumberFields(); i++) {
|
||||
offset = nextOffset;
|
||||
PVField *pvField = pvFields[i];
|
||||
PVField *pvField = pvFields[i].get();
|
||||
FieldConstPtr field = pvField->getField();
|
||||
switch(field->getType()) {
|
||||
case scalar:
|
||||
case scalarArray:
|
||||
case structureArray:{
|
||||
nextOffset++;
|
||||
pvField->pImpl->fieldOffset = offset;
|
||||
pvField->pImpl->nextFieldOffset = nextOffset;
|
||||
pvField->fieldOffset = offset;
|
||||
pvField->nextFieldOffset = nextOffset;
|
||||
break;
|
||||
}
|
||||
case structure: {
|
||||
@@ -220,36 +242,38 @@ void PVField::computeOffset(PVField * pvField) {
|
||||
}
|
||||
}
|
||||
PVField *top = (PVField *)pvTop;
|
||||
top->pImpl->fieldOffset = 0;
|
||||
top->pImpl->nextFieldOffset = nextOffset;
|
||||
PVField *xxx = const_cast<PVField *>(top);
|
||||
xxx->fieldOffset = 0;
|
||||
xxx->nextFieldOffset = nextOffset;
|
||||
}
|
||||
|
||||
void PVField::computeOffset(PVField * pvField,int offset) {
|
||||
int beginOffset = offset;
|
||||
int nextOffset = offset + 1;
|
||||
PVStructure *pvStructure = static_cast<PVStructure *>(pvField);
|
||||
PVFieldPtrArray pvFields = pvStructure->getPVFields();
|
||||
for(int i=0; i < pvStructure->getStructure()->getNumberFields(); i++) {
|
||||
offset = nextOffset;
|
||||
PVField *pvSubField = pvFields[i];
|
||||
FieldConstPtr field = pvSubField->getField();
|
||||
switch(field->getType()) {
|
||||
case scalar:
|
||||
case scalarArray:
|
||||
case structureArray: {
|
||||
nextOffset++;
|
||||
pvSubField->pImpl->fieldOffset = offset;
|
||||
pvSubField->pImpl->nextFieldOffset = nextOffset;
|
||||
break;
|
||||
}
|
||||
case structure: {
|
||||
pvSubField->computeOffset(pvSubField,offset);
|
||||
nextOffset = pvSubField->getNextFieldOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
pvField->pImpl->fieldOffset = beginOffset;
|
||||
pvField->pImpl->nextFieldOffset = nextOffset;
|
||||
void PVField::computeOffset(const PVField * pvField,size_t offset) {
|
||||
int beginOffset = offset;
|
||||
int nextOffset = offset + 1;
|
||||
const PVStructure *pvStructure = static_cast<const PVStructure *>(pvField);
|
||||
const PVFieldPtrArray pvFields = pvStructure->getPVFields();
|
||||
for(size_t i=0; i < pvStructure->getStructure()->getNumberFields(); i++) {
|
||||
offset = nextOffset;
|
||||
PVField *pvSubField = pvFields[i].get();
|
||||
FieldConstPtr field = pvSubField->getField();
|
||||
switch(field->getType()) {
|
||||
case scalar:
|
||||
case scalarArray:
|
||||
case structureArray: {
|
||||
nextOffset++;
|
||||
pvSubField->fieldOffset = offset;
|
||||
pvSubField->nextFieldOffset = nextOffset;
|
||||
break;
|
||||
}
|
||||
case structure: {
|
||||
pvSubField->computeOffset(pvSubField,offset);
|
||||
nextOffset = pvSubField->getNextFieldOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
PVField *xxx = const_cast<PVField *>(pvField);
|
||||
xxx->fieldOffset = beginOffset;
|
||||
xxx->nextFieldOffset = nextOffset;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*PVScalar.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
@@ -17,12 +20,23 @@ namespace epics { namespace pvData {
|
||||
|
||||
PVScalar::~PVScalar() {}
|
||||
|
||||
PVScalar::PVScalar(PVStructure *parent,ScalarConstPtr scalar)
|
||||
: PVField(parent,scalar) {}
|
||||
PVScalar::PVScalar(ScalarConstPtr const & scalar)
|
||||
: PVField(scalar) {}
|
||||
|
||||
ScalarConstPtr PVScalar::getScalar()
|
||||
const ScalarConstPtr PVScalar::getScalar() const
|
||||
{
|
||||
return static_pointer_cast<const Scalar>(PVField::getField());
|
||||
}
|
||||
|
||||
template<>
|
||||
std::ostream& PVScalarValue<int8>::dumpValue(std::ostream& o) const
|
||||
{
|
||||
return o << static_cast<int>(get());
|
||||
}
|
||||
|
||||
template<>
|
||||
std::ostream& PVScalarValue<uint8>::dumpValue(std::ostream& o) const
|
||||
{
|
||||
return o << static_cast<unsigned int>(get());
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*PVScalarArray.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
@@ -17,13 +20,24 @@ namespace epics { namespace pvData {
|
||||
|
||||
PVScalarArray::~PVScalarArray() {}
|
||||
|
||||
PVScalarArray::PVScalarArray(PVStructure *parent,
|
||||
ScalarArrayConstPtr scalarArray)
|
||||
: PVArray(parent,scalarArray) {}
|
||||
PVScalarArray::PVScalarArray(ScalarArrayConstPtr const & scalarArray)
|
||||
: PVArray(scalarArray) {}
|
||||
|
||||
ScalarArrayConstPtr PVScalarArray::getScalarArray()
|
||||
const ScalarArrayConstPtr PVScalarArray::getScalarArray() const
|
||||
{
|
||||
return static_pointer_cast<const ScalarArray>(PVField::getField());
|
||||
}
|
||||
|
||||
template<>
|
||||
std::ostream& PVValueArray<int8>::dumpValue(std::ostream& o, size_t index) const
|
||||
{
|
||||
return o << static_cast<int>(*(get() + index));
|
||||
}
|
||||
|
||||
template<>
|
||||
std::ostream& PVValueArray<uint8>::dumpValue(std::ostream& o, size_t index) const
|
||||
{
|
||||
return o << static_cast<unsigned int>(*(get() + index));
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
253
pvDataApp/factory/PVStructureArray.cpp
Normal file
253
pvDataApp/factory/PVStructureArray.cpp
Normal file
@@ -0,0 +1,253 @@
|
||||
/*PVStructureArray.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::size_t;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
PVStructureArray::PVStructureArray(StructureArrayConstPtr const & structureArray)
|
||||
: PVArray(structureArray),
|
||||
structureArray(structureArray),
|
||||
value(std::tr1::shared_ptr<PVStructurePtrArray>(new PVStructurePtrArray()))
|
||||
{
|
||||
}
|
||||
|
||||
size_t PVStructureArray::append(size_t number)
|
||||
{
|
||||
size_t currentLength = getLength();
|
||||
size_t newLength = currentLength + number;
|
||||
setCapacity(newLength);
|
||||
setLength(newLength);
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
PVStructurePtrArray *to = value.get();
|
||||
for(size_t i=currentLength; i<newLength; i++) {
|
||||
(*to)[i] =getPVDataCreate()->createPVStructure(structure);
|
||||
}
|
||||
return newLength;
|
||||
}
|
||||
|
||||
bool PVStructureArray::remove(size_t offset,size_t number)
|
||||
{
|
||||
size_t length = getLength();
|
||||
if(offset+number>length) return false;
|
||||
PVStructurePtrArray vec = *value.get();
|
||||
for(size_t i = offset; i+number < length; i++) {
|
||||
vec[i] = vec[i + number];
|
||||
}
|
||||
size_t newLength = length - number;
|
||||
setCapacityLength(newLength,newLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVStructureArray::compress() {
|
||||
size_t length = getCapacity();
|
||||
size_t newLength = 0;
|
||||
PVStructurePtrArray vec = *value.get();
|
||||
for(size_t i=0; i<length; i++) {
|
||||
if(vec[i].get()!=NULL) {
|
||||
newLength++;
|
||||
continue;
|
||||
}
|
||||
// find first non 0
|
||||
size_t notNull = 0;
|
||||
for(size_t j=i+1;j<length;j++) {
|
||||
if(vec[j].get()!=NULL) {
|
||||
notNull = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(notNull!=0) {
|
||||
vec[i] = vec[notNull];
|
||||
vec[notNull].reset();
|
||||
newLength++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
setCapacityLength(newLength,newLength);
|
||||
}
|
||||
|
||||
void PVStructureArray::setCapacity(size_t capacity) {
|
||||
if(getCapacity()==capacity) return;
|
||||
if(!isCapacityMutable()) {
|
||||
std::string message("not capacityMutable");
|
||||
PVField::message(message, errorMessage);
|
||||
return;
|
||||
}
|
||||
size_t length = getLength();
|
||||
if(length>capacity) length = capacity;
|
||||
size_t oldCapacity = getCapacity();
|
||||
if(oldCapacity>capacity) {
|
||||
PVStructurePtrArray array;
|
||||
array.reserve(capacity);
|
||||
array.resize(length);
|
||||
PVStructurePtr * from = get();
|
||||
for (size_t i=0; i<length; i++) array[i] = from[i];
|
||||
value->swap(array);
|
||||
} else {
|
||||
value->reserve(capacity);
|
||||
}
|
||||
setCapacityLength(capacity,length);
|
||||
}
|
||||
|
||||
void PVStructureArray::setLength(size_t length) {
|
||||
if(PVArray::getLength()==length) return;
|
||||
size_t capacity = PVArray::getCapacity();
|
||||
if(length>capacity) {
|
||||
if(!PVArray::isCapacityMutable()) {
|
||||
std::string message("not capacityMutable");
|
||||
PVField::message(message, errorMessage);
|
||||
return;
|
||||
}
|
||||
setCapacity(length);
|
||||
}
|
||||
value->resize(length);
|
||||
PVArray::setCapacityLength(capacity,length);
|
||||
}
|
||||
|
||||
StructureArrayConstPtr PVStructureArray::getStructureArray() const
|
||||
{
|
||||
return structureArray;
|
||||
}
|
||||
|
||||
size_t PVStructureArray::get(
|
||||
size_t offset, size_t len, StructureArrayData &data)
|
||||
{
|
||||
size_t n = len;
|
||||
size_t length = getLength();
|
||||
if(offset+len > length) {
|
||||
n = length - offset;
|
||||
if(n<0) n = 0;
|
||||
}
|
||||
data.data = *value.get();
|
||||
data.offset = offset;
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t PVStructureArray::put(size_t offset,size_t len,
|
||||
const_vector const & from, size_t fromOffset)
|
||||
{
|
||||
if(isImmutable()) {
|
||||
message(String("field is immutable"), errorMessage);
|
||||
return 0;
|
||||
}
|
||||
if(&from==value.get()) return 0;
|
||||
if(len<1) return 0;
|
||||
size_t length = getLength();
|
||||
size_t capacity = getCapacity();
|
||||
if(offset+len > length) {
|
||||
size_t newlength = offset + len;
|
||||
if(newlength>capacity) {
|
||||
setCapacity(newlength);
|
||||
capacity = getCapacity();
|
||||
newlength = capacity;
|
||||
len = newlength - offset;
|
||||
if(len<=0) return 0;
|
||||
}
|
||||
length = newlength;
|
||||
setLength(length);
|
||||
}
|
||||
PVStructurePtrArray *to = value.get();
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
for(size_t i=0; i<len; i++) {
|
||||
PVStructurePtr frompv = from[i+fromOffset];
|
||||
if(frompv.get()!=NULL) {
|
||||
if(frompv->getStructure()!=structure) {
|
||||
throw std::invalid_argument(String(
|
||||
"Element is not a compatible structure"));
|
||||
}
|
||||
}
|
||||
(*to)[i+offset] = frompv;
|
||||
}
|
||||
postPut();
|
||||
setLength(length);
|
||||
return len;
|
||||
}
|
||||
|
||||
void PVStructureArray::shareData(
|
||||
std::tr1::shared_ptr<std::vector<PVStructurePtr> > const & sharedValue,
|
||||
std::size_t capacity,
|
||||
std::size_t length)
|
||||
{
|
||||
value = sharedValue;
|
||||
setCapacityLength(capacity,length);
|
||||
}
|
||||
|
||||
void PVStructureArray::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const {
|
||||
serialize(pbuffer, pflusher, 0, getLength());
|
||||
}
|
||||
|
||||
void PVStructureArray::deserialize(ByteBuffer *pbuffer,
|
||||
DeserializableControl *pcontrol) {
|
||||
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
|
||||
if(size>=0) {
|
||||
// prepare array, if necessary
|
||||
if(size>getCapacity()) setCapacity(size);
|
||||
setLength(size);
|
||||
PVStructurePtrArray *pvArray = value.get();
|
||||
for(size_t i = 0; i<size; i++) {
|
||||
pcontrol->ensureData(1);
|
||||
size_t temp = pbuffer->getByte();
|
||||
if(temp==0) {
|
||||
(*pvArray)[i].reset();
|
||||
}
|
||||
else {
|
||||
if((*pvArray)[i].get()==NULL) {
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
(*pvArray)[i] = getPVDataCreate()->createPVStructure(structure);
|
||||
}
|
||||
(*pvArray)[i]->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
}
|
||||
postPut();
|
||||
}
|
||||
}
|
||||
|
||||
void PVStructureArray::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const {
|
||||
// cache
|
||||
size_t length = getLength();
|
||||
|
||||
// check bounds
|
||||
if(offset<0)
|
||||
offset = 0;
|
||||
else if(offset>length) offset = length;
|
||||
if(count<0) count = length;
|
||||
|
||||
size_t maxCount = length-offset;
|
||||
if(count>maxCount) count = maxCount;
|
||||
|
||||
PVStructurePtrArray pvArray = *value.get();
|
||||
// write
|
||||
SerializeHelper::writeSize(count, pbuffer, pflusher);
|
||||
for(size_t i = 0; i<count; i++) {
|
||||
if(pbuffer->getRemaining()<1) pflusher->flushSerializeBuffer();
|
||||
PVStructurePtr pvStructure = pvArray[i+offset];
|
||||
if(pvStructure.get()==NULL) {
|
||||
pbuffer->putByte(0);
|
||||
}
|
||||
else {
|
||||
pbuffer->putByte(1);
|
||||
pvStructure->serialize(pbuffer, pflusher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,9 +1,12 @@
|
||||
/* StandardField.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
@@ -12,187 +15,42 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static StandardField* standardField = 0;
|
||||
|
||||
static String notImplemented("not implemented");
|
||||
static FieldCreate* fieldCreate = 0;
|
||||
static String valueFieldName("value");
|
||||
StandardField::StandardField()
|
||||
: fieldCreate(getFieldCreate()),
|
||||
notImplemented("not implemented"),
|
||||
valueFieldName("value")
|
||||
{}
|
||||
|
||||
// following are preallocated structures
|
||||
|
||||
static StructureConstPtr alarmField;
|
||||
static StructureConstPtr timeStampField;
|
||||
static StructureConstPtr displayField;
|
||||
static StructureConstPtr controlField;
|
||||
static StructureConstPtr booleanAlarmField;
|
||||
static StructureConstPtr byteAlarmField;
|
||||
static StructureConstPtr shortAlarmField;
|
||||
static StructureConstPtr intAlarmField;
|
||||
static StructureConstPtr longAlarmField;
|
||||
static StructureConstPtr floatAlarmField;
|
||||
static StructureConstPtr doubleAlarmField;
|
||||
static StructureConstPtr enumeratedAlarmField;
|
||||
|
||||
|
||||
static void createAlarm() {
|
||||
FieldConstPtrArray fields = new FieldConstPtr[3];
|
||||
fields[0] = fieldCreate->createScalar(String("severity"),pvInt);
|
||||
fields[1] = fieldCreate->createScalar(String("status"),pvInt);
|
||||
fields[2] = fieldCreate->createScalar(String("message"),pvString);
|
||||
alarmField = fieldCreate->createStructure(String("alarm"),3,fields);
|
||||
void StandardField::init()
|
||||
{
|
||||
createAlarm();
|
||||
createTimeStamp();
|
||||
createDisplay();
|
||||
createControl();
|
||||
createBooleanAlarm();
|
||||
createByteAlarm();
|
||||
createShortAlarm();
|
||||
createIntAlarm();
|
||||
createLongAlarm();
|
||||
createUByteAlarm();
|
||||
createUShortAlarm();
|
||||
createUIntAlarm();
|
||||
createULongAlarm();
|
||||
createFloatAlarm();
|
||||
createDoubleAlarm();
|
||||
createEnumeratedAlarm();
|
||||
}
|
||||
|
||||
static void createTimeStamp() {
|
||||
FieldConstPtrArray fields = new FieldConstPtr[3];
|
||||
fields[0] = fieldCreate->createScalar(String("secondsPastEpoch"),pvLong);
|
||||
fields[1] = fieldCreate->createScalar(String("nanoSeconds"),pvInt);
|
||||
fields[2] = fieldCreate->createScalar(String("userTag"),pvInt);
|
||||
timeStampField = fieldCreate->createStructure(String("timeStamp"),3,fields);
|
||||
}
|
||||
StandardField::~StandardField(){}
|
||||
|
||||
static void createDisplay() {
|
||||
FieldConstPtrArray limitFields = new FieldConstPtr[2];
|
||||
limitFields[0] = fieldCreate->createScalar(String("low"),pvDouble);
|
||||
limitFields[1] = fieldCreate->createScalar(String("high"),pvDouble);
|
||||
FieldConstPtrArray fields = new FieldConstPtr[4];
|
||||
fields[0] = fieldCreate->createScalar(String("description"),pvString);
|
||||
fields[1] = fieldCreate->createScalar(String("format"),pvString);
|
||||
fields[2] = fieldCreate->createScalar(String("units"),pvString);
|
||||
fields[3] = fieldCreate->createStructure(String("limit"),2,limitFields);
|
||||
displayField = fieldCreate->createStructure(String("display"),4,fields);
|
||||
}
|
||||
|
||||
static void createControl() {
|
||||
FieldConstPtrArray limitFields = new FieldConstPtr[2];
|
||||
limitFields[0] = fieldCreate->createScalar(String("low"),pvDouble);
|
||||
limitFields[1] = fieldCreate->createScalar(String("high"),pvDouble);
|
||||
FieldConstPtrArray fields = new FieldConstPtr[2];
|
||||
fields[0] = fieldCreate->createStructure(String("limit"),2,limitFields);
|
||||
fields[1] = fieldCreate->createScalar(String("minStep"),pvDouble);
|
||||
controlField = fieldCreate->createStructure(String("control"),2,fields);
|
||||
}
|
||||
|
||||
static void createBooleanAlarm() {
|
||||
FieldConstPtrArray fields = new FieldConstPtr[4];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("falseSeverity"),pvInt);
|
||||
fields[2] = fieldCreate->createScalar(String("trueSeverity"),pvInt);
|
||||
fields[3] = fieldCreate->createScalar(String("changeStateSeverity"),pvInt);
|
||||
booleanAlarmField = fieldCreate->createStructure(String("valueAlarm"),4,fields);
|
||||
}
|
||||
|
||||
static void createByteAlarm() {
|
||||
int numFields = 10;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("lowAlarmLimit"),pvByte);
|
||||
fields[2] = fieldCreate->createScalar(String("lowWarningLimit"),pvByte);
|
||||
fields[3] = fieldCreate->createScalar(String("highWarningLimit"),pvByte);
|
||||
fields[4] = fieldCreate->createScalar(String("highAlarmLimit"),pvByte);
|
||||
fields[5] = fieldCreate->createScalar(String("lowAlarmSeverity"),pvInt);
|
||||
fields[6] = fieldCreate->createScalar(String("lowWarningSeverity"),pvInt);
|
||||
fields[7] = fieldCreate->createScalar(String("highWarningSeverity"),pvInt);
|
||||
fields[8] = fieldCreate->createScalar(String("highAlarmSeverity"),pvInt);
|
||||
fields[9] = fieldCreate->createScalar(String("hystersis"),pvByte);
|
||||
byteAlarmField = fieldCreate->createStructure(String("valueAlarm"),numFields,fields);
|
||||
}
|
||||
|
||||
static void createShortAlarm() {
|
||||
int numFields = 10;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("lowAlarmLimit"),pvShort);
|
||||
fields[2] = fieldCreate->createScalar(String("lowWarningLimit"),pvShort);
|
||||
fields[3] = fieldCreate->createScalar(String("highWarningLimit"),pvShort);
|
||||
fields[4] = fieldCreate->createScalar(String("highAlarmLimit"),pvShort);
|
||||
fields[5] = fieldCreate->createScalar(String("lowAlarmSeverity"),pvInt);
|
||||
fields[6] = fieldCreate->createScalar(String("lowWarningSeverity"),pvInt);
|
||||
fields[7] = fieldCreate->createScalar(String("highWarningSeverity"),pvInt);
|
||||
fields[8] = fieldCreate->createScalar(String("highAlarmSeverity"),pvInt);
|
||||
fields[9] = fieldCreate->createScalar(String("hystersis"),pvShort);
|
||||
shortAlarmField = fieldCreate->createStructure(String("valueAlarm"),numFields,fields);
|
||||
}
|
||||
|
||||
static void createIntAlarm() {
|
||||
int numFields = 10;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("lowAlarmLimit"),pvInt);
|
||||
fields[2] = fieldCreate->createScalar(String("lowWarningLimit"),pvInt);
|
||||
fields[3] = fieldCreate->createScalar(String("highWarningLimit"),pvInt);
|
||||
fields[4] = fieldCreate->createScalar(String("highAlarmLimit"),pvInt);
|
||||
fields[5] = fieldCreate->createScalar(String("lowAlarmSeverity"),pvInt);
|
||||
fields[6] = fieldCreate->createScalar(String("lowWarningSeverity"),pvInt);
|
||||
fields[7] = fieldCreate->createScalar(String("highWarningSeverity"),pvInt);
|
||||
fields[8] = fieldCreate->createScalar(String("highAlarmSeverity"),pvInt);
|
||||
fields[9] = fieldCreate->createScalar(String("hystersis"),pvInt);
|
||||
intAlarmField = fieldCreate->createStructure(String("valueAlarm"),numFields,fields);
|
||||
}
|
||||
|
||||
static void createLongAlarm() {
|
||||
int numFields = 10;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("lowAlarmLimit"),pvLong);
|
||||
fields[2] = fieldCreate->createScalar(String("lowWarningLimit"),pvLong);
|
||||
fields[3] = fieldCreate->createScalar(String("highWarningLimit"),pvLong);
|
||||
fields[4] = fieldCreate->createScalar(String("highAlarmLimit"),pvLong);
|
||||
fields[5] = fieldCreate->createScalar(String("lowAlarmSeverity"),pvInt);
|
||||
fields[6] = fieldCreate->createScalar(String("lowWarningSeverity"),pvInt);
|
||||
fields[7] = fieldCreate->createScalar(String("highWarningSeverity"),pvInt);
|
||||
fields[8] = fieldCreate->createScalar(String("highAlarmSeverity"),pvInt);
|
||||
fields[9] = fieldCreate->createScalar(String("hystersis"),pvLong);
|
||||
longAlarmField = fieldCreate->createStructure(String("valueAlarm"),numFields,fields);
|
||||
}
|
||||
|
||||
static void createFloatAlarm() {
|
||||
int numFields = 10;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("lowAlarmLimit"),pvFloat);
|
||||
fields[2] = fieldCreate->createScalar(String("lowWarningLimit"),pvFloat);
|
||||
fields[3] = fieldCreate->createScalar(String("highWarningLimit"),pvFloat);
|
||||
fields[4] = fieldCreate->createScalar(String("highAlarmLimit"),pvFloat);
|
||||
fields[5] = fieldCreate->createScalar(String("lowAlarmSeverity"),pvInt);
|
||||
fields[6] = fieldCreate->createScalar(String("lowWarningSeverity"),pvInt);
|
||||
fields[7] = fieldCreate->createScalar(String("highWarningSeverity"),pvInt);
|
||||
fields[8] = fieldCreate->createScalar(String("highAlarmSeverity"),pvInt);
|
||||
fields[9] = fieldCreate->createScalar(String("hystersis"),pvFloat);
|
||||
floatAlarmField = fieldCreate->createStructure(String("valueAlarm"),numFields,fields);
|
||||
}
|
||||
|
||||
static void createDoubleAlarm() {
|
||||
int numFields = 10;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("lowAlarmLimit"),pvDouble);
|
||||
fields[2] = fieldCreate->createScalar(String("lowWarningLimit"),pvDouble);
|
||||
fields[3] = fieldCreate->createScalar(String("highWarningLimit"),pvDouble);
|
||||
fields[4] = fieldCreate->createScalar(String("highAlarmLimit"),pvDouble);
|
||||
fields[5] = fieldCreate->createScalar(String("lowAlarmSeverity"),pvInt);
|
||||
fields[6] = fieldCreate->createScalar(String("lowWarningSeverity"),pvInt);
|
||||
fields[7] = fieldCreate->createScalar(String("highWarningSeverity"),pvInt);
|
||||
fields[8] = fieldCreate->createScalar(String("highAlarmSeverity"),pvInt);
|
||||
fields[9] = fieldCreate->createScalar(String("hystersis"),pvDouble);
|
||||
doubleAlarmField = fieldCreate->createStructure(String("valueAlarm"),numFields,fields);
|
||||
}
|
||||
|
||||
static void createEnumeratedAlarm() {
|
||||
int numFields = 3;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
fields[0] = fieldCreate->createScalar(String("active"),pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(String("stateSeverity"),pvInt);
|
||||
fields[2] = fieldCreate->createScalar(String("changeStateSeverity"),pvInt);
|
||||
enumeratedAlarmField = fieldCreate->createStructure(String("valueAlarm"),numFields,fields);
|
||||
}
|
||||
|
||||
static StructureConstPtr createProperties(String fieldName,FieldConstPtr field,String properties) {
|
||||
StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,String properties)
|
||||
{
|
||||
bool gotAlarm = false;
|
||||
bool gotTimeStamp = false;
|
||||
bool gotDisplay = false;
|
||||
@@ -207,7 +65,7 @@ static StructureConstPtr createProperties(String fieldName,FieldConstPtr field,S
|
||||
StructureConstPtr valueAlarm;
|
||||
Type type= field->getType();
|
||||
while(gotValueAlarm) {
|
||||
if(type==scalar) {
|
||||
if(type==epics::pvData::scalar) {
|
||||
ScalarConstPtr scalar = static_pointer_cast<const Scalar>(field);
|
||||
ScalarType scalarType = scalar->getScalarType();
|
||||
switch(scalarType) {
|
||||
@@ -216,26 +74,31 @@ static StructureConstPtr createProperties(String fieldName,FieldConstPtr field,S
|
||||
case pvShort: valueAlarm = shortAlarmField; break;
|
||||
case pvInt: valueAlarm = intAlarmField; break;
|
||||
case pvLong: valueAlarm = longAlarmField; break;
|
||||
case pvUByte: valueAlarm = ubyteAlarmField; break;
|
||||
case pvUShort: valueAlarm = ushortAlarmField; break;
|
||||
case pvUInt: valueAlarm = uintAlarmField; break;
|
||||
case pvULong: valueAlarm = ulongAlarmField; break;
|
||||
case pvFloat: valueAlarm = floatAlarmField; break;
|
||||
case pvDouble: valueAlarm = doubleAlarmField; break;
|
||||
default:
|
||||
throw std::logic_error(String("valueAlarm property for illegal type"));
|
||||
case pvString:
|
||||
throw std::logic_error(String("valueAlarm property not supported for pvString"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(type==structure) {
|
||||
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
|
||||
if(structurePtr->getNumberFields()==2) {
|
||||
StringArray names = structurePtr->getFieldNames();
|
||||
if(names.size()==2) {
|
||||
FieldConstPtrArray fields = structurePtr->getFields();
|
||||
FieldConstPtr first = fields[0];
|
||||
FieldConstPtr second = fields[1];
|
||||
String nameFirst = first->getFieldName();
|
||||
String nameSecond = second->getFieldName();
|
||||
String nameFirst = names[0];
|
||||
String nameSecond = names[1];
|
||||
int compareFirst = nameFirst.compare("index");
|
||||
int compareSecond = nameSecond.compare("choices");
|
||||
if(compareFirst==0 && compareSecond==0) {
|
||||
if(first->getType()==scalar
|
||||
&& second->getType()==scalarArray) {
|
||||
if(first->getType()==epics::pvData::scalar
|
||||
&& second->getType()==epics::pvData::scalarArray) {
|
||||
ScalarConstPtr scalarFirst = static_pointer_cast<const Scalar>(first);
|
||||
ScalarArrayConstPtr scalarArraySecond =
|
||||
static_pointer_cast<const ScalarArray>(second);
|
||||
@@ -250,138 +113,430 @@ static StructureConstPtr createProperties(String fieldName,FieldConstPtr field,S
|
||||
}
|
||||
throw std::logic_error(String("valueAlarm property for illegal type"));
|
||||
}
|
||||
int numFields = numProp+1;
|
||||
FieldConstPtrArray fields = new FieldConstPtr[numFields];
|
||||
size_t numFields = numProp+1;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
int next = 0;
|
||||
names[0] = "value";
|
||||
fields[next++] = field;
|
||||
if(gotAlarm) {fields[next++] = alarmField;}
|
||||
if(gotTimeStamp) {fields[next++] = timeStampField;}
|
||||
if(gotDisplay) {fields[next++] = displayField;}
|
||||
if(gotControl) {fields[next++] = controlField;}
|
||||
if(gotValueAlarm) {fields[next++] = valueAlarm;}
|
||||
return fieldCreate->createStructure(fieldName,numFields,fields);
|
||||
if(gotAlarm) {
|
||||
names[next] = "alarm";
|
||||
fields[next++] = alarmField;
|
||||
}
|
||||
if(gotTimeStamp) {
|
||||
names[next] = "timeStamp";
|
||||
fields[next++] = timeStampField;
|
||||
}
|
||||
if(gotDisplay) {
|
||||
names[next] = "display";
|
||||
fields[next++] = displayField;
|
||||
}
|
||||
if(gotControl) {
|
||||
names[next] = "control";
|
||||
fields[next++] = controlField;
|
||||
}
|
||||
if(gotValueAlarm) {
|
||||
names[next] = "valueAlarm";
|
||||
fields[next++] = valueAlarm;
|
||||
}
|
||||
return fieldCreate->createStructure(id,names,fields);
|
||||
}
|
||||
|
||||
|
||||
ScalarConstPtr StandardField::scalar(String fieldName,ScalarType type)
|
||||
{
|
||||
return fieldCreate->createScalar(fieldName,type);
|
||||
void StandardField::createAlarm() {
|
||||
size_t num = 3;
|
||||
FieldConstPtrArray fields(num);
|
||||
StringArray names(num);
|
||||
names[0] = "severity";
|
||||
names[1] = "status";
|
||||
names[2] = "message";
|
||||
fields[0] = fieldCreate->createScalar(pvInt);
|
||||
fields[1] = fieldCreate->createScalar(pvInt);
|
||||
fields[2] = fieldCreate->createScalar(pvString);
|
||||
alarmField = fieldCreate->createStructure("alarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createTimeStamp() {
|
||||
size_t num = 3;
|
||||
FieldConstPtrArray fields(num);
|
||||
StringArray names(num);
|
||||
names[0] = "secondsPastEpoch";
|
||||
names[1] = "nanoSeconds";
|
||||
names[2] = "userTag";
|
||||
fields[0] = fieldCreate->createScalar(pvLong);
|
||||
fields[1] = fieldCreate->createScalar(pvInt);
|
||||
fields[2] = fieldCreate->createScalar(pvInt);
|
||||
timeStampField = fieldCreate->createStructure("time_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createDisplay() {
|
||||
size_t num = 5;
|
||||
FieldConstPtrArray fields(num);
|
||||
StringArray names(num);
|
||||
names[0] = "limitLow";
|
||||
names[1] = "limitHigh";
|
||||
names[2] = "description";
|
||||
names[3] = "format";
|
||||
names[4] = "units";
|
||||
fields[0] = fieldCreate->createScalar(pvDouble);
|
||||
fields[1] = fieldCreate->createScalar(pvDouble);
|
||||
fields[2] = fieldCreate->createScalar(pvString);
|
||||
fields[3] = fieldCreate->createScalar(pvString);
|
||||
fields[4] = fieldCreate->createScalar(pvString);
|
||||
displayField = fieldCreate->createStructure("display_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createControl() {
|
||||
size_t num = 3;
|
||||
FieldConstPtrArray fields(num);
|
||||
StringArray names(num);
|
||||
names[0] = "limitLow";
|
||||
names[1] = "limitHigh";
|
||||
names[2] = "minStep";
|
||||
fields[0] = fieldCreate->createScalar(pvDouble);
|
||||
fields[1] = fieldCreate->createScalar(pvDouble);
|
||||
fields[2] = fieldCreate->createScalar(pvDouble);
|
||||
controlField = fieldCreate->createStructure("control_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createBooleanAlarm() {
|
||||
size_t numFields = 4;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "falseSeverity";
|
||||
names[2] = "trueSeverity";
|
||||
names[3] = "changeStateSeverity";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvInt);
|
||||
fields[2] = fieldCreate->createScalar(pvInt);
|
||||
fields[3] = fieldCreate->createScalar(pvInt);
|
||||
booleanAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createByteAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvByte);
|
||||
fields[2] = fieldCreate->createScalar(pvByte);
|
||||
fields[3] = fieldCreate->createScalar(pvByte);
|
||||
fields[4] = fieldCreate->createScalar(pvByte);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvByte);
|
||||
byteAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createShortAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvShort);
|
||||
fields[2] = fieldCreate->createScalar(pvShort);
|
||||
fields[3] = fieldCreate->createScalar(pvShort);
|
||||
fields[4] = fieldCreate->createScalar(pvShort);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvShort);
|
||||
shortAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createIntAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvInt);
|
||||
fields[2] = fieldCreate->createScalar(pvInt);
|
||||
fields[3] = fieldCreate->createScalar(pvInt);
|
||||
fields[4] = fieldCreate->createScalar(pvInt);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvInt);
|
||||
intAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createLongAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvLong);
|
||||
fields[2] = fieldCreate->createScalar(pvLong);
|
||||
fields[3] = fieldCreate->createScalar(pvLong);
|
||||
fields[4] = fieldCreate->createScalar(pvLong);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvLong);
|
||||
longAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createUByteAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvUByte);
|
||||
fields[2] = fieldCreate->createScalar(pvUByte);
|
||||
fields[3] = fieldCreate->createScalar(pvUByte);
|
||||
fields[4] = fieldCreate->createScalar(pvUByte);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvUByte);
|
||||
ubyteAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createUShortAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvUShort);
|
||||
fields[2] = fieldCreate->createScalar(pvUShort);
|
||||
fields[3] = fieldCreate->createScalar(pvUShort);
|
||||
fields[4] = fieldCreate->createScalar(pvUShort);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvUShort);
|
||||
ushortAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createUIntAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvUInt);
|
||||
fields[2] = fieldCreate->createScalar(pvUInt);
|
||||
fields[3] = fieldCreate->createScalar(pvUInt);
|
||||
fields[4] = fieldCreate->createScalar(pvUInt);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvUInt);
|
||||
uintAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createULongAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvULong);
|
||||
fields[2] = fieldCreate->createScalar(pvULong);
|
||||
fields[3] = fieldCreate->createScalar(pvULong);
|
||||
fields[4] = fieldCreate->createScalar(pvULong);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvULong);
|
||||
ulongAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createFloatAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvFloat);
|
||||
fields[2] = fieldCreate->createScalar(pvFloat);
|
||||
fields[3] = fieldCreate->createScalar(pvFloat);
|
||||
fields[4] = fieldCreate->createScalar(pvFloat);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvFloat);
|
||||
floatAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createDoubleAlarm() {
|
||||
size_t numFields = 10;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "lowAlarmLimit";
|
||||
names[2] = "lowWarningLimit";
|
||||
names[3] = "highWarningLimit";
|
||||
names[4] = "highAlarmLimit";
|
||||
names[5] = "lowAlarmSeverity";
|
||||
names[6] = "lowWarningSeverity";
|
||||
names[7] = "highWarningSeverity";
|
||||
names[8] = "highAlarmSeverity";
|
||||
names[9] = "hystersis";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalar(pvDouble);
|
||||
fields[2] = fieldCreate->createScalar(pvDouble);
|
||||
fields[3] = fieldCreate->createScalar(pvDouble);
|
||||
fields[4] = fieldCreate->createScalar(pvDouble);
|
||||
fields[5] = fieldCreate->createScalar(pvInt);
|
||||
fields[6] = fieldCreate->createScalar(pvInt);
|
||||
fields[7] = fieldCreate->createScalar(pvInt);
|
||||
fields[8] = fieldCreate->createScalar(pvInt);
|
||||
fields[9] = fieldCreate->createScalar(pvDouble);
|
||||
doubleAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
void StandardField::createEnumeratedAlarm() {
|
||||
size_t numFields = 3;
|
||||
FieldConstPtrArray fields(numFields);
|
||||
StringArray names(numFields);
|
||||
names[0] = "active";
|
||||
names[1] = "stateSeverity";
|
||||
names[2] = "changeStateSeverity";
|
||||
fields[0] = fieldCreate->createScalar(pvBoolean);
|
||||
fields[1] = fieldCreate->createScalarArray(pvInt);
|
||||
fields[2] = fieldCreate->createScalar(pvInt);
|
||||
enumeratedAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
|
||||
}
|
||||
|
||||
|
||||
StructureConstPtr StandardField::scalar(
|
||||
String fieldName,ScalarType type,String properties)
|
||||
ScalarType type,String const &properties)
|
||||
{
|
||||
ScalarConstPtr field = fieldCreate->createScalar(valueFieldName,type);
|
||||
return createProperties(fieldName,field,properties);
|
||||
}
|
||||
|
||||
ScalarArrayConstPtr StandardField::scalarArray(
|
||||
String fieldName,ScalarType elementType)
|
||||
{
|
||||
return fieldCreate->createScalarArray(fieldName,elementType);
|
||||
ScalarConstPtr field = fieldCreate->createScalar(type); // scalar_t
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTScalar",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::scalarArray(
|
||||
String fieldName,ScalarType elementType, String properties)
|
||||
ScalarType elementType, String const &properties)
|
||||
{
|
||||
ScalarArrayConstPtr field = fieldCreate->createScalarArray(
|
||||
valueFieldName,elementType);
|
||||
return createProperties(fieldName,field,properties);
|
||||
ScalarArrayConstPtr field = fieldCreate->createScalarArray(elementType); // scalar_t[]
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTScalarArray",field,properties);
|
||||
}
|
||||
|
||||
StructureArrayConstPtr StandardField::structureArray(
|
||||
String fieldName,StructureConstPtr structure)
|
||||
{
|
||||
return fieldCreate->createStructureArray(fieldName,structure);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::structureArray(
|
||||
String fieldName,StructureConstPtr structure,String properties)
|
||||
StructureConstPtr const & structure,String const &properties)
|
||||
{
|
||||
StructureArrayConstPtr field = fieldCreate->createStructureArray(
|
||||
valueFieldName,structure);
|
||||
return createProperties(fieldName,field,properties);
|
||||
structure);
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTAny",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::structure(
|
||||
String fieldName,int numFields,FieldConstPtrArray fields)
|
||||
StructureConstPtr StandardField::enumerated()
|
||||
{
|
||||
return fieldCreate->createStructure(fieldName,numFields,fields);
|
||||
size_t num = 2;
|
||||
FieldConstPtrArray fields(num);
|
||||
StringArray names(num);
|
||||
names[0] = "index";
|
||||
names[1] = "choices";
|
||||
fields[0] = fieldCreate->createScalar(pvInt);
|
||||
fields[1] = fieldCreate->createScalarArray(pvString);
|
||||
return fieldCreate->createStructure("enum_t",names,fields);
|
||||
// NOTE: if this method is used to get NTEnum wihtout properties the ID will be wrong!
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumerated(String fieldName)
|
||||
StructureConstPtr StandardField::enumerated(String const &properties)
|
||||
{
|
||||
FieldConstPtrArray fields = new FieldConstPtr[2];
|
||||
fields[0] = fieldCreate->createScalar(String("index"),pvInt);
|
||||
fields[1] = fieldCreate->createScalarArray(String("choices"),pvString);
|
||||
return fieldCreate->createStructure(fieldName,2,fields);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumerated(
|
||||
String fieldName,String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated(valueFieldName);
|
||||
return createProperties(fieldName,field,properties);
|
||||
}
|
||||
|
||||
ScalarConstPtr StandardField::scalarValue(ScalarType type)
|
||||
{
|
||||
return fieldCreate->createScalar(valueFieldName,type);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::scalarValue(ScalarType type,String properties)
|
||||
{
|
||||
ScalarConstPtr field = fieldCreate->createScalar(valueFieldName,type);
|
||||
return createProperties(valueFieldName,field,properties);
|
||||
}
|
||||
|
||||
ScalarArrayConstPtr StandardField::scalarArrayValue(ScalarType elementType)
|
||||
{
|
||||
return fieldCreate->createScalarArray(valueFieldName,elementType);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::scalarArrayValue(
|
||||
ScalarType elementType, String properties)
|
||||
{
|
||||
ScalarArrayConstPtr field = fieldCreate->createScalarArray(
|
||||
valueFieldName,elementType);
|
||||
return createProperties(valueFieldName,field,properties);
|
||||
|
||||
}
|
||||
|
||||
StructureArrayConstPtr StandardField::structureArrayValue(
|
||||
StructureConstPtr structure)
|
||||
{
|
||||
return fieldCreate->createStructureArray(valueFieldName,structure);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::structureArrayValue(
|
||||
StructureConstPtr structure,String properties)
|
||||
{
|
||||
StructureArrayConstPtr field = fieldCreate->createStructureArray(
|
||||
valueFieldName,structure);
|
||||
return createProperties(valueFieldName,field,properties);
|
||||
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::structureValue(
|
||||
int numFields,FieldConstPtrArray fields)
|
||||
{
|
||||
return fieldCreate->createStructure(valueFieldName,numFields,fields);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumeratedValue()
|
||||
{
|
||||
FieldConstPtrArray fields = new FieldConstPtr[2];
|
||||
fields[0] = fieldCreate->createScalar(String("index"),pvInt);
|
||||
fields[1] = fieldCreate->createScalarArray(String("choices"),pvString);
|
||||
return fieldCreate->createStructure(valueFieldName,2,fields);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::enumeratedValue( String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated(valueFieldName);
|
||||
return createProperties(valueFieldName,field,properties);
|
||||
StructureConstPtr field = enumerated(); // enum_t
|
||||
return createProperties("uri:ev4:nt/2012/pwd:NTEnum",field,properties);
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::alarm()
|
||||
@@ -414,21 +569,41 @@ StructureConstPtr StandardField::byteAlarm()
|
||||
return byteAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::ubyteAlarm()
|
||||
{
|
||||
return ubyteAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::shortAlarm()
|
||||
{
|
||||
return shortAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::ushortAlarm()
|
||||
{
|
||||
return ushortAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::intAlarm()
|
||||
{
|
||||
return intAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::uintAlarm()
|
||||
{
|
||||
return uintAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::longAlarm()
|
||||
{
|
||||
return longAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::ulongAlarm()
|
||||
{
|
||||
return ulongAlarmField;
|
||||
}
|
||||
|
||||
StructureConstPtr StandardField::floatAlarm()
|
||||
{
|
||||
return floatAlarmField;
|
||||
@@ -444,58 +619,24 @@ StructureConstPtr StandardField::enumeratedAlarm()
|
||||
return enumeratedAlarmField;
|
||||
}
|
||||
|
||||
void StandardField::init()
|
||||
StandardFieldPtr StandardField::getStandardField()
|
||||
{
|
||||
createAlarm();
|
||||
createTimeStamp();
|
||||
createDisplay();
|
||||
createControl();
|
||||
createBooleanAlarm();
|
||||
createByteAlarm();
|
||||
createShortAlarm();
|
||||
createIntAlarm();
|
||||
createLongAlarm();
|
||||
createFloatAlarm();
|
||||
createDoubleAlarm();
|
||||
createEnumeratedAlarm();
|
||||
static StandardFieldPtr standardFieldCreate;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
|
||||
if(standardFieldCreate.get()==0)
|
||||
{
|
||||
standardFieldCreate = StandardFieldPtr(new StandardField());
|
||||
standardFieldCreate->init();
|
||||
}
|
||||
return standardFieldCreate;
|
||||
}
|
||||
|
||||
|
||||
StandardField::StandardField(){init();}
|
||||
|
||||
StandardField::~StandardField(){
|
||||
}
|
||||
|
||||
static void myDeleteStatic(void*)
|
||||
{
|
||||
alarmField.reset();
|
||||
timeStampField.reset();
|
||||
displayField.reset();
|
||||
controlField.reset();
|
||||
booleanAlarmField.reset();
|
||||
byteAlarmField.reset();
|
||||
shortAlarmField.reset();
|
||||
intAlarmField.reset();
|
||||
longAlarmField.reset();
|
||||
floatAlarmField.reset();
|
||||
doubleAlarmField.reset();
|
||||
enumeratedAlarmField.reset();
|
||||
|
||||
}
|
||||
|
||||
static void myInitStatic(void*)
|
||||
{
|
||||
standardField = new StandardField();
|
||||
fieldCreate = getFieldCreate();
|
||||
epicsAtExit(&myDeleteStatic,0);
|
||||
}
|
||||
|
||||
static
|
||||
epicsThreadOnceId myInitOnce = EPICS_THREAD_ONCE_INIT;
|
||||
|
||||
StandardField * getStandardField() {
|
||||
epicsThreadOnce(&myInitOnce,&myInitStatic,0);
|
||||
return standardField;
|
||||
StandardFieldPtr getStandardField() {
|
||||
return StandardField::getStandardField();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* StandardPVField.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <epicsThread.h>
|
||||
@@ -14,340 +17,85 @@
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static StandardField *standardField = 0;
|
||||
|
||||
static String notImplemented("not implemented");
|
||||
static FieldCreate* fieldCreate = 0;
|
||||
static PVDataCreate* pvDataCreate = 0;
|
||||
static StandardPVField *standardPVField = 0;
|
||||
|
||||
static void addExtendsStructureName(PVStructure *pvStructure,String properties)
|
||||
{
|
||||
bool gotAlarm = false;
|
||||
bool gotTimeStamp = false;
|
||||
bool gotDisplay = false;
|
||||
bool gotControl = false;
|
||||
if(properties.find("alarm")!=String::npos) gotAlarm = true;
|
||||
if(properties.find("timeStamp")!=String::npos) gotTimeStamp = true;
|
||||
if(properties.find("display")!=String::npos) gotDisplay = true;
|
||||
if(properties.find("control")!=String::npos) gotControl = true;
|
||||
if(gotAlarm) {
|
||||
PVStructure *pv = pvStructure->getStructureField(String("alarm"));
|
||||
if(pv!=0) pv->putExtendsStructureName(String("alarm"));
|
||||
}
|
||||
if(gotTimeStamp) {
|
||||
PVStructure *pv = pvStructure->getStructureField(String("timeStamp"));
|
||||
if(pv!=0) pv->putExtendsStructureName(String("timeStamp"));
|
||||
}
|
||||
if(gotDisplay) {
|
||||
PVStructure *pv = pvStructure->getStructureField(String("display"));
|
||||
if(pv!=0) pv->putExtendsStructureName(String("display"));
|
||||
}
|
||||
if(gotControl) {
|
||||
PVStructure *pv = pvStructure->getStructureField(String("control"));
|
||||
if(pv!=0) pv->putExtendsStructureName(String("control"));
|
||||
}
|
||||
}
|
||||
|
||||
StandardPVField::StandardPVField(){}
|
||||
StandardPVField::StandardPVField()
|
||||
: standardField(getStandardField()),
|
||||
fieldCreate(getFieldCreate()),
|
||||
pvDataCreate(getPVDataCreate()),
|
||||
notImplemented("not implemented")
|
||||
{}
|
||||
|
||||
StandardPVField::~StandardPVField(){}
|
||||
|
||||
|
||||
PVScalar * StandardPVField::scalar(PVStructure *parent,
|
||||
String fieldName,ScalarType type)
|
||||
PVStructurePtr StandardPVField::scalar(
|
||||
ScalarType type,String const & properties)
|
||||
{
|
||||
ScalarConstPtr field = standardField->scalar(fieldName,type);
|
||||
return pvDataCreate->createPVScalar(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::scalar(PVStructure *parent,
|
||||
String fieldName,ScalarType type,String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->scalar(fieldName,type,properties);
|
||||
PVStructure * pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
StructureConstPtr field = standardField->scalar(type,properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVScalarArray * StandardPVField::scalarArray(PVStructure *parent,
|
||||
String fieldName,ScalarType elementType)
|
||||
PVStructurePtr StandardPVField::scalarArray(
|
||||
ScalarType elementType, String const & properties)
|
||||
{
|
||||
ScalarArrayConstPtr field = standardField->scalarArray(
|
||||
fieldName,elementType);
|
||||
return pvDataCreate->createPVScalarArray(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::scalarArray(PVStructure *parent,
|
||||
String fieldName,ScalarType elementType, String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->scalarArray(
|
||||
fieldName,elementType,properties);
|
||||
PVStructure * pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
StructureConstPtr field = standardField->scalarArray(elementType,properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructureArray * StandardPVField::structureArray(PVStructure *parent,
|
||||
String fieldName,StructureConstPtr structure)
|
||||
PVStructurePtr StandardPVField::structureArray(
|
||||
StructureConstPtr const & structure,String const & properties)
|
||||
{
|
||||
StructureArrayConstPtr field = standardField->structureArray(
|
||||
fieldName,structure);
|
||||
return pvDataCreate->createPVStructureArray(parent,field);
|
||||
}
|
||||
|
||||
PVStructure* StandardPVField::structureArray(PVStructure *parent,
|
||||
String fieldName,StructureConstPtr structure,String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->structureArray(
|
||||
fieldName,structure,properties);
|
||||
PVStructure * pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
StructureConstPtr field = standardField->structureArray(structure,properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::enumerated(PVStructure *parent,
|
||||
String fieldName,StringArray choices,int number)
|
||||
PVStructurePtr StandardPVField::enumerated(StringArray const &choices)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated(fieldName);
|
||||
PVStructure *pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
PVScalarArray *pvScalarArray = pvStructure->getScalarArrayField(
|
||||
StructureConstPtr field = standardField->enumerated();
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"choices",pvString);
|
||||
if(pvScalarArray==0) {
|
||||
if(pvScalarArray.get()==NULL) {
|
||||
throw std::logic_error(String("StandardPVField::enumerated"));
|
||||
}
|
||||
PVStringArray *pvChoices = static_cast<PVStringArray *>(pvScalarArray);
|
||||
pvChoices->put(0,number,choices,0);
|
||||
PVStringArray * pvChoices = static_cast<PVStringArray *>(pvScalarArray.get());
|
||||
pvChoices->put(0,choices.size(),get(choices),0);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::enumerated(PVStructure *parent,
|
||||
String fieldName,StringArray choices,int number, String properties)
|
||||
PVStructurePtr StandardPVField::enumerated(
|
||||
StringArray const &choices,String const & properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumerated(
|
||||
fieldName,properties);
|
||||
PVStructure *pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
PVScalarArray *pvScalarArray = pvStructure->getScalarArrayField(
|
||||
fieldName += ".choices",pvString);
|
||||
if(pvScalarArray==0) {
|
||||
StructureConstPtr field = standardField->enumerated(properties);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(field);
|
||||
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"value.choices",pvString);
|
||||
if(pvScalarArray.get()==NULL) {
|
||||
throw std::logic_error(String("StandardPVField::enumerated"));
|
||||
}
|
||||
PVStringArray *pvChoices = static_cast<PVStringArray *>(pvScalarArray);
|
||||
pvChoices->put(0,number,choices,0);
|
||||
PVStringArray * pvChoices = static_cast<PVStringArray *>(pvScalarArray.get());
|
||||
pvChoices->put(0,choices.size(),get(choices),0);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVScalar * StandardPVField::scalarValue(PVStructure *parent,
|
||||
ScalarType scalarType)
|
||||
StandardPVFieldPtr StandardPVField::getStandardPVField()
|
||||
{
|
||||
ScalarConstPtr field = standardField->scalarValue(scalarType);
|
||||
return pvDataCreate->createPVScalar(parent,field);
|
||||
}
|
||||
static StandardPVFieldPtr standardPVField;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
|
||||
PVStructure * StandardPVField::scalarValue(PVStructure *parent,
|
||||
ScalarType type,String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->scalarValue(type,properties);
|
||||
PVStructure * pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVScalarArray * StandardPVField::scalarArrayValue(PVStructure *parent,
|
||||
ScalarType elementType)
|
||||
{
|
||||
ScalarArrayConstPtr scalarArray =
|
||||
standardField->scalarArrayValue(elementType);
|
||||
return pvDataCreate->createPVScalarArray(0,scalarArray);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::scalarArrayValue(PVStructure *parent,
|
||||
ScalarType elementType, String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->scalarArrayValue(
|
||||
elementType,properties);
|
||||
PVStructure * pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructureArray * StandardPVField::structureArrayValue(PVStructure *parent,
|
||||
StructureConstPtr structure)
|
||||
{
|
||||
StructureArrayConstPtr field = standardField->structureArrayValue(
|
||||
structure);
|
||||
return pvDataCreate->createPVStructureArray(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::structureArrayValue(PVStructure *parent,
|
||||
StructureConstPtr structure,String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->structureArrayValue(
|
||||
structure,properties);
|
||||
PVStructure * pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::enumeratedValue(PVStructure *parent,
|
||||
StringArray choices,int number)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumeratedValue();
|
||||
PVStructure *pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
PVScalarArray *pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"choices",pvString);
|
||||
if(pvScalarArray==0) {
|
||||
throw std::logic_error(String("StandardPVField::enumerated"));
|
||||
if(standardPVField.get()==NULL) {
|
||||
standardPVField= StandardPVFieldPtr(new StandardPVField());
|
||||
}
|
||||
PVStringArray *pvChoices = static_cast<PVStringArray *>(pvScalarArray);
|
||||
pvChoices->put(0,number,choices,0);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::enumeratedValue(PVStructure *parent,
|
||||
StringArray choices, int number,String properties)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumeratedValue( properties);
|
||||
PVStructure *pvStructure = pvDataCreate->createPVStructure(parent,field);
|
||||
addExtendsStructureName(pvStructure,properties);
|
||||
PVScalarArray *pvScalarArray = pvStructure->getScalarArrayField(
|
||||
String("value.choices"),pvString);
|
||||
if(pvScalarArray==0) {
|
||||
throw std::logic_error(String("StandardPVField::enumerated"));
|
||||
}
|
||||
PVStringArray *pvChoices = static_cast<PVStringArray *>(pvScalarArray);
|
||||
pvChoices->put(0,number,choices,0);
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::alarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->alarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::timeStamp(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->timeStamp();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::display(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->display();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::control(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->control();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::booleanAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->booleanAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::byteAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->byteAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::shortAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->shortAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::intAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->intAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::longAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->longAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::floatAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->floatAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::doubleAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->doubleAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::enumeratedAlarm(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr field = standardField->enumeratedAlarm();
|
||||
return pvDataCreate->createPVStructure(parent,field);
|
||||
}
|
||||
|
||||
PVStructure * StandardPVField::powerSupply(PVStructure *parent)
|
||||
{
|
||||
StructureConstPtr alarmField = standardField->alarm();
|
||||
StructureConstPtr timeStampField = standardField->timeStamp();
|
||||
StructureConstPtr voltageField = standardField->scalar(
|
||||
String("voltage"),pvDouble,String("alarm"));
|
||||
StructureConstPtr powerField = standardField->scalar(
|
||||
String("power"),pvDouble,String("alarm"));
|
||||
StructureConstPtr currentField = standardField->scalar(
|
||||
String("current"),pvDouble,String("alarm"));
|
||||
FieldConstPtr fields[3];
|
||||
fields[0] = voltageField;
|
||||
fields[1] = powerField;
|
||||
fields[2] = currentField;
|
||||
StructureConstPtr valueField = standardField->structureValue( 3,fields);
|
||||
fields[0] = alarmField;
|
||||
fields[1] = timeStampField;
|
||||
fields[2] = valueField;
|
||||
StructureConstPtr structureField = standardField->structureValue(3,fields);
|
||||
return pvDataCreate->createPVStructure(parent,structureField);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class StandardPVFieldExt : public StandardPVField {
|
||||
public:
|
||||
StandardPVFieldExt(): StandardPVField(){};
|
||||
};
|
||||
|
||||
static void myDeleteStatic(void*)
|
||||
{
|
||||
delete standardPVField;
|
||||
}
|
||||
|
||||
static void myInitStatic(void*)
|
||||
{
|
||||
fieldCreate = getFieldCreate();
|
||||
pvDataCreate = getPVDataCreate();
|
||||
standardField = getStandardField();
|
||||
standardPVField = new StandardPVFieldExt();
|
||||
epicsAtExit(&myDeleteStatic, 0);
|
||||
}
|
||||
|
||||
static
|
||||
epicsThreadOnceId myInitOnce = EPICS_THREAD_ONCE_INIT;
|
||||
|
||||
StandardPVField * getStandardPVField() {
|
||||
epicsThreadOnce(&myInitOnce, &myInitStatic, 0);
|
||||
return standardPVField;
|
||||
}
|
||||
|
||||
StandardPVFieldPtr getStandardPVField() {
|
||||
return StandardPVField::getStandardPVField();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*TypeFunc.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
@@ -33,7 +36,12 @@ namespace TypeFunc {
|
||||
|
||||
namespace ScalarTypeFunc {
|
||||
bool isInteger(ScalarType type) {
|
||||
if(type>=pvByte && type<=pvLong) return true;
|
||||
if(type>=pvByte && type<=pvULong) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isUInteger(ScalarType type) {
|
||||
if(type>=pvUByte && type<=pvULong) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -48,7 +56,9 @@ namespace ScalarTypeFunc {
|
||||
}
|
||||
|
||||
static const char* names[] = {
|
||||
"boolean", "byte", "short", "int", "long",
|
||||
"boolean",
|
||||
"byte", "short", "int", "long",
|
||||
"ubyte", "ushort", "uint", "ulong",
|
||||
"float", "double", "string",
|
||||
};
|
||||
ScalarType getScalarType(String pvalue) {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*factory.h*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef FACTORY_H
|
||||
#define FACTORY_H
|
||||
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
/* CDRMonitor.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/linkedList.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <BaseTsd.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static
|
||||
epicsThreadOnceId monitorInit = EPICS_THREAD_ONCE_INIT;
|
||||
|
||||
// Must use a pointer w/ lazy init due to lack of
|
||||
// initialization order guarantees
|
||||
CDRMonitor* CDRMonitor::theone = 0;
|
||||
|
||||
CDRMonitor&
|
||||
CDRMonitor::get()
|
||||
{
|
||||
epicsThreadOnce(&monitorInit, &CDRMonitor::init, 0);
|
||||
assert(theone);
|
||||
return *theone;
|
||||
}
|
||||
|
||||
void
|
||||
CDRMonitor::init(void *)
|
||||
{
|
||||
//BUG: No idea how to handle allocation failure at this stage.
|
||||
theone=new CDRMonitor;
|
||||
}
|
||||
|
||||
void
|
||||
CDRMonitor::destroy()
|
||||
{
|
||||
if (theone)
|
||||
{
|
||||
CDRNode *node = theone->first();
|
||||
while (node)
|
||||
{
|
||||
CDRNode* tmp = node;
|
||||
node = node->next();
|
||||
delete tmp;
|
||||
}
|
||||
delete theone;
|
||||
theone = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CDRMonitor::CDRMonitor()
|
||||
:firstNode(0)
|
||||
{}
|
||||
|
||||
CDRCount
|
||||
CDRMonitor::current()
|
||||
{
|
||||
CDRCount total;
|
||||
for(CDRNode *cur=first(); !!cur; cur=cur->next())
|
||||
{
|
||||
total+=cur->get();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void
|
||||
CDRMonitor::show(FILE *fd, bool destroy)
|
||||
{
|
||||
for(CDRNode *cur=first(); !!cur; cur=cur->next())
|
||||
{
|
||||
cur->show(fd);
|
||||
}
|
||||
if (destroy)
|
||||
CDRMonitor::destroy();
|
||||
}
|
||||
|
||||
void
|
||||
CDRMonitor::show(std::ostream& out, bool destroy) const
|
||||
{
|
||||
for(CDRNode *cur=first(); !!cur; cur=cur->next())
|
||||
{
|
||||
cur->show(out);
|
||||
}
|
||||
if (destroy)
|
||||
CDRMonitor::destroy();
|
||||
}
|
||||
|
||||
void
|
||||
CDRNode::show(FILE *fd)
|
||||
{
|
||||
Lock x(guard);
|
||||
if(!current.cons && !current.dtys && !current.refs)
|
||||
return;
|
||||
fprintf(fd,"%s: totalConstruct %lu totalDestruct %lu",
|
||||
nodeName.c_str(), (unsigned long)current.cons,
|
||||
(unsigned long)current.dtys);
|
||||
ssize_t alive=current.cons;
|
||||
alive-=current.dtys;
|
||||
if(current.refs)
|
||||
fprintf(fd," totalReference %ld", current.refs);
|
||||
if(alive)
|
||||
fprintf(fd," ACTIVE %ld\n", (long)alive);
|
||||
else
|
||||
fprintf(fd,"\n");
|
||||
}
|
||||
|
||||
void
|
||||
CDRNode::show(std::ostream& out) const
|
||||
{
|
||||
Lock x(guard);
|
||||
if(!current.cons && !current.dtys && !current.refs)
|
||||
return;
|
||||
out<<nodeName<<" totalConstruct "<<current.cons
|
||||
<<" totalDestruct "<<current.dtys;
|
||||
ssize_t alive=current.cons;
|
||||
alive-=current.dtys;
|
||||
if(current.refs)
|
||||
out<<" totalReference "<<current.refs;
|
||||
if(alive)
|
||||
out<<" ACTIVE "<<alive;
|
||||
out<<"\n";
|
||||
}
|
||||
|
||||
void
|
||||
onceNode(void* raw)
|
||||
{
|
||||
CDRNodeInstance* inst=static_cast<CDRNodeInstance*>(raw);
|
||||
inst->node=new CDRNode(inst->name);
|
||||
}
|
||||
|
||||
}} // namespace epics::pvData
|
||||
|
||||
std::ostream& operator<<(std::ostream& out,const epics::pvData::CDRMonitor& mon)
|
||||
{
|
||||
mon.show(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out,const epics::pvData::CDRNode& node)
|
||||
{
|
||||
node.show(out);
|
||||
return out;
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/* CDRMonitor.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef CDRMONITOR_H
|
||||
#define CDRMONITOR_H
|
||||
#include <ostream>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
//! Used to pass around snapshots
|
||||
struct CDRCount { // default copy and assignment are ok
|
||||
size_t cons, dtys;
|
||||
long refs;
|
||||
CDRCount():cons(0),dtys(0),refs(0){}
|
||||
CDRCount& operator+=(const CDRCount& o)
|
||||
{cons+=o.cons; dtys+=o.dtys; refs+=o.refs; return *this;}
|
||||
CDRCount& operator=(size_t count) // reset counters
|
||||
{cons=count; dtys=count; refs=count; return *this;}
|
||||
};
|
||||
|
||||
class CDRNode;
|
||||
|
||||
//! @brief Global registrar for CDRNodes
|
||||
class CDRMonitor : private NoDefaultMethods {
|
||||
public:
|
||||
static CDRMonitor& get();
|
||||
static void destroy();
|
||||
|
||||
CDRNode* addNode(CDRNode& next)
|
||||
{
|
||||
CDRNode *ret=firstNode;
|
||||
firstNode=&next;
|
||||
return ret;
|
||||
}
|
||||
|
||||
CDRCount current(); //!< current global count
|
||||
|
||||
CDRNode* first() const{return firstNode;}
|
||||
|
||||
void show(FILE*, bool destroy = false);
|
||||
void show(std::ostream&, bool destroy = false) const;
|
||||
private:
|
||||
// Private ctor for singleton
|
||||
CDRMonitor();
|
||||
CDRNode *firstNode;
|
||||
|
||||
static CDRMonitor *theone;
|
||||
static void init(void*);
|
||||
};
|
||||
|
||||
//! Counters for Construction, Destruction, and References of one class
|
||||
class CDRNode : private NoDefaultMethods {
|
||||
public:
|
||||
CDRNode(const String& name)
|
||||
:nodeName(name)
|
||||
,current()
|
||||
,guard()
|
||||
,nextNode(CDRMonitor::get().addNode(*this))
|
||||
{}
|
||||
void construct(){Lock x(guard); current.cons++;}
|
||||
void destruct(){Lock x(guard); current.dtys++;}
|
||||
void incRef(){Lock x(guard); current.refs++;}
|
||||
void decRef(){Lock x(guard); current.refs--;}
|
||||
|
||||
CDRNode* next() const{return nextNode;}
|
||||
|
||||
CDRCount get() const{Lock x(guard); return current;}
|
||||
|
||||
void show(FILE*);
|
||||
void show(std::ostream&) const;
|
||||
private:
|
||||
const String nodeName;
|
||||
CDRCount current;
|
||||
mutable Mutex guard;
|
||||
CDRNode * const nextNode;
|
||||
};
|
||||
|
||||
struct CDRNodeInstance
|
||||
{
|
||||
CDRNode *node;
|
||||
epicsThreadOnceId once;
|
||||
const char* const name;
|
||||
};
|
||||
|
||||
void onceNode(void* raw);
|
||||
|
||||
static inline
|
||||
CDRNode*
|
||||
getNode(CDRNodeInstance *inst)
|
||||
{
|
||||
epicsThreadOnce(&inst->once,&onceNode,
|
||||
static_cast<void*>(inst));
|
||||
return inst->node;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) \
|
||||
static CDRNodeInstance NAME ## _node={0,EPICS_THREAD_ONCE_INIT,#NAME}
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) \
|
||||
getNode(&NAME ## _node)->destruct()
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) \
|
||||
getNode(&NAME ## _node)->construct()
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_INCREF(NAME) \
|
||||
getNode(&NAME ## _node)->incRef()
|
||||
#define PVDATA_REFCOUNT_MONITOR_DECREF(NAME) \
|
||||
getNode(&NAME ## _node)->decRef()
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME)
|
||||
#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME)
|
||||
#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME)
|
||||
#define PVDATA_REFCOUNT_MONITOR_INCREF(NAME)
|
||||
#define PVDATA_REFCOUNT_MONITOR_DECREF(NAME)
|
||||
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
std::ostream& operator<<(std::ostream&,const epics::pvData::CDRMonitor&);
|
||||
std::ostream& operator<<(std::ostream&,const epics::pvData::CDRNode&);
|
||||
|
||||
#endif /* CDRMONITOR_H */
|
||||
@@ -1,36 +1,37 @@
|
||||
/* bitSet.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mes
|
||||
*/
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(bitSet);
|
||||
BitSet::shared_pointer BitSet::create(uint32 nbits)
|
||||
{
|
||||
return BitSet::shared_pointer(new BitSet(nbits));
|
||||
}
|
||||
|
||||
BitSet::BitSet() : words(0), wordsLength(0), wordsInUse(0) {
|
||||
initWords(BITS_PER_WORD);
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(bitSet);
|
||||
}
|
||||
|
||||
BitSet::BitSet(uint32 nbits) : words(0), wordsLength(0), wordsInUse(0) {
|
||||
initWords(nbits);
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(bitSet);
|
||||
}
|
||||
|
||||
BitSet::~BitSet() {
|
||||
delete[] words;
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(bitSet);
|
||||
}
|
||||
|
||||
void BitSet::initWords(uint32 nbits) {
|
||||
@@ -193,6 +194,10 @@ namespace epics { namespace pvData {
|
||||
return sum;
|
||||
}
|
||||
|
||||
uint32 BitSet::size() const {
|
||||
return wordsLength * BITS_PER_WORD;
|
||||
}
|
||||
|
||||
BitSet& BitSet::operator&=(const BitSet& set) {
|
||||
|
||||
while (wordsInUse > set.wordsInUse)
|
||||
@@ -332,10 +337,10 @@ namespace epics { namespace pvData {
|
||||
int32 i = nextSetBit(0);
|
||||
char tmp[30];
|
||||
if (i != -1) {
|
||||
sprintf(tmp,"%d",i); *buffer += tmp;
|
||||
sprintf(tmp,"%d",(int)i); *buffer += tmp;
|
||||
for (i = nextSetBit(i+1); i >= 0; i = nextSetBit(i+1)) {
|
||||
int32 endOfRun = nextClearBit(i);
|
||||
do { *buffer += ", "; sprintf(tmp,"%d",i); *buffer += tmp; } while (++i < endOfRun);
|
||||
do { *buffer += ", "; sprintf(tmp,"%d",(int)i); *buffer += tmp; } while (++i < endOfRun);
|
||||
}
|
||||
}
|
||||
*buffer += '}';
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* bitSet.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mse
|
||||
*/
|
||||
#ifndef BITSET_H
|
||||
#define BITSET_H
|
||||
#include <stdexcept>
|
||||
@@ -13,6 +16,9 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class BitSet;
|
||||
typedef std::tr1::shared_ptr<BitSet> BitSetPtr;
|
||||
|
||||
/**
|
||||
* This class implements a vector of bits that grows as needed. Each
|
||||
* component of the bit set has a {@code bool} value. The
|
||||
@@ -39,6 +45,7 @@ namespace epics { namespace pvData {
|
||||
class BitSet : public Serializable {
|
||||
public:
|
||||
POINTER_DEFINITIONS(BitSet);
|
||||
static BitSet::shared_pointer create(uint32 nbits);
|
||||
/**
|
||||
* Creates a new bit set. All bits are initially {@code false}.
|
||||
*/
|
||||
@@ -113,7 +120,7 @@ namespace epics { namespace pvData {
|
||||
* use the following loop:
|
||||
*
|
||||
* <pre> {@code
|
||||
* for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
|
||||
* for (int32 i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
|
||||
* // operate on index i here
|
||||
* }}</pre>
|
||||
*
|
||||
@@ -147,6 +154,15 @@ namespace epics { namespace pvData {
|
||||
*/
|
||||
uint32 cardinality() const;
|
||||
|
||||
/**
|
||||
* Returns the number of bits of space actually in use by this
|
||||
* {@code BitSet} to represent bit values.
|
||||
* The maximum element in the set is the size - 1st element.
|
||||
*
|
||||
* @return the number of bits currently in this bit set
|
||||
*/
|
||||
uint32 size() const;
|
||||
|
||||
/**
|
||||
* Performs a logical <b>AND</b> of this target bit set with the
|
||||
* argument bit set. This bit set is modified so that each bit in it
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mes
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* byteBuffer.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mse
|
||||
*/
|
||||
#ifndef BYTEBUFFER_H
|
||||
#define BYTEBUFFER_H
|
||||
|
||||
@@ -153,7 +156,7 @@ inline double swap(double val)
|
||||
}
|
||||
|
||||
#define is_aligned(POINTER, BYTE_COUNT) \
|
||||
(((uintptr_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)
|
||||
(((std::ptrdiff_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)
|
||||
|
||||
/*template <bool ENDIANESS_SUPPORT = false,
|
||||
bool UNALIGNED_ACCESS = false,
|
||||
@@ -165,6 +168,12 @@ inline double swap(double val)
|
||||
#define ADAPTIVE_ACCESS true
|
||||
#define USE_INLINE_MEMCPY true
|
||||
|
||||
#if defined (__GNUC__) && (__GNUC__ < 3)
|
||||
#define GET(T) get((T*)0)
|
||||
#else
|
||||
#define GET(T) get<T>()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class implements {@code Bytebuffer} that is like the {@code java.nio.ByteBuffer}.
|
||||
* <p>A {@code BitSet} is not safe for multithreaded use without
|
||||
@@ -182,7 +191,7 @@ public:
|
||||
* @param byteOrder The byte order.
|
||||
* Must be one of EPICS_BYTE_ORDER,EPICS_ENDIAN_LITTLE,EPICS_ENDIAN_BIG,
|
||||
*/
|
||||
ByteBuffer(uintptr_t size, int byteOrder = EPICS_BYTE_ORDER) :
|
||||
ByteBuffer(std::size_t size, int byteOrder = EPICS_BYTE_ORDER) :
|
||||
_buffer(0), _size(size),
|
||||
_reverseEndianess(byteOrder != EPICS_BYTE_ORDER),
|
||||
_reverseFloatEndianess(byteOrder != EPICS_FLOAT_WORD_ORDER)
|
||||
@@ -244,9 +253,9 @@ public:
|
||||
* Returns the current position.
|
||||
* @return The current position in the raw data.
|
||||
*/
|
||||
inline uintptr_t getPosition()
|
||||
inline std::size_t getPosition()
|
||||
{
|
||||
return (((uintptr_t)(const void *)_position) - ((uintptr_t)(const void *)_buffer));
|
||||
return (std::size_t)(((std::ptrdiff_t)(const void *)_position) - ((std::ptrdiff_t)(const void *)_buffer));
|
||||
}
|
||||
/**
|
||||
* Sets the buffer position.
|
||||
@@ -255,7 +264,7 @@ public:
|
||||
* @param pos The offset into the raw buffer.
|
||||
* The new position value; must be no larger than the current limit
|
||||
*/
|
||||
inline void setPosition(uintptr_t pos)
|
||||
inline void setPosition(std::size_t pos)
|
||||
{
|
||||
_position = _buffer + pos;
|
||||
}
|
||||
@@ -264,9 +273,9 @@ public:
|
||||
*
|
||||
* @return The offset into the raw buffer.
|
||||
*/
|
||||
inline uintptr_t getLimit()
|
||||
inline std::size_t getLimit()
|
||||
{
|
||||
return (((uintptr_t)(const void *)_limit) - ((uintptr_t)(const void *)_buffer));
|
||||
return (std::size_t)(((std::ptrdiff_t)(const void *)_limit) - ((std::ptrdiff_t)(const void *)_buffer));
|
||||
}
|
||||
/**
|
||||
* Sets this buffer's limit.
|
||||
@@ -276,7 +285,7 @@ public:
|
||||
* @param limit The new position value;
|
||||
* must be no larger than the current limit
|
||||
*/
|
||||
inline void setLimit(uintptr_t limit)
|
||||
inline void setLimit(std::size_t limit)
|
||||
{
|
||||
_limit = _buffer + limit;
|
||||
}
|
||||
@@ -285,73 +294,26 @@ public:
|
||||
*
|
||||
* @return The number of elements remaining in this buffer.
|
||||
*/
|
||||
inline uintptr_t getRemaining()
|
||||
inline std::size_t getRemaining()
|
||||
{
|
||||
return (((uintptr_t)(const void *)_limit) - ((uintptr_t)(const void *)_position));
|
||||
return (std::size_t)(((std::ptrdiff_t)(const void *)_limit) - ((std::ptrdiff_t)(const void *)_position));
|
||||
}
|
||||
/**
|
||||
* Returns The size, i.e. capacity of the raw data buffer in bytes.
|
||||
*
|
||||
* @return The size of the raw data buffer.
|
||||
*/
|
||||
inline uintptr_t getSize()
|
||||
inline std::size_t getSize()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the value into the raw buffer as a byte stream in the current byte order.
|
||||
*
|
||||
* @param value The value to be put into the byte buffer.
|
||||
*/
|
||||
template<typename T>
|
||||
inline void put(T value)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
*(_position++) = (int8)value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access pretty good (e.g. x86)
|
||||
*((T*)_position) = value;
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
*((T*)_position) = value;
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(_position, &value, sizeof(T));
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
_position[i] = ((char*)&value)[i];
|
||||
_position += sizeof(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
inline void put(T value);
|
||||
/**
|
||||
* Put the value into the raw buffer at the specified index as a byte stream in the current byte order.
|
||||
*
|
||||
@@ -359,108 +321,20 @@ public:
|
||||
* @param value The value to be put into the byte buffer.
|
||||
*/
|
||||
template<typename T>
|
||||
inline void put(uintptr_t index, T value)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
*(_buffer + index) = (int8)value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
*((T*)(_buffer + index)) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
*((T*)(_buffer + index)) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(_buffer + index, &value, sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
char *p = _buffer + index;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
p[i] = ((char*)&value)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
inline void put(std::size_t index, T value);
|
||||
/**
|
||||
* Get the new object from the byte buffer. The item MUST have type {@code T}.
|
||||
* The position is adjusted based on the type.
|
||||
*
|
||||
* @return The object.
|
||||
*/
|
||||
#if defined (__GNUC__) && (__GNUC__ < 3)
|
||||
template<typename T>
|
||||
inline T get()
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
return (int8)(*(_position++));
|
||||
}
|
||||
|
||||
|
||||
T value;
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
value = *((T*)_position);
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
value = *((T*)_position);
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(&value, _position, sizeof(T));
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((char*)&value)[i] = _position[i];
|
||||
_position += sizeof(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline T get(const T*);
|
||||
#else
|
||||
template<typename T>
|
||||
inline T get();
|
||||
#endif
|
||||
/**
|
||||
* Get the new object from the byte buffer at the specified index.
|
||||
* The item MUST have type {@code T}.
|
||||
@@ -470,53 +344,7 @@ public:
|
||||
* @return The object.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T get(uintptr_t index)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
return (int8)(*(_buffer + index));
|
||||
}
|
||||
|
||||
|
||||
T value;
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
value = *((T*)(_buffer + index));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
value = *((T*)(_buffer + index));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(&value, _buffer + index, sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
char* p = _buffer + index;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((char*)&value)[i] = p[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
inline T get(std::size_t index);
|
||||
/**
|
||||
* Put a sub-array of bytes into the byte buffer.
|
||||
* The position is increased by the count.
|
||||
@@ -525,7 +353,7 @@ public:
|
||||
* @param offset The starting position within src.
|
||||
* @param count The number of bytes to put into the byte buffer,
|
||||
*/
|
||||
inline void put(const char* src, uintptr_t src_offset, uintptr_t count) {
|
||||
inline void put(const char* src, std::size_t src_offset, std::size_t count) {
|
||||
//if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer overflow");
|
||||
memcpy(_position, src + src_offset, count);
|
||||
_position += count;
|
||||
@@ -538,7 +366,7 @@ public:
|
||||
* @param offset The starting position within src.
|
||||
* @param count The number of bytes to put into the byte buffer,
|
||||
*/
|
||||
inline void get(char* dest, uintptr_t dest_offset, uintptr_t count) {
|
||||
inline void get(char* dest, std::size_t dest_offset, std::size_t count) {
|
||||
//if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer overflow");
|
||||
memcpy(dest + dest_offset, _position, count);
|
||||
_position += count;
|
||||
@@ -551,32 +379,7 @@ public:
|
||||
* @param count The number of elements.
|
||||
*/
|
||||
template<typename T>
|
||||
inline void putArray(T* values, uintptr_t count)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
put((const char*)values, 0, count);
|
||||
return;
|
||||
}
|
||||
|
||||
T* start = (T*)_position;
|
||||
|
||||
size_t n = sizeof(T)*count;
|
||||
// we require aligned arrays...
|
||||
memcpy(_position, values, n);
|
||||
_position += n;
|
||||
|
||||
// ... so that we can be fast changing endianess
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
for (uintptr_t i = 0; i < count; i++)
|
||||
{
|
||||
*start = swap<T>(*start);
|
||||
start++;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void putArray(T* values, std::size_t count);
|
||||
/**
|
||||
* Get an array of type {@code T} from the byte buffer.
|
||||
* The position is adjusted.
|
||||
@@ -585,32 +388,7 @@ public:
|
||||
* @param count The number of elements.
|
||||
*/
|
||||
template<typename T>
|
||||
inline void getArray(T* values, uintptr_t count)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
get((char*)values, 0, count);
|
||||
return;
|
||||
}
|
||||
|
||||
T* start = (T*)values;
|
||||
|
||||
size_t n = sizeof(T)*count;
|
||||
// we require aligned arrays...
|
||||
memcpy(values, _position, n);
|
||||
_position += n;
|
||||
|
||||
// ... so that we can be fast changing endianess
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
for (uintptr_t i = 0; i < count; i++)
|
||||
{
|
||||
*start = swap<T>(*start);
|
||||
start++;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void getArray(T* values, std::size_t count);
|
||||
/**
|
||||
* Is the byte order the EPICS_BYTE_ORDER
|
||||
* @return (false,true) if (is, is not) the EPICS_BYTE_ORDER
|
||||
@@ -625,10 +403,10 @@ public:
|
||||
* Size MUST be a power of 2.
|
||||
* @param size The alignment requirement.
|
||||
*/
|
||||
inline void align(int size)
|
||||
inline void align(std::size_t size)
|
||||
{
|
||||
const uintptr_t k = size - 1;
|
||||
_position = (char*)((((uintptr_t)(const void *)_position) + k) & ~(k));
|
||||
const std::size_t k = size - 1;
|
||||
_position = (char*)((((std::ptrdiff_t)(const void *)_position) + k) & ~(k));
|
||||
}
|
||||
/**
|
||||
* Put a boolean value into the byte buffer.
|
||||
@@ -679,142 +457,140 @@ public:
|
||||
* @param index The offset in the byte buffer,
|
||||
* @param value The value.
|
||||
*/
|
||||
inline void putBoolean(uintptr_t index, bool value) { put< int8>(index, value); }
|
||||
inline void putBoolean(std::size_t index, bool value) { put< int8>(index, value); }
|
||||
/**
|
||||
* Put a byte value into the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer,
|
||||
* @param value The value.
|
||||
*/
|
||||
inline void putByte (uintptr_t index, int8 value) { put< int8>(index, value); }
|
||||
inline void putByte (std::size_t index, int8 value) { put< int8>(index, value); }
|
||||
/**
|
||||
* Put a short value into the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer,
|
||||
* @param value The value.
|
||||
*/
|
||||
inline void putShort (uintptr_t index, int16 value) { put< int16>(index, value); }
|
||||
inline void putShort (std::size_t index, int16 value) { put< int16>(index, value); }
|
||||
/**
|
||||
* Put an int value into the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer,
|
||||
* @param value The value.
|
||||
*/
|
||||
inline void putInt (uintptr_t index, int32 value) { put< int32>(index, value); }
|
||||
inline void putInt (std::size_t index, int32 value) { put< int32>(index, value); }
|
||||
/**
|
||||
* Put a long value into the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer,
|
||||
* @param value The value.
|
||||
*/
|
||||
inline void putLong (uintptr_t index, int64 value) { put< int64>(index, value); }
|
||||
inline void putLong (std::size_t index, int64 value) { put< int64>(index, value); }
|
||||
/**
|
||||
* Put a float value into the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer,
|
||||
* @param value The value.
|
||||
*/
|
||||
inline void putFloat (uintptr_t index, float value) { put< float>(index, value); }
|
||||
inline void putFloat (std::size_t index, float value) { put< float>(index, value); }
|
||||
/**
|
||||
* Put a double value into the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer,
|
||||
* @param value The value.
|
||||
*/
|
||||
inline void putDouble (uintptr_t index,double value) { put<double>(index, value); }
|
||||
|
||||
inline void putDouble (std::size_t index, double value) { put<double>(index, value); }
|
||||
/**
|
||||
* Get a boolean value from the byte buffer.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
inline bool getBoolean() { return get< int8>() != 0; }
|
||||
inline bool getBoolean() { return GET( int8) != 0; }
|
||||
/**
|
||||
* Get a byte value from the byte buffer.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
inline int8 getByte () { return get< int8>(); }
|
||||
inline int8 getByte () { return GET( int8); }
|
||||
/**
|
||||
* Get a short value from the byte buffer.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
inline int16 getShort () { return get< int16>(); }
|
||||
inline int16 getShort () { return GET( int16); }
|
||||
/**
|
||||
* Get a int value from the byte buffer.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
inline int32 getInt () { return get< int32>(); }
|
||||
inline int32 getInt () { return GET( int32); }
|
||||
/**
|
||||
* Get a long value from the byte buffer.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
inline int64 getLong () { return get< int64>(); }
|
||||
inline int64 getLong () { return GET( int64); }
|
||||
/**
|
||||
* Get a float value from the byte buffer.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
inline float getFloat () { return get< float>(); }
|
||||
inline float getFloat () { return GET( float); }
|
||||
/**
|
||||
* Get a double value from the byte buffer.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
inline double getDouble () { return get<double>(); }
|
||||
|
||||
inline double getDouble () { return GET(double); }
|
||||
/**
|
||||
* Get a boolean value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline bool getBoolean(uintptr_t index) { return get< int8>(index) != 0; }
|
||||
inline bool getBoolean(std::size_t index) { return get< int8>(index) != 0; }
|
||||
/**
|
||||
* Get a byte value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline int8 getByte (uintptr_t index) { return get< int8>(index); }
|
||||
inline int8 getByte (std::size_t index) { return get< int8>(index); }
|
||||
/**
|
||||
* Get a short value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline int16 getShort (uintptr_t index) { return get< int16>(index); }
|
||||
inline int16 getShort (std::size_t index) { return get< int16>(index); }
|
||||
/**
|
||||
* Get an int value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline int32 getInt (uintptr_t index) { return get< int32>(index); }
|
||||
inline int32 getInt (std::size_t index) { return get< int32>(index); }
|
||||
/**
|
||||
* Get a long value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline int64 getLong (uintptr_t index) { return get< int64>(index); }
|
||||
inline int64 getLong (std::size_t index) { return get< int64>(index); }
|
||||
/**
|
||||
* Get a float value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param index The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline float getFloat (uintptr_t index) { return get< float>(index); }
|
||||
inline float getFloat (std::size_t index) { return get< float>(index); }
|
||||
/**
|
||||
* Get a boolean value from the byte buffer at the specified index.
|
||||
*
|
||||
* @param double The offset in the byte buffer.
|
||||
* @return The value.
|
||||
*/
|
||||
inline double getDouble (uintptr_t index) { return get<double>(index); }
|
||||
inline double getDouble (std::size_t index) { return get<double>(index); }
|
||||
|
||||
// TODO remove
|
||||
inline const char* getArray()
|
||||
@@ -827,7 +603,7 @@ private:
|
||||
char* _buffer;
|
||||
char* _position;
|
||||
char* _limit;
|
||||
uintptr_t _size;
|
||||
std::size_t _size;
|
||||
bool _reverseEndianess;
|
||||
bool _reverseFloatEndianess;
|
||||
};
|
||||
@@ -844,6 +620,264 @@ private:
|
||||
return _reverseFloatEndianess;
|
||||
}
|
||||
|
||||
// the following methods must come after the specialized reverse<>() methods to make pre-gcc3 happy
|
||||
|
||||
template<typename T>
|
||||
inline void ByteBuffer::put(T value)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
*(_position++) = (int8)value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access pretty good (e.g. x86)
|
||||
*((T*)_position) = value;
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
*((T*)_position) = value;
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(_position, &value, sizeof(T));
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
_position[i] = ((char*)&value)[i];
|
||||
_position += sizeof(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void ByteBuffer::put(std::size_t index, T value)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
*(_buffer + index) = (int8)value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
*((T*)(_buffer + index)) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
*((T*)(_buffer + index)) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(_buffer + index, &value, sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
char *p = _buffer + index;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
p[i] = ((char*)&value)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined (__GNUC__) && (__GNUC__ < 3)
|
||||
template<typename T>
|
||||
inline T ByteBuffer::get(const T*)
|
||||
#else
|
||||
template<typename T>
|
||||
inline T ByteBuffer::get()
|
||||
#endif
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
return (int8)(*(_position++));
|
||||
}
|
||||
|
||||
|
||||
T value;
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
value = *((T*)_position);
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
value = *((T*)_position);
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(&value, _position, sizeof(T));
|
||||
_position += sizeof(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((char*)&value)[i] = _position[i];
|
||||
_position += sizeof(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T ByteBuffer::get(std::size_t index)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
return (int8)(*(_buffer + index));
|
||||
}
|
||||
|
||||
|
||||
T value;
|
||||
|
||||
if (UNALIGNED_ACCESS)
|
||||
{
|
||||
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
|
||||
value = *((T*)(_buffer + index));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this check and branching does not always payoff
|
||||
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
|
||||
{
|
||||
value = *((T*)(_buffer + index));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USE_INLINE_MEMCPY)
|
||||
{
|
||||
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
|
||||
memcpy(&value, _buffer + index, sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: compiler should optimize this and unroll the loop
|
||||
char* p = _buffer + index;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((char*)&value)[i] = p[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
value = swap<T>(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void ByteBuffer::putArray(T* values, std::size_t count)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
put((const char*)values, 0, count);
|
||||
return;
|
||||
}
|
||||
|
||||
T* start = (T*)_position;
|
||||
|
||||
size_t n = sizeof(T)*count;
|
||||
// we require aligned arrays...
|
||||
memcpy(_position, values, n);
|
||||
_position += n;
|
||||
|
||||
// ... so that we can be fast changing endianess
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
for (std::size_t i = 0; i < count; i++)
|
||||
{
|
||||
*start = swap<T>(*start);
|
||||
start++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void ByteBuffer::getArray(T* values, std::size_t count)
|
||||
{
|
||||
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
|
||||
if (sizeof(T) == 1)
|
||||
{
|
||||
get((char*)values, 0, count);
|
||||
return;
|
||||
}
|
||||
|
||||
T* start = (T*)values;
|
||||
|
||||
size_t n = sizeof(T)*count;
|
||||
// we require aligned arrays...
|
||||
memcpy(values, _position, n);
|
||||
_position += n;
|
||||
|
||||
// ... so that we can be fast changing endianess
|
||||
if (ENDIANESS_SUPPORT && reverse<T>())
|
||||
{
|
||||
for (std::size_t i = 0; i < count; i++)
|
||||
{
|
||||
*start = swap<T>(*start);
|
||||
start++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* destroyable.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mse
|
||||
*/
|
||||
#ifndef DESTROYABLE_H
|
||||
#define DESTROYABLE_H
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mes
|
||||
*/
|
||||
|
||||
#include <pv/epicsException.h>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* event.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
@@ -20,24 +23,20 @@
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(event);
|
||||
static String alreadyOn("already on list");
|
||||
|
||||
Event::~Event() {
|
||||
epicsEventDestroy(id);
|
||||
id = 0;
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(event);
|
||||
}
|
||||
|
||||
|
||||
Event::Event(bool full)
|
||||
: id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty))
|
||||
: id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty)),
|
||||
alreadyOn("already on list")
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(event);
|
||||
}
|
||||
|
||||
void Event::signal()
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
/* event.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef EVENT_H
|
||||
#define EVENT_H
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <epicsEvent.h>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class Event : private NoDefaultMethods {
|
||||
class Event;
|
||||
typedef std::tr1::shared_ptr<Event> EventPtr;
|
||||
|
||||
class Event {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Event);
|
||||
explicit Event(bool = false);
|
||||
~Event();
|
||||
void signal();
|
||||
@@ -24,6 +31,7 @@ public:
|
||||
bool tryWait (); /* false if empty */
|
||||
private:
|
||||
epicsEventId id;
|
||||
String alreadyOn;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,118 +1,67 @@
|
||||
/* executor.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <pv/linkedList.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/thread.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/executor.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
// special instance to stop the executor thread
|
||||
static
|
||||
class ExecutorShutdown : public Command {
|
||||
virtual void command(){};
|
||||
} executorShutdown;
|
||||
virtual void command();
|
||||
};
|
||||
|
||||
void ExecutorShutdown::command()
|
||||
{
|
||||
}
|
||||
|
||||
static
|
||||
Command *shutdown=&executorShutdown;
|
||||
std::tr1::shared_ptr<Command> shutdown(new ExecutorShutdown());
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(executor);
|
||||
|
||||
typedef LinkedListNode<ExecutorNode> ExecutorListNode;
|
||||
typedef LinkedList<ExecutorNode> ExecutorList;
|
||||
|
||||
class ExecutorNode {
|
||||
public:
|
||||
ExecutorNode(Command *command);
|
||||
|
||||
Command *command;
|
||||
ExecutorListNode node;
|
||||
ExecutorListNode runNode;
|
||||
};
|
||||
|
||||
ExecutorNode::ExecutorNode(Command *command)
|
||||
: command(command),
|
||||
node(*this),
|
||||
runNode(*this)
|
||||
{}
|
||||
|
||||
class ExecutorPvt : public Runnable{
|
||||
public:
|
||||
ExecutorPvt(String threadName,ThreadPriority priority);
|
||||
~ExecutorPvt();
|
||||
ExecutorNode * createNode(Command *command);
|
||||
void execute(ExecutorNode *node);
|
||||
virtual void run();
|
||||
private:
|
||||
ExecutorList executorList;
|
||||
ExecutorList runList;
|
||||
Event moreWork;
|
||||
Event stopped;
|
||||
Mutex mutex;
|
||||
Thread thread;
|
||||
};
|
||||
|
||||
ExecutorPvt::ExecutorPvt(String threadName,ThreadPriority priority)
|
||||
: executorList(),
|
||||
runList(),
|
||||
moreWork(),
|
||||
stopped(),
|
||||
mutex(),
|
||||
thread(threadName,priority,this)
|
||||
{}
|
||||
|
||||
ExecutorPvt::~ExecutorPvt()
|
||||
Executor::Executor(String threadName,ThreadPriority priority)
|
||||
: thread(threadName,priority,this)
|
||||
{
|
||||
ExecutorNode shutdownNode(shutdown);
|
||||
}
|
||||
|
||||
execute(&shutdownNode);
|
||||
Executor::~Executor()
|
||||
{
|
||||
execute(shutdown);
|
||||
stopped.wait();
|
||||
|
||||
// The thread signals 'stopped' while still holding
|
||||
// the lock. By taking it we wait for the run() function
|
||||
// to actually return
|
||||
Lock xx(mutex);
|
||||
|
||||
ExecutorListNode *node;
|
||||
while((node=executorList.removeHead())!=0) {
|
||||
delete &node->getObject();
|
||||
}
|
||||
head.reset();
|
||||
tail.reset();
|
||||
}
|
||||
|
||||
void ExecutorPvt::run()
|
||||
void Executor::run()
|
||||
{
|
||||
Lock xx(mutex);
|
||||
while(true) {
|
||||
ExecutorListNode * executorListNode = 0;
|
||||
while(runList.isEmpty()) {
|
||||
while(head.get()==NULL) {
|
||||
xx.unlock();
|
||||
moreWork.wait();
|
||||
xx.lock();
|
||||
}
|
||||
executorListNode = runList.removeHead();
|
||||
|
||||
if(!executorListNode) continue;
|
||||
Command *cmd=executorListNode->getObject().command;
|
||||
|
||||
if(cmd==shutdown) break;
|
||||
|
||||
CommandPtr command = head;
|
||||
if(command.get()==NULL) continue;
|
||||
if(command.get()==shutdown.get()) break;
|
||||
xx.unlock();
|
||||
try {
|
||||
executorListNode->getObject().command->command();
|
||||
command->command();
|
||||
}catch(std::exception& e){
|
||||
//TODO: feed into logging mechanism
|
||||
fprintf(stderr, "Executor: Unhandled exception: %s",e.what());
|
||||
@@ -122,41 +71,20 @@ void ExecutorPvt::run()
|
||||
|
||||
xx.lock();
|
||||
}
|
||||
|
||||
stopped.signal();
|
||||
}
|
||||
|
||||
ExecutorNode * ExecutorPvt::createNode(Command *command)
|
||||
void Executor::execute(CommandPtr const & command)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
ExecutorNode *executorNode = new ExecutorNode(command);
|
||||
executorList.addTail(executorNode->node);
|
||||
return executorNode;
|
||||
command->next.reset();
|
||||
if(head.get()==NULL) {
|
||||
head = command;
|
||||
moreWork.signal();
|
||||
return;
|
||||
}
|
||||
if(tail.get()==NULL) return;
|
||||
tail->next = command;
|
||||
}
|
||||
|
||||
void ExecutorPvt::execute(ExecutorNode *node)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(node->runNode.isOnList()) return;
|
||||
bool isEmpty = runList.isEmpty();
|
||||
runList.addTail(node->runNode);
|
||||
if(isEmpty) moreWork.signal();
|
||||
}
|
||||
|
||||
Executor::Executor(String threadName,ThreadPriority priority)
|
||||
: pImpl(new ExecutorPvt(threadName,priority))
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(executor);
|
||||
}
|
||||
|
||||
Executor::~Executor() {
|
||||
delete pImpl;
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(executor);
|
||||
}
|
||||
|
||||
ExecutorNode * Executor::createNode(Command*command)
|
||||
{return pImpl->createNode(command);}
|
||||
|
||||
void Executor::execute(ExecutorNode *node) {pImpl->execute(node);}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,36 +1,52 @@
|
||||
/* executor.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef EXECUTOR_H
|
||||
#define EXECUTOR_H
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/thread.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
// This is created by Executor.createNode and passed to Executor.execute
|
||||
class ExecutorNode;
|
||||
class Command;
|
||||
class Executor;
|
||||
typedef std::tr1::shared_ptr<Command> CommandPtr;
|
||||
typedef std::tr1::shared_ptr<Executor> ExecutorPtr;
|
||||
|
||||
class Command {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Command);
|
||||
virtual ~Command(){}
|
||||
virtual void command() = 0;
|
||||
private:
|
||||
CommandPtr next;
|
||||
friend class Executor;
|
||||
};
|
||||
|
||||
class Executor : private NoDefaultMethods {
|
||||
class Executor : public Runnable{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Executor);
|
||||
Executor(String threadName,ThreadPriority priority);
|
||||
~Executor();
|
||||
ExecutorNode * createNode(Command *command);
|
||||
void execute(ExecutorNode *node);
|
||||
void execute(CommandPtr const &node);
|
||||
virtual void run();
|
||||
private:
|
||||
class ExecutorPvt *pImpl;
|
||||
CommandPtr head;
|
||||
CommandPtr tail;
|
||||
epics::pvData::Mutex mutex;
|
||||
epics::pvData::Event moreWork;
|
||||
epics::pvData::Event stopped;
|
||||
epics::pvData::Thread thread;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/* linkedList.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef LINKEDLIST_H
|
||||
#define LINKEDLIST_H
|
||||
#include <pv/linkedListVoid.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
template <typename T>
|
||||
class LinkedList;
|
||||
|
||||
template <typename T>
|
||||
class LinkedListNode : private LinkedListVoidNode {
|
||||
public:
|
||||
LinkedListNode(T &object) : LinkedListVoidNode(&object){}
|
||||
~LinkedListNode() {}
|
||||
T &getObject() { return *static_cast<T *>(LinkedListVoidNode::getObject());}
|
||||
bool isOnList() {return LinkedListVoidNode::isOnList();}
|
||||
friend class LinkedList<T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LinkedList : private LinkedListVoid {
|
||||
public:
|
||||
LinkedList() : LinkedListVoid() {}
|
||||
~LinkedList() {}
|
||||
int getLength() {return LinkedListVoid::getLength();}
|
||||
void addTail(LinkedListNode<T> &listNode)
|
||||
{
|
||||
LinkedListVoid::addTail(static_cast<LinkedListVoidNode &>(listNode));
|
||||
}
|
||||
void addHead(LinkedListNode<T> &listNode)
|
||||
{
|
||||
LinkedListVoid::addHead(static_cast<LinkedListVoidNode &>(listNode));
|
||||
}
|
||||
void insertAfter(LinkedListNode<T> &listNode,
|
||||
LinkedListNode<T> &addNode)
|
||||
{
|
||||
LinkedListVoid::insertAfter(
|
||||
static_cast<LinkedListVoidNode &>(listNode),
|
||||
static_cast<LinkedListVoidNode &>(addNode));
|
||||
}
|
||||
void insertBefore(LinkedListNode<T> &listNode,
|
||||
LinkedListNode<T> &addNode)
|
||||
{
|
||||
LinkedListVoid::insertBefore(
|
||||
static_cast<LinkedListVoidNode &>(listNode),
|
||||
static_cast<LinkedListVoidNode &>(addNode));
|
||||
}
|
||||
LinkedListNode<T> *removeTail(){
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::removeTail());
|
||||
}
|
||||
LinkedListNode<T> *removeHead(){
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::removeHead());
|
||||
}
|
||||
void remove(LinkedListNode<T> &listNode){
|
||||
LinkedListVoid::remove(static_cast<LinkedListVoidNode &>(listNode));
|
||||
}
|
||||
LinkedListNode<T> *getHead(){
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getHead());
|
||||
}
|
||||
LinkedListNode<T> *getTail(){
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getTail());
|
||||
}
|
||||
LinkedListNode<T> *getNext(LinkedListNode<T> &listNode){
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getNext(
|
||||
static_cast<LinkedListVoidNode &>(listNode)));
|
||||
}
|
||||
LinkedListNode<T> *getPrev(LinkedListNode<T> &listNode){
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getPrev(
|
||||
static_cast<LinkedListVoidNode &>(listNode)));
|
||||
}
|
||||
bool isEmpty() { return LinkedListVoid::isEmpty();}
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
#endif /* LINKEDLIST_H */
|
||||
|
||||
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
/* linkedListVoid.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/linkedListVoid.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static String alreadyOnList("already on list");
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(LinkedListNode);
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(LinkedList);
|
||||
|
||||
LinkedListVoidNode::LinkedListVoidNode(void *object)
|
||||
: object(object),before(0),after(0),linkedListVoid(0)
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedListNode);
|
||||
}
|
||||
|
||||
LinkedListVoidNode::LinkedListVoidNode(bool isHead)
|
||||
: object(this),before(this),after(this)
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedListNode);
|
||||
}
|
||||
|
||||
|
||||
LinkedListVoidNode::~LinkedListVoidNode()
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(LinkedListNode);
|
||||
}
|
||||
|
||||
void *LinkedListVoidNode::getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
bool LinkedListVoidNode::isOnList()
|
||||
{
|
||||
if(before==0 && after==0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkedListVoid::LinkedListVoid()
|
||||
: head(new LinkedListVoidNode(true)),length(0)
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedList);
|
||||
}
|
||||
|
||||
LinkedListVoid::~LinkedListVoid()
|
||||
{
|
||||
delete head;
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(LinkedList);
|
||||
}
|
||||
|
||||
int LinkedListVoid::getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::addTail(LinkedListVoidNode &node)
|
||||
{
|
||||
if(node.before!=0 || node.after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node.linkedListVoid = this;
|
||||
node.before = head->before;
|
||||
node.after = head;
|
||||
head->before->after = &node;
|
||||
head->before = &node;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::addHead(LinkedListVoidNode &node)
|
||||
{
|
||||
if(node.before!=0 || node.after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node.linkedListVoid = this;
|
||||
node.after = head->after;
|
||||
node.before = head;
|
||||
head->after->before = &node;
|
||||
head->after = &node;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::insertAfter(LinkedListVoidNode &node,
|
||||
LinkedListVoidNode &addNode)
|
||||
{
|
||||
LinkedListVoidNode *existingNode = &node;
|
||||
LinkedListVoidNode *newNode = &addNode;
|
||||
if(existingNode->after==0 || existingNode->before==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
if(node.linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
newNode->linkedListVoid = this;
|
||||
newNode->after = existingNode->after;
|
||||
newNode->before = existingNode;
|
||||
existingNode->after->before = newNode;
|
||||
existingNode->after = newNode;
|
||||
++length;
|
||||
}
|
||||
|
||||
void LinkedListVoid::insertBefore(LinkedListVoidNode &node,
|
||||
LinkedListVoidNode &addNode)
|
||||
{
|
||||
LinkedListVoidNode *existingNode = &node;
|
||||
LinkedListVoidNode *newNode = &addNode;
|
||||
if(existingNode->after==0 || existingNode->before==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
}
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
if(node.linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
newNode->linkedListVoid = this;
|
||||
newNode->after = existingNode;
|
||||
newNode->before = existingNode->before;
|
||||
existingNode->before->after = newNode;
|
||||
existingNode->before = newNode;
|
||||
++length;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::removeTail()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
LinkedListVoidNode *node = head->before;
|
||||
remove(*head->before);
|
||||
return node;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::removeHead()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
LinkedListVoidNode *node = head->after;
|
||||
remove(*head->after);
|
||||
return node;
|
||||
}
|
||||
|
||||
void LinkedListVoid::remove(LinkedListVoidNode &node)
|
||||
{
|
||||
if(node.before==0 || node.after==0) {
|
||||
throw std::logic_error(String("node not on list"));
|
||||
}
|
||||
if(node.linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
node.linkedListVoid = 0;
|
||||
LinkedListVoidNode *prev = node.before;
|
||||
LinkedListVoidNode *next = node.after;
|
||||
node.after = node.before = 0;
|
||||
prev->after = next;
|
||||
next->before = prev;
|
||||
length--;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getHead()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
return head->after;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getTail()
|
||||
{
|
||||
if(head->after==head) return 0;
|
||||
return head->before;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getNext(LinkedListVoidNode &listNode)
|
||||
{
|
||||
if(listNode.linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
if(listNode.after==head) return 0;
|
||||
return listNode.after;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getPrev(LinkedListVoidNode &listNode)
|
||||
{
|
||||
if(listNode.linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
if(listNode.before==head) return 0;
|
||||
return listNode.before;
|
||||
}
|
||||
|
||||
bool LinkedListVoid::isEmpty()
|
||||
{
|
||||
if(head->after==head) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,68 +0,0 @@
|
||||
/* linkedListVoid.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef LINKEDLISTVOID_H
|
||||
#define LINKEDLISTVOID_H
|
||||
#include <pv/pvType.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class LinkedListVoid;
|
||||
class LinkedListVoidNode;
|
||||
|
||||
class LinkedListVoidNode {
|
||||
public:
|
||||
~LinkedListVoidNode();
|
||||
void *getObject();
|
||||
bool isOnList();
|
||||
protected:
|
||||
LinkedListVoidNode(void *object);
|
||||
private:
|
||||
LinkedListVoidNode(bool isHead);
|
||||
friend class LinkedListVoid;
|
||||
void *object;
|
||||
LinkedListVoidNode *before;
|
||||
LinkedListVoidNode *after;
|
||||
LinkedListVoid *linkedListVoid;
|
||||
// do not implement the following
|
||||
LinkedListVoidNode(const LinkedListVoidNode&);
|
||||
LinkedListVoidNode & operator=(const LinkedListVoidNode&);
|
||||
};
|
||||
|
||||
class LinkedListVoid {
|
||||
public:
|
||||
~LinkedListVoid();
|
||||
int getLength();
|
||||
void addTail(LinkedListVoidNode &listNode);
|
||||
void addHead(LinkedListVoidNode &listNode);
|
||||
void insertAfter(LinkedListVoidNode &listNode,
|
||||
LinkedListVoidNode &addNode);
|
||||
void insertBefore(LinkedListVoidNode &listNode,
|
||||
LinkedListVoidNode &addNode);
|
||||
LinkedListVoidNode *removeTail();
|
||||
LinkedListVoidNode *removeHead();
|
||||
void remove(LinkedListVoidNode &listNode);
|
||||
LinkedListVoidNode *getHead();
|
||||
LinkedListVoidNode *getTail();
|
||||
LinkedListVoidNode *getNext(LinkedListVoidNode &listNode);
|
||||
LinkedListVoidNode *getPrev(LinkedListVoidNode &listNode);
|
||||
bool isEmpty();
|
||||
protected:
|
||||
LinkedListVoid();
|
||||
private:
|
||||
friend class LinkedListVoidNode;
|
||||
LinkedListVoidNode *head;
|
||||
int length;
|
||||
// do not implement the following
|
||||
LinkedListVoid(const LinkedListVoid&);
|
||||
LinkedListVoid & operator=(const LinkedListVoid&);
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* LINKEDLISTVOID_H */
|
||||
|
||||
|
||||
|
||||
39
pvDataApp/misc/localStaticLock.cpp
Normal file
39
pvDataApp/misc/localStaticLock.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/* localStaticLock.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mse
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
31
pvDataApp/misc/localStaticLock.h
Normal file
31
pvDataApp/misc/localStaticLock.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* localStaticLock.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mse
|
||||
*/
|
||||
#ifndef LOCALSTATICLOCK_H
|
||||
#define LOCALSTATICLOCK_H
|
||||
|
||||
#include <pv/lock.h>
|
||||
|
||||
extern epics::pvData::Mutex& getLocalStaticInitMutex();
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||
// noop
|
||||
#define LOCAL_STATIC_LOCK
|
||||
#else
|
||||
#define LOCAL_STATIC_LOCK epics::pvData::Lock localStaticInitMutexLock(getLocalStaticInitMutex());
|
||||
#endif
|
||||
|
||||
static class MutexInitializer {
|
||||
public:
|
||||
MutexInitializer ();
|
||||
~MutexInitializer ();
|
||||
} localStaticMutexInitializer; // Note object here in the header.
|
||||
|
||||
|
||||
#endif /* LOCALSTATICLOCK_H */
|
||||
@@ -1,9 +1,12 @@
|
||||
/* lock.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef LOCK_H
|
||||
#define LOCK_H
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -1,136 +1,111 @@
|
||||
/* messageQueue.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/requester.h>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
#include <pv/queue.h>
|
||||
#include <pv/messageQueue.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(messageQueue);
|
||||
|
||||
typedef MessageNode * MessageNodePtr;
|
||||
typedef QueueElement<MessageNode> MessageElement;
|
||||
typedef MessageElement *MessageElementPtr;
|
||||
typedef Queue<MessageNode> MessageNodeQueue;
|
||||
|
||||
|
||||
MessageNode::MessageNode()
|
||||
: message(String()),messageType(infoMessage){}
|
||||
: messageType(infoMessage)
|
||||
{}
|
||||
|
||||
MessageNode::~MessageNode() {
|
||||
}
|
||||
|
||||
String MessageNode::getMessage() const { return message;};
|
||||
|
||||
MessageType MessageNode::getMessageType() const { return messageType;}
|
||||
|
||||
void MessageNode::setMessageNull() {message = String();}
|
||||
|
||||
class MessageQueuePvt {
|
||||
public:
|
||||
MessageNodePtr *messageNodeArray;
|
||||
MessageNodeQueue *queue;
|
||||
MessageNodePtr lastPut;
|
||||
MessageElementPtr lastGet;
|
||||
int size;
|
||||
int overrun;
|
||||
};
|
||||
|
||||
MessageQueue::MessageQueue(int size)
|
||||
: pImpl(new MessageQueuePvt)
|
||||
String MessageNode::getMessage() const
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(messageQueue);
|
||||
pImpl->size = size;
|
||||
pImpl->overrun = 0;
|
||||
pImpl->lastPut = 0;
|
||||
pImpl->lastGet = 0;
|
||||
pImpl->messageNodeArray = new MessageNodePtr[size];
|
||||
for(int i=0; i<size; i++) {
|
||||
pImpl->messageNodeArray[i] = new MessageNode();
|
||||
}
|
||||
pImpl->queue = new MessageNodeQueue(pImpl->messageNodeArray,size);
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
MessageType MessageNode::getMessageType() const
|
||||
{
|
||||
return messageType;
|
||||
}
|
||||
|
||||
MessageQueuePtr MessageQueue::create(int size)
|
||||
{
|
||||
MessageNodePtrArray nodeArray;
|
||||
nodeArray.reserve(size);
|
||||
for(int i=0; i<size; i++) {
|
||||
nodeArray.push_back(
|
||||
MessageNodePtr(new MessageNode()));
|
||||
}
|
||||
return std::tr1::shared_ptr<MessageQueue>(new MessageQueue(nodeArray));
|
||||
}
|
||||
|
||||
MessageQueue::MessageQueue(MessageNodePtrArray &data)
|
||||
: Queue<MessageNode>(data),
|
||||
overrun(0)
|
||||
{ }
|
||||
|
||||
MessageQueue::~MessageQueue()
|
||||
{
|
||||
delete pImpl->queue;
|
||||
for(int i=0; i< pImpl->size; i++) {
|
||||
delete pImpl->messageNodeArray[i];
|
||||
}
|
||||
delete[] pImpl->messageNodeArray;
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(messageQueue);
|
||||
}
|
||||
|
||||
MessageNode *MessageQueue::get() {
|
||||
if(pImpl->lastGet!=0) {
|
||||
throw std::logic_error(
|
||||
String("MessageQueue::get() but did not release last"));
|
||||
}
|
||||
MessageElementPtr element = pImpl->queue->getUsed();
|
||||
if(element==0) return 0;
|
||||
pImpl->lastGet = element;
|
||||
return element->getObject();
|
||||
MessageNodePtr &MessageQueue::get() {
|
||||
if(getNumberUsed()==0) return nullNode;
|
||||
lastGet = getUsed();
|
||||
return lastGet;
|
||||
}
|
||||
|
||||
void MessageQueue::release() {
|
||||
if(pImpl->lastGet==0) return;
|
||||
pImpl->queue->releaseUsed(pImpl->lastGet);
|
||||
pImpl->lastGet = 0;
|
||||
if(lastGet.get()==NULL) return;
|
||||
releaseUsed(lastGet);
|
||||
lastGet.reset();
|
||||
}
|
||||
|
||||
bool MessageQueue::put(String message,MessageType messageType,bool replaceLast)
|
||||
{
|
||||
MessageElementPtr element = pImpl->queue->getFree();
|
||||
if(element!=0) {
|
||||
MessageNodePtr node = element->getObject();
|
||||
MessageNodePtr node = getFree();
|
||||
if(node.get()!= NULL) {
|
||||
node->message = message;
|
||||
node->messageType = messageType;
|
||||
pImpl->lastPut = node;
|
||||
pImpl->queue->setUsed(element);
|
||||
lastPut = node;
|
||||
setUsed(node);
|
||||
return true;
|
||||
}
|
||||
pImpl->overrun++;
|
||||
overrun++;
|
||||
if(replaceLast) {
|
||||
MessageNodePtr node = pImpl->lastPut;
|
||||
node = lastPut;
|
||||
node->message = message;
|
||||
node->messageType = messageType;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MessageQueue::isEmpty() const
|
||||
bool MessageQueue::isEmpty()
|
||||
{
|
||||
int free = pImpl->queue->getNumberFree();
|
||||
if(free==pImpl->size) return true;
|
||||
int free = getNumberFree();
|
||||
if(free==capacity()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MessageQueue::isFull() const
|
||||
bool MessageQueue::isFull()
|
||||
{
|
||||
if(pImpl->queue->getNumberFree()==0) return true;
|
||||
if(getNumberFree()==0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int MessageQueue::getClearOverrun()
|
||||
{
|
||||
int num = pImpl->overrun;
|
||||
pImpl->overrun = 0;
|
||||
int num = overrun;
|
||||
overrun = 0;
|
||||
return num;
|
||||
}
|
||||
|
||||
MessageQueuePtr createMessageQueue(int size)
|
||||
{
|
||||
MessageNodePtrArray nodeArray;
|
||||
nodeArray.reserve(size);
|
||||
for(int i=0; i<size; i++) {
|
||||
nodeArray.push_back(
|
||||
MessageNodePtr(new MessageNode()));
|
||||
}
|
||||
return std::tr1::shared_ptr<MessageQueue>(new MessageQueue(nodeArray));
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,44 +1,61 @@
|
||||
/* messageQueue.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef MESSAGEQUEUE_H
|
||||
#define MESSAGEQUEUE_H
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/requester.h>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/queue.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class MessageNode;
|
||||
class MessageQueue;
|
||||
typedef std::tr1::shared_ptr<MessageNode> MessageNodePtr;
|
||||
typedef std::vector<MessageNodePtr> MessageNodePtrArray;
|
||||
typedef std::tr1::shared_ptr<MessageQueue> MessageQueuePtr;
|
||||
|
||||
class MessageNode {
|
||||
public:
|
||||
MessageNode();
|
||||
String getMessage() const;
|
||||
MessageType getMessageType() const;
|
||||
void setMessageNull();
|
||||
private:
|
||||
MessageNode();
|
||||
~MessageNode();
|
||||
friend class MessageQueue;
|
||||
String message;
|
||||
MessageType messageType;
|
||||
friend class MessageQueue;
|
||||
};
|
||||
|
||||
class MessageQueue : private NoDefaultMethods {
|
||||
class MessageQueue : public Queue<MessageNode> {
|
||||
public:
|
||||
MessageQueue(int size);
|
||||
~MessageQueue();
|
||||
MessageNode *get();
|
||||
POINTER_DEFINITIONS(MessageQueue);
|
||||
static MessageQueuePtr create(int size);
|
||||
MessageQueue(MessageNodePtrArray &nodeArray);
|
||||
virtual ~MessageQueue();
|
||||
MessageNodePtr &get();
|
||||
// must call release before next get
|
||||
void release();
|
||||
// return (false,true) if message (was not, was) put into queue
|
||||
bool put(String message,MessageType messageType,bool replaceLast);
|
||||
bool isEmpty() const;
|
||||
bool isFull() const;
|
||||
bool isEmpty() ;
|
||||
bool isFull() ;
|
||||
int getClearOverrun();
|
||||
private:
|
||||
class MessageQueuePvt *pImpl;
|
||||
MessageNodePtr nullNode;
|
||||
MessageNodePtr lastGet;
|
||||
MessageNodePtr lastPut;
|
||||
uint32 overrun;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* noDefaultMethods.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef NO_DEFAULT_METHODS_H
|
||||
#define NO_DEFAULT_METHODS_H
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -1,50 +1,127 @@
|
||||
/* queue.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <pv/sharedPtr.h>
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
#include <pv/queueVoid.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
template <typename T>
|
||||
class Queue;
|
||||
|
||||
template <typename T>
|
||||
class QueueElement;
|
||||
|
||||
template <typename T>
|
||||
class QueueElement : private QueueElementVoid {
|
||||
class Queue
|
||||
{
|
||||
public:
|
||||
T *getObject() { return static_cast<T *>(QueueElementVoid::getObject());}
|
||||
protected:
|
||||
QueueElement(T *object) : QueueElementVoid(static_cast<void *>(object)){}
|
||||
~QueueElement() {}
|
||||
friend class Queue<T>;
|
||||
POINTER_DEFINITIONS(Queue);
|
||||
typedef std::tr1::shared_ptr<T> queueElementPtr;
|
||||
typedef std::vector<queueElementPtr> queueElementPtrArray;
|
||||
Queue(queueElementPtrArray &);
|
||||
virtual ~Queue();
|
||||
void clear();
|
||||
int capacity();
|
||||
int getNumberFree();
|
||||
int getNumberUsed();
|
||||
queueElementPtr & getFree();
|
||||
void setUsed(queueElementPtr &element);
|
||||
queueElementPtr & getUsed();
|
||||
void releaseUsed(queueElementPtr &element);
|
||||
private:
|
||||
queueElementPtr nullElement;
|
||||
queueElementPtrArray elements;
|
||||
int size;
|
||||
int numberFree;
|
||||
int numberUsed;
|
||||
int nextGetFree;
|
||||
int nextSetUsed;
|
||||
int nextGetUsed;
|
||||
int nextReleaseUsed;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Queue : private QueueVoid {
|
||||
public:
|
||||
Queue(T *array[],int number)
|
||||
: QueueVoid((ObjectPtr*)array,number)
|
||||
//: QueueVoid(static_cast<ObjectPtr*>(array),number)
|
||||
{}
|
||||
~Queue() {}
|
||||
void clear() {QueueVoid::clear();}
|
||||
int getNumberFree() {return QueueVoid::getNumberFree();}
|
||||
int capacity() {return QueueVoid::capacity();}
|
||||
QueueElement<T> *getFree() {
|
||||
return static_cast<QueueElement<T> *>(QueueVoid::getFree());}
|
||||
void setUsed(QueueElement<T> *queueElement) {
|
||||
QueueVoid::setUsed(static_cast<QueueElementVoid *>(queueElement));}
|
||||
QueueElement<T> *getUsed() {
|
||||
return static_cast<QueueElement<T> *>(QueueVoid::getUsed());}
|
||||
void releaseUsed(QueueElement<T> *queueElement) {
|
||||
QueueVoid::releaseUsed(static_cast<QueueElementVoid *>(queueElement));}
|
||||
};
|
||||
Queue<T>::Queue(std::vector<queueElementPtr> &xxx)
|
||||
: size(xxx.size()),
|
||||
numberFree(size),
|
||||
numberUsed(0),
|
||||
nextGetFree(0),
|
||||
nextSetUsed(0),
|
||||
nextGetUsed(0),
|
||||
nextReleaseUsed(0)
|
||||
{
|
||||
elements.swap(xxx);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Queue<T>::~Queue(){}
|
||||
|
||||
template <typename T>
|
||||
int Queue<T>::capacity(){return size;}
|
||||
|
||||
template <typename T>
|
||||
int Queue<T>::getNumberFree(){return numberFree;}
|
||||
|
||||
template <typename T>
|
||||
int Queue<T>::getNumberUsed(){return numberUsed;}
|
||||
|
||||
template <typename T>
|
||||
void Queue<T>::clear()
|
||||
{
|
||||
numberFree = size;
|
||||
numberUsed = 0;
|
||||
nextGetFree = 0;
|
||||
nextSetUsed = 0;
|
||||
nextGetUsed = 0;
|
||||
nextReleaseUsed = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::tr1::shared_ptr<T> & Queue<T>::getFree()
|
||||
{
|
||||
if(numberFree==0) return nullElement;
|
||||
numberFree--;
|
||||
int ind = nextGetFree;
|
||||
std::tr1::shared_ptr<T> queueElement = elements[nextGetFree++];
|
||||
if(nextGetFree>=size) nextGetFree = 0;
|
||||
return elements[ind];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Queue<T>::setUsed(std::tr1::shared_ptr<T> &element)
|
||||
{
|
||||
if(element!=elements[nextSetUsed++]) {
|
||||
throw std::logic_error("not correct queueElement");
|
||||
}
|
||||
numberUsed++;
|
||||
if(nextSetUsed>=size) nextSetUsed = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::tr1::shared_ptr<T> & Queue<T>::getUsed()
|
||||
{
|
||||
if(numberUsed==0) return nullElement;
|
||||
int ind = nextGetUsed;
|
||||
std::tr1::shared_ptr<T> queueElement = elements[nextGetUsed++];
|
||||
if(nextGetUsed>=size) nextGetUsed = 0;
|
||||
return elements[ind];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Queue<T>::releaseUsed(std::tr1::shared_ptr<T> &element)
|
||||
{
|
||||
if(element!=elements[nextReleaseUsed++]) {
|
||||
throw std::logic_error(
|
||||
"not queueElement returned by last call to getUsed");
|
||||
}
|
||||
if(nextReleaseUsed>=size) nextReleaseUsed = 0;
|
||||
numberUsed--;
|
||||
numberFree++;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/* queueVoid.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/queueVoid.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(queueElement);
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(queue);
|
||||
|
||||
QueueElementVoid::QueueElementVoid(ObjectPtr object)
|
||||
: object(object)
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(queueElement);
|
||||
}
|
||||
|
||||
|
||||
QueueElementVoid::~QueueElementVoid()
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(queueElement);
|
||||
}
|
||||
|
||||
ObjectPtr QueueElementVoid::getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QueueVoid::QueueVoid(ObjectPtr object[],int number)
|
||||
: array(new QueueElementVoidPtr[number]),number(number),
|
||||
numberFree(number),numberUsed(0),
|
||||
nextGetFree(0),nextSetUsed(),
|
||||
nextGetUsed(0),nextReleaseUsed(0)
|
||||
{
|
||||
for(int i=0; i<number; i++) {
|
||||
array[i] = new QueueElementVoid(object[i]);
|
||||
}
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(queue);
|
||||
}
|
||||
|
||||
QueueVoid::~QueueVoid()
|
||||
{
|
||||
for(int i=0; i<number; i++) {
|
||||
delete array[i];
|
||||
}
|
||||
delete[]array;
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(queue);
|
||||
}
|
||||
|
||||
void QueueVoid::clear()
|
||||
{
|
||||
numberFree = number;
|
||||
numberUsed = 0;
|
||||
nextGetFree = 0;
|
||||
nextSetUsed = 0;
|
||||
nextGetUsed = 0;
|
||||
nextReleaseUsed = 0;
|
||||
}
|
||||
|
||||
int QueueVoid::getNumberFree()
|
||||
{
|
||||
return numberFree;
|
||||
}
|
||||
|
||||
int QueueVoid::capacity()
|
||||
{
|
||||
return number;
|
||||
}
|
||||
|
||||
QueueElementVoid * QueueVoid::getFree()
|
||||
{
|
||||
if(numberFree==0) return 0;
|
||||
numberFree--;
|
||||
QueueElementVoid *queueElement = array[nextGetFree++];
|
||||
if(nextGetFree>=number) nextGetFree = 0;
|
||||
return queueElement;
|
||||
}
|
||||
|
||||
void QueueVoid::setUsed(QueueElementVoid *queueElement)
|
||||
{
|
||||
if(queueElement!=array[nextSetUsed++]) {
|
||||
throw std::logic_error(String("not correct queueElement"));
|
||||
}
|
||||
numberUsed++;
|
||||
if(nextSetUsed>=number) nextSetUsed = 0;
|
||||
}
|
||||
|
||||
QueueElementVoid * QueueVoid::getUsed()
|
||||
{
|
||||
if(numberUsed==0) return 0;
|
||||
QueueElementVoid *queueElement = array[nextGetUsed++];
|
||||
if(nextGetUsed>=number) nextGetUsed = 0;
|
||||
return queueElement;
|
||||
}
|
||||
|
||||
void QueueVoid::releaseUsed(QueueElementVoid *queueElement)
|
||||
{
|
||||
if(queueElement!=array[nextReleaseUsed++]) {
|
||||
throw std::logic_error(String(
|
||||
"not queueElement returned by last call to getUsed"));
|
||||
}
|
||||
if(nextReleaseUsed>=number) nextReleaseUsed = 0;
|
||||
numberUsed--;
|
||||
numberFree++;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,56 +0,0 @@
|
||||
/* queueVoid.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef QUEUEVOID_H
|
||||
#define QUEUEVOID_H
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class QueueVoid;
|
||||
class QueueElementVoid;
|
||||
|
||||
typedef void * ObjectPtr;
|
||||
typedef QueueElementVoid * QueueElementVoidPtr;
|
||||
typedef QueueElementVoidPtr * QueueElementVoidPtrArray;
|
||||
|
||||
class QueueElementVoid {
|
||||
protected:
|
||||
ObjectPtr getObject();
|
||||
QueueElementVoid(ObjectPtr object);
|
||||
~QueueElementVoid();
|
||||
ObjectPtr object;
|
||||
friend class QueueVoid;
|
||||
};
|
||||
|
||||
|
||||
class QueueVoid {
|
||||
protected:
|
||||
QueueVoid(ObjectPtr array[],int number);
|
||||
~QueueVoid();
|
||||
void clear();
|
||||
int getNumberFree();
|
||||
int capacity();
|
||||
QueueElementVoidPtr getFree();
|
||||
void setUsed(QueueElementVoid *queueElement);
|
||||
QueueElementVoid *getUsed();
|
||||
void releaseUsed(QueueElementVoid *queueElement);
|
||||
private:
|
||||
friend class QueueElementVoid;
|
||||
QueueElementVoidPtrArray array;
|
||||
int number;
|
||||
int numberFree;
|
||||
int numberUsed;
|
||||
int nextGetFree;
|
||||
int nextSetUsed;
|
||||
int nextGetUsed;
|
||||
int nextReleaseUsed;
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
#endif /* QUEUEVOID_H */
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,34 @@
|
||||
/* requester.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/requester.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
const size_t messageTypeCount = 4;
|
||||
static std::string typeName[messageTypeCount] = {
|
||||
String("info"),
|
||||
String("warning"),
|
||||
String("error"),
|
||||
String("fatalError")
|
||||
};
|
||||
static StringArray messageTypeName(messageTypeCount);
|
||||
|
||||
String getMessageTypeName(MessageType messageType)
|
||||
{
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
if(messageTypeName[0].size()==0) {
|
||||
messageTypeName[0] = "info";
|
||||
messageTypeName[1] = "warning";
|
||||
messageTypeName[2] = "error";
|
||||
messageTypeName[3] = "fatalError";
|
||||
}
|
||||
return messageTypeName[messageType];
|
||||
}
|
||||
|
||||
|
||||
|
||||
StringArray messageTypeName = typeName;
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* requester.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef REQUESTER_H
|
||||
#define REQUESTER_H
|
||||
#include <string>
|
||||
@@ -13,20 +16,20 @@
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class Requester;
|
||||
typedef std::tr1::shared_ptr<Requester> RequesterPtr;
|
||||
|
||||
enum MessageType {
|
||||
infoMessage,warningMessage,errorMessage,fatalErrorMessage
|
||||
};
|
||||
|
||||
extern StringArray messageTypeName;
|
||||
extern String getMessageTypeName(MessageType messageType);
|
||||
extern const size_t messageTypeCount;
|
||||
class Requester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Requester);
|
||||
|
||||
virtual ~Requester(){}
|
||||
virtual String getRequesterName() = 0;
|
||||
virtual void message(String message,MessageType messageType) = 0;
|
||||
virtual void message(String const & message,MessageType messageType) = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
/* serialize.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef SERIALIZE_H
|
||||
#define SERIALIZE_H
|
||||
#include <pv/byteBuffer.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class SerializableControl;
|
||||
@@ -15,20 +19,23 @@ namespace epics { namespace pvData {
|
||||
class BitSetSerializable;
|
||||
class SerializableArray;
|
||||
class BitSet;
|
||||
class Field;
|
||||
|
||||
class SerializableControl {
|
||||
public:
|
||||
virtual ~SerializableControl(){}
|
||||
virtual void flushSerializeBuffer() =0;
|
||||
virtual void ensureBuffer(int size) =0;
|
||||
virtual void alignBuffer(int alignment) =0;
|
||||
virtual void ensureBuffer(std::size_t size) =0;
|
||||
virtual void alignBuffer(std::size_t alignment) =0;
|
||||
virtual void cachedSerialize(std::tr1::shared_ptr<const Field> const & field, ByteBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
class DeserializableControl {
|
||||
public:
|
||||
virtual ~DeserializableControl(){}
|
||||
virtual void ensureData(int size) =0;
|
||||
virtual void alignData(int alignment) =0;
|
||||
virtual void ensureData(std::size_t size) =0;
|
||||
virtual void alignData(std::size_t alignment) =0;
|
||||
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
class Serializable {
|
||||
@@ -54,7 +61,7 @@ namespace epics { namespace pvData {
|
||||
public:
|
||||
virtual ~SerializableArray(){}
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher, int offset, int count) const = 0;
|
||||
SerializableControl *flusher, std::size_t offset, std::size_t count) const = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
@@ -23,14 +23,14 @@ using namespace std;
|
||||
namespace epics {
|
||||
namespace pvData {
|
||||
|
||||
void SerializeHelper::writeSize(int s, ByteBuffer* buffer,
|
||||
void SerializeHelper::writeSize(std::size_t s, ByteBuffer* buffer,
|
||||
SerializableControl* flusher) {
|
||||
flusher->ensureBuffer(sizeof(int64)+1);
|
||||
SerializeHelper::writeSize(s, buffer);
|
||||
}
|
||||
|
||||
void SerializeHelper::writeSize(int s, ByteBuffer* buffer) {
|
||||
if(s==-1) // null
|
||||
void SerializeHelper::writeSize(std::size_t s, ByteBuffer* buffer) {
|
||||
if(s==(std::size_t)-1) // null // TODO remove
|
||||
buffer->putByte(-1);
|
||||
else if(s<254)
|
||||
buffer->putByte(s);
|
||||
@@ -41,7 +41,7 @@ namespace epics {
|
||||
}
|
||||
}
|
||||
|
||||
int SerializeHelper::readSize(ByteBuffer* buffer,
|
||||
std::size_t SerializeHelper::readSize(ByteBuffer* buffer,
|
||||
DeserializableControl* control) {
|
||||
control->ensureData(1);
|
||||
int8 b = buffer->getByte();
|
||||
@@ -54,17 +54,17 @@ namespace epics {
|
||||
return s;
|
||||
}
|
||||
else
|
||||
return (int)(b<0 ? b+256 : b);
|
||||
return (std::size_t)(b<0 ? b+256 : b);
|
||||
}
|
||||
|
||||
void SerializeHelper::serializeString(const String& value,
|
||||
ByteBuffer* buffer, SerializableControl* flusher) {
|
||||
int len = value.length();
|
||||
std::size_t len = value.length();
|
||||
SerializeHelper::writeSize(len, buffer, flusher);
|
||||
if (len<=0) return;
|
||||
int i = 0;
|
||||
std::size_t i = 0;
|
||||
while(true) {
|
||||
int maxToWrite = min(len-i, (int)buffer->getRemaining());
|
||||
std::size_t maxToWrite = min(len-i, buffer->getRemaining());
|
||||
buffer->put(value.data(), i, maxToWrite); // ASCII
|
||||
i += maxToWrite;
|
||||
if(i<len)
|
||||
@@ -75,19 +75,19 @@ namespace epics {
|
||||
}
|
||||
|
||||
void SerializeHelper::serializeSubstring(const String& value,
|
||||
int offset, int count, ByteBuffer* buffer,
|
||||
std::size_t offset, std::size_t count, ByteBuffer* buffer,
|
||||
SerializableControl* flusher) {
|
||||
if(offset<0)
|
||||
offset = 0;
|
||||
else if(offset>(int)value.length()) offset = value.length();
|
||||
else if(offset>(std::size_t)value.length()) offset = value.length();
|
||||
|
||||
if(offset+count>(int)value.length()) count = value.length()-offset;
|
||||
if(offset+count>(std::size_t)value.length()) count = value.length()-offset;
|
||||
|
||||
SerializeHelper::writeSize(count, buffer, flusher);
|
||||
if (count<=0) return;
|
||||
int i = 0;
|
||||
std::size_t i = 0;
|
||||
while(true) {
|
||||
int maxToWrite = min(count-i, (int)buffer->getRemaining());
|
||||
std::size_t maxToWrite = min(count-i, buffer->getRemaining());
|
||||
buffer->put(value.data(), offset+i, maxToWrite); // ASCII
|
||||
i += maxToWrite;
|
||||
if(i<count)
|
||||
@@ -102,13 +102,13 @@ namespace epics {
|
||||
String SerializeHelper::deserializeString(ByteBuffer* buffer,
|
||||
DeserializableControl* control) {
|
||||
|
||||
int size = SerializeHelper::readSize(buffer, control);
|
||||
if(size>0)
|
||||
std::size_t size = SerializeHelper::readSize(buffer, control);
|
||||
if(size!=(size_t)-1) // TODO null strings check, to be removed in the future
|
||||
{
|
||||
if ((int)buffer->getRemaining()>=size)
|
||||
if (buffer->getRemaining()>=size)
|
||||
{
|
||||
// entire string is in buffer, simply create a string out of it (copy)
|
||||
int pos = buffer->getPosition();
|
||||
std::size_t pos = buffer->getPosition();
|
||||
String str(buffer->getArray()+pos, size);
|
||||
buffer->setPosition(pos+size);
|
||||
return str;
|
||||
@@ -118,10 +118,10 @@ namespace epics {
|
||||
String str;
|
||||
str.reserve(size);
|
||||
try {
|
||||
int i = 0;
|
||||
std::size_t i = 0;
|
||||
while(true) {
|
||||
int toRead = min(size-i, (int)buffer->getRemaining());
|
||||
int pos = buffer->getPosition();
|
||||
std::size_t toRead = min(size-i, buffer->getRemaining());
|
||||
std::size_t pos = buffer->getPosition();
|
||||
str.append(buffer->getArray()+pos, toRead);
|
||||
buffer->setPosition(pos+toRead);
|
||||
i += toRead;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/*
|
||||
@@ -31,7 +31,7 @@ namespace epics {
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
*/
|
||||
static void writeSize(int s, ByteBuffer* buffer,
|
||||
static void writeSize(std::size_t s, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
@@ -40,7 +40,7 @@ namespace epics {
|
||||
* @param[in] buffer deserialization buffer.
|
||||
* @returns array size.
|
||||
*/
|
||||
static int readSize(ByteBuffer* buffer,
|
||||
static std::size_t readSize(ByteBuffer* buffer,
|
||||
DeserializableControl* control);
|
||||
|
||||
/**
|
||||
@@ -62,8 +62,8 @@ namespace epics {
|
||||
* @param[in] buffer serialization buffer
|
||||
* @param[in] flusher flusher
|
||||
*/
|
||||
static void serializeSubstring(const String& value, int offset,
|
||||
int count, ByteBuffer* buffer,
|
||||
static void serializeSubstring(const String& value, std::size_t offset,
|
||||
std::size_t count, ByteBuffer* buffer,
|
||||
SerializableControl* flusher);
|
||||
|
||||
/**
|
||||
@@ -93,7 +93,7 @@ namespace epics {
|
||||
* @param[in] s size to encode
|
||||
* @param[in] buffer serialization buffer
|
||||
*/
|
||||
static void writeSize(int s, ByteBuffer* buffer);
|
||||
static void writeSize(std::size_t s, ByteBuffer* buffer);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author Michael DavidSaver
|
||||
*/
|
||||
|
||||
#ifndef SHAREDPTR_H
|
||||
#define SHAREDPTR_H
|
||||
@@ -23,7 +26,7 @@
|
||||
|
||||
// where should we look?
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__>=4
|
||||
#if defined(__GNUC__) && __GNUC__>=4 && !defined(__vxworks)
|
||||
// GCC >=4.0.0
|
||||
# define SHARED_FROM_TR1
|
||||
|
||||
@@ -47,6 +50,12 @@
|
||||
# include <tr1/memory>
|
||||
|
||||
#elif defined(SHARED_FROM_BOOST)
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ < 3
|
||||
#define BOOST_EXCEPTION_DISABLE
|
||||
#define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#endif
|
||||
|
||||
# include <boost/tr1/memory.hpp>
|
||||
|
||||
#else
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*pvData.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <pv/status.h>
|
||||
#include <pv/epicsException.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
@@ -13,17 +16,17 @@ namespace epics { namespace pvData {
|
||||
const char* Status::StatusTypeName[] = { "OK", "WARNING", "ERROR", "FATAL" };
|
||||
epics::pvData::String Status::m_emptyString;
|
||||
|
||||
Status Status::OK;
|
||||
Status Status::Ok;
|
||||
|
||||
//PVDATA_REFCOUNT_MONITOR_DEFINE(status);
|
||||
|
||||
Status::Status() :
|
||||
m_type(STATUSTYPE_OK)
|
||||
m_statusType(STATUSTYPE_OK)
|
||||
{
|
||||
}
|
||||
|
||||
Status::Status(StatusType type, String message) :
|
||||
m_type(type), m_message(message)
|
||||
Status::Status(StatusType type, String const & message) :
|
||||
m_statusType(type), m_message(message)
|
||||
{
|
||||
if (type == STATUSTYPE_OK)
|
||||
throw std::invalid_argument("type == STATUSTYPE_OK");
|
||||
@@ -31,8 +34,8 @@ Status::Status(StatusType type, String message) :
|
||||
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
|
||||
}
|
||||
|
||||
Status::Status(StatusType type, String message, String stackDump) :
|
||||
m_type(type), m_message(message), m_stackDump(stackDump)
|
||||
Status::Status(StatusType type, String const & message, String const & stackDump) :
|
||||
m_statusType(type), m_message(message), m_stackDump(stackDump)
|
||||
{
|
||||
if (type == STATUSTYPE_OK)
|
||||
throw std::invalid_argument("type == STATUSTYPE_OK");
|
||||
@@ -46,7 +49,7 @@ Status::~Status() {
|
||||
|
||||
Status::StatusType Status::getType() const
|
||||
{
|
||||
return m_type;
|
||||
return m_statusType;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,25 +65,25 @@ epics::pvData::String Status::getStackDump() const
|
||||
|
||||
bool Status::isOK() const
|
||||
{
|
||||
return (m_type == STATUSTYPE_OK);
|
||||
return (m_statusType == STATUSTYPE_OK);
|
||||
}
|
||||
|
||||
bool Status::isSuccess() const
|
||||
{
|
||||
return (m_type == STATUSTYPE_OK || m_type == STATUSTYPE_WARNING);
|
||||
return (m_statusType == STATUSTYPE_OK || m_statusType == STATUSTYPE_WARNING);
|
||||
}
|
||||
|
||||
void Status::serialize(ByteBuffer *buffer, SerializableControl *flusher) const
|
||||
{
|
||||
flusher->ensureBuffer(1);
|
||||
if (m_type == STATUSTYPE_OK)
|
||||
if (m_statusType == STATUSTYPE_OK)
|
||||
{
|
||||
// special code for okStatus (optimization)
|
||||
buffer->putByte((int8)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->putByte((int8)m_type);
|
||||
buffer->putByte((int8)m_statusType);
|
||||
SerializeHelper::serializeString(m_message, buffer, flusher);
|
||||
SerializeHelper::serializeString(m_stackDump, buffer, flusher);
|
||||
}
|
||||
@@ -93,15 +96,15 @@ void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
|
||||
if (typeCode == (int8)-1)
|
||||
{
|
||||
// in most of the cases status will be OK, we statistically optimize
|
||||
if (m_type != STATUSTYPE_OK)
|
||||
if (m_statusType != STATUSTYPE_OK)
|
||||
{
|
||||
m_type = STATUSTYPE_OK;
|
||||
m_statusType = STATUSTYPE_OK;
|
||||
m_message = m_stackDump = m_emptyString;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = (StatusType)typeCode;
|
||||
m_statusType = (StatusType)typeCode;
|
||||
m_message = SerializeHelper::deserializeString(buffer, flusher);
|
||||
m_stackDump = SerializeHelper::deserializeString(buffer, flusher);
|
||||
}
|
||||
@@ -117,7 +120,7 @@ String Status::toString() const
|
||||
void Status::toString(StringBuilder buffer, int indentLevel) const
|
||||
{
|
||||
*buffer += "Status [type=";
|
||||
*buffer += StatusTypeName[m_type];
|
||||
*buffer += StatusTypeName[m_statusType];
|
||||
if (!m_message.empty())
|
||||
{
|
||||
*buffer += ", message=";
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* status.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mse
|
||||
*/
|
||||
#ifndef STATUS_H
|
||||
#define STATUS_H
|
||||
|
||||
@@ -36,7 +39,7 @@ namespace epics { namespace pvData {
|
||||
|
||||
static const char* StatusTypeName[];
|
||||
|
||||
static Status OK;
|
||||
static Status Ok;
|
||||
|
||||
/**
|
||||
* Creates OK status; STATUSTYPE_OK, empty message and stackDump.
|
||||
@@ -46,12 +49,12 @@ namespace epics { namespace pvData {
|
||||
/**
|
||||
* Create non-OK status.
|
||||
*/
|
||||
Status(StatusType type, epics::pvData::String message);
|
||||
Status(StatusType type, epics::pvData::String const & message);
|
||||
|
||||
/**
|
||||
* Create non-OK status.
|
||||
*/
|
||||
Status(StatusType type, epics::pvData::String message, epics::pvData::String stackDump);
|
||||
Status(StatusType type, epics::pvData::String const & message, epics::pvData::String const & stackDump);
|
||||
|
||||
~Status();
|
||||
|
||||
@@ -98,7 +101,7 @@ namespace epics { namespace pvData {
|
||||
|
||||
static epics::pvData::String m_emptyString;
|
||||
|
||||
StatusType m_type;
|
||||
StatusType m_statusType;
|
||||
String m_message;
|
||||
String m_stackDump;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* thread.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef THREAD_H
|
||||
#define THREAD_H
|
||||
#include <memory>
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
/* timeFunction.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#include <pv/noDefaultMethods.h>
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/timeFunction.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
TimeFunction::TimeFunction(TimeFunctionRequester *requester)
|
||||
TimeFunction::TimeFunction(TimeFunctionRequesterPtr const &requester)
|
||||
: requester(requester) {}
|
||||
|
||||
|
||||
|
||||
@@ -1,29 +1,39 @@
|
||||
/* timeFunction.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef TIMEFUNCTION_H
|
||||
#define TIMEFUNCTION_H
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class TimeFunctionRequester;
|
||||
class TimeFunction;
|
||||
typedef std::tr1::shared_ptr<TimeFunctionRequester> TimeFunctionRequesterPtr;
|
||||
typedef std::tr1::shared_ptr<TimeFunction> TimeFunctionPtr;
|
||||
|
||||
class TimeFunctionRequester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(TimeFunctionRequester);
|
||||
virtual ~TimeFunctionRequester(){}
|
||||
virtual void function() = 0;
|
||||
};
|
||||
|
||||
class TimeFunction : private NoDefaultMethods {
|
||||
|
||||
class TimeFunction {
|
||||
public:
|
||||
TimeFunction(TimeFunctionRequester *requester);
|
||||
POINTER_DEFINITIONS(TimeFunction);
|
||||
TimeFunction(TimeFunctionRequesterPtr const & requester);
|
||||
~TimeFunction();
|
||||
double timeCall();
|
||||
private:
|
||||
TimeFunctionRequester *requester;
|
||||
TimeFunctionRequesterPtr requester;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* timer.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -11,224 +14,201 @@
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
#include <pv/linkedList.h>
|
||||
#include <pv/thread.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/timer.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/convert.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(timerNode);
|
||||
PVDATA_REFCOUNT_MONITOR_DEFINE(timer);
|
||||
TimerCallback::TimerCallback()
|
||||
: period(0.0),
|
||||
onList(false)
|
||||
{
|
||||
}
|
||||
|
||||
typedef LinkedListNode<TimerNode::Pvt> TimerListNode;
|
||||
typedef LinkedList<TimerNode::Pvt> TimerList;
|
||||
|
||||
class TimerNode::Pvt {
|
||||
public:
|
||||
TimerNode *timerNode;
|
||||
TimerCallback *callback;
|
||||
TimerListNode timerListNode;
|
||||
TimeStamp timeToRun;
|
||||
Timer::Pvt *timerPvt;
|
||||
double period;
|
||||
Pvt(TimerNode &timerNode,TimerCallback &callback);
|
||||
~Pvt(){}
|
||||
private:
|
||||
};
|
||||
|
||||
TimerNode::Pvt::Pvt(TimerNode &timerNode,TimerCallback &callback)
|
||||
: timerNode(&timerNode),callback(&callback),
|
||||
timerListNode(*this),timeToRun(),
|
||||
timerPvt(0), period(0.0)
|
||||
{}
|
||||
|
||||
struct Timer::Pvt : public Runnable{
|
||||
public:
|
||||
Pvt(String threadName,ThreadPriority priority);
|
||||
virtual void run();
|
||||
public: // only used by this source module
|
||||
TimerList timerList;
|
||||
Mutex mutex;
|
||||
Event waitForWork;
|
||||
Event waitForDone;
|
||||
bool alive;
|
||||
Thread thread;
|
||||
void addElement(TimerNode::Pvt &node);
|
||||
};
|
||||
|
||||
Timer::Pvt::Pvt(String threadName,ThreadPriority priority)
|
||||
: timerList(),
|
||||
mutex(),
|
||||
waitForWork(false),
|
||||
Timer::Timer(String threadName,ThreadPriority priority)
|
||||
: waitForWork(false),
|
||||
waitForDone(false),
|
||||
alive(true),
|
||||
thread(threadName,priority,this)
|
||||
{}
|
||||
|
||||
void Timer::Pvt::addElement(TimerNode::Pvt &node)
|
||||
void Timer::addElement(TimerCallbackPtr const & timerCallback)
|
||||
{
|
||||
TimerListNode *nextNode = timerList.getHead();
|
||||
if(nextNode==0) {
|
||||
timerList.addTail(node.timerListNode);
|
||||
timerCallback->onList = true;
|
||||
if(head.get()==NULL) {
|
||||
head = timerCallback;
|
||||
timerCallback->next.reset();
|
||||
return;
|
||||
}
|
||||
TimerCallbackPtr nextNode(head);
|
||||
TimerCallbackPtr prevNode;
|
||||
while(true) {
|
||||
TimerNode::Pvt &timerListNode = nextNode->getObject();
|
||||
if((node.timeToRun)<(timerListNode.timeToRun)) {
|
||||
timerList.insertBefore(timerListNode.timerListNode,node.timerListNode);
|
||||
return;
|
||||
}
|
||||
nextNode = timerList.getNext(timerListNode.timerListNode);
|
||||
if(nextNode==0) {
|
||||
timerList.addTail(node.timerListNode);
|
||||
if(timerCallback->timeToRun < nextNode->timeToRun) {
|
||||
if(prevNode.get()!=NULL) {
|
||||
prevNode->next = timerCallback;
|
||||
} else {
|
||||
head = timerCallback;
|
||||
}
|
||||
timerCallback->next = nextNode;
|
||||
return;
|
||||
}
|
||||
if(nextNode->next.get()==NULL) {
|
||||
nextNode->next = timerCallback;
|
||||
timerCallback->next.reset();
|
||||
return;
|
||||
}
|
||||
prevNode = nextNode;
|
||||
nextNode = nextNode->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TimerNode::TimerNode(TimerCallback &callback)
|
||||
: pImpl(new Pvt(*this,callback))
|
||||
void Timer::cancel(TimerCallbackPtr const &timerCallback)
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(timerNode);
|
||||
Lock xx(mutex);
|
||||
if(!timerCallback->onList) return;
|
||||
TimerCallbackPtr nextNode(head);
|
||||
TimerCallbackPtr prevNode;
|
||||
while(true) {
|
||||
if(nextNode.get()==timerCallback.get()) {
|
||||
if(prevNode.get()!=NULL) {
|
||||
prevNode->next = timerCallback->next;
|
||||
} else {
|
||||
head = timerCallback->next;
|
||||
}
|
||||
timerCallback->next.reset();
|
||||
timerCallback->onList = false;
|
||||
return;
|
||||
}
|
||||
prevNode = nextNode;
|
||||
nextNode = nextNode->next;
|
||||
}
|
||||
throw std::logic_error(String(""));
|
||||
}
|
||||
|
||||
bool Timer::isScheduled(TimerCallbackPtr const &timerCallback)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
return timerCallback->onList;
|
||||
}
|
||||
|
||||
|
||||
TimerNode::~TimerNode()
|
||||
{
|
||||
cancel();
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(timerNode);
|
||||
}
|
||||
|
||||
void TimerNode::cancel()
|
||||
{
|
||||
Timer::Pvt *timerPvt = pImpl->timerPvt;
|
||||
if(timerPvt==0) return;
|
||||
Lock xx(timerPvt->mutex);
|
||||
if(pImpl->timerPvt==0) return;
|
||||
pImpl->timerPvt->timerList.remove(pImpl->timerListNode);
|
||||
pImpl->timerPvt = 0;
|
||||
}
|
||||
|
||||
bool TimerNode::isScheduled()
|
||||
{
|
||||
Timer::Pvt *pvt = pImpl->timerPvt;
|
||||
if(pvt==0) return false;
|
||||
Lock xx(pvt->mutex);
|
||||
return pImpl->timerListNode.isOnList();
|
||||
}
|
||||
|
||||
|
||||
void Timer::Pvt::run()
|
||||
void Timer::run()
|
||||
{
|
||||
TimeStamp currentTime;
|
||||
while(true) {
|
||||
currentTime.getCurrent();
|
||||
TimeStamp *timeToRun = 0;
|
||||
double period = 0.0;
|
||||
TimerNode::Pvt *nodeToCall = 0;
|
||||
TimerCallbackPtr nodeToCall;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
currentTime.getCurrent();
|
||||
if (!alive) break;
|
||||
TimerListNode *timerListNode = timerList.getHead();
|
||||
if(timerListNode!=0) {
|
||||
TimerNode::Pvt *timerNodePvt = &timerListNode->getObject();
|
||||
timeToRun = &timerNodePvt->timeToRun;
|
||||
TimerCallbackPtr timerCallback = head;
|
||||
if(timerCallback.get()!=NULL) {
|
||||
double diff = TimeStamp::diff(
|
||||
*timeToRun,currentTime);
|
||||
timerCallback->timeToRun,currentTime);
|
||||
if(diff<=0.0) {
|
||||
nodeToCall = timerNodePvt;
|
||||
timerList.removeHead();
|
||||
period = timerNodePvt->period;
|
||||
nodeToCall = timerCallback;
|
||||
nodeToCall->onList = false;
|
||||
head = head->next;
|
||||
period = timerCallback->period;
|
||||
if(period>0.0) {
|
||||
timerNodePvt->timeToRun += period;
|
||||
addElement(*timerNodePvt);
|
||||
} else {
|
||||
timerNodePvt->timerPvt = 0;
|
||||
}
|
||||
timerListNode = timerList.getHead();
|
||||
if(timerListNode!=0) {
|
||||
timerNodePvt = &timerListNode->getObject();
|
||||
timeToRun = &timerNodePvt->timeToRun;
|
||||
} else {
|
||||
timeToRun = 0;
|
||||
timerCallback->timeToRun += period;
|
||||
addElement(timerCallback);
|
||||
}
|
||||
timerCallback = head;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(nodeToCall!=0) {
|
||||
nodeToCall->callback->callback();
|
||||
if(nodeToCall.get()!=NULL) {
|
||||
nodeToCall->callback();
|
||||
}
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(!alive) break;
|
||||
}
|
||||
if(timeToRun==0) {
|
||||
if(head.get()==NULL) {
|
||||
waitForWork.wait();
|
||||
} else {
|
||||
double delay = TimeStamp::diff(*timeToRun,currentTime);
|
||||
double delay = TimeStamp::diff(head->timeToRun,currentTime);
|
||||
waitForWork.wait(delay);
|
||||
}
|
||||
}
|
||||
waitForDone.signal();
|
||||
}
|
||||
|
||||
Timer::Timer(String threadName, ThreadPriority priority)
|
||||
: pImpl(new Pvt(threadName,priority))
|
||||
{
|
||||
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(timer);
|
||||
}
|
||||
|
||||
Timer::~Timer() {
|
||||
{
|
||||
Lock xx(pImpl->mutex);
|
||||
pImpl->alive = false;
|
||||
Lock xx(mutex);
|
||||
alive = false;
|
||||
}
|
||||
pImpl->waitForWork.signal();
|
||||
pImpl->waitForDone.wait();
|
||||
TimerListNode *node = 0;
|
||||
while((node = pImpl->timerList.removeHead())!=0) {
|
||||
node->getObject().callback->timerStopped();
|
||||
waitForWork.signal();
|
||||
waitForDone.wait();
|
||||
TimerCallbackPtr timerCallback;
|
||||
while(true) {
|
||||
timerCallback = head;
|
||||
if(head.get()==NULL) break;
|
||||
head->timerStopped();
|
||||
head = timerCallback->next;
|
||||
timerCallback->next.reset();
|
||||
timerCallback->onList = false;
|
||||
}
|
||||
PVDATA_REFCOUNT_MONITOR_DESTRUCT(timer);
|
||||
}
|
||||
|
||||
void Timer::scheduleAfterDelay(TimerNode &timerNode,double delay)
|
||||
void Timer::scheduleAfterDelay(
|
||||
TimerCallbackPtr const &timerCallback,
|
||||
double delay)
|
||||
{
|
||||
schedulePeriodic(timerNode,delay,0.0);
|
||||
schedulePeriodic(timerCallback,delay,0.0);
|
||||
}
|
||||
void Timer::schedulePeriodic(TimerNode &timerNode,double delay,double period)
|
||||
|
||||
void Timer::schedulePeriodic(
|
||||
TimerCallbackPtr const &timerCallback,
|
||||
double delay,
|
||||
double period)
|
||||
{
|
||||
TimerNode::Pvt *timerNodePvt = timerNode.pImpl.get();
|
||||
if(timerNodePvt->timerListNode.isOnList()) {
|
||||
if(isScheduled(timerCallback)) {
|
||||
throw std::logic_error(String("already queued"));
|
||||
}
|
||||
{
|
||||
Lock xx(pImpl->mutex);
|
||||
if(!pImpl->alive) {
|
||||
timerNodePvt->callback->timerStopped();
|
||||
Lock xx(mutex);
|
||||
if(!alive) {
|
||||
timerCallback->timerStopped();
|
||||
return;
|
||||
}
|
||||
}
|
||||
TimeStamp *timeStamp = &timerNodePvt->timeToRun;
|
||||
timeStamp->getCurrent();
|
||||
*timeStamp += delay;
|
||||
timerNodePvt->period = period;
|
||||
TimeStamp timeStamp;
|
||||
timeStamp.getCurrent();
|
||||
timeStamp += delay;
|
||||
timerCallback->timeToRun.getCurrent();
|
||||
timerCallback->timeToRun += delay;
|
||||
timerCallback->period = period;
|
||||
bool isFirst = false;
|
||||
{
|
||||
Lock xx(pImpl->mutex);
|
||||
timerNodePvt->timerPvt = pImpl.get();
|
||||
pImpl->addElement(*timerNodePvt);
|
||||
TimerNode::Pvt *first = &pImpl->timerList.getHead()->getObject();
|
||||
if(first==timerNodePvt) isFirst = true;
|
||||
Lock xx(mutex);
|
||||
addElement(timerCallback);
|
||||
if(timerCallback.get()==head.get()) isFirst = true;
|
||||
}
|
||||
if(isFirst) pImpl->waitForWork.signal();
|
||||
if(isFirst) waitForWork.signal();
|
||||
}
|
||||
|
||||
void Timer::toString(StringBuilder builder)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(!alive) return;
|
||||
TimeStamp currentTime;
|
||||
TimerCallbackPtr nodeToCall(head);
|
||||
currentTime.getCurrent();
|
||||
while(true) {
|
||||
if(nodeToCall.get()==NULL) return;
|
||||
TimeStamp timeToRun = nodeToCall->timeToRun;
|
||||
double period = nodeToCall->period;
|
||||
double diff = TimeStamp::diff(timeToRun,currentTime);
|
||||
char buffer[50];
|
||||
sprintf(buffer,"timeToRun %f period %f\n",diff,period);
|
||||
*builder += buffer;
|
||||
nodeToCall = nodeToCall->next;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* timer.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
#include <memory>
|
||||
@@ -15,44 +18,57 @@
|
||||
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/thread.h>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class TimerCallback;
|
||||
class Timer;
|
||||
typedef std::tr1::shared_ptr<TimerCallback> TimerCallbackPtr;
|
||||
typedef std::tr1::shared_ptr<Timer> TimerPtr;
|
||||
|
||||
class TimerCallback {
|
||||
public:
|
||||
POINTER_DEFINITIONS(TimerCallback);
|
||||
TimerCallback();
|
||||
virtual ~TimerCallback(){}
|
||||
virtual void callback() = 0;
|
||||
virtual void timerStopped() = 0;
|
||||
};
|
||||
|
||||
class TimerNode {
|
||||
public:
|
||||
TimerNode(TimerCallback &timerCallback);
|
||||
~TimerNode();
|
||||
void cancel();
|
||||
bool isScheduled();
|
||||
class Pvt;
|
||||
private:
|
||||
std::auto_ptr<Pvt> pImpl;
|
||||
TimerCallbackPtr next;
|
||||
TimeStamp timeToRun;
|
||||
double period;
|
||||
bool onList;
|
||||
friend class Timer;
|
||||
};
|
||||
|
||||
class Timer : private NoDefaultMethods {
|
||||
class Timer : public Runnable {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Timer);
|
||||
|
||||
Timer(String threadName, ThreadPriority priority);
|
||||
~Timer();
|
||||
void scheduleAfterDelay(TimerNode &timerNode,double delay);
|
||||
void schedulePeriodic(TimerNode &timerNode,double delay,double period);
|
||||
|
||||
class Pvt;
|
||||
virtual ~Timer();
|
||||
virtual void run();
|
||||
void scheduleAfterDelay(
|
||||
TimerCallbackPtr const &timerCallback,
|
||||
double delay);
|
||||
void schedulePeriodic(
|
||||
TimerCallbackPtr const &timerCallback,
|
||||
double delay,
|
||||
double period);
|
||||
void cancel(TimerCallbackPtr const &timerCallback);
|
||||
bool isScheduled(TimerCallbackPtr const &timerCallback);
|
||||
void toString(StringBuilder builder);
|
||||
private:
|
||||
std::auto_ptr<Pvt> pImpl;
|
||||
void addElement(TimerCallbackPtr const &timerCallback);
|
||||
TimerCallbackPtr head;
|
||||
Mutex mutex;
|
||||
Event waitForWork;
|
||||
Event waitForDone;
|
||||
bool alive;
|
||||
Thread thread;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* monitor.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef MONITOR_H
|
||||
#define MONITOR_H
|
||||
|
||||
@@ -15,92 +18,92 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class MonitorElement;
|
||||
typedef std::tr1::shared_ptr<MonitorElement> MonitorElementPtr;
|
||||
typedef std::vector<MonitorElementPtr> MonitorElementPtrArray;
|
||||
|
||||
class Monitor;
|
||||
typedef std::tr1::shared_ptr<Monitor> MonitorPtr;
|
||||
|
||||
|
||||
/**
|
||||
* Class instance representing monitor element.
|
||||
* @author mrk
|
||||
*/
|
||||
class MonitorElement {
|
||||
public:
|
||||
POINTER_DEFINITIONS(MonitorElement);
|
||||
MonitorElement(){}
|
||||
MonitorElement(PVStructurePtr const & pvStructurePtr)
|
||||
: pvStructurePtr(pvStructurePtr),
|
||||
changedBitSet(BitSet::create(pvStructurePtr->getNumberFields())),
|
||||
overrunBitSet(BitSet::create(pvStructurePtr->getNumberFields()))
|
||||
{}
|
||||
PVStructurePtr pvStructurePtr;
|
||||
BitSet::shared_pointer changedBitSet;
|
||||
BitSet::shared_pointer overrunBitSet;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for Monitor.
|
||||
* @author mrk
|
||||
*/
|
||||
class Monitor : public Destroyable{
|
||||
public:
|
||||
POINTER_DEFINITIONS(Monitor);
|
||||
virtual ~Monitor(){}
|
||||
/**
|
||||
* Class instance representing monitor element.
|
||||
* @author mrk
|
||||
* Start monitoring.
|
||||
* @return completion status.
|
||||
*/
|
||||
class MonitorElement {
|
||||
public:
|
||||
POINTER_DEFINITIONS(MonitorElement);
|
||||
virtual ~MonitorElement(){}
|
||||
/**
|
||||
* Get the PVStructure.
|
||||
* @return The PVStructure.
|
||||
*/
|
||||
virtual PVStructure::shared_pointer const & getPVStructure() = 0;
|
||||
/**
|
||||
* Get the bitSet showing which fields have changed.
|
||||
* @return The bitSet.
|
||||
*/
|
||||
virtual BitSet::shared_pointer const & getChangedBitSet() = 0;
|
||||
/**
|
||||
* Get the bitSet showing which fields have been changed more than once.
|
||||
* @return The bitSet.
|
||||
*/
|
||||
virtual BitSet::shared_pointer const & getOverrunBitSet() = 0;
|
||||
};
|
||||
|
||||
|
||||
virtual Status start() = 0;
|
||||
/**
|
||||
* Interface for Monitor.
|
||||
* @author mrk
|
||||
* Stop Monitoring.
|
||||
* @return completion status.
|
||||
*/
|
||||
class Monitor : public Destroyable, private NoDefaultMethods {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Monitor);
|
||||
virtual ~Monitor(){}
|
||||
/**
|
||||
* Start monitoring.
|
||||
* @return completion status.
|
||||
*/
|
||||
virtual Status start() = 0;
|
||||
/**
|
||||
* Stop Monitoring.
|
||||
* @return completion status.
|
||||
*/
|
||||
virtual Status stop() = 0;
|
||||
/**
|
||||
* If monitor has occurred return data.
|
||||
* @return monitorElement for modified data.
|
||||
* Must call get to determine if data is available.
|
||||
*/
|
||||
virtual MonitorElement::shared_pointer const & poll() = 0;
|
||||
/**
|
||||
* Release a MonitorElement that was returned by poll.
|
||||
* @param monitorElement
|
||||
*/
|
||||
virtual void release(MonitorElement::shared_pointer const & monitorElement) = 0;
|
||||
};
|
||||
|
||||
|
||||
virtual Status stop() = 0;
|
||||
/**
|
||||
* Requester for ChannelMonitor.
|
||||
* @author mrk
|
||||
* If monitor has occurred return data.
|
||||
* @return monitorElement for modified data.
|
||||
* Must call get to determine if data is available.
|
||||
*/
|
||||
class MonitorRequester : public virtual Requester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(MonitorRequester);
|
||||
virtual ~MonitorRequester(){}
|
||||
/**
|
||||
* The client and server have both completed the createMonitor request.
|
||||
* @param status Completion status.
|
||||
* @param monitor The monitor
|
||||
* @param structure The structure defining the data.
|
||||
*/
|
||||
virtual void monitorConnect(Status const &status,
|
||||
Monitor::shared_pointer const & monitor, StructureConstPtr const & structure) = 0;
|
||||
/**
|
||||
* A monitor event has occurred.
|
||||
* The requester must call Monitor.poll to get data.
|
||||
* @param monitor The monitor.
|
||||
*/
|
||||
virtual void monitorEvent(Monitor::shared_pointer const &monitor) = 0;
|
||||
/**
|
||||
* The data source is no longer available.
|
||||
* @param monitor The monitor.
|
||||
*/
|
||||
virtual void unlisten(Monitor::shared_pointer const &monitor) = 0;
|
||||
};
|
||||
virtual MonitorElementPtr poll() = 0;
|
||||
/**
|
||||
* Release a MonitorElement that was returned by poll.
|
||||
* @param monitorElement
|
||||
*/
|
||||
virtual void release(MonitorElementPtr const & monitorElement) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Requester for ChannelMonitor.
|
||||
* @author mrk
|
||||
*/
|
||||
class MonitorRequester : public virtual Requester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(MonitorRequester);
|
||||
virtual ~MonitorRequester(){}
|
||||
/**
|
||||
* The client and server have both completed the createMonitor request.
|
||||
* @param status Completion status.
|
||||
* @param monitor The monitor
|
||||
* @param structure The structure defining the data.
|
||||
*/
|
||||
virtual void monitorConnect(Status const & status,
|
||||
MonitorPtr const & monitor, StructureConstPtr const & structure) = 0;
|
||||
/**
|
||||
* A monitor event has occurred.
|
||||
* The requester must call Monitor.poll to get data.
|
||||
* @param monitor The monitor.
|
||||
*/
|
||||
virtual void monitorEvent(MonitorPtr const & monitor) = 0;
|
||||
/**
|
||||
* The data source is no longer available.
|
||||
* @param monitor The monitor.
|
||||
*/
|
||||
virtual void unlisten(MonitorPtr const & monitor) = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* MONITOR_H */
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
/* monitorQueue.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/* Marty Kraimer 2011.03 */
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
#include <pv/monitorQueue.h>
|
||||
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
typedef QueueElement<MonitorElement::shared_pointer> MonitorQueueElement;
|
||||
|
||||
class MonitorElementImpl : public MonitorElement {
|
||||
public:
|
||||
MonitorElementImpl(PVStructure::shared_pointer pvStructure);
|
||||
~MonitorElementImpl(){}
|
||||
virtual PVStructure::shared_pointer const & getPVStructure();
|
||||
virtual BitSet::shared_pointer const & getChangedBitSet();
|
||||
virtual BitSet::shared_pointer const & getOverrunBitSet();
|
||||
void setQueueElement(MonitorQueueElement *queueElement);
|
||||
MonitorQueueElement *getQueueElement();
|
||||
private:
|
||||
PVStructure::shared_pointer pvStructure;
|
||||
BitSet::shared_pointer changedBitSet;
|
||||
BitSet::shared_pointer overrunBitSet;
|
||||
MonitorQueueElement *queueElement;
|
||||
};
|
||||
|
||||
MonitorElementImpl::MonitorElementImpl(PVStructure::shared_pointer pvStructure)
|
||||
: pvStructure(pvStructure),
|
||||
changedBitSet(BitSet::shared_pointer(
|
||||
new BitSet(pvStructure->getNumberFields()))),
|
||||
overrunBitSet(BitSet::shared_pointer(
|
||||
new BitSet(pvStructure->getNumberFields()))),
|
||||
queueElement(0)
|
||||
{}
|
||||
|
||||
PVStructure::shared_pointer const & MonitorElementImpl::getPVStructure()
|
||||
{
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
BitSet::shared_pointer const & MonitorElementImpl::getChangedBitSet()
|
||||
{
|
||||
return changedBitSet;
|
||||
}
|
||||
|
||||
BitSet::shared_pointer const & MonitorElementImpl::getOverrunBitSet()
|
||||
{
|
||||
return overrunBitSet;
|
||||
}
|
||||
|
||||
void MonitorElementImpl::setQueueElement(MonitorQueueElement *queueElement)
|
||||
{
|
||||
this->queueElement = queueElement;
|
||||
}
|
||||
|
||||
MonitorQueueElement *MonitorElementImpl::getQueueElement()
|
||||
{
|
||||
return queueElement;
|
||||
}
|
||||
|
||||
MonitorQueue::MonitorQueue(PVStructureSharedPointerPtrArray structures,int number)
|
||||
: number(number),
|
||||
structures(structures),
|
||||
queue(0),
|
||||
queueElements(new MonitorElement::shared_pointer*[number]),
|
||||
nullElement(MonitorElement::shared_pointer())
|
||||
{
|
||||
if(number<2) {
|
||||
throw std::logic_error(String("queueSize must be >=2"));
|
||||
}
|
||||
|
||||
for(int i=0; i<number; i++) {
|
||||
queueElements[i] = new MonitorElement::shared_pointer(
|
||||
new MonitorElementImpl(*structures[i]));
|
||||
}
|
||||
queue = new Queue<MonitorElement::shared_pointer>(queueElements,number);
|
||||
MonitorQueueElement *queueElement;
|
||||
for(int i=0; i<number;i++) {
|
||||
queueElement = queue->getFree();
|
||||
MonitorElementImpl * element = static_cast<MonitorElementImpl *>(
|
||||
queueElement->getObject()->get());
|
||||
element->setQueueElement(queueElement);
|
||||
queue->setUsed(queueElement);
|
||||
queue->releaseUsed(queueElement);
|
||||
}
|
||||
}
|
||||
|
||||
MonitorQueue::~MonitorQueue()
|
||||
{
|
||||
delete queue;
|
||||
for(int i=0; i<number; i++) {
|
||||
delete queueElements[i];
|
||||
}
|
||||
delete[] queueElements;
|
||||
for(int i=0; i<number; i++) delete structures[i];
|
||||
delete[] structures;
|
||||
}
|
||||
|
||||
PVStructureSharedPointerPtrArray MonitorQueue::createStructures(
|
||||
PVStructurePtrArray array,int number)
|
||||
{
|
||||
PVStructureSharedPointerPtrArray elements =
|
||||
new PVStructureSharedPointerPtr[number];
|
||||
for(int i=0; i<number; i++){
|
||||
elements[i] = new PVStructure::shared_pointer(array[i]);
|
||||
}
|
||||
delete[] array;
|
||||
return elements;
|
||||
}
|
||||
|
||||
void MonitorQueue::clear()
|
||||
{
|
||||
queue->clear();
|
||||
}
|
||||
|
||||
int MonitorQueue::getNumberFree()
|
||||
{
|
||||
return queue->getNumberFree();
|
||||
}
|
||||
|
||||
int MonitorQueue::capacity()
|
||||
{
|
||||
return number;
|
||||
}
|
||||
|
||||
MonitorElement::shared_pointer const & MonitorQueue::getFree()
|
||||
{
|
||||
MonitorQueueElement *queueElement = queue->getFree();
|
||||
if(queueElement==0) return nullElement;
|
||||
return *queueElement->getObject();
|
||||
}
|
||||
|
||||
void MonitorQueue::setUsed(MonitorElement::shared_pointer const & element)
|
||||
{
|
||||
MonitorElementImpl *impl = static_cast<MonitorElementImpl *>(element.get());
|
||||
queue->setUsed(impl->getQueueElement());
|
||||
}
|
||||
|
||||
MonitorElement::shared_pointer const & MonitorQueue::getUsed()
|
||||
{
|
||||
MonitorQueueElement *queueElement = queue->getUsed();
|
||||
if(queueElement==0) return nullElement;
|
||||
return *queueElement->getObject();
|
||||
}
|
||||
|
||||
void MonitorQueue::releaseUsed(MonitorElement::shared_pointer const & element)
|
||||
{
|
||||
MonitorElementImpl *impl = static_cast<MonitorElementImpl *>(element.get());
|
||||
queue->releaseUsed(impl->getQueueElement());
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/* monitorQueue.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/* Marty Kraimer 2011.03 */
|
||||
#ifndef MONITORQUEUE_H
|
||||
#define MONITORQUEUE_H
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/monitor.h>
|
||||
#include <pv/queue.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
typedef PVStructure::shared_pointer* PVStructureSharedPointerPtr;
|
||||
typedef PVStructureSharedPointerPtr* PVStructureSharedPointerPtrArray;
|
||||
|
||||
class MonitorQueue {
|
||||
public:
|
||||
MonitorQueue(PVStructureSharedPointerPtrArray structures,int number);
|
||||
~MonitorQueue();
|
||||
static PVStructureSharedPointerPtrArray createStructures(
|
||||
PVStructurePtrArray array,int number);
|
||||
void clear();
|
||||
int getNumberFree();
|
||||
int capacity();
|
||||
MonitorElement::shared_pointer const & getFree();
|
||||
void setUsed(MonitorElement::shared_pointer const & element);
|
||||
MonitorElement::shared_pointer const & getUsed();
|
||||
void releaseUsed(MonitorElement::shared_pointer const & element);
|
||||
private:
|
||||
int number;
|
||||
PVStructureSharedPointerPtrArray structures;
|
||||
Queue<MonitorElement::shared_pointer> *queue;
|
||||
MonitorElement::shared_pointer **queueElements;
|
||||
MonitorElement::shared_pointer nullElement;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* MONITORQUEUE_H */
|
||||
@@ -1,26 +1,21 @@
|
||||
/* alarm.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/alarm.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
const size_t severityCount = 5;
|
||||
static String severityNames[severityCount] =
|
||||
{
|
||||
String("NONE"),
|
||||
String("MINOR"),
|
||||
String("MAJOR"),
|
||||
String("INVALID"),
|
||||
String("UNDEFINED")
|
||||
};
|
||||
|
||||
AlarmSeverity AlarmSeverityFunc::getSeverity(int value)
|
||||
{
|
||||
@@ -37,8 +32,21 @@ AlarmSeverity AlarmSeverityFunc::getSeverity(int value)
|
||||
throw std::logic_error(String("should never get here"));
|
||||
}
|
||||
|
||||
StringArray AlarmSeverityFunc::getSeverityNames()
|
||||
StringArrayPtr AlarmSeverityFunc::getSeverityNames()
|
||||
{
|
||||
static size_t severityCount = 5;
|
||||
static StringArrayPtr severityNames;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
if(severityNames.get()==NULL) {
|
||||
severityNames = StringArrayPtr(new StringArray());
|
||||
severityNames->reserve(severityCount);
|
||||
severityNames->push_back("NONE");
|
||||
severityNames->push_back("MINOR");
|
||||
severityNames->push_back("MAJOR");
|
||||
severityNames->push_back("INVALID");
|
||||
severityNames->push_back("UNDEFINED");
|
||||
}
|
||||
return severityNames;
|
||||
}
|
||||
|
||||
@@ -54,19 +62,6 @@ AlarmSeverity Alarm::getSeverity() const
|
||||
throw std::logic_error(String("should never get here"));
|
||||
}
|
||||
|
||||
const size_t statusCount = 8;
|
||||
static String statusNames[statusCount] =
|
||||
{
|
||||
String("NONE"),
|
||||
String("DEVICE"),
|
||||
String("DRIVER"),
|
||||
String("RECORD"),
|
||||
String("DB"),
|
||||
String("CONF"),
|
||||
String("UNDEFINED"),
|
||||
String("CLIENT")
|
||||
};
|
||||
|
||||
AlarmStatus AlarmStatusFunc::getStatus(int value)
|
||||
{
|
||||
if(value<0 || value>7) {
|
||||
@@ -85,8 +80,24 @@ AlarmStatus AlarmStatusFunc::getStatus(int value)
|
||||
throw std::logic_error(String("should never get here"));
|
||||
}
|
||||
|
||||
StringArray AlarmStatusFunc::getStatusNames()
|
||||
StringArrayPtr AlarmStatusFunc::getStatusNames()
|
||||
{
|
||||
static size_t statusCount = 8;
|
||||
static StringArrayPtr statusNames;
|
||||
static Mutex mutex;
|
||||
Lock xx(mutex);
|
||||
if(statusNames.get()==NULL) {
|
||||
statusNames = StringArrayPtr(new StringArray());
|
||||
statusNames->reserve(statusCount);
|
||||
statusNames->push_back("NONE");
|
||||
statusNames->push_back("DEVICE");
|
||||
statusNames->push_back("DRIVER");
|
||||
statusNames->push_back("RECORD");
|
||||
statusNames->push_back("DB");
|
||||
statusNames->push_back("CONF");
|
||||
statusNames->push_back("UNDEFINED");
|
||||
statusNames->push_back("CLIENT");
|
||||
}
|
||||
return statusNames;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* alarm.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <pv/pvType.h>
|
||||
#ifndef ALARM_H
|
||||
@@ -24,14 +27,14 @@ extern const size_t severityCount;
|
||||
class AlarmSeverityFunc {
|
||||
public:
|
||||
static AlarmSeverity getSeverity(int value);
|
||||
static StringArray getSeverityNames();
|
||||
static StringArrayPtr getSeverityNames();
|
||||
};
|
||||
|
||||
extern const size_t statusCount;
|
||||
class AlarmStatusFunc {
|
||||
public:
|
||||
static AlarmStatus getStatus(int value);
|
||||
static StringArray getStatusNames();
|
||||
static StringArrayPtr getStatusNames();
|
||||
};
|
||||
|
||||
class Alarm {
|
||||
@@ -39,7 +42,7 @@ public:
|
||||
Alarm() : severity(0),status(0), message(String("")) {}
|
||||
//default constructors and destructor are OK
|
||||
String getMessage() const {return message;}
|
||||
void setMessage(String value) {message = value;}
|
||||
void setMessage(String const &value) {message = value;}
|
||||
AlarmSeverity getSeverity() const;
|
||||
void setSeverity(AlarmSeverity value) {severity = value;}
|
||||
AlarmStatus getStatus() const;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* control.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef CONTROL_H
|
||||
#define CONTROL_H
|
||||
namespace epics { namespace pvData {
|
||||
@@ -14,11 +17,14 @@ public:
|
||||
//default constructors and destructor are OK
|
||||
double getLow() const {return low;}
|
||||
double getHigh() const {return high;}
|
||||
double getMinStep() const {return minStep;}
|
||||
void setLow(double value) {low = value;}
|
||||
void setHigh(double value) {high = value;}
|
||||
void setMinStep(double value) {minStep = value;}
|
||||
private:
|
||||
double low;
|
||||
double high;
|
||||
double minStep;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* display.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/pvData.h>
|
||||
@@ -22,11 +25,11 @@ public:
|
||||
void setLow(double value){low = value;}
|
||||
void setHigh(double value){high = value;}
|
||||
String getDescription() const {return description;}
|
||||
void setDescription(String value) {description = value;}
|
||||
void setDescription(String const & value) {description = value;}
|
||||
String getFormat() const {return format;}
|
||||
void setFormat(String value) {format = value;}
|
||||
void setFormat(String const & value) {format = value;}
|
||||
String getUnits() const {return units;}
|
||||
void setUnits(String value) {units = value;}
|
||||
void setUnits(String const & value) {units = value;}
|
||||
private:
|
||||
String description;
|
||||
String format;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvAlarm.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <pv/pvType.h>
|
||||
@@ -12,71 +15,55 @@
|
||||
#include <pv/pvAlarm.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static String noAlarmFound("No alarm structure found");
|
||||
static String notAttached("Not attached to an alarm structure");
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
bool PVAlarm::attach(PVField *pvField)
|
||||
String PVAlarm::noAlarmFound("No alarm structure found");
|
||||
String PVAlarm::notAttached("Not attached to an alarm structure");
|
||||
|
||||
bool PVAlarm::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
PVStructure *pvStructure = 0;
|
||||
if(pvField->getField()->getFieldName().compare("alarm")!=0) {
|
||||
if(pvField->getField()->getFieldName().compare("value")!=0) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
PVStructure *pvParent = pvField->getParent();
|
||||
if(pvParent==0) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStructure = pvParent->getStructureField(String("alarm"));
|
||||
if(pvStructure==0) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStructure = static_cast<PVStructure*>(pvField);
|
||||
}
|
||||
PVInt *pvInt = pvStructure->getIntField(String("severity"));
|
||||
if(pvInt==0) {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvSeverity = pvInt;
|
||||
pvInt = pvStructure->getIntField(String("status"));
|
||||
if(pvInt==0) {
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvSeverity = pvStructure->getIntField("severity");
|
||||
if(pvSeverity.get()==NULL) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStatus = pvInt;
|
||||
PVString *pvString = pvStructure->getStringField(String("message"));
|
||||
if(pvInt==0) {
|
||||
pvStatus = pvStructure->getIntField("status");
|
||||
if(pvStatus.get()==NULL) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
pvSeverity.reset();
|
||||
return false;
|
||||
}
|
||||
pvMessage = pvStructure->getStringField("message");
|
||||
if(pvMessage.get()==NULL) {
|
||||
pvField->message(noAlarmFound,errorMessage);
|
||||
pvSeverity.reset();
|
||||
pvStatus.reset();
|
||||
return false;
|
||||
}
|
||||
pvMessage = pvString;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVAlarm::detach()
|
||||
{
|
||||
pvSeverity = 0;
|
||||
pvStatus = 0;
|
||||
pvMessage = 0;
|
||||
pvSeverity.reset();
|
||||
pvStatus.reset();
|
||||
pvMessage.reset();
|
||||
}
|
||||
|
||||
bool PVAlarm::isAttached()
|
||||
{
|
||||
if(pvSeverity==0 || pvMessage==0) return false;
|
||||
if(pvSeverity.get()==NULL) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVAlarm::get(Alarm & alarm) const
|
||||
{
|
||||
if(pvSeverity==0 || pvMessage==0) {
|
||||
if(pvSeverity.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
alarm.setSeverity(AlarmSeverityFunc::getSeverity(pvSeverity->get()));
|
||||
@@ -86,7 +73,7 @@ void PVAlarm::get(Alarm & alarm) const
|
||||
|
||||
bool PVAlarm::set(Alarm const & alarm)
|
||||
{
|
||||
if(pvSeverity==0 || pvMessage==0) {
|
||||
if(pvSeverity.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
if(pvSeverity->isImmutable() || pvMessage->isImmutable()) return false;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvAlarm.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef PVALARM_H
|
||||
#define PVALARM_H
|
||||
#include <string>
|
||||
@@ -15,11 +18,11 @@ namespace epics { namespace pvData {
|
||||
|
||||
class PVAlarm {
|
||||
public:
|
||||
PVAlarm() : pvSeverity(0),pvStatus(0),pvMessage(0) {}
|
||||
PVAlarm() {}
|
||||
//default constructors and destructor are OK
|
||||
//returns (false,true) if pvField(isNot, is valid enumerated structure
|
||||
//An automatic detach is issued if already attached.
|
||||
bool attach(PVField *pvField);
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
void detach();
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
@@ -27,9 +30,11 @@ public:
|
||||
void get(Alarm & alarm) const;
|
||||
bool set(Alarm const & alarm);
|
||||
private:
|
||||
PVInt *pvSeverity;
|
||||
PVInt *pvStatus;
|
||||
PVString *pvMessage;
|
||||
PVIntPtr pvSeverity;
|
||||
PVIntPtr pvStatus;
|
||||
PVStringPtr pvMessage;
|
||||
static String noAlarmFound;
|
||||
static String notAttached;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvControl.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <pv/pvType.h>
|
||||
@@ -12,64 +15,46 @@
|
||||
#include <pv/pvControl.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static String noControlFound("No control structure found");
|
||||
static String notAttached("Not attached to an control structure");
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
bool PVControl::attach(PVField *pvField)
|
||||
String PVControl::noControlFound("No control structure found");
|
||||
String PVControl::notAttached("Not attached to an control structure");
|
||||
|
||||
bool PVControl::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
PVStructure *pvStructure = 0;
|
||||
if(pvField->getField()->getFieldName().compare("control")!=0) {
|
||||
if(pvField->getField()->getFieldName().compare("value")!=0) {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
PVStructure *pvParent = pvField->getParent();
|
||||
if(pvParent==0) {
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStructure = pvParent->getStructureField(String("control"));
|
||||
if(pvStructure==0) {
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStructure = static_cast<PVStructure*>(pvField);
|
||||
}
|
||||
PVDouble *pvDouble = pvStructure->getDoubleField(String("limit.low"));
|
||||
if(pvDouble==0) {
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvLow = pvStructure->getDoubleField("limitLow");
|
||||
if(pvLow.get()==NULL) {
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvLow = pvDouble;
|
||||
pvDouble = pvStructure->getDoubleField(String("limit.high"));
|
||||
if(pvDouble==0) {
|
||||
pvLow = 0;
|
||||
pvHigh = pvStructure->getDoubleField(String("limitHigh"));
|
||||
if(pvHigh.get()==NULL) {
|
||||
pvLow.reset();
|
||||
pvField->message(noControlFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvHigh = pvDouble;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVControl::detach()
|
||||
{
|
||||
pvLow = 0;
|
||||
pvHigh = 0;
|
||||
pvLow.reset();
|
||||
pvHigh.reset();
|
||||
}
|
||||
|
||||
bool PVControl::isAttached(){
|
||||
if(pvLow==0 || pvHigh==0) return false;
|
||||
if(pvLow.get()==NULL) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVControl::get(Control &control) const
|
||||
{
|
||||
if(pvLow==0 || pvHigh==0) {
|
||||
if(pvLow.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
control.setLow(pvLow->get());
|
||||
@@ -78,7 +63,7 @@ void PVControl::get(Control &control) const
|
||||
|
||||
bool PVControl::set(Control const & control)
|
||||
{
|
||||
if(pvLow==0 || pvHigh==0) {
|
||||
if(pvLow.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
if(pvLow->isImmutable() || pvHigh->isImmutable()) return false;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvControl.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <pv/control.h>
|
||||
#include <pv/pvData.h>
|
||||
#ifndef PVCONTROL_H
|
||||
@@ -12,11 +15,11 @@ namespace epics { namespace pvData {
|
||||
|
||||
class PVControl {
|
||||
public:
|
||||
PVControl() : pvLow(0),pvHigh(0) {}
|
||||
PVControl(){}
|
||||
//default constructors and destructor are OK
|
||||
//returns (false,true) if pvField(isNot, is valid enumerated structure
|
||||
//An automatic detach is issued if already attached.
|
||||
bool attach(PVField *pvField);
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
void detach();
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
@@ -24,8 +27,10 @@ public:
|
||||
void get(Control &) const;
|
||||
bool set(Control const & control);
|
||||
private:
|
||||
PVDouble *pvLow;
|
||||
PVDouble *pvHigh;
|
||||
PVDoublePtr pvLow;
|
||||
PVDoublePtr pvHigh;
|
||||
static String noControlFound;
|
||||
static String notAttached;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvDisplay.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <pv/pvType.h>
|
||||
@@ -12,59 +15,43 @@
|
||||
#include <pv/pvDisplay.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static String noDisplayFound("No display structure found");
|
||||
static String notAttached("Not attached to an display structure");
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
bool PVDisplay::attach(PVField *pvField)
|
||||
String PVDisplay::noDisplayFound("No display structure found");
|
||||
String PVDisplay::notAttached("Not attached to an display structure");
|
||||
|
||||
bool PVDisplay::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
PVStructure *pvStructure = 0;
|
||||
if(pvField->getField()->getFieldName().compare("display")!=0) {
|
||||
if(pvField->getField()->getFieldName().compare("value")!=0) {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
PVStructure *pvParent = pvField->getParent();
|
||||
if(pvParent==0) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStructure = pvParent->getStructureField(String("display"));
|
||||
if(pvStructure==0) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStructure = static_cast<PVStructure*>(pvField);
|
||||
}
|
||||
pvDescription = pvStructure->getStringField(String("description"));
|
||||
if(pvDescription==0) {
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvDescription = pvStructure->getStringField("description");
|
||||
if(pvDescription.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvFormat = pvStructure->getStringField(String("format"));
|
||||
if(pvFormat==0) {
|
||||
pvFormat = pvStructure->getStringField("format");
|
||||
if(pvFormat.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvUnits = pvStructure->getStringField(String("units"));
|
||||
if(pvUnits==0) {
|
||||
pvUnits = pvStructure->getStringField("units");
|
||||
if(pvUnits.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvLow = pvStructure->getDoubleField(String("limit.low"));
|
||||
if(pvLow==0) {
|
||||
pvLow = pvStructure->getDoubleField(String("limitLow"));
|
||||
if(pvLow.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
}
|
||||
pvHigh = pvStructure->getDoubleField(String("limit.high"));
|
||||
if(pvHigh==0) {
|
||||
pvHigh = pvStructure->getDoubleField(String("limitHigh"));
|
||||
if(pvHigh.get()==NULL) {
|
||||
pvField->message(noDisplayFound,errorMessage);
|
||||
detach();
|
||||
return false;
|
||||
@@ -74,22 +61,21 @@ bool PVDisplay::attach(PVField *pvField)
|
||||
|
||||
void PVDisplay::detach()
|
||||
{
|
||||
pvDescription = 0;
|
||||
pvFormat = 0;
|
||||
pvUnits = 0;
|
||||
pvLow = 0;
|
||||
pvHigh = 0;
|
||||
pvDescription.reset();
|
||||
pvFormat.reset();
|
||||
pvUnits.reset();
|
||||
pvLow.reset();
|
||||
pvHigh.reset();
|
||||
}
|
||||
|
||||
bool PVDisplay::isAttached() {
|
||||
if(pvDescription==0 || pvFormat==0 || pvUnits==0 || pvLow==0 || pvHigh==0)
|
||||
return false;
|
||||
if(pvDescription.get()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVDisplay::get(Display & display) const
|
||||
{
|
||||
if(pvDescription==0 || pvFormat==0 || pvUnits==0 || pvLow==0 || pvHigh==0) {
|
||||
if(pvDescription.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
display.setDescription(pvDescription->get());
|
||||
@@ -101,13 +87,12 @@ void PVDisplay::get(Display & display) const
|
||||
|
||||
bool PVDisplay::set(Display const & display)
|
||||
{
|
||||
if(pvDescription==0 || pvFormat==0 || pvUnits==0 || pvLow==0 || pvHigh==0) {
|
||||
if(pvDescription.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
if(pvDescription->isImmutable() || pvFormat->isImmutable()) return false;
|
||||
if(pvUnits->isImmutable() || pvLow->isImmutable() || pvHigh->isImmutable())
|
||||
return false;
|
||||
|
||||
pvDescription->put(display.getDescription());
|
||||
pvFormat->put(display.getFormat());
|
||||
pvUnits->put(display.getUnits());
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvDisplay.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/pvData.h>
|
||||
@@ -14,11 +17,10 @@ namespace epics { namespace pvData {
|
||||
|
||||
class PVDisplay {
|
||||
public:
|
||||
PVDisplay()
|
||||
: pvDescription(0),pvFormat(),pvUnits(),pvLow(),pvHigh() {}
|
||||
PVDisplay() {}
|
||||
//default constructors and destructor are OK
|
||||
//An automatic detach is issued if already attached.
|
||||
bool attach(PVField *pvField);
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
void detach();
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
@@ -26,11 +28,13 @@ public:
|
||||
void get(Display &) const;
|
||||
bool set(Display const & display);
|
||||
private:
|
||||
PVString *pvDescription;
|
||||
PVString *pvFormat;
|
||||
PVString *pvUnits;
|
||||
PVDouble *pvLow;
|
||||
PVDouble *pvHigh;
|
||||
static String noDisplayFound;
|
||||
static String notAttached;
|
||||
PVStringPtr pvDescription;
|
||||
PVStringPtr pvFormat;
|
||||
PVStringPtr pvUnits;
|
||||
PVDoublePtr pvLow;
|
||||
PVDoublePtr pvHigh;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvEnumerated.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <pv/pvType.h>
|
||||
@@ -12,48 +15,48 @@
|
||||
#include <pv/pvEnumerated.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
static String notStructure("field is not a structure");
|
||||
static String notEnumerated("field is not an enumerated structure");
|
||||
static String notAttached("Not attached to an enumerated structure");
|
||||
String PVEnumerated::notFound("No enumerated structure found");
|
||||
String PVEnumerated::notAttached("Not attached to an enumerated structure");
|
||||
|
||||
bool PVEnumerated::attach(PVField *pvField)
|
||||
bool PVEnumerated::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(notStructure,errorMessage);
|
||||
pvField->message(notFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
||||
pvIndex = pvStructure->getIntField("index");
|
||||
if(pvIndex.get()==NULL) {
|
||||
pvField->message(notFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
PVStructure *pvStructure = static_cast<PVStructure*>(pvField);
|
||||
PVInt *pvInt = pvStructure->getIntField(String("index"));
|
||||
if(pvInt==0) {
|
||||
pvField->message(notEnumerated,errorMessage);
|
||||
PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField(
|
||||
"choices",pvString);
|
||||
if(pvScalarArray.get()==NULL) {
|
||||
pvIndex.reset();
|
||||
pvField->message(notFound,errorMessage);
|
||||
return false;
|
||||
}
|
||||
PVScalarArray *pvScalarArray = pvStructure->getScalarArrayField(
|
||||
String("choices"),pvString);
|
||||
if(pvScalarArray==0) {
|
||||
pvField->message(notEnumerated,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvIndex = pvInt;
|
||||
pvChoices = static_cast<PVStringArray *>(pvScalarArray);
|
||||
pvChoices = static_pointer_cast<PVStringArray>(pvScalarArray);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVEnumerated::detach()
|
||||
{
|
||||
pvIndex = 0;
|
||||
pvChoices = 0;
|
||||
pvIndex.reset();
|
||||
pvChoices.reset();
|
||||
}
|
||||
|
||||
bool PVEnumerated::isAttached() {
|
||||
if(pvIndex==0 || pvChoices==0) return false;
|
||||
if(pvIndex.get()==NULL) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PVEnumerated::setIndex(int32 index)
|
||||
{
|
||||
if(pvIndex==0 || pvChoices==0) {
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
if(pvIndex->isImmutable()) return false;
|
||||
@@ -63,7 +66,7 @@ bool PVEnumerated::setIndex(int32 index)
|
||||
|
||||
int32 PVEnumerated::getIndex()
|
||||
{
|
||||
if(pvIndex==0 || pvChoices==0) {
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
return pvIndex->get();
|
||||
@@ -71,48 +74,47 @@ int32 PVEnumerated::getIndex()
|
||||
|
||||
String PVEnumerated::getChoice()
|
||||
{
|
||||
if(pvIndex==0 || pvChoices==0) {
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
int index = pvIndex->get();
|
||||
StringArrayData data;
|
||||
pvChoices->get(0,pvChoices->getLength(),&data);
|
||||
pvChoices->get(0,pvChoices->getLength(),data);
|
||||
return data.data[index];
|
||||
}
|
||||
|
||||
bool PVEnumerated::choicesMutable()
|
||||
{
|
||||
if(pvIndex==0 || pvChoices==0) {
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
return pvChoices->isImmutable();
|
||||
}
|
||||
|
||||
StringArray PVEnumerated:: getChoices()
|
||||
StringArrayPtr const & PVEnumerated:: getChoices()
|
||||
{
|
||||
if(pvIndex==0 || pvChoices==0) {
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
StringArrayData data;
|
||||
pvChoices->get(0,pvChoices->getLength(),&data);
|
||||
return data.data;
|
||||
return pvChoices->getSharedVector();
|
||||
}
|
||||
|
||||
int32 PVEnumerated::getNumberChoices()
|
||||
{
|
||||
if(pvIndex==0 || pvChoices==0) {
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
return pvChoices->getLength();
|
||||
}
|
||||
|
||||
bool PVEnumerated:: setChoices(StringArray choices,int32 numberChoices)
|
||||
bool PVEnumerated:: setChoices(StringArray & choices)
|
||||
{
|
||||
if(pvIndex==0 || pvChoices==0) {
|
||||
if(pvIndex.get()==NULL ) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
if(pvChoices->isImmutable()) return false;
|
||||
pvChoices->put(0,numberChoices,choices,0);
|
||||
pvChoices->put(0,choices.size(),get(choices),0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvEnumerated.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/pvData.h>
|
||||
@@ -13,12 +16,12 @@ namespace epics { namespace pvData {
|
||||
|
||||
class PVEnumerated {
|
||||
public:
|
||||
PVEnumerated() : pvIndex(0), pvChoices(0) {}
|
||||
PVEnumerated() {}
|
||||
//default constructors and destructor are OK
|
||||
//This class should not be extended
|
||||
//returns (false,true) if pvField(isNot, is valid enumerated structure
|
||||
//An automatic detach is issued if already attached.
|
||||
bool attach(PVField *pvField);
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
void detach();
|
||||
bool isAttached();
|
||||
// each of the following throws logic_error is not attached to PVField
|
||||
@@ -27,12 +30,14 @@ public:
|
||||
int32 getIndex();
|
||||
String getChoice();
|
||||
bool choicesMutable();
|
||||
StringArray getChoices();
|
||||
StringArrayPtr const & getChoices();
|
||||
int32 getNumberChoices();
|
||||
bool setChoices(StringArray choices,int32 numberChoices);
|
||||
bool setChoices(StringArray & choices);
|
||||
private:
|
||||
PVInt *pvIndex;
|
||||
PVStringArray *pvChoices;
|
||||
static String notFound;
|
||||
static String notAttached;
|
||||
PVIntPtr pvIndex;
|
||||
PVStringArrayPtr pvChoices;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvTimeStamp.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <pv/pvType.h>
|
||||
@@ -12,78 +15,52 @@
|
||||
#include <pv/pvTimeStamp.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static String noTimeStamp("No timeStamp structure found");
|
||||
static String notAttached("Not attached to a timeStamp structure");
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
bool PVTimeStamp::attach(PVField *pvField)
|
||||
String PVTimeStamp::noTimeStamp("No timeStamp structure found");
|
||||
String PVTimeStamp::notAttached("Not attached to a timeStamp structure");
|
||||
|
||||
bool PVTimeStamp::attach(PVFieldPtr const & pvField)
|
||||
{
|
||||
PVStructure *pvStructure = 0;
|
||||
if(pvField->getField()->getFieldName().compare("timeStamp")!=0) {
|
||||
PVStructure *pvParent = pvField->getParent();
|
||||
if(pvParent==0) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
if(pvField->getField()->getFieldName().compare("value")!=0) {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
|
||||
PVStructure* pvStructure = xxx.get();
|
||||
while(true) {
|
||||
PVLongPtr pvLong = pvStructure->getLongField("secondsPastEpoch");
|
||||
if(pvLong.get()!=NULL) {
|
||||
pvSecs = pvLong;
|
||||
pvNano = pvStructure->getIntField("nanoSeconds");
|
||||
pvUserTag = pvStructure->getIntField("userTag");
|
||||
}
|
||||
if(pvSecs.get()!=NULL
|
||||
&& pvNano.get()!=NULL
|
||||
&& pvUserTag.get()!=NULL) return true;
|
||||
detach();
|
||||
// look up the tree for a timeSyamp
|
||||
while(pvParent!=0) {
|
||||
PVStructure *pvs = pvParent->getStructureField(String("timeStamp"));
|
||||
if(pvs!=0) {
|
||||
pvStructure = pvs;
|
||||
break;
|
||||
}
|
||||
pvParent = pvParent->getParent();
|
||||
}
|
||||
if(pvStructure==0) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvStructure = static_cast<PVStructure*>(pvField);
|
||||
pvStructure = pvStructure->getParent();
|
||||
if(pvStructure==NULL) break;
|
||||
}
|
||||
PVLong *pvLong = pvStructure->getLongField(String("secondsPastEpoch"));
|
||||
if(pvLong==0) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvSecs = pvLong;
|
||||
PVInt *pvInt = pvStructure->getIntField(String("nanoSeconds"));
|
||||
if(pvLong==0) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvNano = pvInt;
|
||||
pvInt = pvStructure->getIntField(String("userTag"));
|
||||
if(pvInt==0) {
|
||||
pvField->message(noTimeStamp,errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvUserTag = pvInt;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PVTimeStamp::detach()
|
||||
{
|
||||
pvSecs = 0;
|
||||
pvUserTag = 0;
|
||||
pvNano = 0;
|
||||
pvSecs.reset();
|
||||
pvUserTag.reset();
|
||||
pvNano.reset();
|
||||
}
|
||||
|
||||
bool PVTimeStamp::isAttached() {
|
||||
if(pvSecs==0 || pvNano==0) return false;
|
||||
if(pvSecs.get()==NULL) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PVTimeStamp::get(TimeStamp & timeStamp) const
|
||||
{
|
||||
if(pvSecs==0 || pvNano==0) {
|
||||
if(pvSecs.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
timeStamp.put(pvSecs->get(),pvNano->get());
|
||||
@@ -92,7 +69,7 @@ void PVTimeStamp::get(TimeStamp & timeStamp) const
|
||||
|
||||
bool PVTimeStamp::set(TimeStamp const & timeStamp)
|
||||
{
|
||||
if(pvSecs==0 || pvNano==0 || pvUserTag==0) {
|
||||
if(pvSecs.get()==NULL) {
|
||||
throw std::logic_error(notAttached);
|
||||
}
|
||||
if(pvSecs->isImmutable() || pvNano->isImmutable()) return false;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* pvTimeStamp.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <pv/pvType.h>
|
||||
@@ -15,12 +18,12 @@ namespace epics { namespace pvData {
|
||||
|
||||
class PVTimeStamp {
|
||||
public:
|
||||
PVTimeStamp() : pvSecs(0),pvUserTag(0), pvNano(0) {}
|
||||
PVTimeStamp(){}
|
||||
//default constructors and destructor are OK
|
||||
//This class should not be extended
|
||||
|
||||
//returns (false,true) if pvField(isNot, is valid timeStamp structure
|
||||
bool attach(PVField *pvField);
|
||||
bool attach(PVFieldPtr const & pvField);
|
||||
void detach();
|
||||
bool isAttached();
|
||||
// following throw logic_error is not attached to PVField
|
||||
@@ -28,9 +31,11 @@ public:
|
||||
void get(TimeStamp &) const;
|
||||
bool set(TimeStamp const & timeStamp);
|
||||
private:
|
||||
PVLong* pvSecs;
|
||||
PVInt* pvUserTag;
|
||||
PVInt* pvNano;
|
||||
static String noTimeStamp;
|
||||
static String notAttached;
|
||||
PVLongPtr pvSecs;
|
||||
PVIntPtr pvUserTag;
|
||||
PVIntPtr pvNano;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* timeStamp.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* timeStamp.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef TIMESTAMP_H
|
||||
#define TIMESTAMP_H
|
||||
#include <ctime>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* convert.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* Author - Marty Kraimer
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef CONVERT_H
|
||||
#define CONVERT_H
|
||||
#include <string>
|
||||
@@ -47,30 +50,42 @@ static inline bool operator!=(const StructureArray& a, const StructureArray& b)
|
||||
* numeric types. It is not possible to convert between a scalar
|
||||
* and an array.
|
||||
* Numeric conversions are between types:
|
||||
* pvByte, pvShort, pvInt,
|
||||
* pvLong, pvFloat, or pvDouble.</p>
|
||||
* pvByte, pvShort, pvInt, pvLong,
|
||||
* pvUByte, pvUShort, pvUInt, pvULong,
|
||||
* pvFloat, or pvDouble.</p>
|
||||
*
|
||||
* <p>getString converts any supported type to a String.
|
||||
* Code that implements a PVField interface can implement
|
||||
* Code that implements a PVField interface should implement
|
||||
* method toString by calling this method.</p>
|
||||
*
|
||||
* <p>fromString converts a String to a scalar.
|
||||
* fromStringArray converts an array of String
|
||||
* fromStringArray converts an array of Strings
|
||||
* to a pvArray, which must have a scaler element type.
|
||||
* A scalar field is a numeric field or pvBoolean or pvString.</p>
|
||||
* <p>All from methods put data into a PVField, e.g. from means where the PVField gets it's data.</p>
|
||||
*/
|
||||
|
||||
class Convert : NoDefaultMethods {
|
||||
class Convert;
|
||||
typedef std::tr1::shared_ptr<Convert> ConvertPtr;
|
||||
|
||||
class Convert {
|
||||
public:
|
||||
Convert();
|
||||
static ConvertPtr getConvert();
|
||||
~Convert();
|
||||
/**
|
||||
* Get the full fieldName for the pvField.
|
||||
* @param builder The builder that will have the result.
|
||||
* @param pvField The pvField.
|
||||
*/
|
||||
void getFullName(StringBuilder buf,PVField *pvField);
|
||||
void getFullName(StringBuilder buf,PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Do fields have the same definition.
|
||||
*
|
||||
* @param First field
|
||||
* @param Second field
|
||||
* @return (false, true) if the fields (are not, are) the same.
|
||||
*/
|
||||
bool equals(PVFieldPtr const &a,PVFieldPtr const &b);
|
||||
/**
|
||||
* Do fields have the same definition.
|
||||
*
|
||||
@@ -86,14 +101,29 @@ public:
|
||||
* If a PVField is a structure or array be prepared for a very long string.
|
||||
* @param indentLevel indentation level
|
||||
*/
|
||||
void getString(StringBuilder buf,PVField * pvField,int indentLevel);
|
||||
void getString(StringBuilder buf,PVFieldPtr const & pvField,int indentLevel);
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
* param buf buffer for the result
|
||||
* @param pv The PVField to convert to a string.
|
||||
* If the PVField is a structure or array be prepared for a very long string.
|
||||
*/
|
||||
void getString(StringBuilder buf,PVField *pvField);
|
||||
void getString(StringBuilder buf,PVFieldPtr const & pvField);
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
* @param buf buffer for the result
|
||||
* @param pv a PVField to convert to a string.
|
||||
* If a PVField is a structure or array be prepared for a very long string.
|
||||
* @param indentLevel indentation level
|
||||
*/
|
||||
void getString(StringBuilder buf,PVField const * pvField,int indentLevel);
|
||||
/**
|
||||
* Convert a PVField to a string.
|
||||
* param buf buffer for the result
|
||||
* @param pv The PVField to convert to a string.
|
||||
* If the PVField is a structure or array be prepared for a very long string.
|
||||
*/
|
||||
void getString(StringBuilder buf,PVField const * pvField);
|
||||
/**
|
||||
* Convert from an array of String to a PVScalar
|
||||
* @param pv The PV.
|
||||
@@ -101,14 +131,17 @@ public:
|
||||
* @param fromStartIndex The first element if the array of strings.
|
||||
* @throws std::logic_error if the array of String does not have a valid values.
|
||||
*/
|
||||
int fromString(PVStructure *pv, std::vector<String>& from, int fromStartIndex = 0);
|
||||
std::size_t fromString(
|
||||
PVStructurePtr const &pv,
|
||||
StringArray const & from,
|
||||
std::size_t fromStartIndex = 0);
|
||||
/**
|
||||
* Convert from a String to a PVScalar
|
||||
* @param pv The PV.
|
||||
* @param from The String value to convert and put into a PV.
|
||||
* @throws std::logic_error if the String does not have a valid value.
|
||||
*/
|
||||
void fromString(PVScalar *pv, String from);
|
||||
void fromString(PVScalarPtr const & pv, String const & from);
|
||||
/**
|
||||
* Convert from a String to a PVScalarArray.
|
||||
* The String must be a comma separated set of values optionally enclosed in []
|
||||
@@ -118,7 +151,7 @@ public:
|
||||
* @throws std::invalid_argument if the element Type is not a scalar.
|
||||
* @throws std::logic_error if the String does not have a valid array values.
|
||||
*/
|
||||
int fromString(PVScalarArray *pv, String from);
|
||||
std::size_t fromString(PVScalarArrayPtr const & pv, String from);
|
||||
/**
|
||||
* Convert a PVScalarArray from a String array.
|
||||
* The array element type must be a scalar.
|
||||
@@ -131,8 +164,11 @@ public:
|
||||
* @throws std::invalid_argument if the element Type is not a scalar.
|
||||
* @throws std::logic_error if the String does not have a valid value.
|
||||
*/
|
||||
int fromStringArray(PVScalarArray *pv, int offset, int length,
|
||||
StringArray from, int fromOffset);
|
||||
std::size_t fromStringArray(
|
||||
PVScalarArrayPtr const & pv,
|
||||
std::size_t offset, std::size_t length,
|
||||
StringArray const & from,
|
||||
std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PVScalarArray to a String array.
|
||||
* @param pv The PV.
|
||||
@@ -142,8 +178,11 @@ public:
|
||||
* @param toOffset Starting element in the string array.
|
||||
* @return Number of elements converted.
|
||||
*/
|
||||
int toStringArray(PVScalarArray *pv, int offset, int length,
|
||||
StringArray to, int toOffset);
|
||||
std::size_t toStringArray(PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
StringArray & to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Are from and to valid arguments to copy.
|
||||
* This first checks of both arguments have the same Type.
|
||||
@@ -153,7 +192,7 @@ public:
|
||||
* @param to The destination.
|
||||
* @return (false,true) is the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyCompatible(FieldConstPtr from, FieldConstPtr to);
|
||||
bool isCopyCompatible(FieldConstPtr const & from, FieldConstPtr const & to);
|
||||
/**
|
||||
* Copy from a PVField to another PVField.
|
||||
* This calls one on copyScalar, copyArray, copyStructure.
|
||||
@@ -162,7 +201,7 @@ public:
|
||||
* @param to The destination
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
void copy(PVField *from,PVField *to);
|
||||
void copy(PVFieldPtr const & from, PVFieldPtr const & to);
|
||||
/**
|
||||
* Are from and to valid arguments to copyScalar.
|
||||
* false will be returned if either argument is not a scalar as defined by Type.isScalar().
|
||||
@@ -177,14 +216,15 @@ public:
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyScalarCompatible(
|
||||
ScalarConstPtr from, ScalarConstPtr to);
|
||||
ScalarConstPtr const & from,
|
||||
ScalarConstPtr const & to);
|
||||
/**
|
||||
* Copy from a scalar pv to another scalar pv.
|
||||
* @param from the source.
|
||||
* @param to the destination.
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
void copyScalar(PVScalar *from, PVScalar *to);
|
||||
void copyScalar(PVScalarPtr const & from, PVScalarPtr const & to);
|
||||
/**
|
||||
* Are from and to valid arguments to copyArray.
|
||||
* The results are like isCopyScalarCompatible except that the tests are made on the elementType.
|
||||
@@ -192,8 +232,9 @@ public:
|
||||
* @param to The to array.
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyScalarArrayCompatible(ScalarArrayConstPtr from,
|
||||
ScalarArrayConstPtr to);
|
||||
bool isCopyScalarArrayCompatible(
|
||||
ScalarArrayConstPtr const & from,
|
||||
ScalarArrayConstPtr const & to);
|
||||
/**
|
||||
* Convert from a source PV array to a destination PV array.
|
||||
* @param from The source array.
|
||||
@@ -204,8 +245,12 @@ public:
|
||||
* @return Number of elements converted.
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
int copyScalarArray(PVScalarArray *from, int offset,
|
||||
PVScalarArray *to, int toOffset, int length);
|
||||
std::size_t copyScalarArray(
|
||||
PVScalarArrayPtr const & from,
|
||||
std::size_t offset,
|
||||
PVScalarArrayPtr const & to,
|
||||
std::size_t toOffset,
|
||||
std::size_t length);
|
||||
/**
|
||||
* Are from and to valid arguments for copyStructure.
|
||||
* They are only compatible if they have the same Structure description.
|
||||
@@ -214,7 +259,7 @@ public:
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyStructureCompatible(
|
||||
StructureConstPtr from, StructureConstPtr to);
|
||||
StructureConstPtr const & from, StructureConstPtr const & to);
|
||||
/**
|
||||
* Copy from a structure pv to another structure pv.
|
||||
* NOTE: Only compatible nodes are copied. This means:
|
||||
@@ -228,7 +273,7 @@ public:
|
||||
* @param to The destination.
|
||||
* @throws std::invalid_argument if the arguments are not compatible.
|
||||
*/
|
||||
void copyStructure(PVStructure *from, PVStructure *to);
|
||||
void copyStructure(PVStructurePtr const & from, PVStructurePtr const & to);
|
||||
/**
|
||||
* Are from and to valid for copyStructureArray.
|
||||
* @param from The from StructureArray.
|
||||
@@ -236,103 +281,158 @@ public:
|
||||
* @return (false,true) If the arguments (are not, are) compatible.
|
||||
*/
|
||||
bool isCopyStructureArrayCompatible(
|
||||
StructureArrayConstPtr from, StructureArrayConstPtr to);
|
||||
StructureArrayConstPtr const & from, StructureArrayConstPtr const & to);
|
||||
/**
|
||||
* Copy from a structure array to another structure array.
|
||||
* @param from The source array.
|
||||
* @param to The destination array.
|
||||
*/
|
||||
void copyStructureArray(
|
||||
PVStructureArray *from, PVStructureArray *to);
|
||||
PVStructureArrayPtr const & from, PVStructureArrayPtr const & to);
|
||||
/**
|
||||
* Convert a PV to a <byte>.
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
*/
|
||||
int8 toByte(PVScalar *pv);
|
||||
int8 toByte(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a short.
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
int16 toShort(PVScalar *pv);
|
||||
int16 toShort(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a short.
|
||||
* Convert a PV to a int.
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
int32 toInt(PVScalar *pv);
|
||||
int32 toInt(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to an int
|
||||
* Convert a PV to an long
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
int64 toLong(PVScalar *pv);
|
||||
int64 toLong(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a ubyte.
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
*/
|
||||
uint8 toUByte(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a ushort.
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
uint16 toUShort(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a uint.
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
uint32 toUInt(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to an ulong
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
uint64 toULong(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a float
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
float toFloat(PVScalar *pv);
|
||||
float toFloat(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a double
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
double toDouble(PVScalar *pv);
|
||||
double toDouble(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV to a String
|
||||
* @param pv a PV
|
||||
* @return converted value
|
||||
*/
|
||||
String toString(PVScalar *pv);
|
||||
String toString(PVScalarPtr const & pv);
|
||||
/**
|
||||
* Convert a PV from a byte
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromByte(PVScalar *pv,int8 from);
|
||||
void fromByte(PVScalarPtr const & pv,int8 from);
|
||||
/**
|
||||
* Convert a PV from a short
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromShort(PVScalar *pv,int16 from);
|
||||
void fromShort(PVScalarPtr const & pv,int16 from);
|
||||
/**
|
||||
* Convert a PV from an int
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromInt(PVScalar *pv, int32 from);
|
||||
void fromInt(PVScalarPtr const & pv, int32 from);
|
||||
/**
|
||||
* Convert a PV from a long
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromLong(PVScalar *pv, int64 from);
|
||||
void fromLong(PVScalarPtr const & pv, int64 from);
|
||||
/**
|
||||
* Convert a PV from a ubyte
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromUByte(PVScalarPtr const & pv,uint8 from);
|
||||
/**
|
||||
* Convert a PV from a ushort
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromUShort(PVScalarPtr const & pv,uint16 from);
|
||||
/**
|
||||
* Convert a PV from an uint
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromUInt(PVScalarPtr const & pv, uint32 from);
|
||||
/**
|
||||
* Convert a PV from a ulong
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromULong(PVScalarPtr const & pv, uint64 from);
|
||||
/**
|
||||
* Convert a PV from a float
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromFloat(PVScalar* pv, float from);
|
||||
void fromFloat(PVScalarPtr const & pv, float from);
|
||||
/**
|
||||
* Convert a PV from a double
|
||||
* @param pv a PV
|
||||
* @param from value to put into PV
|
||||
* @throws std::invalid_argument if the Type is not a numeric scalar
|
||||
*/
|
||||
void fromDouble(PVScalar *pv, double from);
|
||||
void fromDouble(PVScalarPtr const & pv, double from);
|
||||
/**
|
||||
* Convert a PV array to a byte array.
|
||||
* @param pv a PV
|
||||
@@ -343,8 +443,11 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int toByteArray(PVScalarArray *pv, int offset, int length,
|
||||
ByteArray to, int toOffset);
|
||||
std::size_t toByteArray(PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
int8* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to a short array.
|
||||
* @param pv a PV
|
||||
@@ -355,8 +458,11 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int toShortArray(PVScalarArray *pv, int offset, int length,
|
||||
ShortArray to, int toOffset);
|
||||
std::size_t toShortArray(PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
int16* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to an int array.
|
||||
* @param pv a PV
|
||||
@@ -367,8 +473,11 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int toIntArray(PVScalarArray *pv, int offset, int length,
|
||||
IntArray to, int toOffset);
|
||||
std::size_t toIntArray(PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
int32* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to a long array.
|
||||
* @param pv a PV
|
||||
@@ -379,8 +488,73 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int toLongArray(PVScalarArray *pv, int offset, int length,
|
||||
LongArray to, int toOffset);
|
||||
std::size_t toLongArray(PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
int64* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to a ubyte array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param to where to put the PV data
|
||||
* @param toOffset starting element in the array
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t toUByteArray(PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
uint8* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to a ushort array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param to where to put the PV data
|
||||
* @param toOffset starting element in the array
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t toUShortArray(PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
uint16* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to an uint array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param to where to put the PV data
|
||||
* @param toOffset starting element in the array
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t toUIntArray(
|
||||
PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
uint32* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to a ulong array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param to where to put the PV data
|
||||
* @param toOffset starting element in the array
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t toULongArray(
|
||||
PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
uint64* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to a float array.
|
||||
* @param pv a PV
|
||||
@@ -391,8 +565,12 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int toFloatArray(PVScalarArray *pv, int offset, int length,
|
||||
FloatArray to, int toOffset);
|
||||
std::size_t toFloatArray(
|
||||
PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
float* to,
|
||||
std::size_t toOffset);
|
||||
/**
|
||||
* Convert a PV array to a double array.
|
||||
* @param pv a PV
|
||||
@@ -403,8 +581,12 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int toDoubleArray(PVScalarArray *pv, int offset, int length,
|
||||
DoubleArray to, int toOffset);
|
||||
std::size_t toDoubleArray(
|
||||
PVScalarArrayPtr const & pv,
|
||||
std::size_t offset,
|
||||
std::size_t length,
|
||||
double* to, std::size_t
|
||||
toOffset);
|
||||
/**
|
||||
* Convert a PV array from a byte array.
|
||||
* @param pv a PV
|
||||
@@ -415,8 +597,12 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int fromByteArray(PVScalarArray *pv, int offset, int length,
|
||||
ByteArray from, int fromOffset);
|
||||
std::size_t fromByteArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const int8* from, std::size_t fromOffset);
|
||||
std::size_t fromByteArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const ByteArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from a short array.
|
||||
* @param pv a PV
|
||||
@@ -427,8 +613,12 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int fromShortArray(PVScalarArray *pv, int offset, int length,
|
||||
ShortArray from, int fromOffset);
|
||||
std::size_t fromShortArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const int16* from, std::size_t fromOffset);
|
||||
std::size_t fromShortArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const ShortArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from an int array.
|
||||
* @param pv a PV
|
||||
@@ -439,8 +629,12 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int fromIntArray(PVScalarArray *pv, int offset, int length,
|
||||
IntArray from, int fromOffset);
|
||||
std::size_t fromIntArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const int32* from, std::size_t fromOffset);
|
||||
std::size_t fromIntArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const IntArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from a long array.
|
||||
* @param pv a PV
|
||||
@@ -451,8 +645,76 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int fromLongArray(PVScalarArray *pv, int offset, int length,
|
||||
LongArray from, int fromOffset);
|
||||
std::size_t fromLongArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const int64* from, std::size_t fromOffset);
|
||||
std::size_t fromLongArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const LongArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from a ubyte array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param from value to put into PV
|
||||
* @param fromOffset
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t fromUByteArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const uint8* from, std::size_t fromOffset);
|
||||
std::size_t fromUByteArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const UByteArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from a ushort array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param from value to put into PV
|
||||
* @param fromOffset starting element in the source array
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t fromUShortArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const uint16* from, std::size_t fromOffset);
|
||||
std::size_t fromUShortArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const UShortArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from an uint array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param from value to put into PV
|
||||
* @param fromOffset starting element in the source array
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t fromUIntArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const uint32* from, std::size_t fromOffset);
|
||||
std::size_t fromUIntArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const UIntArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from a ulong array.
|
||||
* @param pv a PV
|
||||
* @param offset starting element in a PV
|
||||
* @param length number of elements to transfer
|
||||
* @param from value to put into PV
|
||||
* @param fromOffset starting element in the source array
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
std::size_t fromULongArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const uint64* from, std::size_t fromOffset);
|
||||
std::size_t fromULongArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const ULongArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from a float array.
|
||||
* @param pv a PV
|
||||
@@ -463,8 +725,12 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int fromFloatArray(PVScalarArray *pv, int offset, int length,
|
||||
FloatArray from, int fromOffset);
|
||||
std::size_t fromFloatArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const float* from, std::size_t fromOffset);
|
||||
std::size_t fromFloatArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const FloatArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convert a PV array from a double array.
|
||||
* @param pv a PV
|
||||
@@ -475,8 +741,12 @@ public:
|
||||
* @return number of elements converted
|
||||
* @throws std::invalid_argument if the element type is not numeric
|
||||
*/
|
||||
int fromDoubleArray(PVScalarArray *pv, int offset, int length,
|
||||
DoubleArray from, int fromOffset);
|
||||
std::size_t fromDoubleArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const double* from, std::size_t fromOffset);
|
||||
std::size_t fromDoubleArray(
|
||||
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
|
||||
const DoubleArray & from, std::size_t fromOffset);
|
||||
/**
|
||||
* Convenience method for implementing toString.
|
||||
* It generates a newline and inserts blanks at the beginning of the newline.
|
||||
@@ -484,9 +754,15 @@ public:
|
||||
* @param indentLevel Indent level, Each level is four spaces.
|
||||
*/
|
||||
void newLine(StringBuilder buf, int indentLevel);
|
||||
private:
|
||||
Convert();
|
||||
PVDataCreatePtr pvDataCreate;
|
||||
String trueString;
|
||||
String falseString;
|
||||
String illegalScalarType;
|
||||
};
|
||||
|
||||
extern Convert * getConvert();
|
||||
extern ConvertPtr getConvert();
|
||||
|
||||
}}
|
||||
#endif /* CONVERT_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,11 @@
|
||||
/* pvIntrospect.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* Author - Marty Kraimer
|
||||
*/
|
||||
/**
|
||||
* @author mrk and Michael Davidsaver
|
||||
*/
|
||||
#ifndef PVINTROSPECT_H
|
||||
#define PVINTROSPECT_H
|
||||
@@ -11,8 +13,10 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/byteBuffer.h>
|
||||
#include <pv/serialize.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class Field;
|
||||
@@ -28,7 +32,7 @@ typedef std::tr1::shared_ptr<const Field> FieldConstPtr;
|
||||
/**
|
||||
* typedef for an array of shared pointer to an immutable Field.
|
||||
*/
|
||||
typedef FieldConstPtr * FieldConstPtrArray;
|
||||
typedef std::vector<FieldConstPtr> FieldConstPtrArray;
|
||||
/**
|
||||
* typedef for a shared pointer to an immutable Scalar.
|
||||
*/
|
||||
@@ -110,6 +114,22 @@ enum ScalarType {
|
||||
* The type is long, i. e. a 64 bit signed integer.
|
||||
*/
|
||||
pvLong,
|
||||
/**
|
||||
* The type is unsigned byte, i. e. a 8 bit unsigned integer.
|
||||
*/
|
||||
pvUByte,
|
||||
/**
|
||||
* The type is unsigned short, i. e. a 16 bit unsigned integer.
|
||||
*/
|
||||
pvUShort,
|
||||
/**
|
||||
* The type is unsigned int, i. e. a 32 bit unsigned integer.
|
||||
*/
|
||||
pvUInt,
|
||||
/**
|
||||
* The type is unsigned long, i. e. a 64 bit unsigned integer.
|
||||
*/
|
||||
pvULong,
|
||||
/**
|
||||
* The type is float, i. e. 32 bit IEEE floating point,
|
||||
*/
|
||||
@@ -129,11 +149,17 @@ enum ScalarType {
|
||||
*/
|
||||
namespace ScalarTypeFunc {
|
||||
/**
|
||||
* Is the type an integer, i. e. is it one of byte,...long
|
||||
* Is the type an integer, i. e. is it one of byte,...ulong
|
||||
* @param scalarType The type.
|
||||
* @return (false,true) if the scalarType is an integer.
|
||||
*/
|
||||
bool isInteger(ScalarType scalarType);
|
||||
/**
|
||||
* Is the type an unsigned integer, i. e. is it one of ubyte,...ulong
|
||||
* @param scalarType The type.
|
||||
* @return (false,true) if the scalarType is an integer.
|
||||
*/
|
||||
bool isUInteger(ScalarType scalarType);
|
||||
/**
|
||||
* Is the type numeric, i. e. is it one of byte,...,double
|
||||
* @param scalarType The type.
|
||||
@@ -152,7 +178,7 @@ namespace ScalarTypeFunc {
|
||||
* @return The scalarType.
|
||||
* An exception is thrown if the name is not the name of a scalar type.
|
||||
*/
|
||||
ScalarType getScalarType(String value);
|
||||
ScalarType getScalarType(String const &value);
|
||||
/**
|
||||
* Get a name for the scalarType.
|
||||
* @param scalarType The type.
|
||||
@@ -170,23 +196,25 @@ namespace ScalarTypeFunc {
|
||||
/**
|
||||
* This class implements introspection object for field.
|
||||
*/
|
||||
class Field : public std::tr1::enable_shared_from_this<Field> {
|
||||
class Field :
|
||||
virtual public Serializable,
|
||||
public std::tr1::enable_shared_from_this<Field> {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Field);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Field();
|
||||
/**
|
||||
* Get the name of the field.
|
||||
* @return The field name.
|
||||
*/
|
||||
String getFieldName() const{return m_fieldName;}
|
||||
/**
|
||||
* Get the field type.
|
||||
* @return The type.
|
||||
*/
|
||||
Type getType() const{return m_type;}
|
||||
Type getType() const{return m_fieldType;}
|
||||
/**
|
||||
* Get the identification string.
|
||||
* @return The identification string, can be empty.
|
||||
*/
|
||||
virtual String getID() const = 0;
|
||||
/**
|
||||
* Convert the scalarType to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
@@ -198,22 +226,14 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder builder,int indentLevel) const;
|
||||
/**
|
||||
* Rename the field.
|
||||
* @param newName The new name.
|
||||
* This MUST not be called after the field is put into use!!!
|
||||
*/
|
||||
void renameField(String newName);
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
* @param fieldName The field name.
|
||||
* @param fieldName The field type.
|
||||
*/
|
||||
Field(String fieldName,Type type);
|
||||
Field(Type type);
|
||||
private:
|
||||
String m_fieldName;
|
||||
Type m_type;
|
||||
Type m_fieldType;
|
||||
|
||||
friend class StructureArray;
|
||||
friend class Structure;
|
||||
@@ -254,9 +274,16 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual String getID() const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
|
||||
protected:
|
||||
Scalar(String fieldName,ScalarType scalarType);
|
||||
Scalar(ScalarType scalarType);
|
||||
private:
|
||||
const int8 getTypeCodeLUT() const;
|
||||
ScalarType scalarType;
|
||||
friend class FieldCreate;
|
||||
};
|
||||
@@ -267,10 +294,14 @@ private:
|
||||
class ScalarArray : public Field{
|
||||
public:
|
||||
POINTER_DEFINITIONS(ScalarArray);
|
||||
ScalarArray(String fieldName,ScalarType scalarType);
|
||||
typedef ScalarArray& reference;
|
||||
typedef const ScalarArray& const_reference;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param scalarType The scalarType for the field.
|
||||
*/
|
||||
ScalarArray(ScalarType scalarType);
|
||||
/**
|
||||
* Get the scalarType for the elements.
|
||||
* @return the scalarType
|
||||
@@ -287,12 +318,20 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual String getID() const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~ScalarArray();
|
||||
private:
|
||||
const int8 getTypeCodeLUT() const;
|
||||
const String getIDScalarArrayLUT() const;
|
||||
ScalarType elementType;
|
||||
friend class FieldCreate;
|
||||
};
|
||||
@@ -306,7 +345,6 @@ public:
|
||||
typedef StructureArray& reference;
|
||||
typedef const StructureArray& const_reference;
|
||||
|
||||
const Structure& structure() const {return *pstructure;}
|
||||
/**
|
||||
* Get the introspection interface for the array elements.
|
||||
* @return The introspection interface.
|
||||
@@ -319,13 +357,18 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel=0) const;
|
||||
|
||||
virtual String getID() const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param fieldName The name for the field.
|
||||
* @param structure The introspection interface for the elements.
|
||||
*/
|
||||
StructureArray(String fieldName,StructureConstPtr structure);
|
||||
StructureArray(StructureConstPtr const & structure);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
@@ -341,6 +384,12 @@ private:
|
||||
class Structure : public Field {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Structure);
|
||||
|
||||
/**
|
||||
* Default structure ID.
|
||||
*/
|
||||
static epics::pvData::String DEFAULT_ID;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
@@ -352,41 +401,45 @@ public:
|
||||
* Get the number of immediate subfields in the structure/
|
||||
* @return The number of fields.
|
||||
*/
|
||||
int getNumberFields() const {return numberFields;}
|
||||
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.
|
||||
*/
|
||||
FieldConstPtr getField(String fieldName) const;
|
||||
FieldConstPtr getField(String const &fieldName) const;
|
||||
/**
|
||||
* Get the field for the specified fieldName.
|
||||
* @param fieldName 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.
|
||||
*/
|
||||
FieldConstPtr getField(std::size_t index) const {return fields[index];}
|
||||
/**
|
||||
* Get the field index for the specified fieldName.
|
||||
* @return The introspection interface.
|
||||
* This will be -1 if the field is not in the structure.
|
||||
*/
|
||||
int getFieldIndex(String fieldName) const;
|
||||
std::size_t getFieldIndex(String const &fieldName) const;
|
||||
/**
|
||||
* Get the fields in the structure.
|
||||
* @return The array of fields.
|
||||
*/
|
||||
FieldConstPtrArray getFields() const {return fields;}
|
||||
FieldConstPtrArray const & getFields() const {return fields;}
|
||||
/**
|
||||
* Append a field to the structure.
|
||||
* @param field The field to append.
|
||||
* Get the names of the fields in the structure.
|
||||
* @return The array of fieldNames.
|
||||
*/
|
||||
void appendField(FieldConstPtr field);
|
||||
StringArray const & getFieldNames() const {return fieldNames;}
|
||||
void renameField(std::size_t fieldIndex,String const & newName)
|
||||
{fieldNames[fieldIndex] = newName;}
|
||||
/**
|
||||
* Append an array of fields to the structure.
|
||||
* @param field The fields to append.
|
||||
* The array MUST be allocated on the heap.
|
||||
* The structure takes ownership of the field array.
|
||||
* Get the name of the field with the specified index;
|
||||
* @param fieldIndex The index of the desired field.
|
||||
* @return The fieldName.
|
||||
*/
|
||||
void appendFields(int numberFields,FieldConstPtrArray fields);
|
||||
/**
|
||||
* Remove a field from the structure.
|
||||
* @param field The field to remove.
|
||||
*/
|
||||
void removeField(int index);
|
||||
String getFieldName(std::size_t fieldIndex){return fieldNames[fieldIndex];}
|
||||
/**
|
||||
* Convert the structure to a string and add it to builder.
|
||||
* @param builder The string builder.
|
||||
@@ -398,68 +451,109 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual String getID() const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
|
||||
|
||||
protected:
|
||||
Structure(String fieldName, int numberFields,FieldConstPtrArray fields);
|
||||
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, String const & id = DEFAULT_ID);
|
||||
private:
|
||||
int numberFields;
|
||||
FieldConstPtrArray fields;
|
||||
void toStringCommon(StringBuilder buf,int indentLevel) const;
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
String id;
|
||||
friend class FieldCreate;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a singlton class for creating introspection interfaces.
|
||||
*/
|
||||
class FieldCreate : NoDefaultMethods {
|
||||
class FieldCreate;
|
||||
typedef std::tr1::shared_ptr<FieldCreate> FieldCreatePtr;
|
||||
|
||||
class FieldCreate {
|
||||
public:
|
||||
/**
|
||||
* Create a new Field like an existing field but with a different name.
|
||||
* @param fieldName The field name.
|
||||
* @param field An existing field
|
||||
* @return a {@code Field} interface for the newly created object.
|
||||
*/
|
||||
FieldConstPtr create(String fieldName,FieldConstPtr field) const;
|
||||
static FieldCreatePtr getFieldCreate();
|
||||
/**
|
||||
* Create a {@code ScalarField}.
|
||||
* @param fieldName The field name.
|
||||
* @param scalarType The scalar type.
|
||||
* @return a {@code Scalar} interface for the newly created object.
|
||||
* @throws An {@code IllegalArgumentException} if an illegal type is specified.
|
||||
*/
|
||||
ScalarConstPtr createScalar(String fieldName,ScalarType scalarType) const;
|
||||
ScalarConstPtr createScalar(ScalarType scalarType) const;
|
||||
/**
|
||||
* Create an {@code Array} field.
|
||||
* @param fieldName The field name
|
||||
* @param elementType The {@code scalarType} for array elements
|
||||
* @return An {@code Array} Interface for the newly created object.
|
||||
*/
|
||||
ScalarArrayConstPtr createScalarArray(String fieldName,
|
||||
ScalarType elementType) const;
|
||||
ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
|
||||
/**
|
||||
* Create an {@code Array} field that is has element type <i>Structure</i>
|
||||
* @param fieldName The field name
|
||||
* @param elementStructure The {@code Structure} for each array element.
|
||||
* @return An {@code Array} Interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr createStructure (String fieldName,
|
||||
int numberFields,FieldConstPtrArray fields) const;
|
||||
StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
|
||||
/**
|
||||
* Create a {@code Structure} field.
|
||||
* @param fieldName The field name
|
||||
* @param fields The array of {@code Field}s for the structure.
|
||||
* @param fieldNames The array of {@code fieldNames} for the structure.
|
||||
* @param fields The array of {@code fields} for the structure.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
*/
|
||||
StructureArrayConstPtr createStructureArray(String fieldName,
|
||||
StructureConstPtr structure) const;
|
||||
StructureConstPtr createStructure (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
* Create a {@code Structure} field with identification string.
|
||||
* @param id The identification string for the structure.
|
||||
* @param fieldNames The array of {@code fieldNames} for the structure.
|
||||
* @param fields The array of {@code fields} for the structure.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr createStructure (
|
||||
String const & id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
* Append a field to a structure.
|
||||
* @param structure The structure to which the field is appended.
|
||||
* @param fieldName The name of the field.
|
||||
* @param field The field.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr appendField(
|
||||
StructureConstPtr const & structure,
|
||||
String const & fieldName, FieldConstPtr const & field) const;
|
||||
/**
|
||||
* Append fields to a structure.
|
||||
* @param structure The structure to which the fields appended.
|
||||
* @param fieldName The names of the fields.
|
||||
* @param field The fields.
|
||||
* @return a {@code Structure} interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr appendFields(
|
||||
StructureConstPtr const & structure,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
* Deserialize {@code Field} instance from given byte buffer.
|
||||
* @param buffer Buffer containing serialized {@code Field} instance.
|
||||
* @param control Deserialization control instance.
|
||||
* @return a deserialized {@code Field} instance.
|
||||
*/
|
||||
FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
|
||||
|
||||
private:
|
||||
FieldCreate();
|
||||
friend FieldCreate * getFieldCreate();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the single class that implemnents FieldCreate,
|
||||
* @param The fieldCreate factory.
|
||||
*/
|
||||
extern FieldCreate * getFieldCreate();
|
||||
extern FieldCreatePtr getFieldCreate();
|
||||
|
||||
}}
|
||||
#endif /* PVINTROSPECT_H */
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/* pvType.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* Author - Marty Kraimer
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
|
||||
/* Definitions for the primitive types for pvData.
|
||||
@@ -13,7 +15,19 @@
|
||||
#ifndef PVTYPE_H
|
||||
#define PVTYPE_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __vxworks
|
||||
typedef int intptr_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
#define INT64_MAX (0x7fffffffffffffffLL)
|
||||
#define UINT64_MAX (0xffffffffffffffffLL)
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <pv/sharedPtr.h>
|
||||
#include <pv/localStaticLock.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -24,7 +38,7 @@ namespace epics { namespace pvData {
|
||||
/**
|
||||
* boolean, i.e. can only have the values {@code false} or {@code true}
|
||||
*/
|
||||
typedef bool boolean;
|
||||
typedef uint8_t boolean;
|
||||
/**
|
||||
* A 8 bit signed integer
|
||||
*/
|
||||
@@ -41,6 +55,14 @@ typedef int32_t int32;
|
||||
* A 64 bit signed integer
|
||||
*/
|
||||
typedef int64_t int64;
|
||||
/**
|
||||
* A 8 bit unsigned integer
|
||||
*/
|
||||
typedef uint8_t uint8;
|
||||
/**
|
||||
* A 16 bit unsigned integer
|
||||
*/
|
||||
typedef uint16_t uint16;
|
||||
/**
|
||||
* A 32 bit unsigned integer
|
||||
*/
|
||||
@@ -60,40 +82,368 @@ typedef std::string String;
|
||||
/**
|
||||
* A boolean array.
|
||||
*/
|
||||
typedef bool * BooleanArray;
|
||||
typedef std::vector<uint8> BooleanArray;
|
||||
typedef std::tr1::shared_ptr<BooleanArray> BooleanArrayPtr;
|
||||
/* get is same is ubyte*/
|
||||
typedef std::vector<uint8>::iterator BooleanArray_iterator;
|
||||
typedef std::vector<uint8>::const_iterator BooleanArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A byte array.
|
||||
*/
|
||||
typedef int8 * ByteArray;
|
||||
typedef std::vector<int8> ByteArray;
|
||||
typedef std::tr1::shared_ptr<ByteArray> ByteArrayPtr;
|
||||
inline int8 * get(ByteArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int8 const * get(ByteArray const &value)
|
||||
{
|
||||
return static_cast<int8 const *>(&value[0]);
|
||||
}
|
||||
inline int8 * get(ByteArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int8 const * get(ByteArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline ByteArray & getVector(ByteArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline ByteArray const & getVector(ByteArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int8>::iterator ByteArray_iterator;
|
||||
typedef std::vector<int8>::const_iterator ByteArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A short array.
|
||||
*/
|
||||
typedef int16 * ShortArray;
|
||||
typedef std::vector<int16> ShortArray;
|
||||
typedef std::tr1::shared_ptr<ShortArray> ShortArrayPtr;
|
||||
inline int16 * get(ShortArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int16 const * get(ShortArray const &value)
|
||||
{
|
||||
return static_cast<int16 const *>(&value[0]);
|
||||
}
|
||||
inline int16 * get(ShortArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int16 const * get(ShortArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline ShortArray & getVector(ShortArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline ShortArray const & getVector(ShortArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int16>::iterator ShortArray_iterator;
|
||||
typedef std::vector<int16>::const_iterator ShortArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A int array.
|
||||
*/
|
||||
typedef int32 * IntArray;
|
||||
typedef std::vector<int32> IntArray;
|
||||
typedef std::tr1::shared_ptr<IntArray> IntArrayPtr;
|
||||
inline int32 * get(IntArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int32 const * get(IntArray const &value)
|
||||
{
|
||||
return static_cast<int32 const *>(&value[0]);
|
||||
}
|
||||
inline int32 * get(IntArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int32 const * get(IntArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline IntArray & getVector(IntArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline IntArray const & getVector(IntArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int32>::iterator IntArray_iterator;
|
||||
typedef std::vector<int32>::const_iterator IntArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A long array.
|
||||
*/
|
||||
typedef int64 * LongArray;
|
||||
typedef std::vector<int64> LongArray;
|
||||
typedef std::tr1::shared_ptr<LongArray> LongArrayPtr;
|
||||
inline int64 * get(LongArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline int64 const * get(LongArray const &value)
|
||||
{
|
||||
return static_cast<int64 const *>(&value[0]);
|
||||
}
|
||||
inline int64 * get(LongArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline int64 const * get(LongArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline LongArray & getVector(LongArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline LongArray const & getVector(LongArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<int64>::iterator LongArray_iterator;
|
||||
typedef std::vector<int64>::const_iterator LongArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned byte array.
|
||||
*/
|
||||
typedef std::vector<uint8> UByteArray;
|
||||
typedef std::tr1::shared_ptr<UByteArray> UByteArrayPtr;
|
||||
inline uint8 * get(UByteArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint8 const * get(UByteArray const &value)
|
||||
{
|
||||
return static_cast<uint8 const *>(&value[0]);
|
||||
}
|
||||
inline uint8 * get(UByteArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint8 const * get(UByteArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline UByteArray & getVector(UByteArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline UByteArray const & getVector(UByteArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint8>::iterator UByteArray_iterator;
|
||||
typedef std::vector<uint8>::const_iterator UByteArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned short array.
|
||||
*/
|
||||
typedef std::vector<uint16> UShortArray;
|
||||
typedef std::tr1::shared_ptr<UShortArray> UShortArrayPtr;
|
||||
inline uint16 * get(UShortArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint16 const * get(UShortArray const &value)
|
||||
{
|
||||
return static_cast<uint16 const *>(&value[0]);
|
||||
}
|
||||
inline uint16 * get(UShortArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint16 const * get(UShortArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline UShortArray & getVector(UShortArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline UShortArray const & getVector(UShortArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint16>::iterator UShortArray_iterator;
|
||||
typedef std::vector<uint16>::const_iterator UShortArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned int array.
|
||||
*/
|
||||
typedef std::vector<uint32> UIntArray;
|
||||
typedef std::tr1::shared_ptr<UIntArray> UIntArrayPtr;
|
||||
inline uint32 * get(UIntArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint32 const * get(UIntArray const &value)
|
||||
{
|
||||
return static_cast<uint32 const *>(&value[0]);
|
||||
}
|
||||
inline uint32 * get(UIntArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint32 const * get(UIntArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline UIntArray & getVector(UIntArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline UIntArray const & getVector(UIntArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint32>::iterator UIntArray_iterator;
|
||||
typedef std::vector<uint32>::const_iterator UIntArray_const_iterator;
|
||||
|
||||
/**
|
||||
* An unsigned long array.
|
||||
*/
|
||||
typedef std::vector<uint64> ULongArray;
|
||||
typedef std::tr1::shared_ptr<ULongArray> ULongArrayPtr;
|
||||
inline uint64 * get(ULongArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline uint64 const * get(ULongArray const &value)
|
||||
{
|
||||
return static_cast<uint64 const *>(&value[0]);
|
||||
}
|
||||
inline uint64 * get(ULongArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline uint64 const * get(ULongArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline ULongArray & getVector(ULongArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline ULongArray const & getVector(ULongArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<uint64>::iterator ULongArray_iterator;
|
||||
typedef std::vector<uint64>::const_iterator ULongArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A float array.
|
||||
*/
|
||||
typedef float * FloatArray;
|
||||
typedef std::vector<float> FloatArray;
|
||||
typedef std::tr1::shared_ptr<FloatArray> FloatArrayPtr;
|
||||
inline float * get(FloatArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline float const * get(FloatArray const &value)
|
||||
{
|
||||
return static_cast<float const *>(&value[0]);
|
||||
}
|
||||
inline float * get(FloatArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline float const * get(FloatArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline FloatArray & getVector(FloatArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline FloatArray const & getVector(FloatArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<float>::iterator FloatArray_iterator;
|
||||
typedef std::vector<float>::const_iterator FloatArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A double array.
|
||||
*/
|
||||
typedef double * DoubleArray;
|
||||
typedef std::vector<double> DoubleArray;
|
||||
typedef std::tr1::shared_ptr<DoubleArray> DoubleArrayPtr;
|
||||
inline double * get(DoubleArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline double const * get(DoubleArray const &value)
|
||||
{
|
||||
return static_cast<double const *>(&value[0]);
|
||||
}
|
||||
inline double * get(DoubleArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline double const * get(DoubleArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline DoubleArray & getVector(DoubleArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline DoubleArray const & getVector(DoubleArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<double>::iterator DoubleArray_iterator;
|
||||
typedef std::vector<double>::const_iterator DoubleArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A string array.
|
||||
*/
|
||||
typedef String* StringArray;
|
||||
typedef std::vector<String> StringArray;
|
||||
typedef std::tr1::shared_ptr<StringArray> StringArrayPtr;
|
||||
inline String * get(StringArray &value)
|
||||
{
|
||||
return &value[0];
|
||||
}
|
||||
inline String const * get(StringArray const &value)
|
||||
{
|
||||
return static_cast<String const *>(&value[0]);
|
||||
}
|
||||
inline String * get(StringArrayPtr &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline String const * get(StringArrayPtr const &value)
|
||||
{
|
||||
return get(*value.get());
|
||||
}
|
||||
inline StringArray & getVector(StringArrayPtr &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
inline StringArray const & getVector(StringArrayPtr const &value)
|
||||
{
|
||||
return *value.get();
|
||||
}
|
||||
typedef std::vector<String>::iterator StringArray_iterator;
|
||||
typedef std::vector<String>::const_iterator StringArray_const_iterator;
|
||||
|
||||
/**
|
||||
* A convenience definition for toString methods
|
||||
*/
|
||||
typedef std::string * StringBuilder;
|
||||
typedef String * StringBuilder;
|
||||
|
||||
}}
|
||||
#endif /* PVTYPE_H */
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* standardField.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* Author - Marty Kraimer
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef STANDARDFIELD_H
|
||||
#define STANDARDFIELD_H
|
||||
#include <string>
|
||||
@@ -20,9 +23,11 @@ namespace epics { namespace pvData {
|
||||
* The property field is a comma separated string of property names of the following:
|
||||
* alarm, timeStamp, display, control, and valueAlarm.
|
||||
* An example is "alarm,timeStamp,valueAlarm".
|
||||
* The method with properties creates a structure with fields named fieldName and each of the property names.s
|
||||
* The method with properties creates a structure with fields named fieldName
|
||||
* and each of the property names.
|
||||
* Each property field is a structure defining the property.
|
||||
* The details about each property is given in the section named "Property". For example the call:
|
||||
* The details about each property is given in the section named "Property".
|
||||
* For example the call:
|
||||
* {@code
|
||||
StructureConstPtr example = standardField->scalar(
|
||||
String("value"),
|
||||
@@ -33,12 +38,13 @@ namespace epics { namespace pvData {
|
||||
structure example
|
||||
double value
|
||||
structure alarm
|
||||
structure severity
|
||||
int index
|
||||
string[] choices
|
||||
structure timeStamp
|
||||
long secondsPastEpoch
|
||||
int nanoSeconds
|
||||
int severity
|
||||
int status
|
||||
string message
|
||||
structure timeStamp
|
||||
long secondsPastEpoch
|
||||
int nanoSeconds
|
||||
int userTag
|
||||
* }
|
||||
* In addition there are methods that create each of the property structures,
|
||||
* i.e. the methods named: alarm, .... enumeratedAlarm."
|
||||
@@ -48,54 +54,77 @@ namespace epics { namespace pvData {
|
||||
* }
|
||||
*/
|
||||
|
||||
class StandardField : private NoDefaultMethods {
|
||||
class StandardField;
|
||||
typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
|
||||
|
||||
class StandardField {
|
||||
public:
|
||||
StandardField();
|
||||
static StandardFieldPtr getStandardField();
|
||||
~StandardField();
|
||||
ScalarConstPtr scalar(String fieldName,ScalarType type);
|
||||
StructureConstPtr scalar(String fieldName,
|
||||
ScalarType type,String properties);
|
||||
ScalarArrayConstPtr scalarArray(String fieldName,
|
||||
ScalarType elementType);
|
||||
StructureConstPtr scalarArray(String fieldName,
|
||||
ScalarType elementType, String properties);
|
||||
StructureArrayConstPtr structureArray(String fieldName,
|
||||
StructureConstPtr structure);
|
||||
StructureConstPtr structureArray(String fieldName,
|
||||
StructureConstPtr structure,String properties);
|
||||
StructureConstPtr structure(String fieldName,
|
||||
int numFields,FieldConstPtrArray fields);
|
||||
StructureConstPtr enumerated(String fieldName);
|
||||
StructureConstPtr enumerated(String fieldName, String properties);
|
||||
ScalarConstPtr scalarValue(ScalarType type);
|
||||
StructureConstPtr scalarValue(ScalarType type,String properties);
|
||||
ScalarArrayConstPtr scalarArrayValue(ScalarType elementType);
|
||||
StructureConstPtr scalarArrayValue(ScalarType elementType,
|
||||
String properties);
|
||||
StructureArrayConstPtr structureArrayValue(StructureConstPtr structure);
|
||||
StructureConstPtr structureArrayValue(StructureConstPtr structure,
|
||||
String properties);
|
||||
StructureConstPtr structureValue(
|
||||
int numFields,FieldConstPtrArray fields);
|
||||
StructureConstPtr enumeratedValue();
|
||||
StructureConstPtr enumeratedValue(String properties);
|
||||
StructureConstPtr scalar(ScalarType type,String const & properties);
|
||||
StructureConstPtr scalarArray(ScalarType elementType, String const & properties);
|
||||
StructureConstPtr structureArray(StructureConstPtr const & structure,String const & properties);
|
||||
StructureConstPtr enumerated();
|
||||
StructureConstPtr enumerated(String const & properties);
|
||||
StructureConstPtr alarm();
|
||||
StructureConstPtr timeStamp();
|
||||
StructureConstPtr display();
|
||||
StructureConstPtr control();
|
||||
StructureConstPtr booleanAlarm();
|
||||
StructureConstPtr byteAlarm();
|
||||
StructureConstPtr ubyteAlarm();
|
||||
StructureConstPtr shortAlarm();
|
||||
StructureConstPtr ushortAlarm();
|
||||
StructureConstPtr intAlarm();
|
||||
StructureConstPtr uintAlarm();
|
||||
StructureConstPtr longAlarm();
|
||||
StructureConstPtr ulongAlarm();
|
||||
StructureConstPtr floatAlarm();
|
||||
StructureConstPtr doubleAlarm();
|
||||
StructureConstPtr enumeratedAlarm();
|
||||
private:
|
||||
static void init();
|
||||
StandardField();
|
||||
void init();
|
||||
StructureConstPtr createProperties(String id,FieldConstPtr field,String properties);
|
||||
FieldCreatePtr fieldCreate;
|
||||
String notImplemented;
|
||||
String valueFieldName;
|
||||
StructureConstPtr alarmField;
|
||||
StructureConstPtr timeStampField;
|
||||
StructureConstPtr displayField;
|
||||
StructureConstPtr controlField;
|
||||
StructureConstPtr booleanAlarmField;
|
||||
StructureConstPtr byteAlarmField;
|
||||
StructureConstPtr shortAlarmField;
|
||||
StructureConstPtr intAlarmField;
|
||||
StructureConstPtr longAlarmField;
|
||||
StructureConstPtr ubyteAlarmField;
|
||||
StructureConstPtr ushortAlarmField;
|
||||
StructureConstPtr uintAlarmField;
|
||||
StructureConstPtr ulongAlarmField;
|
||||
StructureConstPtr floatAlarmField;
|
||||
StructureConstPtr doubleAlarmField;
|
||||
StructureConstPtr enumeratedAlarmField;
|
||||
void createAlarm();
|
||||
void createTimeStamp();
|
||||
void createDisplay();
|
||||
void createControl();
|
||||
void createBooleanAlarm();
|
||||
void createByteAlarm();
|
||||
void createShortAlarm();
|
||||
void createIntAlarm();
|
||||
void createLongAlarm();
|
||||
void createUByteAlarm();
|
||||
void createUShortAlarm();
|
||||
void createUIntAlarm();
|
||||
void createULongAlarm();
|
||||
void createFloatAlarm();
|
||||
void createDoubleAlarm();
|
||||
void createEnumeratedAlarm();
|
||||
friend StandardFieldPtr getStandardField();
|
||||
};
|
||||
|
||||
extern StandardField * getStandardField();
|
||||
extern StandardFieldPtr getStandardField();
|
||||
|
||||
}}
|
||||
#endif /* STANDARDFIELD_H */
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/* standardPVField.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* Author - Marty Kraimer
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#ifndef STANDARDPVFIELD_H
|
||||
#define STANDARDPVFIELD_H
|
||||
@@ -11,6 +13,7 @@
|
||||
#include <stdexcept>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/standardField.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
/**
|
||||
@@ -25,56 +28,27 @@ namespace epics { namespace pvData {
|
||||
* }
|
||||
*/
|
||||
|
||||
class StandardPVField;
|
||||
typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr;
|
||||
|
||||
class StandardPVField : private NoDefaultMethods {
|
||||
public:
|
||||
StandardPVField();
|
||||
static StandardPVFieldPtr getStandardPVField();
|
||||
~StandardPVField();
|
||||
PVScalar * scalar(PVStructure *parent,String fieldName,ScalarType type);
|
||||
PVStructure * scalar(PVStructure *parent,
|
||||
String fieldName,ScalarType type,String properties);
|
||||
PVScalarArray * scalarArray(PVStructure *parent,
|
||||
String fieldName,ScalarType elementType);
|
||||
PVStructure * scalarArray(PVStructure *parent,
|
||||
String fieldName,ScalarType elementType, String properties);
|
||||
PVStructureArray * structureArray(PVStructure *parent,
|
||||
String fieldName,StructureConstPtr structure);
|
||||
PVStructure* structureArray(PVStructure *parent,
|
||||
String fieldName,StructureConstPtr structure,String properties);
|
||||
PVStructure * enumerated(PVStructure *parent,
|
||||
String fieldName,StringArray choices, int number);
|
||||
PVStructure * enumerated(PVStructure *parent,
|
||||
String fieldName,StringArray choices, int number, String properties);
|
||||
PVScalar * scalarValue(PVStructure *parent,ScalarType type);
|
||||
PVStructure * scalarValue(PVStructure *parent,
|
||||
ScalarType type,String properties);
|
||||
PVScalarArray * scalarArrayValue(
|
||||
PVStructure *parent,ScalarType elementType);
|
||||
PVStructure * scalarArrayValue(PVStructure *parent,
|
||||
ScalarType elementType, String properties);
|
||||
PVStructureArray * structureArrayValue(PVStructure *parent,
|
||||
StructureConstPtr structure);
|
||||
PVStructure * structureArrayValue(PVStructure *parent,
|
||||
StructureConstPtr structure,String properties);
|
||||
PVStructure * enumeratedValue(
|
||||
PVStructure *parent,StringArray choices,int number);
|
||||
PVStructure * enumeratedValue(PVStructure *parent,
|
||||
StringArray choices,int number, String properties);
|
||||
PVStructure * alarm(PVStructure *parent);
|
||||
PVStructure * timeStamp(PVStructure *parent);
|
||||
PVStructure * display(PVStructure *parent);
|
||||
PVStructure * control(PVStructure *parent);
|
||||
PVStructure * booleanAlarm(PVStructure *parent);
|
||||
PVStructure * byteAlarm(PVStructure *parent);
|
||||
PVStructure * shortAlarm(PVStructure *parent);
|
||||
PVStructure * intAlarm(PVStructure *parent);
|
||||
PVStructure * longAlarm(PVStructure *parent);
|
||||
PVStructure * floatAlarm(PVStructure *parent);
|
||||
PVStructure * doubleAlarm(PVStructure *parent);
|
||||
PVStructure * enumeratedAlarm(PVStructure *parent);
|
||||
PVStructure * powerSupply(PVStructure *parent);
|
||||
PVStructurePtr scalar(ScalarType type,String const & properties);
|
||||
PVStructurePtr scalarArray(ScalarType elementType, String const & properties);
|
||||
PVStructurePtr structureArray(StructureConstPtr const &structure,String const & properties);
|
||||
PVStructurePtr enumerated(StringArray const &choices);
|
||||
PVStructurePtr enumerated(StringArray const &choices, String const & properties);
|
||||
private:
|
||||
StandardPVField();
|
||||
StandardFieldPtr standardField;
|
||||
FieldCreatePtr fieldCreate;
|
||||
PVDataCreatePtr pvDataCreate;
|
||||
String notImplemented;
|
||||
};
|
||||
|
||||
extern StandardPVField * getStandardPVField();
|
||||
extern StandardPVFieldPtr getStandardPVField();
|
||||
|
||||
}}
|
||||
#endif /* STANDARDPVFIELD_H */
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*bitSetUtil.cpp*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
*/
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/bitSetUtil.h>
|
||||
@@ -11,25 +14,25 @@
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static bool checkBitSetPVField(
|
||||
PVField *pvField,BitSet *bitSet,int initialOffset)
|
||||
PVField *pvField,BitSet *bitSet,int32 initialOffset)
|
||||
{
|
||||
bool atLeastOneBitSet = false;
|
||||
bool allBitsSet = true;
|
||||
int offset = initialOffset;
|
||||
int nbits = pvField->getNumberFields();
|
||||
int32 offset = initialOffset;
|
||||
int32 nbits = pvField->getNumberFields();
|
||||
if(nbits==1) return bitSet->get(offset);
|
||||
int nextSetBit = bitSet->nextSetBit(offset);
|
||||
int32 nextSetBit = bitSet->nextSetBit(offset);
|
||||
if(nextSetBit>=(offset+nbits)) return false;
|
||||
if(bitSet->get(offset)) {
|
||||
if(nbits>1) {
|
||||
for(int i=offset+1; i<offset+nbits; i++) bitSet->clear(i);
|
||||
for(int32 i=offset+1; i<offset+nbits; i++) bitSet->clear(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
PVStructure *pvStructure = static_cast<PVStructure *>(pvField);
|
||||
while(offset<initialOffset + nbits) {
|
||||
PVField *pvSubField = pvStructure->getSubField(offset);
|
||||
int nbitsNow = pvSubField->getNumberFields();
|
||||
PVField *pvSubField = pvStructure->getSubField(offset).get();
|
||||
int32 nbitsNow = pvSubField->getNumberFields();
|
||||
if(nbitsNow==1) {
|
||||
if(bitSet->get(offset)) {
|
||||
atLeastOneBitSet = true;
|
||||
@@ -43,8 +46,8 @@ static bool checkBitSetPVField(
|
||||
PVFieldPtrArray pvSubStructureFields =
|
||||
pvSubStructure->getPVFields();
|
||||
int num = pvSubStructure->getStructure()->getNumberFields();
|
||||
for(int i=0; i<num; i++) {
|
||||
PVField *pvSubSubField = pvSubStructureFields[i];
|
||||
for(int32 i=0; i<num; i++) {
|
||||
PVField *pvSubSubField = pvSubStructureFields[i].get();
|
||||
bool result = checkBitSetPVField(pvSubSubField,bitSet,offset);
|
||||
if(result) {
|
||||
atLeastOneBitSet = true;
|
||||
@@ -60,7 +63,7 @@ static bool checkBitSetPVField(
|
||||
}
|
||||
if(allBitsSet) {
|
||||
if(nbits>1) {
|
||||
for(int i=initialOffset+1; i<initialOffset+nbits; i++){
|
||||
for(int32 i=initialOffset+1; i<initialOffset+nbits; i++){
|
||||
bitSet->clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/*bitSetUtil.h*/
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mes
|
||||
*/
|
||||
#ifndef BITSETUTIL_H
|
||||
#define BITSETUTIL_H
|
||||
#include <pv/noDefaultMethods.h>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Make things golden...
|
||||
|
||||
for ff in *Diff
|
||||
do
|
||||
[ -s "$ff" ] || continue
|
||||
|
||||
cp "${ff%Diff}" "${ff%Diff}Gold"
|
||||
done
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
./testBaseException.sh || exit $?
|
||||
./testPVType.sh || exit $?
|
||||
./testThread.sh || exit $?
|
||||
./testLinkedList.sh || exit $?
|
||||
./testBitSet.sh || exit $?
|
||||
./testByteBuffer.sh || exit $?
|
||||
./testIntrospect.sh || exit $?
|
||||
./testPVData.sh || exit $?
|
||||
./testPVStructureArray.sh || exit $?
|
||||
./testPVAppend.sh || exit $?
|
||||
./testPVAuxInfo.sh || exit $?
|
||||
./testTimeStamp.sh || exit $?
|
||||
./testTimer.sh || exit $?
|
||||
./testQueue.sh || exit $?
|
||||
./testMessageQueue.sh || exit $?
|
||||
./testSerialization.sh || exit $?
|
||||
./testProperty.sh || exit $?
|
||||
@@ -1,46 +0,0 @@
|
||||
|
||||
|
||||
There is a logic_error
|
||||
|
||||
On line 68 of ../testBaseException.cpp
|
||||
../bin/linux-x86/testBaseException[0x80497b9]
|
||||
../bin/linux-x86/testBaseException[0x8049a54]
|
||||
/lib/libc.so.6(__libc_start_main+0xe6)[0x126e36]
|
||||
../bin/linux-x86/testBaseException[0x80490e1]
|
||||
To translate run 'addr2line -e execname 0xXXXXXXX ...'
|
||||
Note: Must be compiled with debug symbols
|
||||
|
||||
|
||||
There is another logic_error
|
||||
|
||||
On line 75 of ../testBaseException.cpp
|
||||
../bin/linux-x86/testBaseException() [0x8049cec]
|
||||
../bin/linux-x86/testBaseException() [0x8049923]
|
||||
../bin/linux-x86/testBaseException() [0x8049a54]
|
||||
/lib/libc.so.6(__libc_start_main+0xe6) [0x126e36]
|
||||
../bin/linux-x86/testBaseException() [0x80490e1]
|
||||
|
||||
testBaseException...
|
||||
|
||||
all is OK
|
||||
On line 48 of ../testBaseException.cpp
|
||||
../bin/linux-x86/testBaseException() [0x8049581]
|
||||
../bin/linux-x86/testBaseException() [0x8049a5c]
|
||||
/lib/libc.so.6(__libc_start_main+0xe6) [0x126e36]
|
||||
../bin/linux-x86/testBaseException() [0x80490e1]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
exception 2
|
||||
On line 57 of ../testBaseException.cpp
|
||||
../bin/linux-x86/testBaseException() [0x80491ec]
|
||||
../bin/linux-x86/testBaseException() [0x80496f9]
|
||||
../bin/linux-x86/testBaseException() [0x8049a5c]
|
||||
/lib/libc.so.6(__libc_start_main+0xe6) [0x126e36]
|
||||
../bin/linux-x86/testBaseException() [0x80490e1]
|
||||
|
||||
|
||||
|
||||
PASSED
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user