123 Commits

Author SHA1 Message Date
Marty Kraimer
aabe0f3594 update links on .html files 2013-09-03 08:37:08 -04:00
dhickin
7c21bf7aa1 Added tag 3.0.0 for changeset 4cecd4b200f8 2013-08-21 12:03:42 +01:00
Marty Kraimer
b518efd196 Added tag 3.0-pre1 for changeset 4cecd4b200f8 2013-07-16 14:47:34 -04:00
Ralph Lange
5f8fa26bf3 jenkins: Fix CloudBees hgweb job 2013-06-19 18:11:04 +02:00
Ralph Lange
a5c835cfeb jenkins: add CloudBees hgweb job to sync repo to SF webspace 2013-06-19 10:59:29 +02:00
Andrew Johnson
d2a649f5fa Fixed compiler warning, 2013-06-12 21:21:44 -05:00
Matej Sekoranja
476f18332a valueAlarm for numeric scalar arrays support 2013-05-31 21:15:54 +02:00
Andrew Johnson
a964e3668d Added jenkins/aps_build script 2013-05-30 17:32:15 -05:00
Marty Kraimer
69be072a07 added test 2013-05-17 19:33:16 -04:00
Marty Kraimer
a2ca21a1a6 changes to queue and to bitSetUtil. 2013-05-16 09:04:42 -04:00
Matej Sekoranja
0dd6f01ef6 direct, i.e. no-copy, de/serialization support 2013-04-12 21:54:11 +02:00
Matej Sekoranja
cd95b75563 gcc 4.7+ compiler warnings removed 2013-02-27 11:44:00 +01:00
Ralph Lange
4122e772c1 merge SF changes 2013-02-26 17:22:16 +01:00
Ralph Lange
2fbe99909c documentation: update Doxyfile 2013-02-26 17:21:28 +01:00
Ralph Lange
d4f3d6209c jenkins: fix URLs for dependencies 2013-02-26 17:20:52 +01:00
Ralph Lange
641a51aa4f Fix .hgignore to use patterns 2013-02-26 17:20:28 +01:00
Matej Sekoranja
67afe84593 mb moved to pvCommonCPP 2013-02-25 10:29:34 +01:00
Matej Sekoranja
66f7c90c51 merge 2013-02-22 21:30:01 +01:00
Matej Sekoranja
959117c391 mb portability, still to be ported to boost atomic 2013-02-22 21:27:26 +01:00
5e810c704f Missing library reference in Makefile 2013-02-21 15:50:57 +01:00
Matej Sekoranja
675243061d -Wextra compiler warnings fixed 2013-02-16 12:50:36 +01:00
Matej Sekoranja
246825d672 base 3.14 fix 2013-02-13 14:29:38 +01:00
Matej Sekoranja
aa1a67d6c1 added micro-benchmark 2013-02-13 14:18:42 +01:00
Matej Sekoranja
97b1848ba3 added array_at manip test 2013-02-11 10:30:30 +01:00
Matej Sekoranja
c4f6132aca added simple operators 'test', added <<= >>= operators to PVScalar 2013-02-08 22:45:04 +01:00
Matej Sekoranja
a0de4f126f operator<< for all PVField, indent and array_at manipulator 2013-02-07 22:52:16 +01:00
Ralph Lange
a8a96def97 jenkins: Publish documentation to .../tip in CloudBees build 2013-01-18 15:19:37 +01:00
Ralph Lange
eaddc30def Add doxygen to Cloudbees build (as local dependency) 2013-01-14 12:22:15 +01:00
Ralph Lange
aa17639e20 Comment out doxygen (which does not work on CloudBees) 2013-01-13 18:32:09 +01:00
Ralph Lange
58d7ad494b Add doxygen run to jenkins build job 2013-01-13 18:20:43 +01:00
Ralph Lange
2895f48bd6 Add build script for Jenkins on Cloudbees 2013-01-13 18:11:55 +01:00
Ralph Lange
8f6ea47501 configure: improved generic RELEASE file 2013-01-11 19:12:50 +01:00
Marty Kraimer
3eb6237343 missing '.' in "This version" and "Previous version" 2012-12-12 15:25:18 -05:00
Marty Kraimer
cb19940fa7 I forget to do an hg add on documentation/pvDataCPP_20121212.html 2012-12-12 15:17:44 -05:00
Marty Kraimer
4bc7e9c8fe several minor problems found while developing pvDatabaseCPP 2012-12-12 14:59:33 -05:00
dhickin
18ba24156c Added tag 2.0-BETA for changeset d70c5ad29163 2012-11-22 15:23:15 +00:00
Marty Kraimer
1d3c4d1762 get rid of unnecessary copies for StringArray 2012-10-29 13:32:34 -04:00
Marty Kraimer
51abc5032c make sure copy of vector is not made 2012-10-20 07:24:07 -04:00
Ralph Lange
69b3692841 Remove IDE configuration files (QtCreator) 2012-10-18 11:36:10 -04:00
Marty Kraimer
d627e08419 fix bug in PVStructure::appendPVField and PVStructure::appendPVFields 2012-10-11 06:19:08 -04:00
Matej Sekoranja
bd9f1d1949 StandardField IDs, dumpValue fix for (u)int8 2012-10-10 17:59:12 +02:00
Matej Sekoranja
04db13d00e default Structure id serialization opt. 2012-10-09 08:43:43 +02:00
Matej Sekoranja
f88f0b4a76 localStaticLock - static local thread-safety 2012-10-08 12:19:21 +02:00
Marty Kraimer
07f9a8c0f6 must include standardField or pvAccessCPP fails 2012-10-03 09:08:51 -04:00
Marty Kraimer
5ba0209f39 get rid of all static global objects 2012-10-03 08:59:23 -04:00
Marty Kraimer
ced439f4c4 fix for crash in pvDataCPP testV3Channel 2012-10-02 16:01:03 -04:00
Matej Sekoranja
cf44ec1191 scalar array (de)serialization fixed 2012-10-01 21:47:43 +02:00
Marty Kraimer
e7458fad01 change name to what it should be 2012-10-01 10:06:01 -04:00
Marty Kraimer
52dfdace88 fix some typos in pvDataCPP.html 2012-10-01 10:02:09 -04:00
Marty Kraimer
a23631a8ca fix bug related to PVStructurePtr createPVStructure(
StringArray const & fieldNames,PVFieldPtrArray const & pvFields);
The old implementation created a new version of each element of pvField.
The new version uses the version from pvFields.
There is a new shared pointer but the new shared pointer referenced the
same PVField as the original.
2012-09-28 06:33:39 -04:00
Unknown
6a378dae0d removed sprintf format warnings 2012-09-14 13:54:35 +02:00
Unknown
0b4a8550e5 type cast warnings removed 2012-09-13 17:50:38 +02:00
Matej Sekoranja
519601595c PVStructure de/serialization fixed 2012-09-12 11:30:58 +02:00
Matej Sekoranja
8dfd8ec02e merge 2012-09-10 08:59:36 +02:00
Matej Sekoranja
4cef1135a3 PVStructure serialization fixed 2012-09-10 08:56:11 +02:00
Unknown
a7bd52bd48 minimize preprocessor branching for vxWorks 2012-09-06 17:12:53 +02:00
Unknown
55df2e06e2 compatibility with vxWorks 2012-09-05 14:11:07 +02:00
Matej Sekoranja
cfc9ebefb0 merge 2012-09-03 23:46:06 +02:00
Matej Sekoranja
516518529c VxWorks ports from Dirk 2012-09-03 23:43:26 +02:00
Marty Kraimer
6b4eb1a1b0 StandardField: fix enumeratedAlarm ; testConvert fix uint64 integer constants 2012-08-28 13:09:37 -04:00
Marty Kraimer
5e3311a024 LICENSE, COPYRIGHT, file header 2012-08-22 14:39:19 -04:00
Matej Sekoranja
233a90e608 merge 2012-08-21 23:35:50 +02:00
Matej Sekoranja
4b26e1c442 dumpValue methods 2012-08-21 23:34:59 +02:00
Marty Kraimer
b216a62d1e changes for "String const&" 2012-08-20 14:51:09 -04:00
Matej Sekoranja
978cb937c4 String const & message 2012-08-20 19:09:01 +02:00
Matej Sekoranja
86adfc091b passing string by const ref 2012-08-20 16:37:26 +02:00
Marty Kraimer
8f3a1dde34 Use "String const &" in many more places 2012-08-20 09:16:43 -04:00
Marty Kraimer
9061e8f731 better implementation of setCapacity 2012-08-20 07:13:05 -04:00
Matej Sekoranja
05be6e6729 append/remove fields now preserves ID 2012-08-20 09:22:27 +02:00
Matej Sekoranja
156a05079e structure array deserialization fixed 2012-08-20 09:03:45 +02:00
Matej Sekoranja
0e48497cd4 array deserialization fixed 2012-08-20 09:01:51 +02:00
Marty Kraimer
fbfed5bab1 make tests more like regresion tests 2012-08-17 14:13:18 -04:00
Marty Kraimer
66fb300873 documentation updated; changes for Field::ID 2012-08-17 06:45:20 -04:00
Matej Sekoranja
6a86496385 added BitSet::size() 2012-07-31 11:47:42 +02:00
Matej Sekoranja
ac10b73e69 Field::getID() added 2012-07-31 10:30:50 +02:00
Matej Sekoranja
689d0875b7 null string check 2012-07-30 22:03:23 +02:00
Matej Sekoranja
d9465b0954 fixed due to monitor.h change 2012-07-24 21:28:37 +02:00
Matej Sekoranja
25b9e5fa5a monitor.h revised 2012-07-24 20:47:56 +02:00
Marty Kraimer
31922eac32 commit so that Matej can look at Monitor 2012-07-23 16:56:49 -04:00
Marty Kraimer
60d3467b1b commit after pull and merge 2012-07-23 07:06:41 -04:00
Marty Kraimer
ec1b5860fd more changes for unsigned 2012-07-23 07:04:25 -04:00
jrowlandls
00196cb7e2 merged 2012-07-20 10:25:34 +01:00
jrowlandls
92c68dfcbc pvData ctypes: added context handler and handle destructor to test example 2012-07-20 10:25:01 +01:00
Marty Kraimer
1db56f4b29 fix bug in unsigned standardField; missing const in pvIntrospect.h 2012-07-19 16:08:11 -04:00
jrowlandls
038567280b pvData: added C api test 2012-07-19 14:22:37 +01:00
Marty Kraimer
022e6304a3 call epicsExitCallAtExits() 2012-07-17 09:40:41 -04:00
Marty Kraimer
5dcd864c58 more shared_pointer everywhere 2012-07-17 09:23:53 -04:00
Marty Kraimer
32790674d6 changes for PVStructureArray 2012-07-08 12:51:46 -04:00
Marty Kraimer
5d6205cb44 changes to PVStructureArray 2012-07-08 08:38:57 -04:00
Marty Kraimer
27c4da5b73 working on PVStructureArray 2012-07-06 13:03:37 -04:00
Marty Kraimer
5d57e9bbcf remove monitorQueue 2012-07-03 14:52:30 -04:00
Marty Kraimer
9775fd4707 redo monotorQueue 2012-07-02 16:17:58 -04:00
Marty Kraimer
12d13bc2c0 fix bug in renameField; Add check for zero length fieldNames in Structure. 2012-06-22 14:04:05 -04:00
Matej Sekoranja
3991a51fd6 size_t changes 2012-06-07 14:15:12 +02:00
Matej Sekoranja
90960d370d added unsigned ints to the test 2012-05-23 08:08:00 +02:00
Marty Kraimer
126fe9c711 use const where appropriate 2012-05-22 11:51:53 -04:00
Matej Sekoranja
770e63b8da removed BitSetPtr due to possible 4.6.1 gcc problem 2012-05-21 21:11:20 +02:00
Marty Kraimer
e9b0dcd9f4 lots of work on Scalar Arrays 2012-05-21 10:06:28 -04:00
Matej Sekoranja
8040ad5fc7 serialization test, shared-ptr const 2012-05-18 11:42:57 +02:00
Marty Kraimer
24a08fe348 after merge 2012-05-17 16:06:15 -04:00
Marty Kraimer
198eb453be add testConvert 2012-05-17 16:04:49 -04:00
Marty Kraimer
e6a97e83ab fix more bugs 2012-05-17 09:15:19 -04:00
Matej Sekoranja
9ab2262e86 serialization/deserialization of Field-s 2012-05-16 22:11:17 +02:00
Marty Kraimer
29593a6eda get rid of unnecessary method in class StructureArray 2012-05-16 06:46:23 -04:00
Marty Kraimer
27ce426f46 return StringArray instead of StringArray & for choices 2012-05-15 16:06:33 -04:00
Marty Kraimer
ca195b44cf more debuging 2012-05-15 11:58:24 -04:00
Marty Kraimer
a396d8e6ac change the way PVField::getFieldName is implemented 2012-05-15 09:40:44 -04:00
Marty Kraimer
d320f00e96 fix messageType name 2012-05-10 06:28:27 -04:00
Marty Kraimer
7a60e02d5c make methods non inline 2012-05-09 15:38:19 -04:00
Marty Kraimer
fb453ea9e5 working on queue code 2012-05-09 14:06:17 -04:00
Marty Kraimer
87bff33c30 support unsigned; move fieldName; pvData use shared_pointer everywhere 2012-05-08 09:29:30 -04:00
Matej Sekoranja
2693201cfd OK -> Ok 2012-03-29 08:19:39 +02:00
Matej Sekoranja
2dba4aab2b Dirk's VxWorks porting 2012-03-28 20:40:49 +02:00
Matej Sekoranja
6caa725f5a Field serialization moved to pvData 2012-03-27 10:32:37 +02:00
msekoranja
198562c36c Added tag 1.1-BETA for changeset 4559c3de0cb4 2012-03-25 22:26:21 +02:00
jrowlandls
686a46f24c Added tag 1.0.1-BETA for changeset 9c59737f56e7 2012-03-14 16:27:36 +00:00
jrowlandls
c6debc3208 Added tag marchtest for changeset a29729ca0ecd 2012-03-07 16:03:20 +00:00
jrowlandls
7d3da0087a added local configs to hgignore 2012-01-03 15:19:28 +00:00
jrowlandls
f8e37ea18f updated RELEASE comments - need a default RELEASE for the build server 2011-12-22 11:11:20 +00:00
jrowlandls
b857c8f69c updated RELEASE comments 2011-12-22 11:08:27 +00:00
Marty Kraimer
b3cfd12487 update abstract 2011-12-20 09:23:43 -05:00
Marty Kraimer
04dc3a18ba change abstract 2011-12-20 08:22:28 -05:00
jrowlandls
1702f2aceb Added tag 1.1-SNAPSHOT for changeset d29d84f4c3f3 2011-12-19 18:25:45 +00:00
216 changed files with 32232 additions and 14334 deletions

View File

@@ -1,7 +1,11 @@
QtC-pvData.creator.user
bin
lib
doc
include
documentation/html
./O.*
^QtC-
^bin/
^lib/
^doc/
^include/
^db/
^dbd/
^documentation/html
envPaths
configure/.*\.local
/O\..*

View File

@@ -1,2 +1,9 @@
459f10877e5628241704f31437b4cbd342df0798 test1
6e8a22d01e824702088195c08bf50bfb6f293de5 1.0-BETA
d29d84f4c3f389f2accd497185b106c8541f95c9 1.1-SNAPSHOT
a29729ca0ecd60b66f2d997031d97911377e44a7 marchtest
9c59737f56e71aef641b70d0f72aa768fd7f8414 1.0.1-BETA
4559c3de0cb4e3420e26272817f58bab005063ec 1.1-BETA
d70c5ad29163306f50979a95b5aebbe9a93cfe76 2.0-BETA
4cecd4b200f88ab57bbb81978c45df2a67bbece1 3.0-pre1
4cecd4b200f88ab57bbb81978c45df2a67bbece1 3.0.0

12
COPYRIGHT Normal file
View 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
*************************************************** */

1694
Doxyfile

File diff suppressed because it is too large Load Diff

78
LICENSE Normal file
View 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.
________________________________________________________________________

View File

@@ -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>

View File

@@ -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

View File

@@ -1,4 +0,0 @@
include
pvDataApp/factory
pvDataApp/misc
pvDataApp/pv

View File

@@ -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

View File

@@ -1,33 +1,25 @@
#RELEASE Location of external products
# pvDataCPP RELEASE - Location of external support modules
#
# IF YOU MAKE ANY CHANGES to this file you MUST at least run
# "gnumake" in this directory afterwards; you usually need
# to run "gnumake rebuild" in the application's top level
# directory each time this file is changed.
# IF YOU CHANGE this file or any file it includes you must
# subsequently do a "gnumake rebuild" in the application's
# top level directory.
#
# NOTE: The build does not check dependencies against files
# that are outside this application, thus you should run
# "gnumake distclean install" in the top directory each time
# EPICS_BASE, SNCSEQ, or any other external module defined
# in the RELEASE file is rebuilt.
# The build process does not check dependencies against files
# that are outside this application, thus you should also do a
# "gnumake rebuild" in the top level directory after EPICS_BASE
# or any other external module pointed to below is rebuilt.
#
# Host/target specific settings can be specified in files named
# Host- or target-specific settings can be given in files named
# RELEASE.$(EPICS_HOST_ARCH).Common
# RELEASE.Common.$(T_A)
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
#If using the sequencer, point SNCSEQ at its top directory:
#SNCSEQ=$(EPICS_BASE)/../modules/soft/seq
# EPICS_BASE usually appears last so other apps can override stuff:
#EPICS_BASE=/opt/epics/base
EPICS_BASE=/home/install/epics/base
#Capfast users may need the following definitions
#CAPFAST_TEMPLATES=
#SCH2EDIF_PATH=
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your EPICS_BASE
# and PVCOMMON build directories, e.g.
# EPICS_BASE = /home/install/epics/base
# PVCOMMON = /home/install/epicsV4/pvCommonCPP
-include $(TOP)/configure/RELEASE.local
-include $(TOP)/../RELEASE.local

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

29
jenkins/aps_build Normal file
View File

@@ -0,0 +1,29 @@
# pvData C++ implementation
# Jenkins @ APS build script
#
# Jenkins invokes scripts with the "-ex" option. So the build is considered a failure
# if any of the commands exits with a non-zero exit code.
#
# Author: Ralph Lange <Ralph.Lange@gmx.de> and Andrew Johnson <anj@aps.anl.gov>
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
# All rights reserved. Use is subject to license terms.
###########################################
# Build
export EPICS_BASE=${HOME}/jobs/epics-base-3.14/workspace
export EPICS_HOST_ARCH=$(${EPICS_BASE}/startup/EpicsHostArch)
cat > configure/RELEASE.local << EOF
PVCOMMON=${HOME}/jobs/epics-pvCommon/workspace
EPICS_BASE=${EPICS_BASE}
EOF
make distclean all
###########################################
# Test
for t in bin/linux-x86_64/test*; do
$t
done

57
jenkins/cloudbees_build Normal file
View File

@@ -0,0 +1,57 @@
# pvData C++ implementation
# Jenkins @ Cloudbees build script
#
# Jenkins invokes scripts with the "-ex" option. So the build is considered a failure
# if any of the commands exits with a non-zero exit code.
#
# Author: Ralph Lange <Ralph.Lange@gmx.de>
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
# All rights reserved. Use is subject to license terms.
###########################################
# Fetch and unpack dependencies
export STUFF=/tmp/stuff
rm -fr ${STUFF}
mkdir -p ${STUFF}
cd ${STUFF}
wget -nv https://openepics.ci.cloudbees.com/job/Base-3.14.12.3_Build/lastSuccessfulBuild/artifact/baseR3.14.12.3.CB-dist.tar.gz
wget -nv https://openepics.ci.cloudbees.com/job/Doxygen-1.8.3_Build/lastSuccessfulBuild/artifact/doxygen-1.8.3.CB-dist.tar.gz
tar -xzf baseR3.14.12.3.CB-dist.tar.gz
tar -xzf doxygen-1.8.3.CB-dist.tar.gz
###########################################
# Build
cd ${WORKSPACE}
export EPICS_BASE=${STUFF}
export EPICS_HOST_ARCH=$(${EPICS_BASE}/startup/EpicsHostArch)
export LD_LIBRARY_PATH=${EPICS_BASE}/lib/${EPICS_HOST_ARCH}
export PATH=${STUFF}/bin:${PATH}
cat > configure/RELEASE.local << EOF
EPICS_BASE=${EPICS_BASE}
EOF
make distclean all
doxygen
###########################################
# Test
for t in bin/linux-x86_64/test*; do
$t
done
###########################################
# Create distribution
tar czf pvData.CB-dist.tar.gz lib include COPYRIGHT LICENSE
###########################################
# Publish documentation
rsync -aP --delete -e ssh documentation epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/pvDataCPP/tip

20
jenkins/cloudbees_hgweb Normal file
View File

@@ -0,0 +1,20 @@
# pvData C++ implementation
# Jenkins @ Cloudbees hgweb sync script
#
# Jenkins invokes scripts with the "-ex" option. So the build is considered a failure
# if any of the commands exits with a non-zero exit code.
#
# Author: Ralph Lange <Ralph.Lange@gmx.de>
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
# All rights reserved. Use is subject to license terms.
###########################################
# Fetch complete repo
rm -fr hgweb
hg clone -U http://hg.code.sf.net/p/epics-pvdata/pvDataCPP hgweb
###########################################
# Sync into SF webspace
rsync -aqP --delete --exclude=\.hg/hgrc -e ssh hgweb/.hg epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/repos/pvDataCPP

View File

@@ -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,12 +91,8 @@ LIBSRCS += bitSetUtil.cpp
SRC_DIRS += $(PVDATA)/monitor
INC += monitor.h
INC += monitorQueue.h
LIBSRCS += monitorQueue.cpp
LIBRARY=pvData
LIBRARY = pvData
pvData_LIBS += Com
include $(TOP)/configure/RULES

View File

@@ -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

View File

@@ -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);
}
}
}
}}

View File

@@ -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*/

View File

@@ -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{
}
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);
void Scalar::toString(StringBuilder buffer,int /*indentLevel*/) const{
*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];
}
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);
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();
}
}}

View File

@@ -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,91 @@
#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;
}
std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array)
{
return array.dumpValue(manip.stream, manip.index);
}
}}

View File

@@ -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);
}
}

View File

@@ -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,16 +59,20 @@ 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;}
void BasePVScalar<T>::put(T val)
{
value = val;
PVField::postPut();
}
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 +80,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,29 +102,33 @@ 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;}
void BasePVString::put(String val)
{
value = val;
postPut();
}
void BasePVString::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const
@@ -131,15 +143,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();
if (offset < 0) offset = 0;
else if (offset > length) offset = length;
if (count < 0) count = 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 +164,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 +231,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;
//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 +300,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 +312,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 +330,35 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
template<typename T>
void DefaultPVArray<T>::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
int size = SerializeHelper::readSize(pbuffer, pcontrol);
// if (size>0) { pcontrol->ensureData(sizeof(T)-1); pbuffer->align(sizeof(T)); }
if(size>=0) {
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
// alignment 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);
// try to avoid deserializing from the buffer
// this is only possible if we do not need to do endian-swapping
if (!pbuffer->reverse<T>())
if (pcontrol->directDeserialize(pbuffer, (char*)(get()), size, sizeof(T)))
{
// inform about the change?
PVField::postPut();
return;
}
// retrieve value from the buffer
int i = 0;
size_t i = 0;
T * pvalue = get();
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(pvalue+i, maxCount);
i += maxCount;
if(i<size)
@@ -285,43 +366,51 @@ 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
}
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)
/*if(offset<0)
offset = 0;
else if(offset>length) offset = length;
if(count<0) count = length;
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;
// try to avoid copying into the buffer
// this is only possible if we do not need to do endian-swapping
if (!pbuffer->reverse<T>())
if (pflusher->directSerialize(pbuffer, (const char*)(get()+offset), count, sizeof(T)))
return;
size_t end = offset+count;
size_t i = offset;
T * pvalue = const_cast<T *>(get());
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)));
pbuffer->putArray(pvalue+i, maxCount);
i += maxCount;
if(i<end)
@@ -336,266 +425,291 @@ void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
template<>
void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
int size = SerializeHelper::readSize(pbuffer, pcontrol);
if(size>=0) {
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
}
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)
/*if(offset<0)
offset = 0;
else if(offset>length) offset = length;
if(count<0) count = length;
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();
}
}}

View File

@@ -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,195 @@ 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.get()!=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& operator<<(std::ostream& o, const PVField& f)
{
std::ostream& ro = f.dumpValue(o);
// TODO I do not want to call getPVAuxInfo() since it lazily creates a new instance of it
//if (f.pvAuxInfo.get()!=NULL) ro << *(f.pvAuxInfo.get());
return ro;
};
namespace format
{
std::ostream& operator<<(std::ostream& os, indent_level const& indent)
{
indent_value(os) = indent.level;
return os;
}
std::ostream& operator<<(std::ostream& os, indent const&)
{
long il = indent_value(os);
std::size_t spaces = static_cast<std::size_t>(il) * 4;
return os << std::string(spaces, ' ');
}
array_at_internal operator<<(std::ostream& str, array_at const& manip)
{
return array_at_internal(manip.index, str);
}
};
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 +259,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;
}
}}

View File

@@ -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());
}
}}

View File

@@ -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

View File

@@ -0,0 +1,276 @@
/*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);
}
}
}
std::ostream& PVStructureArray::dumpValue(std::ostream& o) const
{
o << format::indent() << getStructureArray()->getID() << ' ' << getFieldName() << std::endl;
size_t length = getLength();
if (length > 0)
{
format::indent_scope s(o);
for (size_t i = 0; i < length; i++)
dumpValue(o, i);
}
return o;
}
std::ostream& PVStructureArray::dumpValue(std::ostream& o, std::size_t index) const
{
PVStructurePtrArray pvArray = *value.get();
PVStructurePtr pvStructure = pvArray[index];
return o << *(pvStructure.get());
return o;
}
}}

View File

@@ -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,35 +65,41 @@ static StructureConstPtr createProperties(String fieldName,FieldConstPtr field,S
StructureConstPtr valueAlarm;
Type type= field->getType();
while(gotValueAlarm) {
if(type==scalar) {
ScalarConstPtr scalar = static_pointer_cast<const Scalar>(field);
ScalarType scalarType = scalar->getScalarType();
if(type==epics::pvData::scalar || type==epics::pvData::scalarArray) {
ScalarType scalarType = (type==epics::pvData::scalar) ?
static_pointer_cast<const Scalar>(field)->getScalarType() :
static_pointer_cast<const ScalarArray>(field)->getElementType();
switch(scalarType) {
case pvBoolean: valueAlarm = booleanAlarmField; break;
case pvByte: valueAlarm = byteAlarmField; break;
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 +114,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 +570,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 +620,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();
}
}}

View File

@@ -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();
}
}}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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)
@@ -326,16 +331,16 @@ namespace epics { namespace pvData {
return !(*this == set);
}
void BitSet::toString(StringBuilder buffer, int indentLevel) const
void BitSet::toString(StringBuilder buffer, int /*indentLevel*/) const
{
*buffer += '{';
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 += '}';

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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,11 +603,29 @@ private:
char* _buffer;
char* _position;
char* _limit;
uintptr_t _size;
std::size_t _size;
bool _reverseEndianess;
bool _reverseFloatEndianess;
};
template<>
inline bool ByteBuffer::reverse<bool>()
{
return false;
}
template<>
inline bool ByteBuffer::reverse<int8>()
{
return false;
}
template<>
inline bool ByteBuffer::reverse<uint8>()
{
return false;
}
template<>
inline bool ByteBuffer::reverse<float>()
{
@@ -844,6 +638,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++;
}
}
}
}
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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.
*/
/*

View File

@@ -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()

View File

@@ -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;
};
}}

View File

@@ -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);}
}}

View File

@@ -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;
};
}}

View File

@@ -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 */

View File

@@ -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;
}
}}

View File

@@ -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 */

View 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;
}
}

View 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 */

View File

@@ -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>
@@ -41,6 +44,15 @@ public:
locked=false;
}
}
bool tryLock()
{
if(locked) return true;
if(mutexPtr.tryLock()) {
locked = true;
return true;
}
return false;
}
bool ownsLock() const{return locked;}
private:
Mutex &mutexPtr;

View File

@@ -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));
}
}}

View File

@@ -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;
};
}}

View File

@@ -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 {

View File

@@ -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 const &element);
queueElementPtr & getUsed();
void releaseUsed(queueElementPtr const &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> const &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> const &element)
{
if(element!=elements[nextReleaseUsed++]) {
throw std::logic_error(
"not queueElement returned by last call to getUsed");
}
if(nextReleaseUsed>=size) nextReleaseUsed = 0;
numberUsed--;
numberFree++;
}
}}

View File

@@ -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++;
}
}}

View File

@@ -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 */

View File

@@ -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;
}}

View File

@@ -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;
};
}}

View File

@@ -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,27 @@ 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 bool directSerialize(ByteBuffer *existingBuffer, const char* toSerialize,
std::size_t elementCount, std::size_t elementSize) = 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 bool directDeserialize(ByteBuffer *existingBuffer, char* deserializeTo,
std::size_t elementCount, std::size_t elementSize) = 0;
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer) = 0;
};
class Serializable {
@@ -54,7 +65,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;
};
}}

View File

@@ -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)
/*if(offset<0)
offset = 0;
else if(offset>(int)value.length()) offset = value.length();
else*/ if(offset>value.length()) offset = value.length();
if(offset+count>(int)value.length()) count = value.length()-offset;
if(offset+count>value.length()) count = value.length()-offset;
SerializeHelper::writeSize(count, buffer, flusher);
if (count<=0) return;
int i = 0;
/*if (count<=0)*/ return;
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;

View File

@@ -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);
};

View File

@@ -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

View File

@@ -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);
}
@@ -114,10 +117,10 @@ String Status::toString() const
return str;
}
void Status::toString(StringBuilder buffer, int indentLevel) 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=";

View File

@@ -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;
};

View File

@@ -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>

View File

@@ -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) {}

View File

@@ -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;
};

View File

@@ -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;
}
}
}}

View File

@@ -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;
};
}}

View File

@@ -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 */

View File

@@ -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());
}
}}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
};
}}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
};
}}

View File

@@ -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;

View File

@@ -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;
};
}}

View File

@@ -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());

View File

@@ -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;
};
}}

View File

@@ -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;
}

View File

@@ -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;
};
}}

View File

@@ -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;

View File

@@ -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;
};
}}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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:
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:
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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

Some files were not shown because too many files have changed in this diff Show More