467 Commits

Author SHA1 Message Date
Ralph Lange
7707da0b45 jenkins: adapt doc script to new CloudBees jenkins job 2015-09-14 16:48:33 +02:00
Dave Hickin
d3853bd4e9 Ignore target-specific RELEASE and CONFIG_SITE in git
Tell gir to ignore configuration files such as RELEASE.win32-x86.Common
or CONFIG_SITE.linux-x86_64.Common.
2015-09-02 16:36:26 +01:00
Dave Hickin
7253bac48a Updated copyright notice and license
Updated copyright notice using the one in normativeTypesCPP. Added
Diamond and BNL. Added legal discalimers for Diamond and BNL to license.
Added dates to copyright notice. "All rights reserved" added to
copyright.
2015-09-02 14:04:29 +01:00
dhickin
973fbeeba5 Merge pull request #8 from dhickin/move_getSubFieldT_def_from_class_body
Move getSubFieldT definitions out of class body
2015-09-01 17:03:14 +01:00
dhickin
f22cefba97 Merge pull request #11 from anjohnson/fix-mac-build
Fix build problem on Mac
2015-09-01 17:00:58 +01:00
Ralph Lange
a5abc37b17 Add QtCreator pattern to .gitignore 2015-08-18 16:11:33 +02:00
Ralph Lange
b95fa7be56 jenkins: remove hgweb job; split doc and build jobs; update EPICS Base version 2015-08-18 16:11:05 +02:00
Andrew Johnson
f6cf87a52d Fix build problem on Mac
../../testApp/pv/testPVData.cpp:549:14: error: use of overloaded operator '!='
      is ambiguous (with operand types 'PVIntPtr' (aka 'shared_ptr<PVInt>') and
      'long')
    testOk1(a!=NULL);
            ~^ ~~~~
2015-08-12 15:06:46 -05:00
dhickin
51f36b2281 Merge pull request #10 from dhickin/remove_deprecated_getDerivedTypeField
Remove deprecated PVStructure::get*Field Functions
2015-07-29 12:29:08 +01:00
Dave Hickin
ddebd494c6 Remove deprecated PVStructure::get*Field Functions
Remove the deprecated functions such as getIntField in PVStructure,
whose usage has been replaced by that of the template getSubField
function and which are now no longer called anywhere.
2015-07-28 17:45:26 +01:00
dhickin
d0a8d2b1cd Merge pull request #9 from dhickin/replace_calls_getScalarArrayField
Replace calls of deprecated PVStructure::getScalarArrayField
2015-07-28 17:07:50 +01:00
Dave Hickin
1731a0daf6 USAGE_DEPRECATED macro used for getScalarArrayField 2015-07-24 16:56:49 +01:00
Dave Hickin
3487b3ee9e Remove unused argument in testPVScalarArray 2015-07-24 11:22:50 +01:00
Dave Hickin
5834efb709 Remove calls of deprecated getScalarArrayField 2015-07-24 11:21:58 +01:00
Dave Hickin
52bc6d060d Move getSubFieldT definitions out of class body
Move definitions of 2 getSubFieldT overloads:
shared_ptr<PVT> PVStructure::getSubFieldT(const char *name) const
shared_ptr<PVT> PVStructure::getSubFieldT(size_t fieldOffset) const
out of class body so not implicitly inlined.
2015-07-15 11:34:44 +01:00
dhickin
35ca5f3aed Merge pull request #7 from dhickin/getSubFieldT
GetSubFieldT
2015-07-14 16:19:38 +01:00
Dave Hickin
ac2b6ea8db Make getSubFieldT return shared pointer
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-13 12:48:05 +01:00
Dave Hickin
9827caa3e3 Make overloads of getSubField and getSubFieldT match
For each getSubField overload a throwing getSubFieldT has been added and
vice versa. These have been documented in doxygen and in the module
documentation.

Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-13 12:41:47 +01:00
Dave Hickin
ebe2d6196c Rename getAs getSubFieldT
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-13 12:34:15 +01:00
Dave Hickin
e4689dd3f8 Added unit tests for functions for getting subfields
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-13 12:07:54 +01:00
Dave Hickin
1dba611b8e Improve exception messages when getting PVStructure subfield
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-13 11:47:21 +01:00
Dave Hickin
97cbea6f4d Implement getSubField functions without using exceptions
Implementation of getSubField (and getScalarArrayField) introduced in
the getAs pull request throws an exception then catches it to return a
null pointer. Implement without throwing.

Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-13 02:16:08 +01:00
Dave Hickin
d9963b0631 Add test for getAs when mid-field not structure
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-09 13:22:42 +01:00
Dave Hickin
8418303ce2 Fix bug in new PVStructure::getAs function
Fix seg fault when getAs is called with a string of the form x.y (or
x_1. ... x_n.y) where x or (x1. ... .x_i) is not a structure field.

Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-09 13:21:45 +01:00
Dave Hickin
40952df965 Corrected spelling in test and exception messages
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-08 18:19:53 +01:00
Dave Hickin
4f2c51c480 Correct spelling and typos in doxygen and comments
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-07-08 18:18:37 +01:00
Marty Kraimer
fd31a0d6b0 Merge pull request #6 from mdavidsaver/dropprinter
remove unused PrinterPlain
2015-06-27 07:00:15 -04:00
Michael Davidsaver
9ad725a272 remove unused PrinterPlain 2015-06-25 16:51:04 -04:00
Marty Kraimer
2b6172ba63 Merge pull request #5 from mrkraimer/master
document new PVStructure::getAs method
2015-06-23 10:12:10 -04:00
Marty Kraimer
c521f9299d document new PVStructure::getAs method 2015-06-23 08:24:54 -04:00
Marty Kraimer
1e646f8df1 Merge pull request #4 from mdavidsaver/getasfield
Add PVStructure::getAs<>()
2015-06-23 07:24:30 -04:00
Marty Kraimer
b5a436c1b7 Merge pull request #3 from mdavidsaver/getdeprecate
Deprecated PVStructure::get*Field methods trigger a warning
2015-06-23 07:17:38 -04:00
Michael Davidsaver
4f25c7a3ea remove findSubField 2015-06-22 18:14:23 -04:00
Michael Davidsaver
eadb8ff65b add PVStructure::getAs<>() for field access w/o NULL 2015-06-22 18:14:23 -04:00
Michael Davidsaver
6a80e941a0 replace use of depercated methods 2015-06-22 14:36:27 -04:00
Michael Davidsaver
7fc9b42b3a PVStructure: compiler warning when deprecated methods are used 2015-06-22 14:27:44 -04:00
Dave Hickin
0d857999bf Make default type ID strings const.
Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
2015-06-17 14:51:07 +01:00
Marty Kraimer
8ba71b048e Merge pull request #1 from mdavidsaver/errmsg
Friendlier exception messages w/ stack trace during Field creation
2015-06-15 06:41:34 -04:00
Michael Davidsaver
e07f6c1703 Friendlier exception messages w/ stack trace during Field creation 2015-06-12 13:54:03 -04:00
Marty Kraimer
e4f38121d2 remove qtcreator file 2015-06-10 10:31:08 -04:00
Marty Kraimer
255ee3f151 clean up conversion from hg to got; remove qtcreator files 2015-06-09 08:43:41 -04:00
dhickin
e72dbaabe1 Add some doxygen 2015-06-08 10:06:06 +01:00
dhickin
b39662450f Fix for windows static build static initialisation errors. 2015-06-08 04:58:04 +01:00
dhickin
98da0c0bec Add template getField member functions which return specific field types to Structure and Union. 2015-03-30 09:05:59 +01:00
dhickin
45dde325fd Change the printing of structure array and union array fields of structure introspection objects. Removes superfluous information and brings it in line with pvData meta language. 2015-03-20 17:23:32 +00:00
dhickin
2967a8f798 Declare the one argument constructors of PVField and its derived classes explicit. 2015-03-06 21:05:50 +00:00
Matej Sekoranja
d4bdc73948 documentation/RELEASE_NOTES.md updated 2015-02-18 14:26:19 +01:00
Matej Sekoranja
37c2f6bb17 merge 2015-02-18 10:11:15 +01:00
Matej Sekoranja
a8e4d749e3 flow: Merged <feature> 'copy_refactoring' to <develop> ('default'). 2015-02-18 10:02:17 +01:00
Matej Sekoranja
3df16ee449 flow: Closed <feature> 'copy_refactoring'. 2015-02-18 10:02:17 +01:00
Matej Sekoranja
332c2f959b added copy() method back to convert, since it is usually used by external modules; marked as DEPRECATED 2015-02-17 22:36:28 +01:00
Matej Sekoranja
a1b89c9a3b PVScalar::copy made public; copy tests 2015-02-17 21:54:35 +01:00
Matej Sekoranja
d6921fdac0 removal of some methods from convert 2015-02-17 20:22:37 +01:00
Matej Sekoranja
4cb3c22221 update code to the new method, removed copy from convert 2015-02-17 18:56:56 +01:00
Matej Sekoranja
cc1536b6e1 moved operators to pvData/pvIntrospect, added copy/copyUnchecked methods 2015-02-17 13:59:15 +01:00
Matej Sekoranja
92a178cbf9 flow: Created branch 'feature/copy_refactoring'. 2015-02-17 09:36:44 +01:00
dhickin
fbebce0a49 Make sure postPut is called precisely once and after put in Convert::copyUnion. 2015-02-11 22:17:45 +00:00
Matej Sekoranja
b13bb9819a updated testPlan(0) to actual value 2015-02-11 20:56:38 +01:00
Matej Sekoranja
bb505b8ed9 win32: new operators were missing exports 2015-02-11 15:41:12 +01:00
dhickin
cf030bc711 Call postPut() in Convert::copyUnion(). 2015-02-11 14:04:15 +00:00
Marty Kraimer
6cb95c5cfc fixed possible SEGFAULT in ceateRequest; new stream operator for Field and PVField 2015-02-11 07:26:04 -05:00
Matej Sekoranja
a277a4fdd5 copy schematic 2015-02-11 11:30:39 +01:00
Matej Sekoranja
388799d39d monitors: minor monitor API doc update 2015-02-01 00:46:55 +01:00
Matej Sekoranja
4acf7edf95 non-copy (by reference) retrival of getFields()/getPVFields()/getFieldNames() 2015-01-30 11:35:43 +01:00
Matej Sekoranja
e39346d51e missing swap templates for unsigned types 2015-01-21 20:19:23 +01:00
Ralph Lange
5ae6de4f1d jenkins: fix cloudbees script (commands must return 0) 2014-12-19 14:01:13 +01:00
Ralph Lange
e0f1427af7 jenkins: create and update documentation in only one build configuration 2014-12-19 13:18:52 +01:00
Ralph Lange
69297bdb58 jenkins: make EPICS base a parameter in jenkins job 2014-12-12 09:49:01 +01:00
Marty Kraimer
0fa2f2c2ff merge branch release/4.0 2014-12-11 14:11:54 -05:00
Marty Kraimer
9efce46fff work on doxygen 2014-12-11 09:47:20 -05:00
dhickin
c356ecb402 make local RELEASE.local files take precedence over those in TOP/.. 2014-12-09 13:45:56 +00:00
dhickin
4c6887e7ec Added tag 4.0.3 for changeset 8543734dbf6e 2014-12-05 11:30:03 +00:00
Marty Kraimer
6d338cab15 merge branch release/4.0 2014-12-04 08:30:26 -05:00
dhickin
354fdd412f make "local" *.local files take precedence over those in TOP/.. 2014-12-03 16:55:27 +00:00
dhickin
f3f6141e6a include CONFIG_SITE.local instead of CONFIG.local at top-level. 2014-12-03 16:10:25 +00:00
Matej Sekoranja
f2b43b704c rtems compilation warnings (int32 != int) 2014-11-26 14:12:09 +01:00
Matej Sekoranja
de1478d7ba Event test added 2014-11-25 10:43:07 +01:00
Marty Kraimer
b9592eeb8c Added tag 4.0.2 for changeset af82285f71aa 2014-11-24 06:55:18 -05:00
Marty Kraimer
6a62f9c082 catch std::exception and return NULL PVStructurePtr 2014-11-24 06:54:28 -05:00
Matej Sekoranja
2e4a8b2e23 Structure/Union: bound check access for getFieldName(int)/getField(int) 2014-11-13 18:32:50 +01:00
Marty Kraimer
c5112ffa11 Added tag 4.0.1 for changeset b0d39d12d743 2014-11-11 07:05:19 -05:00
Matej Sekoranja
7b9fda4e81 merge 2014-11-10 21:33:47 +01:00
Matej Sekoranja
278e531806 PVUnion copy allways shallow 2014-11-10 21:30:48 +01:00
Marty Kraimer
047de40642 change date, this version, and previous version 2014-11-10 09:06:35 -05:00
Matej Sekoranja
4e671a1c21 win32 indent problem: local static DLL saga 2014-11-06 22:18:58 +01:00
Matej Sekoranja
f36c8ce280 testByteOrder: use MAIN instead of main 2014-11-06 14:28:49 +01:00
Matej Sekoranja
e77f2c91d7 fixed undeterministic serialization test on clang 2014-11-06 13:03:59 +01:00
Matej Sekoranja
82b0d5ce5f merge 2014-11-06 12:50:04 +01:00
Matej Sekoranja
6117035863 null element handling for structure/union array 2014-11-06 12:48:57 +01:00
Matej Sekoranja
c86e31ad99 vxWorks: type cast fixes 2014-11-06 12:38:01 +01:00
Matej Sekoranja
f506fe1c0e int/int32 compilation fix; now all test spass on RTEMS-i386 2014-11-05 14:05:28 +01:00
Matej Sekoranja
554dc06eda ScalarTypeID mapping fixed in case 'int' == 'long', e.g. RTEMS-i386 2014-11-05 13:52:10 +01:00
Matej Sekoranja
80e1dfd142 removed forces NE2K card or non i386 builds 2014-11-03 13:51:21 +01:00
Matej Sekoranja
6db5cf60dc removing file should not have been commited 2014-11-03 12:41:09 +01:00
Matej Sekoranja
63d181a0ac RTEMS QEMU tests 2014-11-03 12:37:12 +01:00
Matej Sekoranja
73c4896cce tests: VxWorks tests are now ready to be run 2014-10-31 17:49:10 -04:00
Matej Sekoranja
5b1b5ab904 tests: refactored test building so that one test object can be created for VxWorks and RTEMS 2014-10-31 18:29:55 +01:00
Matej Sekoranja
80a537bc4c vxWork tests for all subtests; still need to combine them all to one 2014-10-31 07:57:20 -04:00
Matej Sekoranja
2a8a1d3736 tests: PROD_HOST to TESTPROD_HOST; VxWorks tests for testApp/pv PASSES 2014-10-31 06:42:52 -04:00
Matej Sekoranja
61fbfa0684 Added tag 4.0.0 for changeset f9f187685032 2014-10-29 12:59:39 +01:00
Matej Sekoranja
f06a6bfe7b merge to default branch 2014-10-28 19:37:34 +01:00
Matej Sekoranja
587f81f511 win32 in vs2013 compilation fix 2014-10-28 19:36:57 +01:00
Matej Sekoranja
435ca63d1b ev4 to epics URI 2014-10-28 18:53:11 +01:00
Marty Kraimer
64bb660f44 Added tag 4.0.0 for changeset 9c62aaa83b9d 2014-10-15 14:47:48 -04:00
Marty Kraimer
8bf24de0b3 removed pvArray.html and pvDataDiscussion.html; good ideas now implemented 2014-10-08 15:03:52 -04:00
Marty Kraimer
943ea633a4 more work on pvDataCPP.html; minor changes to examples 2014-10-08 14:48:30 -04:00
dhickin
b1d5f7d7e5 Corrected NTUnio to NTUnion 2014-10-07 15:32:26 +01:00
dhickin
188b94ce19 Corrected spelling of synchrotron in licence. 2014-10-04 02:45:53 +01:00
dhickin
515282abfe Spelling and typos. 2014-10-04 01:33:59 +01:00
dhickin
efbdb722e7 Made sub-field/subfield consistent by changing to subfield. 2014-10-04 01:28:19 +01:00
dhickin
e980823294 Corrected NTUnio->NTUnion. 2014-10-04 00:22:46 +01:00
dhickin
3692f4fb3c Correctly produce <> for templates in code samples for PVUnionArray in pvDataCPP.html. 2014-10-03 15:58:55 +01:00
dhickin
3e645f3c79 Corrected spelling in pvDataCPP.html. 2014-10-03 15:24:20 +01:00
Marty Kraimer
6127763302 Added tag 4.0.0 for changeset 1348c22b1258 2014-09-30 16:59:37 -04:00
Marty Kraimer
19a181b38f change ev4:nt: to 3v4:nt/ 2014-09-30 15:26:23 -04:00
Marty Kraimer
2818b0384c flow: Created branch 'release/4.0'. 2014-09-30 15:06:43 -04:00
Marty Kraimer
36faf8c2ea change URI naming 2014-09-30 15:05:18 -04:00
Marty Kraimer
a208171250 change uri:ev4:nt/2012 to uri:ev4:nt/2014 2014-09-23 14:34:21 -04:00
Marty Kraimer
b8a2b7cff6 get documantation ready for pre release 2014-09-03 09:01:15 -04:00
Marty Kraimer
2a08cbc1a0 add static 2014-08-25 08:09:28 -04:00
Matej Sekoranja
62bc6c1fb1 PVControl::minStep implemented 2014-08-22 22:22:38 +02:00
Matej Sekoranja
1098650421 clang fix 2014-08-20 21:42:29 +02:00
Marty Kraimer
15d85c2f87 fix misspelled field names: nanoSecond => nanosecond; hystersis=>hysteresis 2014-08-20 06:27:24 -04:00
Matej Sekoranja
16fb3f0339 clang fixes 2014-08-19 20:58:12 +02:00
Matej Sekoranja
37f6dff065 bounded string 2014-08-19 20:42:15 +02:00
Marty Kraimer
baf8832fc9 allow record[] field() getField() putField() 2014-08-19 09:15:06 -04:00
Marty Kraimer
b558e11ede major changes to CreateRequest; now compatible with Java version 2014-08-19 08:25:38 -04:00
Matej Sekoranja
103cdabff1 fixed clang std::tr1 import by adding include 2014-08-13 21:53:15 +02:00
Matej Sekoranja
57e33c8f7d clang porting 2014-08-13 09:36:37 +02:00
Matej Sekoranja
da0f65c2d3 fixed size array serialization test 2014-08-12 13:20:00 +02:00
Matej Sekoranja
6535c075f3 fixed sized arrays 2014-08-12 13:17:17 +02:00
Matej Sekoranja
f3c0b9544c dumpValue for boolean fix 2014-08-11 22:09:46 +02:00
Matej Sekoranja
3609fd4745 fixed testCreateRequest, still fails 2014-07-30 21:49:52 +02:00
Matej Sekoranja
622e140622 Fixed/bounded scalar array impl. 2014-07-30 21:41:08 +02:00
Marty Kraimer
a4954c3825 fixed bug in createRequest.cpp 2014-07-30 06:50:22 -04:00
Matej Sekoranja
b6e1b9c203 reuse existing PVField instance on PVUnion::deserialize 2014-07-28 23:23:01 +02:00
Matej Sekoranja
34a35c2658 fixed/bounded array introspection data serialization 2014-07-28 23:05:49 +02:00
Marty Kraimer
90b7c9a17c change in TODO.md; add RELEASE_NOTES.html and TODO.html 2014-07-22 08:49:02 -04:00
Marty Kraimer
c72297020b update documentation 2014-07-10 13:17:26 -04:00
Matej Sekoranja
f07b601dce merge 2014-07-07 20:55:49 +02:00
Matej Sekoranja
63c62a2aae Union::dump indentification fixed 2014-07-07 20:54:38 +02:00
Matej Sekoranja
6888a9d340 Added tag 3.1.0 for changeset 260f35b9c6ca 2014-07-02 00:09:01 +02:00
Matej Sekoranja
72bf9f76a3 forgot to remove friend operator<< 2014-06-19 21:56:56 +02:00
Matej Sekoranja
c0c6213c7c Win32: friend incosistent linkage 2014-06-19 21:24:14 +02:00
Matej Sekoranja
652ef4bc82 merge 2014-06-19 14:29:05 +02:00
Matej Sekoranja
c6eed12139 String -> std::string, toString methods removed 2014-06-19 14:27:48 +02:00
Marty Kraimer
1132e25072 fix bug related to stride 2014-06-13 09:52:30 -04:00
Marty Kraimer
879e3a2b67 support UnionArray 2014-06-12 15:26:31 -04:00
Matej Sekoranja
6ec207141f fixed missing dllimport/dllexport on new code 2014-06-11 11:56:04 +02:00
Matej Sekoranja
45c657ce79 added missing src/copy/Makefile 2014-06-10 13:50:04 +02:00
Matej Sekoranja
888dc11c03 Added tag before_merge_changesAfter3_0_2 for changeset 40b681ffc5cd 2014-06-10 13:39:41 +02:00
Matej Sekoranja
5e3159f800 completed merge 2014-06-09 23:15:57 +02:00
Matej Sekoranja
570ec97eda flow: Closed <feature> 'changesAfter3_0_2'. 2014-06-09 22:53:59 +02:00
Matej Sekoranja
09c75823e6 byteBuffer: wrap support 2014-06-09 08:28:00 +02:00
Marty Kraimer
50c8c3b0bd more work on stride 2014-06-06 11:24:12 -04:00
Marty Kraimer
3fb44312c7 add support for stride 2014-06-05 10:20:01 -04:00
Matej Sekoranja
67bdf2ab8b bitSet <<operator(ostream) 2014-06-01 20:54:07 +02:00
Marty Kraimer
a56ed44e74 fix bugs found by tests in pvIOCJava 2014-05-24 06:47:16 -04:00
Marty Kraimer
3c912c3812 put to union field did not call postPut. 2014-05-21 16:18:38 -04:00
Matej Sekoranja
0ceb87eee1 Array IF added 2014-05-13 00:18:30 +02:00
Marty Kraimer
6510c10884 major update to pvDataCPP.html; minor updates while working on documentation 2014-05-01 10:33:01 -04:00
Andrew Johnson
89da38cfa4 Jenkins fixes.
Remove aps_build script, no longer used.
Tests have all been converted to the EPICS harness,
so don't need running separately.
2014-04-29 12:10:35 -05:00
Andrew Johnson
82b5d0e50b flow: Merged <feature> 'housekeeping' to <develop> ('default'). 2014-04-29 10:43:05 -05:00
Andrew Johnson
bb8789a9ad flow: Closed <feature> 'housekeeping'. 2014-04-29 10:43:05 -05:00
Marty Kraimer
20345ab0dd forgot monitor.h 2014-04-23 09:16:28 -04:00
Marty Kraimer
d5dfb3de0c added monitorPlugin; fixed bug in PVField::getFullName(); 2014-04-23 09:10:37 -04:00
Andrew Johnson
88aabb41e7 Replace USAGE_DEPRECATED with EPICS_DEPRECATED
Also make USAGE_ERROR conditional on the GCC version,
to remove warnings from VxWorks 6.8 builds.
2014-04-21 11:11:09 -05:00
Andrew Johnson
897059303d Merged changes from default branch 2014-04-18 16:55:13 -05:00
Andrew Johnson
0b7607cf04 Merged change from default branch. 2014-04-16 16:08:08 -05:00
Matej Sekoranja
4a512f47de merge 2014-04-09 15:19:43 +02:00
Matej Sekoranja
76a54d38e4 byteBuffer: wrapped buffer support 2014-04-09 15:18:40 +02:00
Matej Sekoranja
b9b03940a2 DefaultArray deserialize fix 2014-04-08 13:27:24 +02:00
Andrew Johnson
8370a97866 Unify configure files with the other V4 modules
Move include/pv setting into src/Makefile
2014-04-03 16:57:14 -05:00
Andrew Johnson
b659c77dbb Fix instructions in RELEASE file 2014-04-02 15:19:14 -05:00
Andrew Johnson
e45b842a6c Enable CHECK_RELEASE warnings 2014-04-02 14:43:32 -05:00
Marty Kraimer
c2f22a4ad8 make testPVCopy.cpp a proper epicsUnitTest 2014-04-02 10:15:53 -04:00
Marty Kraimer
cb15a8676b remove PVData methods that change introspection interface
remove deprecated methods
move CreateRequest from pvAccessCPP to pvDataCPP
move pvCopy from pvDatabaseCPP to pvDataCPP
2014-04-01 09:35:29 -04:00
Andrew Johnson
32ba6d444b Cleaned up CONFIG_SITE file.
Introduced WITH_COVERAGE Make variable
to control build options.
2014-03-31 17:25:22 -05:00
Andrew Johnson
95b7a04041 Makefile fixups 2014-03-28 11:53:39 -05:00
Andrew Johnson
d81ef64799 Remove __rtems__, already defined by the compiler 2014-03-28 11:20:03 -05:00
Andrew Johnson
19269735ae Rename pvDataApp to src, adjust Makefiles. 2014-03-28 10:20:24 -05:00
Matej Sekoranja
f7957c8ea5 merge 2014-03-28 00:04:18 +01:00
Andrew Johnson
1e40797bc4 Split pvDataApp/Makefile into fragments. 2014-03-27 17:58:43 -05:00
Andrew Johnson
ad66f8af73 Tidy up top-level Makefile 2014-03-27 17:36:10 -05:00
Andrew Johnson
d436e61bdb sharedPtr.h: Remove trailing ; from macro expansion. 2014-03-27 17:35:05 -05:00
Andrew Johnson
c71e62746d ParseToPOD needs limits.h on some arch's 2014-03-27 17:34:02 -05:00
Andrew Johnson
d5b0ad5d80 flow: Created branch 'feature/housekeeping'. 2014-03-27 17:28:55 -05:00
Marty Kraimer
34f2d7bc9a created feature branch 2014-03-25 07:23:14 -04:00
Marty Kraimer
fb7f1b622b flow: Created branch 'feature/changesAfter3_0_2'. 2014-03-25 07:04:59 -04:00
Marty Kraimer
4a992e6e1c flow initialization: Added configuration file. 2014-03-25 07:04:47 -04:00
Matej Sekoranja
9593de8c0f DefaultPVArray: removed unnecessary flush at the end of serialization 2014-02-17 12:47:07 +01:00
Matej Sekoranja
8205be5220 #63: implemented PVStructure.get<type>Field() using template method, no more messages emitted 2014-02-14 15:10:18 +01:00
Matej Sekoranja
39c43c4c02 rtems build: testProperty _HOST was missing 2014-02-06 11:58:14 +01:00
Matej Sekoranja
8a9fa956e0 vxWorks (vx68 and later): m_data -> m_sdata; m_data is a macro efined by vxWorks 2014-02-05 22:28:54 +01:00
Matej Sekoranja
06e9c533e3 parseToPOD RTEMS 2014-01-31 11:53:51 +01:00
Matej Sekoranja
5bdcaf43db sharedVector: count > capacity bugfix (2) 2013-12-04 10:49:16 +01:00
Matej Sekoranja
df1d13a155 sharedVector: count > capacity bugfix 2013-12-04 10:01:50 +01:00
Matej Sekoranja
6e7b19b090 added current_function.h 2013-12-03 12:16:08 +01:00
Matej Sekoranja
279b73a477 win32 port : warnings removed 2013-11-28 21:31:02 +01:00
Matej Sekoranja
74239303b3 testPVScalarArray: cast to the right type 2013-11-27 01:45:40 +01:00
Matej Sekoranja
134f390a5f fixed SerializeHelper::writeSize back 2013-11-27 01:37:16 +01:00
Matej Sekoranja
8aa26b78bb win32 port: parseToPOD NEED_LONGLONG check, missing monitor.cpp 2013-11-27 01:15:35 +01:00
Matej Sekoranja
301038664e win32 port: visibility, warnings, templates 2013-11-27 01:11:12 +01:00
Matej Sekoranja
ccad38f2db added programmers cookbook raw draft 2013-11-26 14:46:36 +01:00
Matej Sekoranja
29dee42d34 FieldBuilder: typo addNested() -> endNested() 2013-11-26 13:45:30 +01:00
Matej Sekoranja
f9135c81de testSerialization: fixed warnings 2013-11-26 11:08:16 +01:00
Matej Sekoranja
9400635fd9 testBitSet: replaced printf with testDiag 2013-11-25 22:07:28 +01:00
Marty Kraimer
4102deceb3 convert all tests to use epicsUnitTest 2013-11-25 15:46:00 -05:00
Matej Sekoranja
86306740be typeCast.cpp: do not report index in exception message for scalars 2013-11-22 10:31:21 +01:00
Matej Sekoranja
8e63fc8b25 castVtyped: added index in exeption error message 2013-11-22 09:44:21 +01:00
Matej Sekoranja
3219bd0307 Win32 port: import/export headers 2013-11-20 14:49:40 +01:00
Matej Sekoranja
bdb4430bb6 Win32 port: fix and success compile and run using GCC -fvisibility=hidden 2013-11-20 13:40:07 +01:00
Matej Sekoranja
a574dbf89b start of Win32 port 2013-11-20 13:04:28 +01:00
Matej Sekoranja
47178370d5 FieldBuilder: better method names 2013-11-11 22:36:06 +01:00
dhickin
ac67fddbcb Fixed bug in outputting UnionArrays. 2013-11-11 12:02:35 +00:00
dhickin
e97fab3107 Simpler fix for bug in outputting StructureArrays. 2013-11-08 18:49:57 +00:00
dhickin
fee6f03ec2 Fixed bug in outputting StructureArrays. 2013-11-08 18:27:15 +00:00
Matej Sekoranja
1aff2ec112 tempalte helpers; static initialization order 2013-11-08 13:50:54 +01:00
Matej Sekoranja
57b3e9a8b2 run EPICS Harness Tests on CI 2013-11-08 00:01:24 +01:00
Matej Sekoranja
35dad272eb merge 2013-11-07 14:13:37 +01:00
Matej Sekoranja
d40c41048d PVUnion/PVUnionArray support and tests 2013-11-07 14:12:26 +01:00
Marty Kraimer
03f59c94b4 commit after merge 2013-11-06 07:42:03 -05:00
Marty Kraimer
87718f1c82 get rid of warnings 2013-11-06 07:41:16 -05:00
Matej Sekoranja
cbf7b69ef0 Union/UnionArray implemented, PVUnion/PVUnionArray not yet implemented; also implemented reuse of scalar/scalarArray instances in FieldCreate 2013-11-05 16:15:12 +01:00
Matej Sekoranja
c56c976a22 FieldBuilder (incl. tests) 2013-11-04 19:04:28 +01:00
Marty Kraimer
3579d17a05 moved pvSubArrayCopy from pvDatabaseCPP to pvDataCPP 2013-10-31 06:44:54 -04:00
Marty Kraimer
0f17bd23c7 make bitSet more comnpatible with Java implementation. 2013-10-31 06:03:51 -04:00
Marty Kraimer
db10bed951 update documentation; fix bug in executor; add typedefs to thread.h 2013-10-30 08:13:19 -04:00
Michael Davidsaver
071806f12b remove redundancy in print_cast 2013-10-29 18:06:42 -04:00
Michael Davidsaver
9cd7008efe typeCast String <-> boolean 2013-10-29 17:56:36 -04:00
Michael Davidsaver
14dc098761 no deperecated warning on old vxworks 2013-10-29 16:58:09 -04:00
Michael Davidsaver
8c6a895b19 disambiguate a template 2013-10-29 16:54:02 -04:00
Michael Davidsaver
01b8e69e4b remove illegal copy op
Can bypass freeze/thaw
2013-10-28 17:54:59 -04:00
Michael Davidsaver
11e91ac3fa Merge branch 'shared-vector' 2013-10-28 17:42:11 -04:00
Marty Kraimer
70380b9a43 Added tag 3.0.2 for changeset 58092712d092 2013-09-10 16:54:02 -04:00
Marty Kraimer
fa7a44f5b3 update links in .html files 2013-09-10 16:53:21 -04:00
Andrew Johnson
fb0329c0b5 APS Jenkins adjustment 2013-09-05 12:24:38 -05:00
Andrew Johnson
c3d04fdd08 Fix VxWorks builds 2013-09-05 10:26:56 -05:00
Marty Kraimer
ebb0c97c51 Added tag 3.0.1 for changeset 2a289ff41e2e 2013-09-03 08:37:28 -04:00
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
Michael Davidsaver
de70d90603 shared_vector: simplify slice()
Correctly tracks capacity when user
over-slices.
2013-08-06 11:32:34 -04:00
Michael Davidsaver
31be738c10 minor 2013-08-06 10:43:47 -04:00
Michael Davidsaver
759d268af0 update testPVScalarArray 2013-07-29 15:10:04 -04:00
Michael Davidsaver
f21811eb6a Change enum to type in converters 2013-07-29 15:09:47 -04:00
Michael Davidsaver
c643509c7e PVField converters use type
Use type as template parameter instead of ScalarType
enum value.
2013-07-29 15:08:59 -04:00
Michael Davidsaver
0860f8e6f9 don't use deprecated PVValueArray<T>::get() 2013-07-29 11:44:53 -04:00
Michael Davidsaver
e96b447e37 add print_cast()
Cast value to "printable" type.
A no-op except for char types, which are cast to int
so that they are printed as numbers std::ostream operators.
2013-07-29 11:44:52 -04:00
Michael Davidsaver
0eecd3b1fe document freeze/thaw 2013-07-29 11:44:52 -04:00
Michael Davidsaver
b5b6ae100d update pvD array in tests 2013-07-25 17:30:33 -04:00
Michael Davidsaver
8fd9bf10e5 update pvD array implementation 2013-07-25 17:30:18 -04:00
Michael Davidsaver
9ac030169a update pvD array handling
Interface only uses shared_vector<const T>
storage also uses only const.
2013-07-25 17:22:16 -04:00
Michael Davidsaver
569bd3b681 update testSharedVector 2013-07-25 17:02:08 -04:00
Michael Davidsaver
45bb461c32 shared_vector require freeze/thaw
Remove the implicit cast from non-const to const.
Require the use of freeze/thaw when
changing between const and non-const.

Change argument of const_shared_vector_cast
to a non-const shared_vector reference
to allow it to be cleared by freeze/thaw.
2013-07-25 15:26:29 -04:00
Michael Davidsaver
105c3185f7 remove take(), copyIn(), and copyOut(). 2013-07-19 14:20:55 -04:00
Michael Davidsaver
5565e4e30c Convert don't use copyIn or copyOut 2013-07-19 14:18:04 -04:00
Michael Davidsaver
70ae281f45 test freeze/thaw 2013-07-16 18:59:04 -04:00
Marty Kraimer
b518efd196 Added tag 3.0-pre1 for changeset 4cecd4b200f8 2013-07-16 14:47:34 -04:00
Michael Davidsaver
6e3a344caa fix Convert::fromStringArray
destination should grow to fit
2013-07-16 10:48:01 -04:00
Michael Davidsaver
2e3cbed520 restart testConvert
start with fromStringArray
2013-07-16 10:47:11 -04:00
Michael Davidsaver
5e2e7c81a6 Merge remote branch 'md/master' into pvarr
* md/master:
  added
  minor changes
  comparison between implementations
  Proposed pvData.h interface
  added pvArray.html; made queue.h and bitSetUtil.* compatible with pvDataCPP.
2013-07-09 18:37:53 -04:00
Michael Davidsaver
cff59487ae shared_vector freeze and thaw 2013-07-09 18:24:51 -04:00
Michael Davidsaver
cdcbfe7378 update testPVScalarArray 2013-07-09 18:24:51 -04:00
Michael Davidsaver
0c4ef8f079 PV* use shared_vector_convert 2013-07-09 18:24:50 -04:00
Michael Davidsaver
c0e9dcff21 revise static_shared_vector_cast
Move the work into a special ctor
to allow full inline of casting wrapper

Prevent static_shared_vector_cast from
casting const <-> non-const
2013-07-09 18:24:41 -04:00
Michael Davidsaver
79eeb0fa2a update PVScalar and PVScalarValue<T>
hide the void* members for now.

Define PVScalarValue<T>::getAs and putFrom
to give a more efficient implementation.
2013-07-09 18:24:41 -04:00
Michael Davidsaver
46feb86a99 test shared_vector_convert 2013-07-09 18:24:41 -04:00
Michael Davidsaver
74f68c47d3 shared_vector_convert
Allow converting of shared_vector between types

Conversion utilizes castUnsafe<TO,FROM>().

Converting to/from void is supported.  Convert to void
is an alias for static_shared_vector_cast<void>().
Convert from void utilizes shared_vector<void>::original_type()
and throws std::runtime_error if this is not valid.

Casting now handles 'const void'
is most places where 'void' can be used.
2013-07-09 18:24:40 -04:00
Michael Davidsaver
3c7a738ffc shared_vector<void> tracks original type 2013-07-09 18:24:40 -04:00
Michael Davidsaver
22d4a53d65 create templateMeta.h
Home for common C++ template tricks
2013-07-09 18:24:40 -04:00
Michael Davidsaver
d319e2ed7b add ScalarTypeID template
Define a compile time mapping from
type to ScalarType enum value.
2013-07-09 11:19:46 -04:00
Michael Davidsaver
2cb07a8490 move parts of ScalarTypeFunc to sharedVector.h
Move the parts of ScalarTypeFunc which
deal with untyped shared_vector s
to sharedVector.h to allow sharedVector.h
to include pvIntrospect.h w/o creating
an include loop...
2013-07-09 10:36:48 -04:00
Michael Davidsaver
6900d4bbec make boolean type unambiguous
"char", "signed char", and "unsigned char"
are distinct types.  Define "boolean" to
be whichever is not "int8" or "uint8".
2013-07-08 09:58:37 -04:00
Michael Davidsaver
73450bdbc7 combine shared_vector<T> for void and const void 2013-07-03 14:23:17 -04:00
Marty Kraimer
776ff49ed2 added 2013-07-03 12:11:05 -04:00
Michael Davidsaver
00da6c88ae minor 2013-07-03 11:41:53 -04:00
Michael Davidsaver
986f036d20 replace accepts const_svector
Allows

PVValueArray<T> *a, *b;

a->replace(b->view());
2013-07-03 11:34:32 -04:00
Michael Davidsaver
5699c43b74 correct max_size
Take into account sizeof(E).
2013-07-02 17:42:46 -04:00
Marty Kraimer
b58b97a916 minor changes 2013-06-28 14:17:23 -04:00
Marty Kraimer
5f52f14094 comparison between implementations 2013-06-25 12:18:38 -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
Marty Kraimer
ec6b67ffad Proposed pvData.h interface 2013-06-18 10:01:52 -04:00
Marty Kraimer
3de28e3cef added pvArray.html; made queue.h and bitSetUtil.* compatible with pvDataCPP. 2013-06-13 14:52:27 -04:00
Andrew Johnson
d2a649f5fa Fixed compiler warning, 2013-06-12 21:21:44 -05:00
Michael Davidsaver
23d5aab1e8 add Doxyfile 2013-06-11 17:42:31 -04:00
Michael Davidsaver
cf8c6718dd test PVStructureArray in testSerialization 2013-06-11 17:42:30 -04:00
Michael Davidsaver
b0c8249562 re-write testPVStructureArray 2013-06-11 17:42:30 -04:00
Michael Davidsaver
8cb0b1a7d6 use new PVStructureArray api 2013-06-11 17:42:30 -04:00
Michael Davidsaver
7f9745c8d1 Implement PVStructureArray with shared_vector
Combine as much as possible with scalar array handling.

PVStructureArray becomes PVValueArray<shared_ptr<PVStructure> >

Bulk of shared implementation moved the PVVectorStorage
which has a parametrized base to avoid using multiple inheritance.
2013-06-11 17:42:30 -04:00
Michael Davidsaver
4e749cc8be Improve shared_vector::push_back
push_back now allocates additional space
in powers of 2 up to 1k elements, then
in blocks of 1k elements.
2013-06-11 17:42:30 -04:00
Michael Davidsaver
70c9a7c18f simplify shared_vector ctors
Casting will be done through the copy constructor.
2013-06-11 14:39:40 -04:00
Michael Davidsaver
11e2ee19ea Fix Printer for structure arrays
Not handling NULL elements correctly.
2013-06-11 14:39:40 -04:00
Michael Davidsaver
a4cfab1242 Fix "optimize shared_vector for storing non-POD types"
Can't move references when the source array is
still referenced by other shared_vectors
2013-06-11 14:39:40 -04:00
Michael Davidsaver
be4738f59c remove weak_vector
It seems that shared_ptr::use_count() does
not include weak_ptr instances.  Therefore
shared_ptr::use_count()==1 (aka unique())
does *not* ensure exclusive ownership!

This breaks the assumption used by
shared_vector::make_unique() to avoid
allocating a new array in some cases.
2013-06-10 15:09:42 -04:00
Michael Davidsaver
b63c3da565 add const_pointer to shared_vector 2013-06-10 12:09:29 -04:00
Michael Davidsaver
0b89f08d09 explicit copy and assignment for shared_vector
Add explicit copy constructor and
assignment operator for shared_vector.
2013-06-10 12:09:29 -04:00
Michael Davidsaver
ac53153bea shared_vector: test reference and const_reference
Ensure that these typedefs are present and work
for 'T' and 'const T'.
2013-06-05 16:15:49 -04:00
Michael Davidsaver
bc3187a3f6 optimize shared_vector for storing non-POD types
pass values by reference where appropriate.
When reallocating arrays of shared_ptr
"move" with swap() instead of operator=
to avoid ref counter inc and dec for each
element.
2013-06-03 19:31:05 -04:00
Michael Davidsaver
4294710d9e make viewUnsafe protected
No longer part of the public API of PVValueArray
2013-06-03 19:31:05 -04:00
Matej Sekoranja
476f18332a valueAlarm for numeric scalar arrays support 2013-05-31 21:15:54 +02:00
Michael Davidsaver
82a33460cf pvData update doc comments 2013-05-31 09:58:52 -04:00
Michael Davidsaver
3b6268a4fc add const_iterator to shared_vector 2013-05-31 09:58:52 -04:00
Michael Davidsaver
41425b3fa1 more testIntrospect 2013-05-31 09:58:52 -04:00
Andrew Johnson
a964e3668d Added jenkins/aps_build script 2013-05-30 17:32:15 -05:00
Michael Davidsaver
57804494ef Misc fixes and error checking
fix argument type for getScalarType
mark getFieldName as const
Argument checking for Field construction
2013-05-24 18:28:54 -04:00
Michael Davidsaver
9039a10c9a update testIntrospect with epicsUnitTest 2013-05-24 18:28:54 -04:00
Michael Davidsaver
9e865bc37d Avoid unnecessary copying in copyIn
Only re-use the existing reference if
it is large enough to hold all the new data.
If it isn't then throw it away to avoid
copying its current contents during
the resize().
2013-05-23 18:19:35 -04:00
Michael Davidsaver
54ee8bf7a0 PVStructureArray: setLength before postPut
Ensure that the correct (new) length is seen.
2013-05-23 17:51:52 -04:00
Michael Davidsaver
629c8346d2 postPut in new array API
Call when appropriate (putFrom(), copyIn(), and replace()).
Not called by swap(), take(), reuse(), or shareData().
Users of the second set of methods are expected to call
one of the methods in the first set, or call postPut() directly.

Document when postPut is (not) called.
2013-05-23 17:51:52 -04:00
Michael Davidsaver
1bf2ff430a array resize respect immutability 2013-05-23 17:51:52 -04: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
Michael Davidsaver
572c02bf6e update testOperators 2013-05-08 18:35:51 -04:00
Michael Davidsaver
80777b293f rewrite testPVScalarArray 2013-05-08 18:35:51 -04:00
Michael Davidsaver
3c08834377 update testSerialization 2013-05-08 18:35:51 -04:00
Michael Davidsaver
eeae12e3d4 Convert: remove to/from*Array 2013-05-08 18:35:51 -04:00
Michael Davidsaver
992ac73068 use new API
make copying explicit and replace some
use of PVValueArray<T>::put and get
2013-05-08 18:35:51 -04:00
Michael Davidsaver
e843779555 New array API for PVValueArray using shared_vector<T>
* In PVScalarArray

Add methods assign, getAs/putFrom, and copyOut/copyIn to allow get/put
with implicit convert.

assign() copys on PVScalarArray to another converting as necessary.
If the types do not match then an allocate and convert is done.

getAs/putFrom work with shared_vector<T> and can avoid a allocate
and convert operation if the types match.

copyOut/copyIn use plain C arrays will do either a copy if the types
match, and a convert otherwise.  No allocation is performed.

* In PVValueArray<T>

All array operations re-implemented in terms of
two virtual methods

  virtual const shared_vector<T>& viewUnsafe() const;
  virtual void swap(shared_vector<T>&);

Some convienence methods are also included:

  shared_vector<const T> view() const
  shared_vector<T> take()
  shared_vector<T> reuse()

Deprecate get(...), put(...), and shareData(...)

Remove getVector() and getSharedVector()

Adjust DefaultPVArray accordingly
2013-05-08 18:35:51 -04:00
Michael Davidsaver
5f4ca240b4 add ScalarTypeFunc::elementSize 2013-05-08 18:35:50 -04:00
Michael Davidsaver
79cd374f16 add ScalarTypeFunc::allocArray 2013-05-08 18:35:50 -04:00
Michael Davidsaver
b137b32fc6 test shared_vector<T>
use epicsUnitTest
test handling of void and const void instances
2013-05-08 18:35:50 -04:00
Michael Davidsaver
3cd2bfdef0 shared_vector implementation
Shared ownership of a single C array.

Tracks offset and length for each instance
allowing each owner to "view" a different
piece of the array.

Parts of shared_vector<T> which can work
for T=void are in shared_vector_base<T>.
Specializations shared_vector<void>
and shared_vector<const void> handle
un-typed arrays.

Allow casting to/from typed vector

Offsets and sizes of untyped vectors are tracked in
bytes.  Therefore casting to types where sizeof(T)>1
is undefined if the offset is not a multiple of
sizeof(T).
2013-05-08 18:21:34 -04:00
Michael Davidsaver
461dbdf0f8 remove Convert pointer from PVField
Allow inline construction of Convert
2013-05-08 17:46:31 -04:00
Michael Davidsaver
9e8a6b6304 fix const-ness in PVField compare 2013-05-08 17:46:31 -04:00
Michael Davidsaver
fd5ea89340 typo 2013-05-01 14:27:00 -04:00
Michael Davidsaver
1d1d2b31cd remove remaining state from Convert 2013-05-01 14:20:01 -04:00
Michael Davidsaver
d75656dad7 testTypeCast use epicsUnitTest 2013-05-01 12:41:19 -04:00
Michael Davidsaver
f0aa2fe0e0 fix printer
Don't overflow the stack for deep structures!
2013-05-01 12:18:21 -04:00
Michael Davidsaver
ae847aea2b allow putFrom to implicitly resize 2013-05-01 12:18:21 -04:00
Michael Davidsaver
00ac5bf64f PVStructure::getNumberFields != Structure::getNumberFields
Apparently PVStructure::getNumberFields is one indexed???
2013-05-01 12:18:21 -04:00
Michael Davidsaver
61e8024c65 fix mapping between int* and epicsInt* types 2013-04-30 18:14:05 -04:00
Michael Davidsaver
ee5a370c01 misc 2013-04-30 18:14:05 -04:00
Michael Davidsaver
659ce13e98 replace vector to/from in Convert 2013-04-30 18:14:04 -04:00
Michael Davidsaver
a7fde21300 replace scalar to/from in Convert 2013-04-30 18:14:04 -04:00
Michael Davidsaver
a6bfab2d74 replace copyScalarArray with PVScalarArray::assign 2013-04-30 18:14:04 -04:00
Michael Davidsaver
e948af1851 PVScalar::assign and PVScalarArray::assign 2013-04-30 18:14:04 -04:00
Michael Davidsaver
2062cc5d10 Convert::toStringArray with castUnsafe 2013-04-30 18:14:02 -04:00
Michael Davidsaver
e85d10c6d9 Convert::fromStringArray with castUnsafe 2013-04-30 18:14:02 -04:00
Michael Davidsaver
0e0ab66d45 add PVScalarArray::getAs and PVScalarArray::putFrom 2013-04-30 18:14:02 -04:00
Michael Davidsaver
f2635c7fdc Convert::fromString with castUnsafe 2013-04-30 18:14:02 -04:00
Michael Davidsaver
4d92bbe541 Use PrinterPlain in Convert 2013-04-30 18:14:01 -04:00
Michael Davidsaver
e6e1434fc1 Add PrinterPlain 2013-04-30 18:13:32 -04:00
Michael Davidsaver
5e689f94f4 add PVScalar::getAs and PVScalar::putFrom
Allow get/put to a scalar without knowledge of ScalarType

Currently won't work correctly for PVBoolean
2013-04-26 15:44:05 -04:00
Michael Davidsaver
c1b6d26b8e Convert::equals: move to operator==(PVField&,PVField&) 2013-04-22 16:12:03 -04:00
Michael Davidsaver
f72c5dba84 PVStructure compare typo 2013-04-22 15:47:51 -04:00
Michael Davidsaver
704007092c Convert::getFullName becomes PVField::getFullName
Compatibility wrapper using current Convert API
Allow PVField::getFieldName to be inline'd
Avoid multiple resize and copy operations
on result String.
2013-04-22 14:48:59 -04:00
Michael Davidsaver
2f8c434429 add castUnsafeV
non-template version of castUnsafe<TO>(FROM v)).
2013-04-22 11:59:20 -04:00
Michael Davidsaver
b0c57e7ae3 test castUnsafe w/ transform() 2013-04-22 11:59:20 -04:00
Michael Davidsaver
0e57391b4d vxWorks compatibility 2013-04-22 11:59:20 -04:00
Michael Davidsaver
7ff1a93e72 parseToPOD: fix 64-bit
Try again to detect if uint16_t is long or long long.
2013-04-18 13:54:04 -04:00
Michael Davidsaver
d7eada7216 type casting with castUnsafe<TO>(FROM val) 2013-04-15 14:39:42 -04:00
Michael Davidsaver
c435f71592 testOperators: avoid warning 2013-04-15 14:34:45 -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
jrowlandls
5cfb66656d Added tag 1.0-BETA for changeset 6e8a22d01e82 2011-12-19 18:00:16 +00:00
316 changed files with 78168 additions and 21849 deletions

15
.gitignore vendored Normal file
View File

@@ -0,0 +1,15 @@
bin/
lib/
doc/
include/
db/
dbd/
documentation/html
documentation/*.tag
envPaths
configure/*.local
configure/RELEASE.*
configure/CONFIG_SITE.*
!configure/ExampleRELEASE.local
**/O.*
QtC-*

View File

@@ -1,7 +0,0 @@
QtC-pvData.creator.user
bin
lib
doc
include
documentation/html
./O.*

View File

@@ -1 +0,0 @@
459f10877e5628241704f31437b4cbd342df0798 test1

31
COPYRIGHT Normal file
View File

@@ -0,0 +1,31 @@
This software is in part copyrighted by the various organizations and
individuals listed below. Permission to use it is set out in the file
LICENSE that accompanies the software.
In no event shall any copyright holder 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 they have been advised of the possibility of such
damage.
The copyright holders specifically disclaim 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 the copyright holders have no
obligation either collectively or individually to provide maintenance,
support, updates, enhancements, or modifications.
Copyright (c) 2006 - 2015 All rights reserved
Martin R. Kraimer
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), Ljubljana, Slovenia.
Brookhaven Science Associates, as Operator of Brookhaven
National Laboratory.
Diamond Light Source Ltd., Didcot, United Kingdom.

2491
Doxyfile

File diff suppressed because it is too large Load Diff

114
LICENSE Normal file
View File

@@ -0,0 +1,114 @@
Copyright (c) 2006-2015 Martin R. Kraimer
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
National Laboratory.
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
Copyright (c) 2007-2015 Control System Laboratory,
(COSYLAB) Ljubljana Slovenia
Copyright (c) 2010-2015 Brookhaven Science Associates, as Operator of Brookhaven
National Laboratory
Copyright (c) 2011-2015 Diamond Light Source Limited,
(DLS) Didcot, United Kingdom
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.
______________________________________________________________________
This software is in part copyrighted by the Brookhaven
National Laboratory (BNL).
In no event shall BNL 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
BNL has been advised of the possibility of such damage.
BNL 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 BNL has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________
This software is in part copyrighted by Diamond Light Source Limited (DLS)
In no event shall DLS 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
DLS has been advised of the possibility of such damage.
DLS 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 DLS has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________

View File

@@ -1,12 +1,14 @@
#Makefile at top of application tree
# Makefile for the EPICS V4 pvData module
TOP = .
include $(TOP)/configure/CONFIG
DIRS += configure
DIRS += pvDataApp
pvDataApp_DEPEND_DIRS = configure
DIRS += src
src_DEPEND_DIRS = configure
DIRS += testApp
testApp_DEPEND_DIRS = pvDataApp
testApp_DEPEND_DIRS = src
include $(TOP)/configure/RULES_TOP

View File

@@ -1 +0,0 @@
// ADD PREDEFINED MACROS HERE!

View File

@@ -1 +0,0 @@
[General]

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

@@ -1,30 +1,29 @@
# CONFIG
# CONFIG - Load build configuration data
#
# Do not make changes to this file!
# You might want to change this to some shared set of rules, e.g.
# RULES=/path/to/epics/support/modules/rules/x-y
RULES=$(EPICS_BASE)
# Allow user to override where the build rules come from
RULES = $(EPICS_BASE)
# RELEASE files point to other application tops
include $(TOP)/configure/RELEASE
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/RELEASE.Common.$(T_A)
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
endif
CONFIG=$(RULES)/configure
CONFIG = $(RULES)/configure
include $(CONFIG)/CONFIG
# Override for definition in base
# Override the Base definition:
INSTALL_LOCATION = $(TOP)
include $(TOP)/configure/CONFIG_SITE
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH)
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# CONFIG_SITE files contain other build configuration settings
include $(TOP)/configure/CONFIG_SITE
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
ifdef T_A
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
-include $(TOP)/configure/O.$(T_A)/CONFIG_APP_INCLUDE
endif

View File

@@ -1,35 +1,30 @@
# CONFIG_SITE
# Make any application-specific changes to the EPICS build
# configuration variables in this file.
# configuration variables in this file.
#
# Host/target specific settings can be specified in files named
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# CONFIG_SITE.Common.$(T_A)
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
# CONFIG_SITE.Common.$(T_A)
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
# Set this when you only want to compile this application
# for a subset of the cross-compiled target architectures
# that Base is built for.
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
# CHECK_RELEASE controls the consistency checking of the support
# applications pointed to by the RELEASE* files.
# Normally CHECK_RELEASE should be set to YES.
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking but
# continue building anyway if conflicts are found.
CHECK_RELEASE = YES
# Set this when your IOC and the host use different paths
# to access the application. This will be needed to boot
# from a Microsoft FTP server or with some NFS mounts.
# You must rebuild in the iocBoot directory for this to
# take effect.
#IOCS_APPL_TOP = <path to application top as seen by IOC>
# To install files into a location other than $(TOP) define
# INSTALL_LOCATION here.
#INSTALL_LOCATION=</path/name/to/install/top>
# If you don't want to install into $(TOP) then
# define INSTALL_LOCATION here
#INSTALL_LOCATION=<fullpathname>
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local
ifeq ($(EPICS_TEST_COVERAGE),1)
ifdef WITH_COVERAGE
USR_CPPFLAGS += --coverage
USR_LDFLAGS += --coverage
endif
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
-include $(TOP)/configure/CONFIG_SITE.local

View File

@@ -2,14 +2,6 @@ TOP=..
include $(TOP)/configure/CONFIG
# CHECK_RELEASE controls the consistency checking of the support
# applications defined in the $(TOP)/configure/RELEASE* files.
# Normally CHECK_RELEASE should be set to YES.
# Set CHECK_RELEASE to NO to disable checking completely.
# Set CHECK_RELEASE to WARN to perform consistency checking,
# but continue the build even if conflicts are found.
CHECK_RELEASE = YES
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))

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 PVCOMMON
# and EPICS_BASE build directories, e.g.
# PVCOMMON = /home/install/epicsV4/pvCommonCPP
# EPICS_BASE = /home/install/epics/base
-include $(TOP)/../RELEASE.local
-include $(TOP)/configure/RELEASE.local

1621
documentation/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
<h1>Release 4.1 IN DEVELOPMENT</h1>
<p>The main changes since release 4.0 are:</p>
<ul>
<li>Convert copy methods and equals operators (re)moved</li>
<li>Convert::copyUnion now always copies between subfields.</li>
<li>CreateRequest prevents a possible SEGFAULT.</li>
<li>New stream operators for Field and PVField are provided.</li>
<li>New method getAs that is like getSubField except that it throws exception</li>
</ul>
<h2>Convert copy methods and equals operators</h2>
<p>Convert copy methods where moved and replaced with methods
on PVField classes, i.e.</p>
<pre><code>PVField::copy(const PVField&amp; from)
</code></pre>
<p>Methods</p>
<pre><code>PVField::copyUnchecked(const PVField&amp; from)
</code></pre>
<p>where added to allow unchecked copies, to gain performance
where checked are not needed (anymore).</p>
<p>In addition:
- isCompatibleXXX methods were removed in favour of Field::operator==.
- equals methods were remove in favour of PVField::operator==.
- operator== methods where moved to pvIntrospect.h and pvData.h</p>
<h2>Convert::copyUnion</h2>
<p>Before this method, depending on types for to and from,
sometimes did a shallow cppy, i. e. just made to shared_ptr for to
share the same data as from.
Now it always copies between the subfield of to and from.</p>
<h2>CreateRequest change</h2>
<p>createRequest could cause a SEGFAULT if passed a bad argument.
This has been changed so the it returns a null pvStructure
and provies an error.</p>
<h2>New stream operators</h2>
<p>New steam operators are available for Field and PVField.
Before to print a Field (or any extension) or a PVField (or any extension)
it was necessary to have code like:</p>
<pre><code> void print(StructureConstPtr struct, PVStructurePtr pv)
{
if(struct) {
cout &lt;&lt; *struct &lt;&lt; endl;
} else {
cout &lt;&lt; "nullptr\n"
}
if(pv) {
cout &lt;&lt; *.struct &lt;&lt; endl;
} else {
cout &lt;&lt; "nullptr\n"
}
}
</code></pre>
<p>Now it can be done as follows:</p>
<pre><code> void print(StructureConstPtr struct, PVStructurePtr pv)
{
cout &lt;&lt; struct &lt;&lt; endl;
cout &lt;&lt; pv &lt;&lt; endl;
}
</code></pre>
<h2>New method getAs that is like getSubField except that it throws exception</h2>
<p><b>PVStructure</b> has a new template member <b>getAs(const char *name)</b>
that is like <b>getSubField</b> except that it throws a runtime_error
instead of returning null.</p>
<h1>Release 4.0</h1>
<p>The main changes since release 3.0.2 are:</p>
<ul>
<li>array semantics now enforce Copy On Write.</li>
<li>String no longer defined.</li>
<li>timeStamp and valueAlarm name changes</li>
<li>toString replaced by stream I/O </li>
<li>union is new type.</li>
<li>copy is new.</li>
<li>monitorPlugin is new.</li>
</ul>
<h2>New Semantics for Arrays</h2>
<p>PVScalarArray, PVStructureArray, and PVUnionArray all enforce COW (Copy On Write) Semantics.
In order to limit memory usage the storage for raw data is managed via a new shared_vector facility.
This allows multiple instances of array data to use the shared raw data.
COW is implemented via shared_vectors of const data, i. e. data that can not be modified.</p>
<h2>String no longer defined</h2>
<p>This is replaced by std::string.</p>
<h2>timeStamp and valueAlarm name changes</h2>
<p>In timeStamp nanoSeconds is changed to nanoseconds.</p>
<p>In valueAlarm hystersis is changed to hysteresis</p>
<h2>toString replaced by stream I/O</h2>
<p>pvData.h and pvIntrospect no longer defines toString
Instead they have stream support.
pvIntrospect uses method dump and pvData uses dumpValue.
For example:</p>
<pre><code> PVDoublePtr pvValue;
String buffer;
pvValue-&gt;toString(&amp;buffer);
cout &lt;&lt; buffer &lt;&lt; endl;
buffer.clear();
pvValue-&gt;getField()-&gt;toString(&amp;buffer);
cout &lt;&lt; buffer &lt;&lt; evdl;
</code></pre>
<p>is replaced by</p>
<pre><code> PVDoublePtr pvValue;
cout &lt;&lt; *pvValue &lt;&lt; endl
cout &lt;&lt; *pvValue-&gt;getField() &lt;&lt; endl;
</code></pre>
<h2>union is a new basic type.</h2>
<p>There are two new basic types: union_t and unionArray.</p>
<p>A union is like a structure that has a single subfield.
There are two flavors:</p>
<ul>
<li><b>varient union</b> The field can have any type.</li>
<li><b>union</b> The field can any of specified set of types.</li>
</ul>
<p>The field type can be dynamically changed.</p>
<h2>copy</h2>
<p>This consists of createRequest and pvCopy.
createRequest was moved from pvAccess to here.
pvCopy is moved from pvDatabaseCPP and now depends
only on pvData, i. e. it no longer has any knowledge of PVRecord.</p>
<h2>monitorPlugin</h2>
<p>This is for is for use by code that implements pvAccess monitors.
This is prototype and is subject to debate.</p>
<h1>Release 3.0.2</h1>
<p>This was the starting point for RELEASE_NOTES</p>

View File

@@ -0,0 +1,171 @@
Release 4.1 IN DEVELOPMENT
===========
The main changes since release 4.0 are:
* Convert copy methods and equals operators (re)moved
* Convert::copyUnion now always copies between subfields.
* CreateRequest prevents a possible SEGFAULT.
* New stream operators for Field and PVField are provided.
* New method getSubFieldT that is like getSubField except that it throws exception
Convert copy methods and equals operators
-----------------------------------------
Convert copy methods where moved and replaced with methods
on PVField classes, i.e.
PVField::copy(const PVField& from)
Methods
PVField::copyUnchecked(const PVField& from)
where added to allow unchecked copies, to gain performance
where checked are not needed (anymore).
In addition:
- isCompatibleXXX methods were removed in favour of Field::operator==.
- equals methods were remove in favour of PVField::operator==.
- operator== methods where moved to pvIntrospect.h and pvData.h
Convert::copyUnion
-----------------
Before this method, depending on types for to and from,
sometimes did a shallow cppy, i. e. just made to shared_ptr for to
share the same data as from.
Now it always copies between the subfield of to and from.
CreateRequest change
--------------------
createRequest could cause a SEGFAULT if passed a bad argument.
This has been changed so the it returns a null pvStructure
and provies an error.
New stream operators
--------------------
New steam operators are available for Field and PVField.
Before to print a Field (or any extension) or a PVField (or any extension)
it was necessary to have code like:
void print(StructureConstPtr struct, PVStructurePtr pv)
{
if(struct) {
cout << *struct << endl;
} else {
cout << "nullptr\n"
}
if(pv) {
cout << *.struct << endl;
} else {
cout << "nullptr\n"
}
}
Now it can be done as follows:
void print(StructureConstPtr struct, PVStructurePtr pv)
{
cout << struct << endl;
cout << pv << endl;
}
New method getSubFieldT that is like getSubField except that it throws exception
--------------------
<b>PVStructure</b> has a new template member <b>getSubFieldT(std::string const &fieldName)</b>
that is like <b>getSubField</b> except that it throws a runtime_error
instead of returning null.
Release 4.0
===========
The main changes since release 3.0.2 are:
* array semantics now enforce Copy On Write.
* String no longer defined.
* timeStamp and valueAlarm name changes
* toString replaced by stream I/O
* union is new type.
* copy is new.
* monitorPlugin is new.
New Semantics for Arrays
--------
PVScalarArray, PVStructureArray, and PVUnionArray all enforce COW (Copy On Write) Semantics.
In order to limit memory usage the storage for raw data is managed via a new shared_vector facility.
This allows multiple instances of array data to use the shared raw data.
COW is implemented via shared_vectors of const data, i. e. data that can not be modified.
String no longer defined
---------
This is replaced by std::string.
timeStamp and valueAlarm name changes
--------------
In timeStamp nanoSeconds is changed to nanoseconds.
In valueAlarm hystersis is changed to hysteresis
toString replaced by stream I/O
---------
pvData.h and pvIntrospect no longer defines toString
Instead they have stream support.
pvIntrospect uses method dump and pvData uses dumpValue.
For example:
PVDoublePtr pvValue;
String buffer;
pvValue->toString(&buffer);
cout << buffer << endl;
buffer.clear();
pvValue->getField()->toString(&buffer);
cout << buffer << evdl;
is replaced by
PVDoublePtr pvValue;
cout << *pvValue << endl
cout << *pvValue->getField() << endl;
union is a new basic type.
------------
There are two new basic types: union_t and unionArray.
A union is like a structure that has a single subfield.
There are two flavors:
* <b>varient union</b> The field can have any type.
* <b>union</b> The field can any of specified set of types.
The field type can be dynamically changed.
copy
----
This consists of createRequest and pvCopy.
createRequest was moved from pvAccess to here.
pvCopy is moved from pvDatabaseCPP and now depends
only on pvData, i. e. it no longer has any knowledge of PVRecord.
monitorPlugin
-------------
This is for is for use by code that implements pvAccess monitors.
This is prototype and is subject to debate.
Release 3.0.2
==========
This was the starting point for RELEASE_NOTES

17
documentation/TODO.html Normal file
View File

@@ -0,0 +1,17 @@
<h1>TODO</h1>
<h2>printer</h2>
<p>pv/printer.h is not used.</p>
<h2>doxygen</h2>
<p>There is a lot of public code that does not have doxygen tags.</p>
<h2>postMonitor: PVUnion, PVUnionArray, and PVStructureArray</h2>
<p>PVUnion, PVUnionArray, and PVStructureArray all have elements
that are treated like a top level field.</p>
<p>Currently if a subField of any of these is changed postMonitor is not called for the field itself.</p>
<p>David asked if this could be changed so that it is called.
Marty thinks this may not be a good idea.</p>
<h2>valueAlarm</h2>
<p>normativeTypes.html describes valueAlarm only for a value field that has type
double.
The implementation also supports all the numeric scalar types.</p>
<h2>monitorPlugin</h2>
<p>A debate is on-going about what semantics should be.</p>

33
documentation/TODO.md Normal file
View File

@@ -0,0 +1,33 @@
TODO
===========
doxygen
-------
There is a lot of public code that does not have doxygen tags.
postMonitor: PVUnion, PVUnionArray, and PVStructureArray
--------
PVUnion, PVUnionArray, and PVStructureArray all have elements
that are treated like a top level field.
Currently if a subField of any of these is changed postMonitor is not called for the field itself.
David asked if this could be changed so that it is called.
Marty thinks this may not be a good idea.
valueAlarm
---------
normativeTypes.html describes valueAlarm only for a value field that has type
double.
The implementation also supports all the numeric scalar types.
monitorPlugin
-------------
A debate is on-going about what semantics should be.

View File

@@ -0,0 +1,679 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>EPICS pvDataCPP: copy and monitor</title>
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/base.css" />
<link rel="stylesheet" type="text/css"
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
<style type="text/css">
/*<![CDATA[*/
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
table { margin-left: auto; margin-right: auto }
.diagram { text-align: center; margin: 2.5em 0 }
span.opt { color: grey }
span.nterm { font-style:italic }
span.term { font-family:courier }
span.user { font-family:courier }
span.user:before { content:"<" }
span.user:after { content:">" }
.nonnorm { font-style:italic }
p.ed { color: #AA0000 }
span.ed { color: #AA0000 }
p.ed.priv { display: inline; }
span.ed.priv { display: inline; }
/*]]>*/</style>
<!-- Script that generates the Table of Contents -->
<script type="text/javascript"
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
</script>
</head>
<body>
<div id="toc">
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
</div>
<div id="contents" class="contents">
<h2>support for copy and monitor</h2>
<p><b>copy</b> and <b>monitor</b> are not used in this project.
They are intended for use by pvAccess and by pvAccess servers.
They are provided with this project because the code depends only on
pvData itself.
</p>
<p>This document describes C++ specific code.
<a href="http://epics-pvdata.sourceforge.net/informative/pvRequest.html">
pvRequest.html</a>
provides a language independent overview of <b>copy</b> and <b>monitor</b>.
</p>
<p>
<b>NOTE:pvRequest.html</b> must be updated since it is based on an earlier version of pvCopy that
had knowledge of PVRecord. The C++ version was implemented in pvDatabaseCPP
and the Java version on pvIOCJava.
At present only the C++ version of the new API for pvCopy is implemented.
</p>
<p>Copy provides:
<dl>
<dt>createRequest</dt>
<dd>
The Channel create methods in pvAccess all have an argument
<b>PVStructure pvRequest</b>.<br />
Given an ascii string createRequest creates a PVStructure that provides
a pvData representation of the information from the ascii string.
It is this structure that can be passed to the channel create methods.<br />
The information in a pvRequest selects an arbitrary subset of the
fields in a top level structure that resides in the server.
In addition options can be specified. Both global and field specific
options can be specified.
</dd>
<dt>pvCopy</dt>
<dd>This is a facility used by channel providers.
It provides client specific code that manages a copy of an arbitrary
subset of the fields in a top level structure that resides in the
provider. It also allows provider access to options specified
by the client.
</dd>
</dl>
Monitor provides:
<dl>
<dt>monitor</dt>
<dd>This is support code for channel providers that implement channel
monitor. It, together with the queue facility, provides support for
monitor queues.
</dd>
<dt>monitorPlugin</dt>
<dd>This is support for implementing monitor plugins.
A monitor plugin can be developed that has no knowledge
of pvAccess but only pvData.
</dd>
</dl>
</p>
<h2>support for copy</h2>
<p><b>copy</b> provides the ability to create a structure that has
a copy of an arbitrary subset of the fields in an existing top level
structure. In addition it allows global options and field specific options.
It has two main components: <b>createRequest</b> and <b>pvCopy</b>.
Given a string createRequest creates a pvRequest, which is a PVStructure
that has the format expected by <b>pvCopy</b>.
</p>
<h3>createRequest</h3>
<p>This is mainly used by pvAccess clients. Given a request string it creates
a pvRequest structure that can be passed to the pvAccess create methods.
In turn pvAccess passes the pvRequest to a local channel provider which
then passes it to pvCopy.
</p>
<p>The definition of the public members is:</p>
<pre>
class CreateRequest {
...
static CreateRequestPtr create();
virtual PVStructurePtr createRequest(std::string const &amp;request);
std::string getMessage();
};
</pre>
<p>An example of how it is used is:</p>
<pre>
CreateRequestPtr createRequest = CreateRequest::create();
PVStructurePtr pvRequest = createRequest-&gt;createRequest(request);
if(pvRequest==NULL) {
std::string error = createRequest-&gt;getMessage();
// take some action
} else {
//success do something
}
</pre>
<h3>pvCopy</h3>
<p>The definition of the public members is:</p>
<pre>
class epicsShareClass PVCopyTraverseMasterCallback
{
...
virtual void nextMasterPVField(PVFieldPtr const &amp;pvField);
};
class class epicsShareClass PVCopy
{
...
static PVCopyPtr create(
PVStructurePtr const &amp;pvMaster,
PVStructurePtr const &amp;pvRequest,
std::string const &amp; structureName);
PVStructurePtr getPVMaster();
void traverseMaster(PVCopyTraverseMasterCallbackPtr const &amp; callback);
StructureConstPtr getStructure();
PVStructurePtr createPVStructure();
size_t getCopyOffset(PVFieldPtr const &amp;masterPVField);
size_t getCopyOffset(
PVStructurePtr const &amp;masterPVStructure,
PVFieldPtr const &amp;masterPVField);
PVFieldPtr getMasterPVField(std::size_t structureOffset);
void initCopy(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
void updateCopySetBitSet(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
void updateCopyFromBitSet(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
void updateMaster(
PVStructurePtr const &amp;copyPVStructure,
BitSetPtr const &amp;bitSet);
PVStructurePtr getOptions(std::size_t fieldOffset);
...
};
</pre>
where
<dl>
<dt>PVCopyTraverseMasterCallback::nextMasterPVField</dt>
<dd>
<b>PVCopyTraverseMasterCallback</b> is a callback which must
be implemented by the code that uses pvCopy, normally
the channel provider. It has the single method <b>nextMasterPVField</b>
<br />
<b>nextMasterPVField</b> is called for each field in the master
as a result of a call to <b>traverseMaster</b>.
</dd>
<dt>create</dt>
<dd>
This is the method for creating a PVCopy instance.<br/>
<dl>
<dt>pvMaster</dt>
<dd>the top level structure managed by the server.</dd>
<dt>pvRequest</dt>
<dd>selects the set of subfields desired
and options for each field.</dd>
<dt>structureName</dt>
<dd>the name for the top level of any PVStructure created.
</dd>
</dl>
</dd>
<dt>getPVMaster</dt>
<dd>
Gets the top level structure from pvMaster.
</dd>
<dt>traverseMaster</dt>
<dd>
Traverse all fields of the top level structure of pvMaster.
For each field the callback is called.
</dd>
<dt>getStructure</dt>
<dd>
Get the introspection interface for a PVStructure for e copy.
</dd>
<dt>createPVStructure</dt>
<dd>Create a copy instance.
Monitors keep a queue of monitor elements.
Since each element needs a PVStructure, multiple top level structures
will be created.
</dd>
<dt>getCopyOffset</dt>
<dd>Given a field in pvMaster.
return the offset in copy for the same field.
A value of std::string::npos means that the copy does not have this field.
Two overloaded methods are provided. The first is called if
the field of master is not a structure. The second is for
subfields of a structure.
</dd>
<dt>getMasterPVField</dt>
<dd>
Given a offset in the copy get the corresponding field in pvMaster.
</dd>
<dt>initCopy</dt>
<dd>
Initialize the fields in copyPVStructure
by giving each field the value from the corresponding field in pvMaster.
bitSet will be set to show that all fields are changed.
This means that bit set will have the value <b>{0}</b>.
</dd>
<dt>updateCopySetBitSet</dt>
<dd>
Set all fields in copyPVStructure to the value of the corresponding field
in pvMaster. Each field that is changed has it's corresponding
bit set in bitSet.
</dd>
<dt>updateCopyFromBitSet</dt>
<dd>
For each set bit in bitSet set the field in copyPVStructure to the value
of the corresponding field in pvMaster.
</dd>
<dt>updateMaster</dt>
<dd>
For each set bit in bitSet set the field in pvMaster to the value
of the corresponding field in copyPVStructure.
</dd>
<dt>getOptions</dt>
<dd>
Get the options for the field at the specified offset.
A NULL is returned if no options were specified for the field.
If options were specified,PVStructurePtr is
a structure with a set of PVString subfields that specify name,value
pairs. name is the subField name and value is the subField value.
</dd>
</dl>
<h2>support for monitor</h2>
<p>This consists of two components:
<dl>
<dt>monitor</dt>
<dd>Used by code that implements pvAccess monitors.</dd>
<dt>monitorPlugin</dt>
<dd>Code that provides special semantics for monitors.</dd>
</dl>
</p>
<h3>monitor</h3>
<pre>
class MonitorElement {
MonitorElement(PVStructurePtr const &amp; pvStructurePtr);
PVStructurePtr pvStructurePtr;
BitSetPtr changedBitSet;
BitSetPtr overrunBitSet;
};
class Monitor {
virtual Status start() = 0;
virtual Status stop() = 0;
virtual MonitorElementPtr poll() = 0;
virtual void release(MonitorElementPtr const &amp; monitorElement) = 0;
};
class MonitorRequester : public virtual Requester {
virtual void monitorConnect(Status const &amp; status,
MonitorPtr const &amp; monitor, StructureConstPtr const &amp; structure) = 0;
virtual void monitorEvent(MonitorPtr const &amp; monitor) = 0;
virtual void unlisten(MonitorPtr const &amp; monitor) = 0;
};
</pre>
<h4>monitorElement</h4>
<p><b>MonitorElement</b> holds the data for one element of a monitor queue.
It has the fields:
<dl>
<dt>pvStructurePtr</dt>
<dd>A top level structure with data values at the time the monitors occurs.</dd>
<dt>changedBitSet</dt>
<dd>Shows which fields have changed since the previous monitor.</dd>
<dt>overrunBitSet</dt>
<dd>Shows which fields have changed more han once since the previous monitor.</dd>
</dl>
</p>
<h4>monitorElement queue</h4>
<p>
A queue of monitor elements must be implemented by any channel provider that implements
<b>Channel::createMonitor</b>.
For an example implementation look at pvDatabaseCPP.
It has the following:
<pre>
typedef Queue&lt;MonitorElement&gt; MonitorElementQueue;
typedef std::tr1::shared_ptr&lt;MonitorElementQueue&gt; MonitorElementQueuePtr;
class MultipleElementQueue :
public ElementQueue
{
public:
POINTER_DEFINITIONS(MultipleElementQueue);
virtual ~MultipleElementQueue(){}
MultipleElementQueue(
MonitorLocalPtr const &amp;monitorLocal,
MonitorElementQueuePtr const &amp;queue,
size_t nfields);
virtual void destroy(){}
virtual Status start();
virtual Status stop();
virtual bool dataChanged();
virtual MonitorElementPtr poll();
virtual void release(MonitorElementPtr const &amp;monitorElement);
...
};
</pre>
<h4>Monitor</h4>
<p><b>Monitor</b> must be implemented by any channel provider that implements
<b>Channel::createMonitor</b>.
Remote PVAccess also implements Monitor on the client side.
Note that each client has it's own queue that is not shared with other client.
</p>
<p>Monitor has the following methods:</p>
<dl>
<dt>start</dt>
<dd>
Start monitoring.
This will result in a an initial monitor that has the current value
of all fields.
</dd>
<dt>stop</dt>
<dd>
Stop monitoring.
</dd>
<dt>poll</dt>
<dd>
Called to get a monitor element.
If no new elements are available then a null pointer is returned.
</dd>
<dt>release</dt>
<dd>
Release the monitor element.
The caller owns the monitor element between the calls to poll and release.
</dd>
<dl>
</dl>
<h4>MonitorRequester</h4>
<p>This must be implemented by a pvAccess client.
It has the methods:</p>
<dl>
<dt>monitorConnect</dt>
<dd>
A monitor has either connected of disconnected.
</dd>
<dt>monitorEvent</dt>
<dd>
A new monitor element is available.
</dd>
<dt>unlisten</dt>
<dd>
The channel is going away. The client cam no longer access the monitor.
</dd>
</dl>
<h3>monitorPlugin</h3>
<pre>
class MonitorPlugin
{
virtual std::string const &amp; getName() = 0;
virtual bool causeMonitor(
PVFieldPtr const &amp;pvField,
PVStructurePtr const &amp;pvTop,
MonitorElementPtr const &amp;monitorElement) = 0;
virtual void monitorDone(
MonitorElementPtr const &amp;monitorElement);
virtual void startMonitoring();
virtual void stopMonitoring();
virtual void beginGroupPut();
virtual void endGroupPut();
};
class MonitorPluginCreator
{
virtual MonitorPluginPtr create(
FieldConstPtr const &amp;field,
StructureConstPtr const &amp;top,
PVStructurePtr const &amp;pvFieldOptions) = 0;
virtual std::string const &amp; getName() = 0;
}
class MonitorPluginManager
{
static MonitorPluginManagerPtr get();
bool addPlugin(
std::string const &amp;pluginName,
MonitorPluginCreatorPtr const &amp;creator);
MonitorPluginCreatorPtr findPlugin(std::string const &amp;pluginName);
void showNames();
};
</pre>
<h4>MonitorPlugin</h4>
<p><b>MonitorPlugin</b> must be implemented by the plugin implementation.
It has methods:</p>
<dl>
<dt>getName</dt>
<dd>Get the name of the plugin.</dd>
<dt>causeMonitor</dt>
<dd>
Should the value of pvField cause a monitor to be raised.
pvField and pvTop are fields in the top level structure
being monitored. monitorElement has the top level structure
for the copy</b>.
The implementation should <b>not</b> modify the fields in the structure
being monitored.
Called with pvTop locked.
</dd>
<dt>monitorDone</dt>
<dd>
Called just before monitorElement will be given to client.
The plugin can change the data values and bitSets in monitorElement.
Called with pvTop unlocked.
</dd>
<dt>startMonitoring</dt>
<dd>
Monitoring is starting.
</dd>
<dt>stopMonitoring</dt>
<dd>
Monitoring is being stopped.
</dd>
<dt>beginGroupPut</dt>
<dd>
A set of puts is starting.
Called with pvTop locked.
</dd>
<dt>endGroupPut</dt>
<dd>
The set of puts is complete.
Called with pvTop locked.
</dd>
</dl>
<h4>MonitorPluginCreator</h4>
<p><b>MonitorPluginCreator</b> must also be implemented by the plugin implementation.
It is called for each field instance that has options of the from
<b>[plugin=name...]</b> where <b>name</b> is the name of the plugin.
Note that a plugin instance will belong to a single client.
It has methods:</p>
<dl>
<dt>getName</dt>
<dd>Get the name of the plugin.</dd>
<dt>create</dt>
<dd>
Create a new plugin instance.
If the arguments are not compatible with the plugin a NULL shared pointer is
returned.<br/>
pvFieldOptions is
a structure with a set of PVString subfields that specify <b>name,value</b>
pairs. name is the subField name and value is the subField value.<br/>
Note that a plugin will below to a single client.
</dd>
<dl>
<h4>MonitorPluginManager</h4>
<p><b>MonitorPluginManager</b> has the methods:</p>
<dl>
<dt>get</dt>
<dd>
MonitorPluginManager is a singleton.
The first call to get will create the single instance.
Further calls will return the single instance.
</dd>
<dt>addPlugin</dt>
<dd>
Add a new plugin.
</dd>
<dt>findPlugin</dt>
<dd>
Find a plugin. A NULL shared pointer is returned if it has not been added.
</dd>
<dt>showNames</dt>
<dd>
Show the names of all plugins that have been added.
</dd>
</dl>
<p><b>NOTE:</b>
Should the method <b>causeMonitor</b>
have arguments <b>pvField</b> and <b>pvTop</b>
be defined so that they can not be modified.
This would be possible if the following was defined:
<pre>
typedef std::tr1::shared_ptr&lt;const PVField&gt; PVFieldConstPtr;
typedef std::tr1::shared_ptr&lt;const PVStructure&gt; PVStructureConstPtr;
</pre>
then the definition for causeMonitor could be:
<pre>
virtual bool causeMonitor(
PVFieldConstPtr const &amp;pvField,
PVStructureConstPtr const &amp;pvTop,
MonitorElementPtr const &amp;monitorElement) = 0;
</pre>
But just adding these definitions is not sufficient.
In addition all methods defined in pvDataCPP must be checked.
In particular many of the methods in <b>Convert</b> must have
their arguments modified.
Big job.
</p>
<h2>monitorPlugin example</h2>
<h3>Example Plugin Overview</h3>
<p>This section describes an example plugin that:</p>
<ul>
<li>Only raises monitors when a field changes value.<br />
If no plugin is provided
the default is to raise a monitor when a put is issued to a field.</li>
<li>Optionally a change will not raise a monitor.<br />
The change will, however,
appear if a put to another field raise a monitor.</li>
</ul>
<p>As an example assume that a channel provided by pvAccess has a top level structure
that represents a power supply.</p>
<pre>
structure powerSupply
structure alarm
structure timeStamp
structure power
double value
structure alarm
structure display
structure voltage
double value
structure alarm
structure display
structure current
double value
structure alarm
structure display
</pre>
<p>A pvAccess client wants to create a monitor on the powerSupply as follows:
The client wants a top level structure that looks like:
<pre>
structure powerSupply
structure alarm
structure timeStamp
structure power
double value
structure voltage
double value
structure current
double value
</pre>
In addition the client wants monitors to occur only when one of the monitored
fields changes value but not just because a put occured.
Also if only the timeStamp changes value then that should not cause a monitor.
</p>
<p>The example monitor plugin implements the semantics the
client wants. It can be attached to any field via the following options:
<pre>
[plugin=onChange,raiseMonitor=value]
</pre>
This plugin will trigger a monitor for the field only if the field changes
value. In addition <b>value</b> equals <b>false</b> means do not raise a monitor
for changes to this field.
But if a change to another field does cause a monitor the change to this field
will be passed to the client.
</p>
<p>
Assume that the client has already connected to the channel.
The client can then issue the commands:</p>
<pre>
std::string request("field(alarm[plugin=onChange]");
request += ",timeStamp[plugin=onChange,raiseMonitor=false]";
request += ",power.value[plugin=onChange";
request += ",voltage.value[plugin=onChange";
request += ",current.value[plugin=onChange";
PVStructurePtr pvRequest = createRequest-&gt;createRequest(request);
MonitorPtr monitor = channel-&gt;createMonitor(monitorRequester,pvRequest);
</pre>
<h3>Example Plugin Code</h3>
<p>The header file to create the example has the definition:</p>
<pre>
class ExampleMonitorPlugin{
public:
static void create();
};
</pre>
<p>The implementation is:</p>
<pre>
class OnChangePlugin : public MonitorPlugin
{
public:
virtual ~OnChangePlugin(){}
OnChangePlugin() {}
bool init(
FieldConstPtr const &amp;field,
StructureConstPtr const &amp;top,
PVStructurePtr const &amp;pvFieldOptions)
{
pvField = getPVDataCreate()-&gt;createPVField(field);
raiseMonitor = true;
if(pvFieldOptions!=NULL) {
PVStringPtr pvString =
pvFieldOptions-&gt;getSubField&lt;PVString&gt;("raiseMonitor");
if(pvString!=NULL) {
std::string value = pvString-&gt;get();
if(value.compare("false")==0) raiseMonitor = false;
}
}
return true;
}
virtual std::string &amp;getName(){return pluginName;}
virtual bool causeMonitor(
PVFieldPtr const &amp;pvNew,
PVStructurePtr const &amp;pvTop,
MonitorElementPtr const &amp;monitorElement)
{
bool isSame = convert-&gt;equals(pvNew,pvField);
if(isSame) return false;
convert-&gt;copy(pvNew,pvField);
return raiseMonitor;
}
private:
PVFieldPtr pvField;
bool raiseMonitor;
};
class OnChangePluginCreator : public MonitorPluginCreator
{
public:
virtual std::string &amp;getName(){return pluginName;}
virtual MonitorPluginPtr create(
FieldConstPtr const &amp;field,
StructureConstPtr const &amp;top,
PVStructurePtr const &amp;pvFieldOptions)
{
OnChangePluginPtr plugin(new OnChangePlugin());
bool result = plugin-&gt;init(field,top,pvFieldOptions);
if(!result) return MonitorPluginPtr();
return plugin;
}
};
void ExampleMonitorPlugin::create()
{
static OnChangePluginCreatorPtr plugin;
static Mutex mutex;
Lock xx(mutex);
if(plugin==NULL) {
plugin = OnChangePluginCreatorPtr(new OnChangePluginCreator());
MonitorPluginManager::get()-&gt;addPlugin(pluginName,plugin);
}
}
</pre>
</div>
</body>
</html>

BIN
documentation/examples.zip Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
pvDataCPP cookbook
------------------
Creating introspection data interfaces
// create a scalar
getFieldCreate()->createScalar(pvDouble);
// create a scalar array
getFieldCreate()->createScalarArray(pvDouble);
// create a structure
getFieldCreate()->createFieldBuilder()->
setId("enum_t")->
add("index", pvDouble)->
addArray("choices", pvString)->
createStructure();
// create a structure (cntd.)
StructureConstPtr enum_t =
getFieldCreate()->createFieldBuilder()->
setId("enum_t")->
add("index", pvInt)->
addArray("choices", pvString)->
createStructure();
// create a structure (cntd.)
StructureConstPtr ntEnum =
getFieldCreate()->createFieldBuilder()->
setId("epics:nt/NTEnum:1.0")->
add("value", enum_t)->
addNestedStructure("timeStamp")->
setId("time_t")->
add("secondsPastEpoch", pvLong)->
add("nanoseconds", pvInt)->
add("userTag", pvInt)->
endNested()->
createStructure();
// create an union == same as structure
---
Creating data containers
// create a scalar
PVDouble::shared_pointer doubleValue = getPVDataCreate()->createPVScalar<PVDouble>();
// create a scalar array
PVDoubleArray::shared_pointer doubleArrayValue = getPVDataCreate()->createPVScalarArray<PVDouble>();
// create a structure
PVStructure::shared_pointer struct = getPVDataCreate()->createPVStructure(ntEnum);
// create an union
PVUnion::shared_pointer pvUnion = getPVDataCreate()->createPVUnion(unionIF);
// create a structure array
PVStructureArray::shared_pointer structArray = getPVDataCreate()->createPVStructureArray(ntEnum);
// scalar usage
PVInt::shared_pointer index = struct->getSubField<PVInt>("value.index");
int32 ix = index->get();
index->put(3);
std::cout << *index << std::endl;
// using <<=, >>= operators to get/set
*doubleValue <<= 12.3;
double val;
*doubleValue >>= val;
// array usage
PVStringArray::shared_pointer choices = struct->getSubField<PVStringArray>("value.choices");
// use view() to access read-only data
PVStringArray::const_svector data(choices->view());
for (std::size_t i = 0; i < data.size(); i++)
std::cout << data[i] << std::endl;
// use replace() to put new data
PVStringArray::svector newdata;
newdata.push_back("zero");
newdata.push_back("one");
newdata.push_back("two");
choices->replace(freeze(newdata));
// (add more use-cases) here
// print entire array
std::cout << *choices << std::endl;
// print elmenet at index == 1
std::cout << format::array_at(1) << *choices << std::endl;
----
Union handling
Union::const_shared_pointer punion =
getFieldCreate()->createFieldBuilder()->
add("doubleValue", pvDouble)->
add("intValue", pvInt)->
createUnion();
PVUnion::shared_pointer u = getPVDataCreate()->createPVUnion(punion);
// select and put
// this create a new instance of PVDouble (everytime select() is called)
PVDouble::shared_pointer doubleValue = u->select<PVDouble>("doubleValue");
doubeValue->put(12);
// select using index (and direct put)
u->select<PVDouble>(0)->put(12);
// select using existing PVField (PVUnion stores by-reference)
u->set("doubleValue", doubleValue);
// get selected field name or index
std::string selectedFN = u->getSelectedFieldName();
int32 selectedIndex = u->getSelectedIndex();
// get currently selected (knowing it's PVDouble)
PVDouble value = u->get<PVDouble>();
Variant Union handling
PVUnion::shared_pointer any = getPVDataCreate()->createPVVariantUnion();
PVDouble::shared_pointer doubleValue = getPVDataCreate()->createPVScalar<PVDouble>();
doubleValue->put(12.8);
any->set(doubleValue);
PVDouble::shared_pointer doubleValue2 = any->get<PVDouble>();
// variant union work by-reference (pointers match also)
// doubleValue.get() == doubleValue2.get()
------
Convert
// convert to int
int32 i = doubleValue->getAs<int32>();
// from int
doubleValue->putFrom<int32>(i);
// from string
doubleValue->putFrom<std::string>("12.3");
// from scalar field
doubleValue->assign(pvScalar);
// convert to int array
PVIntArray::const_svector intData;
doubleArrayValue->getAs<int32>(intData);
// from string array
PVStringArray::svector labels;
labels.push_back("zero");
labels.push_back("one");
labels.push_back("two");
doubleArrayValue->putFrom<std::string>(labels);
// from scalar array
doubleArrayValue->assign(pvScalarArray);

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

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

56
jenkins/cloudbees_build Normal file
View File

@@ -0,0 +1,56 @@
# 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
# Copyright (C) 2014-2015 ITER Organization.
# All rights reserved. Use is subject to license terms.
###########################################
# Determine EPICS Base version
DEFAULT_BASE=3.14.12.5
BASE=${1:-${DEFAULT_BASE}}
USE_MB=${2:-"MB_NO"}
###########################################
# 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-${BASE}_Build/lastSuccessfulBuild/artifact/base-${BASE}.CB-dist.tar.gz
tar -xzf base-${BASE}.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
###########################################
# Test
make runtests
###########################################
# Create distribution
tar czf pvData.CB-dist.tar.gz lib include COPYRIGHT LICENSE

51
jenkins/cloudbees_doc Normal file
View File

@@ -0,0 +1,51 @@
# pvData C++ implementation
# Jenkins @ Cloudbees documentation generation and deployment
#
# 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
# Copyright (C) 2014-2015 ITER Organization.
# All rights reserved. Use is subject to license terms.
###########################################
# Set EPICS Base version and upload target
BASE=3.15.2
PUBLISH=${1:-DONT}
###########################################
# Fetch and unpack dependencies
export STUFF=/tmp/stuff
rm -fr ${STUFF}
mkdir -p ${STUFF}
cd ${STUFF}
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 doxygen-1.8.3.CB-dist.tar.gz
###########################################
# Generate
cd ${WORKSPACE}
wget -nv https://openepics.ci.cloudbees.com/job/pvDataCPP_Build/BASE=${BASE},USE_MB=MB_NO/lastSuccessfulBuild/artifact/pvData.CB-dist.tar.gz
tar -xzf pvData.CB-dist.tar.gz
export PATH=${STUFF}/bin:${PATH}
doxygen
###########################################
# Publish
if [ "${PUBLISH}" != "DONT" ]; then
# Upload explicit dummy to ensure target directory exists
echo "Created by CloudBees Jenkins upload job. Should be deleted as part of the job." > DUMMY
rsync -q -e ssh DUMMY epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/pvDataCPP/${PUBLISH}/DUMMY
rsync -aqP --delete -e ssh documentation epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/pvDataCPP/${PUBLISH}/
fi

View File

@@ -1,108 +0,0 @@
TOP = ..
include $(TOP)/configure/CONFIG
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
INC += bitSet.h
INC += byteBuffer.h
INC += epicsException.h
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
LIBSRCS += CDRMonitor.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
SRC_DIRS += $(PVDATA)/pv
INC += pvType.h
INC += pvIntrospect.h
INC += pvData.h
INC += convert.h
INC += standardField.h
INC += standardPVField.h
SRC_DIRS += $(PVDATA)/factory
INC += factory.h
LIBSRCS += TypeFunc.cpp
LIBSRCS += PVAuxInfoImpl.cpp
LIBSRCS += FieldCreateFactory.cpp
LIBSRCS += PVField.cpp
LIBSRCS += PVScalar.cpp
LIBSRCS += PVArray.cpp
LIBSRCS += PVScalarArray.cpp
LIBSRCS += PVStructure.cpp
LIBSRCS += DefaultPVStructureArray.cpp
LIBSRCS += PVDataCreateFactory.cpp
LIBSRCS += Convert.cpp
LIBSRCS += Compare.cpp
LIBSRCS += StandardField.cpp
LIBSRCS += StandardPVField.cpp
SRC_DIRS += $(PVDATA)/property
INC += alarm.h
INC += pvAlarm.h
INC += control.h
INC += pvControl.h
INC += display.h
INC += pvDisplay.h
INC += pvEnumerated.h
INC += timeStamp.h
INC += pvTimeStamp.h
LIBSRCS += alarm.cpp
LIBSRCS += pvAlarm.cpp
LIBSRCS += pvControl.cpp
LIBSRCS += pvDisplay.cpp
LIBSRCS += pvEnumerated.cpp
LIBSRCS += timeStamp.cpp
LIBSRCS += pvTimeStamp.cpp
SRC_DIRS += $(PVDATA)/pvMisc
INC += bitSetUtil.h
LIBSRCS += bitSetUtil.cpp
SRC_DIRS += $(PVDATA)/monitor
INC += monitor.h
INC += monitorQueue.h
LIBSRCS += monitorQueue.cpp
LIBRARY=pvData
pvData_LIBS += Com
include $(TOP)/configure/RULES

View File

@@ -1,97 +0,0 @@
#include <pv/convert.h>
#include <algorithm>
#include <iterator>
#include <sstream>
namespace epics { namespace pvData {
// PVXXX object comparison
bool operator==(PVField& left, PVField& right)
{
return getConvert()->equals(left,right);
}
// Introspection object comparision
/** Field equality conditions:
* 1) same instance
* 2) same type (field and scalar/element), same name, same subfields (if any)
*/
bool operator==(const Field& a, const Field& b)
{
if(&a==&b)
return true;
if(a.getType()!=b.getType())
return false;
switch(a.getType()) {
case scalar: {
const Scalar &A=static_cast<const Scalar&>(a);
const Scalar &B=static_cast<const Scalar&>(b);
return A==B;
}
case scalarArray: {
const ScalarArray &A=static_cast<const ScalarArray&>(a);
const ScalarArray &B=static_cast<const ScalarArray&>(b);
return A==B;
}
case structure: {
const Structure &A=static_cast<const Structure&>(a);
const Structure &B=static_cast<const Structure&>(b);
return A==B;
}
case structureArray: {
const StructureArray &A=static_cast<const StructureArray&>(a);
const StructureArray &B=static_cast<const StructureArray&>(b);
return A==B;
}
default:
throw std::logic_error("Invalid Field type in comparision");
}
}
bool operator==(const Scalar& a, const Scalar& b)
{
if(&a==&b)
return true;
return a.getScalarType()==b.getScalarType() && a.getFieldName()==b.getFieldName();
}
bool operator==(const ScalarArray& a, const ScalarArray& b)
{
if(&a==&b)
return true;
return a.getElementType()==b.getElementType() && a.getFieldName()==b.getFieldName();
}
bool operator==(const Structure& a, const Structure& b)
{
if(&a==&b)
return true;
int 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++)
if (*(af[i].get()) != *(bf[i].get()))
return false;
return true;
}
bool operator==(const StructureArray& a, const StructureArray& b)
{
return a.structure() == b.structure();
}
namespace nconvert {
} // namespace nconvert
}} // namespace epics::pvData

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,260 +0,0 @@
/*FieldCreateFactory.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/lock.h>
#include <pv/pvIntrospect.h>
#include <pv/convert.h>
#include <pv/factory.h>
#include <pv/CDRMonitor.h>
using std::tr1::static_pointer_cast;
namespace epics { namespace pvData {
static DebugLevel debugLevel = lowDebug;
static void newLine(StringBuilder buffer, int indentLevel)
{
*buffer += "\n";
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)
{
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(field);
}
Field::~Field() {
PVDATA_REFCOUNT_MONITOR_DESTRUCT(field);
// note that compiler automatically calls destructor for fieldName
if(debugLevel==highDebug) printf("~Field %s\n",m_fieldName.c_str());
}
void Field::renameField(String newName)
{
m_fieldName = newName;
}
void Field::toString(StringBuilder buffer,int indentLevel) const{
*buffer += " ";
*buffer += m_fieldName.c_str();
}
Scalar::Scalar(String fieldName,ScalarType scalarType)
: Field(fieldName,scalar),scalarType(scalarType){}
Scalar::~Scalar(){}
void Scalar::toString(StringBuilder buffer,int indentLevel) const{
ScalarTypeFunc::toString(buffer,scalarType);
Field::toString(buffer,indentLevel);
}
ScalarArray::ScalarArray(String fieldName,ScalarType elementType)
: Field(fieldName,scalarArray),elementType(elementType){}
ScalarArray::~ScalarArray() {}
void ScalarArray::toString(StringBuilder buffer,int indentLevel) const{
ScalarTypeFunc::toString(buffer,elementType);
*buffer += "[]";
Field::toString(buffer,indentLevel);
}
StructureArray::StructureArray(String fieldName,StructureConstPtr structure)
: Field(fieldName,structureArray),pstructure(structure)
{
}
StructureArray::~StructureArray() {
if(debugLevel==highDebug) printf("~StructureArray\n");
}
void StructureArray::toString(StringBuilder buffer,int indentLevel) const {
*buffer += "structure[]";
Field::toString(buffer,indentLevel);
newLine(buffer,indentLevel + 1);
pstructure->toString(buffer,indentLevel + 1);
}
Structure::Structure (String fieldName,
int numberFields, FieldConstPtrArray infields)
: Field(fieldName,structure),
numberFields(numberFields),
fields(infields)
{
for(int i=0; i<numberFields; i++) {
String name = fields[i]->getFieldName();
// look for duplicates
for(int j=i+1; j<numberFields; j++) {
String otherName = fields[j]->getFieldName();
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());
delete[] fields;
}
FieldConstPtr Structure::getField(String fieldName) const {
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(pfield->getFieldName());
if(result==0) return pfield;
}
return FieldConstPtr();
}
int Structure::getFieldIndex(String fieldName) const {
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(pfield->getFieldName());
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++) {
FieldConstPtr pfield = fields[i];
pfield->toString(buffer,indentLevel+1);
if(i<numberFields-1) newLine(buffer,indentLevel+1);
}
}
ScalarConstPtr FieldCreate::createScalar(String fieldName,
ScalarType scalarType) const
{
ScalarConstPtr scalar(new Scalar(fieldName,scalarType), Field::Deleter());
return scalar;
}
ScalarArrayConstPtr FieldCreate::createScalarArray(
String fieldName,ScalarType elementType) const
{
ScalarArrayConstPtr scalarArray(new ScalarArray(fieldName,elementType), Field::Deleter());
return scalarArray;
}
StructureConstPtr FieldCreate::createStructure (
String fieldName,int numberFields,
FieldConstPtr fields[]) const
{
StructureConstPtr structure(new Structure(
fieldName,numberFields,fields), Field::Deleter());
return structure;
}
StructureArrayConstPtr FieldCreate::createStructureArray(
String fieldName,StructureConstPtr structure) const
{
StructureArrayConstPtr structureArray(new StructureArray(fieldName,structure), Field::Deleter());
return structureArray;
}
FieldConstPtr FieldCreate::create(String fieldName,
FieldConstPtr pfield) const
{
FieldConstPtr ret;
Type type = pfield->getType();
switch(type) {
case scalar: {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(pfield);
return createScalar(fieldName,pscalar->getScalarType());
}
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);
}
static FieldCreate* fieldCreate = 0;
FieldCreate::FieldCreate()
{
}
FieldCreate * getFieldCreate() {
static Mutex mutex;
Lock xx(mutex);
if(fieldCreate==0) fieldCreate = new FieldCreate();
return fieldCreate;
}
}}

View File

@@ -1,89 +0,0 @@
/*PVArray.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/factory.h>
namespace epics { namespace pvData {
class PVArrayPvt {
public:
PVArrayPvt() : length(0),capacity(0),capacityMutable(true)
{}
int length;
int capacity;
bool capacityMutable;
};
PVArray::PVArray(PVStructure *parent,FieldConstPtr field)
: PVField(parent,field),pImpl(new PVArrayPvt())
{ }
PVArray::~PVArray()
{
delete pImpl;
}
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;
}
bool PVArray::isCapacityMutable()
{
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;
}
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;
}
}}

View File

@@ -1,102 +0,0 @@
/*PVAuxInfo.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/noDefaultMethods.h>
#include <pv/pvData.h>
#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])
{
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(pvAuxInfo);
}
PVAuxInfo::~PVAuxInfo()
{
PVDATA_REFCOUNT_MONITOR_DESTRUCT(pvAuxInfo);
for(int i=0; i<numberInfo; i++) delete pvInfos[i];
delete[] pvInfos;
}
PVField * PVAuxInfo::getPVField() {
return pvField;
}
PVScalar * PVAuxInfo::createInfo(String 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;
}
}
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;
return pvScalar;
}
PVScalar * PVAuxInfo::getInfo(String key)
{
for(int i=0; i<numberInfo; i++) {
PVScalar *pvScalar = pvInfos[i];
if(key.compare(pvScalar->getField()->getFieldName())==0) return pvScalar;
}
return 0;
}
PVScalar * PVAuxInfo::getInfo(int index)
{
if(index<0 || index>=numberInfo) return 0;
return pvInfos[index];
}
int PVAuxInfo::getNumberInfo() { return numberInfo;}
void PVAuxInfo::toString(StringBuilder buf)
{
PVAuxInfo::toString(buf,0);
}
void PVAuxInfo::toString(StringBuilder buf,int indentLevel)
{
if(numberInfo==0) return;
Convert *convert = getConvert();
convert->newLine(buf,indentLevel);
*buf += "auxInfo";
for(int i=0; i<numberInfo; i++) {
convert->newLine(buf,indentLevel+1);
PVScalar *value = pvInfos[i];
value->toString(buf,indentLevel + 1);
}
}
}}

View File

@@ -1,601 +0,0 @@
/*PVDataCreateFactory.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.
*/
#ifdef _WIN32
#define NOMINMAX
#endif
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/lock.h>
#include <pv/pvIntrospect.h>
#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 {
static Convert* convert = 0;
static FieldCreate * fieldCreate = 0;
static PVDataCreate* pvDataCreate = 0;
/** Default storage for scalar values
*/
template<typename T>
class BasePVScalar : public PVScalarValue<T> {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
BasePVScalar(PVStructure *parent,ScalarConstPtr scalar);
virtual ~BasePVScalar();
virtual T get();
virtual void put(T val);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const;
virtual void deserialize(ByteBuffer *pbuffer,
DeserializableControl *pflusher);
private:
T value;
};
template<typename T>
BasePVScalar<T>::BasePVScalar(PVStructure *parent,ScalarConstPtr scalar)
: PVScalarValue<T>(parent,scalar),value(0)
{}
//Note: '0' is a suitable default for all POD types (not String)
template<typename T>
BasePVScalar<T>::~BasePVScalar() {}
template<typename T>
T BasePVScalar<T>::get() { return value;}
template<typename T>
void BasePVScalar<T>::put(T val){value = val;}
template<typename T>
void BasePVScalar<T>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const {
pflusher->ensureBuffer(sizeof(T));
pbuffer->put<T>(value);
}
template<typename T>
void BasePVScalar<T>::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pflusher)
{
pflusher->ensureData(sizeof(T));
value = pbuffer->get<T>();
}
typedef BasePVScalar<bool> BasePVBoolean;
typedef BasePVScalar<int8> BasePVByte;
typedef BasePVScalar<int16> BasePVShort;
typedef BasePVScalar<int32> BasePVInt;
typedef BasePVScalar<int64> BasePVLong;
typedef BasePVScalar<float> BasePVFloat;
typedef BasePVScalar<double> BasePVDouble;
// BasePVString is special case, since it implements SerializableArray
class BasePVString : public PVString {
public:
typedef String value_type;
typedef String* pointer;
typedef const String* const_pointer;
BasePVString(PVStructure *parent,ScalarConstPtr scalar);
virtual ~BasePVString();
virtual String get();
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;
private:
String value;
};
BasePVString::BasePVString(PVStructure *parent,ScalarConstPtr scalar)
: PVString(parent,scalar),value()
{}
BasePVString::~BasePVString() {}
String BasePVString::get() { return value;}
void BasePVString::put(String val){value = val;}
void BasePVString::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const
{
SerializeHelper::serializeString(value, pbuffer, pflusher);
}
void BasePVString::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pflusher)
{
value = SerializeHelper::deserializeString(pbuffer, pflusher);
}
void BasePVString::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, int offset, int 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 int maxCount = length - offset;
if (count > maxCount)
count = maxCount;
// write
SerializeHelper::serializeSubstring(value, offset, count, pbuffer, pflusher);
}
/** Default storage for arrays
*/
template<typename T>
class DefaultPVArray : public PVValueArray<T> {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
DefaultPVArray(PVStructure *parent,ScalarArrayConstPtr 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);
// 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;
private:
pointer value;
};
template<typename T>
DefaultPVArray<T>::DefaultPVArray(PVStructure *parent,
ScalarArrayConstPtr scalarArray)
: PVValueArray<T>(parent,scalarArray),value(new T[0])
{ }
template<typename T>
DefaultPVArray<T>::~DefaultPVArray()
{
delete[] value;
}
template<typename T>
void DefaultPVArray<T>::setCapacity(int capacity)
{
if(PVArray::getCapacity()==capacity) return;
if(!PVArray::isCapacityMutable()) {
std::string message("not capacityMutable");
PVField::message(message, errorMessage);
return;
}
int 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;
PVArray::setCapacityLength(capacity,length);
}
template<typename T>
int DefaultPVArray<T>::get(int offset, int len, PVArrayData<T> *data)
{
int n = len;
int length = this->getLength();
if(offset+len > length) {
n = length-offset;
if(n<0) n = 0;
}
data->data = value;
data->offset = offset;
return n;
}
template<typename T>
int DefaultPVArray<T>::put(int offset,int len,
pointer from,int fromOffset)
{
if(PVField::isImmutable()) {
PVField::message("field is immutable",errorMessage);
return 0;
}
if(from==value) return len;
if(len<1) return 0;
int length = this->getLength();
int capacity = this->getCapacity();
if(offset+len > length) {
int newlength = offset + len;
if(newlength>capacity) {
setCapacity(newlength);
newlength = this->getCapacity();
len = newlength - offset;
if(len<=0) return 0;
}
length = newlength;
}
for(int i=0;i<len;i++) {
value[i+offset] = from[i+fromOffset];
}
this->setLength(length);
this->postPut();
return len;
}
template<typename T>
void DefaultPVArray<T>::shareData(pointer shareValue,int capacity,int length)
{
delete[] value;
value = shareValue;
PVArray::setCapacityLength(capacity,length);
}
template<typename T>
void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const {
serialize(pbuffer, pflusher, 0, this->getLength());
}
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) {
// prepare array, if necessary
if(size>this->getCapacity()) this->setCapacity(size);
// retrieve value from the buffer
int i = 0;
while(true) {
/*
int maxIndex = std::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);
i += maxCount;
if(i<size)
pcontrol->ensureData(sizeof(T)); // this is not OK since can exceen max local buffer (size-i)*sizeof(T));
else
break;
}
// set new length
this->setLength(size);
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 {
// cache
int length = this->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);
//if (count == 0) return; pcontrol->ensureData(sizeof(T)-1); pbuffer->align(sizeof(T));
int end = offset+count;
int i = offset;
while(true) {
/*
int maxIndex = std::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);
i += maxCount;
if(i<end)
pflusher->flushSerializeBuffer();
else
break;
}
}
// specializations for String
template<>
void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
int 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);
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();
// 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);
int end = offset+count;
for(int i = offset; i<end; i++)
SerializeHelper::serializeString(value[i], pbuffer, pflusher);
}
typedef DefaultPVArray<bool> DefaultPVBooleanArray;
typedef DefaultPVArray<int8> BasePVByteArray;
typedef DefaultPVArray<int16> BasePVShortArray;
typedef DefaultPVArray<int32> BasePVIntArray;
typedef DefaultPVArray<int64> BasePVLongArray;
typedef DefaultPVArray<float> BasePVFloatArray;
typedef DefaultPVArray<double> BasePVDoubleArray;
typedef DefaultPVArray<String> BasePVStringArray;
// Factory
PVDataCreate::PVDataCreate(){ }
PVField *PVDataCreate::createPVField(PVStructure *parent,
FieldConstPtr field)
{
switch(field->getType()) {
case scalar: {
ScalarConstPtr xx = static_pointer_cast<const Scalar>(field);
return createPVScalar(parent,xx);
}
case scalarArray: {
ScalarArrayConstPtr xx = static_pointer_cast<const ScalarArray>(field);
return (PVField *)createPVScalarArray(parent,xx);
}
case structure: {
StructureConstPtr xx = static_pointer_cast<const Structure>(field);
return (PVField *)createPVStructure(parent,xx);
}
case structureArray: {
StructureArrayConstPtr xx = static_pointer_cast<const StructureArray>(field);
return createPVStructureArray(parent,xx);
}
}
String message("PVDataCreate::createPVField should never get here");
throw std::logic_error(message);
}
PVField *PVDataCreate::createPVField(PVStructure *parent,
String fieldName,PVField * fieldToClone)
{
switch(fieldToClone->getField()->getType()) {
case scalar:
return createPVScalar(parent,fieldName,(PVScalar*)fieldToClone);
case scalarArray:
return (PVField *)createPVScalarArray(parent,fieldName,
(PVScalarArray *)fieldToClone);
case structure:
return (PVField *)createPVStructure(parent,fieldName,
(PVStructure *)fieldToClone);
case structureArray:
String message(
"PVDataCreate::createPVField structureArray not valid fieldToClone");
throw std::invalid_argument(message);
}
String message("PVDataCreate::createPVField should never get here");
throw std::logic_error(message);
}
PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,ScalarConstPtr scalar)
{
ScalarType scalarType = scalar->getScalarType();
switch(scalarType) {
case pvBoolean:
return new BasePVBoolean(parent,scalar);
case pvByte:
return new BasePVByte(parent,scalar);
case pvShort:
return new BasePVShort(parent,scalar);
case pvInt:
return new BasePVInt(parent,scalar);
case pvLong:
return new BasePVLong(parent,scalar);
case pvFloat:
return new BasePVFloat(parent,scalar);
case pvDouble:
return new BasePVDouble(parent,scalar);
case pvString:
return new BasePVString(parent,scalar);
}
String message("PVDataCreate::createPVScalar should never get here");
throw std::logic_error(message);
}
PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,
String fieldName,ScalarType scalarType)
{
ScalarConstPtr scalar = fieldCreate->createScalar(fieldName,scalarType);
return createPVScalar(parent,scalar);
}
PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,
String fieldName,PVScalar * 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);
}
return pvScalar;
}
PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent,
ScalarArrayConstPtr scalarArray)
{
switch(scalarArray->getElementType()) {
case pvBoolean:
return new DefaultPVBooleanArray(parent,scalarArray);
case pvByte:
return new BasePVByteArray(parent,scalarArray);
case pvShort:
return new BasePVShortArray(parent,scalarArray);
case pvInt:
return new BasePVIntArray(parent,scalarArray);
case pvLong:
return new BasePVLongArray(parent,scalarArray);
case pvFloat:
return new BasePVFloatArray(parent,scalarArray);
case pvDouble:
return new BasePVDoubleArray(parent,scalarArray);
case pvString:
return new BasePVStringArray(parent,scalarArray);
}
String message("PVDataCreate::createPVScalarArray should never get here");
throw std::logic_error(message);
}
PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent,
String fieldName,ScalarType elementType)
{
return createPVScalarArray(parent,
fieldCreate->createScalarArray(fieldName, elementType));
}
PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent,
String fieldName,PVScalarArray * arrayToClone)
{
PVScalarArray *pvArray = createPVScalarArray(parent,fieldName,
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);
}
return pvArray;
}
PVStructureArray *PVDataCreate::createPVStructureArray(PVStructure *parent,
StructureArrayConstPtr structureArray)
{
return new BasePVStructureArray(parent,structureArray);
}
PVStructure *PVDataCreate::createPVStructure(PVStructure *parent,
StructureConstPtr structure)
{
PVStructure *pvStructure = new PVStructure(parent,structure);
return pvStructure;
}
PVStructure *PVDataCreate::createPVStructure(PVStructure *parent,
String fieldName,int numberFields,FieldConstPtrArray fields)
{
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;;
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);
}
return pvStructure;
}
PVDataCreate * getPVDataCreate() {
static Mutex mutex;
Lock xx(mutex);
if(pvDataCreate==0){
pvDataCreate = new PVDataCreate();
convert = getConvert();
fieldCreate = getFieldCreate();
}
return pvDataCreate;
}
}}

View File

@@ -1,255 +0,0 @@
/*PVField.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/lock.h>
#include <pv/pvData.h>
#include <pv/factory.h>
#include <pv/convert.h>
#include <pv/CDRMonitor.h>
using std::tr1::const_pointer_cast;
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())
{
}
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)
{
if(pImpl->parent!=0) {
String parentName = pImpl->parent->getField()->getFieldName();
if(parentName.length()>0) {
fieldName = parentName + "." + fieldName;
}
pImpl->parent->message(fieldName,message,messageType);
return;
}
if(pImpl->requester) {
String mess = fieldName + " " + message;
pImpl->requester->message(mess,messageType);
} else {
printf("%s %s %s\n",
messageTypeName[messageType].c_str(),
fieldName.c_str(),
message.c_str());
}
}
void PVField::message(String message,MessageType messageType)
{
PVField::message(pImpl->field->getFieldName(),message,messageType);
}
void PVField::setRequester(Requester *requester)
{
if(pImpl->parent!=0) {
throw std::logic_error(String(
"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"));
}
pImpl->requester = requester;
}
int PVField::getFieldOffset()
{
if(pImpl->nextFieldOffset==0) computeOffset(this);
return pImpl->fieldOffset;
}
int PVField::getNextFieldOffset()
{
if(pImpl->nextFieldOffset==0) computeOffset(this);
return pImpl->nextFieldOffset;
}
int PVField::getNumberFields()
{
if(pImpl->nextFieldOffset==0) computeOffset(this);
return (pImpl->nextFieldOffset - pImpl->fieldOffset);
}
PVAuxInfo * PVField::getPVAuxInfo(){
if(pImpl->pvAuxInfo==0) {
pImpl->pvAuxInfo = new PVAuxInfo(this);
}
return pImpl->pvAuxInfo;
}
bool PVField::isImmutable() {return pImpl->immutable;}
void PVField::setImmutable() {pImpl->immutable = true;}
FieldConstPtr PVField::getField() {return pImpl->field;}
PVStructure * PVField::getParent() {return pImpl->parent;}
bool PVField::renameField(String newName)
{
if(pImpl->parent!=0) {
StructureConstPtr structure = pImpl->parent->getStructure();
int index = structure->getFieldIndex(newName);
if(index>=0) return false;
}
Field::shared_pointer field(const_pointer_cast<Field>(pImpl->field));
field->renameField(newName);
return true;
}
void PVField::postPut()
{
if(pImpl->postHandler!=0) pImpl->postHandler->postPut();
}
void PVField::setPostHandler(PostHandler *postHandler)
{
if(pImpl->postHandler!=0) {
if(postHandler==pImpl->postHandler) return;
String message(
"PVField::setPostHandler a postHandler is already registered");
throw std::logic_error(message);
}
pImpl->postHandler = postHandler;
}
void PVField::setParent(PVStructure * parent)
{
pImpl->parent = parent;
}
bool PVField::equals(PVField &pv)
{
return pImpl->convert->equals(*this,pv);
}
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);
}
void PVField::computeOffset(PVField * pvField) {
PVStructure *pvTop = pvField->getParent();
if(pvTop==0) {
if(pvField->getField()->getType()!=structure) {
pvField->pImpl->fieldOffset = 0;
pvField->pImpl->nextFieldOffset = 1;
return;
}
pvTop = static_cast<PVStructure *>(pvField);
} else {
while(pvTop->getParent()!=0) pvTop = pvTop->getParent();
}
int offset = 0;
int nextOffset = 1;
PVFieldPtrArray pvFields = pvTop->getPVFields();
for(int i=0; i < pvTop->getStructure()->getNumberFields(); i++) {
offset = nextOffset;
PVField *pvField = pvFields[i];
FieldConstPtr field = pvField->getField();
switch(field->getType()) {
case scalar:
case scalarArray:
case structureArray:{
nextOffset++;
pvField->pImpl->fieldOffset = offset;
pvField->pImpl->nextFieldOffset = nextOffset;
break;
}
case structure: {
pvField->computeOffset(pvField,offset);
nextOffset = pvField->getNextFieldOffset();
}
}
}
PVField *top = (PVField *)pvTop;
top->pImpl->fieldOffset = 0;
top->pImpl->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;
}
}}

View File

@@ -1,28 +0,0 @@
/*PVScalar.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/factory.h>
using std::tr1::static_pointer_cast;
namespace epics { namespace pvData {
PVScalar::~PVScalar() {}
PVScalar::PVScalar(PVStructure *parent,ScalarConstPtr scalar)
: PVField(parent,scalar) {}
ScalarConstPtr PVScalar::getScalar()
{
return static_pointer_cast<const Scalar>(PVField::getField());
}
}}

View File

@@ -1,567 +0,0 @@
/*PVStructure.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 <vector>
#include <pv/pvData.h>
#include <pv/pvIntrospect.h>
#include <pv/convert.h>
#include <pv/factory.h>
#include <pv/bitSet.h>
using std::tr1::static_pointer_cast;
using std::tr1::const_pointer_cast;
namespace epics { namespace pvData {
class PVStructurePvt {
public:
PVStructurePvt();
~PVStructurePvt();
int numberFields;
PVFieldPtrArray pvFields;
String extendsStructureName;
};
PVStructurePvt::PVStructurePvt()
: numberFields(0), pvFields(0),extendsStructureName("")
{
}
PVStructurePvt::~PVStructurePvt()
{
for(int i=0; i<numberFields; i++) {
delete pvFields[i];
}
if (pvFields) delete[] pvFields;
}
static PVField *findSubField(String fieldName,PVStructure *pvStructure);
PVStructure::PVStructure(PVStructure *parent,StructureConstPtr structurePtr)
: PVField(parent,structurePtr),pImpl(new PVStructurePvt())
{
int numberFields = structurePtr->getNumberFields();
FieldConstPtrArray fields = structurePtr->getFields();
pImpl->numberFields = numberFields;
pImpl->pvFields = new PVFieldPtr[numberFields];
PVFieldPtrArray pvFields = pImpl->pvFields;
PVDataCreate *pvDataCreate = getPVDataCreate();
for(int i=0; i<numberFields; i++) {
pvFields[i] = pvDataCreate->createPVField(this,fields[i]);
}
}
PVStructure::PVStructure(PVStructure *parent,StructureConstPtr structurePtr,
PVFieldPtrArray pvFields
)
: PVField(parent,structurePtr),pImpl(new PVStructurePvt())
{
int numberFields = structurePtr->getNumberFields();
pImpl->numberFields = numberFields;
pImpl->pvFields = pvFields;
for(int i=0; i<numberFields; i++) {
PVField *pvField = pvFields[i];
setParentPvt(pvField,this);
}
}
void PVStructure::setParentPvt(PVField *pvField,PVStructure *parent)
{
pvField->setParent(parent);
if(pvField->getField()->getType()==structure) {
PVStructure *subStructure = static_cast<PVStructure*>(pvField);
PVFieldPtr *subFields = subStructure->getPVFields();
int numberFields = subStructure->getStructure()->getNumberFields();
for(int i=0; i<numberFields; i++) {
PVField *subField = static_cast<PVField*>(subFields[i]);
setParentPvt(subField,subStructure);
}
}
}
PVStructure::~PVStructure()
{
delete pImpl;
}
StructureConstPtr PVStructure::getStructure()
{
return static_pointer_cast<const Structure>(PVField::getField());
}
PVFieldPtrArray PVStructure::getPVFields()
{
return pImpl->pvFields;
}
PVFieldPtr PVStructure::getSubField(String fieldName)
{
return findSubField(fieldName,this);
}
PVFieldPtr PVStructure::getSubField(int fieldOffset)
{
if(fieldOffset<=getFieldOffset()) {
if(fieldOffset==getFieldOffset()) return this;
return 0;
}
if(fieldOffset>getNextFieldOffset()) return 0;
int numFields = pImpl->numberFields;
PVFieldPtrArray pvFields = pImpl->pvFields;
for(int i=0; i<numFields; i++) {
PVField *pvField = pvFields[i];
if(pvField->getFieldOffset()==fieldOffset) return pvField;
if(pvField->getNextFieldOffset()<=fieldOffset) continue;
if(pvField->getField()->getType()==structure) {
return ((PVStructure*)pvField)->getSubField(fieldOffset);
}
}
String message("PVStructure.getSubField: Logic error");
throw std::logic_error(message);
}
void PVStructure::appendPVField(PVFieldPtr pvField)
{
Structure::shared_pointer structure = const_pointer_cast<Structure>(getStructure());
structure->appendField(pvField->getField());
int origLength = pImpl->numberFields;
PVFieldPtrArray oldPVFields = pImpl->pvFields;
PVFieldPtrArray newPVFields = new PVFieldPtr[origLength + 1];
for(int i=0; i<origLength; i++) {
newPVFields[i] = oldPVFields[i];
}
// note that origLength IS new element
newPVFields[origLength] = pvField;
delete[] pImpl->pvFields;
pImpl->pvFields = newPVFields;
pImpl->numberFields = origLength + 1;
}
void PVStructure::appendPVFields(int numberNewFields,PVFieldPtrArray pvFields)
{
if (numberNewFields<0)
throw std::logic_error("Number of fields must be >=0");
Structure::shared_pointer structure = const_pointer_cast<Structure>(getStructure());
std::vector<FieldConstPtr> fields(numberNewFields);
for(int i=0; i<numberNewFields; i++) fields[i] = pvFields[i]->getField();
structure->appendFields(numberNewFields,&fields[0]);
int origLength = pImpl->numberFields;
PVFieldPtrArray oldPVFields = pImpl->pvFields;
int numberFields = origLength + numberNewFields;
PVFieldPtrArray newPVFields = new PVFieldPtr[numberFields];
for(int i=0; i<origLength; i++) {
newPVFields[i] = oldPVFields[i];
}
for(int i=0; i<numberNewFields; i++) {
newPVFields[i+origLength] = pvFields[i];
}
delete[] pImpl->pvFields;
pImpl->pvFields = newPVFields;
pImpl->numberFields = numberFields;
}
void PVStructure::removePVField(String fieldName)
{
PVField *pvField = getSubField(fieldName);
if(pvField==0) {
String message("removePVField ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return;
}
int origLength = pImpl->numberFields;
int newLength = origLength - 1;
PVFieldPtrArray origPVFields = pImpl->pvFields;
PVFieldPtrArray newPVFields = new PVFieldPtr[newLength];
int newIndex = 0;
int indRemove = -1;
for(int i=0; i<origLength; i++) {
if(origPVFields[i]==pvField) {
indRemove = i;
} else {
newPVFields[newIndex++] = origPVFields[i];
}
}
Structure *structure = const_cast<Structure *>(getStructure().get());
structure->removeField(indRemove);
delete origPVFields[indRemove];
delete[] pImpl->pvFields;
pImpl->pvFields = newPVFields;
pImpl->numberFields = newLength;
}
PVBoolean *PVStructure::getBooleanField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvBoolean) {
return (PVBoolean*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type boolean ";
this->message(message, errorMessage);
return 0;
}
PVByte *PVStructure::getByteField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvByte) {
return (PVByte*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type byte ";
this->message(message, errorMessage);
return 0;
}
PVShort *PVStructure::getShortField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvShort) {
return (PVShort*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type short ";
this->message(message, errorMessage);
return 0;
}
PVInt *PVStructure::getIntField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvInt) {
return (PVInt*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type int ";
this->message(message, errorMessage);
return 0;
}
PVLong *PVStructure::getLongField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvLong) {
return (PVLong*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type long ";
this->message(message, errorMessage);
return 0;
}
PVFloat *PVStructure::getFloatField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvFloat) {
return (PVFloat*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type float ";
this->message(message, errorMessage);
return 0;
}
PVDouble *PVStructure::getDoubleField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvDouble) {
return (PVDouble*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type double ";
this->message(message, errorMessage);
return 0;
}
PVString *PVStructure::getStringField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvString) {
return (PVString*)pvField;
}
}
String message("fieldName ");
message += fieldName + " does not have type string ";
this->message(message, errorMessage);
return 0;
}
PVStructure *PVStructure::getStructureField(String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==structure) {
return((PVStructure *)pvField);
}
String message("fieldName ");
message += fieldName + " does not have type structure ";
this->message(message, errorMessage);
return 0;
}
PVScalarArray *PVStructure::getScalarArrayField(
String fieldName,ScalarType elementType)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
FieldConstPtr field = pvField->getField();
Type type = field->getType();
if(type!=scalarArray) {
String message("fieldName ");
message += fieldName + " does not have type array ";
this->message(message, errorMessage);
return 0;
}
ScalarArrayConstPtr pscalarArray
= static_pointer_cast<const ScalarArray>(pvField->getField());
if(pscalarArray->getElementType()!=elementType) {
String message("fieldName ");
message += fieldName + " is array but does not have elementType ";
ScalarTypeFunc::toString(&message,elementType);
this->message(message, errorMessage);
return 0;
}
return (PVScalarArray*)pvField;
}
PVStructureArray *PVStructure::getStructureArrayField(
String fieldName)
{
PVField *pvField = findSubField(fieldName,this);
if(pvField==0) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return 0;
}
if(pvField->getField()->getType()==structureArray) {
return((PVStructureArray *)pvField);
}
String message("fieldName ");
message += fieldName + " does not have type structureArray ";
this->message(message, errorMessage);
return 0;
}
String PVStructure::getExtendsStructureName()
{
return pImpl->extendsStructureName;
}
bool PVStructure::putExtendsStructureName(
String extendsStructureName)
{
if(pImpl->extendsStructureName.length()!=0) return false;
pImpl->extendsStructureName = extendsStructureName;
return true;
}
void PVStructure::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const {
for(int i = 0; i<pImpl->numberFields; i++)
pImpl->pvFields[i]->serialize(pbuffer, pflusher);
}
void PVStructure::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
for(int i = 0; i<pImpl->numberFields; i++)
pImpl->pvFields[i]->deserialize(pbuffer, pcontrol);
}
void PVStructure::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, BitSet *pbitSet) const {
int offset = const_cast<PVStructure*>(this)->getFieldOffset();
int numberFields = const_cast<PVStructure*>(this)->getNumberFields();
int next = pbitSet->nextSetBit(offset);
// no more changes or no changes in this structure
if(next<0||next>=offset+numberFields) return;
// entire structure
if(offset==next) {
serialize(pbuffer, pflusher);
return;
}
for(int i = 0; i<pImpl->numberFields; i++) {
PVField* pvField = pImpl->pvFields[i];
offset = pvField->getFieldOffset();
numberFields = pvField->getNumberFields();
next = pbitSet->nextSetBit(offset);
// no more changes
if(next<0) return;
// no change in this pvField
if(next>=offset+numberFields) continue;
// serialize field or fields
if(numberFields==1)
pvField->serialize(pbuffer, pflusher);
else
((PVStructure*)pvField)->serialize(pbuffer, pflusher,
pbitSet);
}
}
void PVStructure::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol, BitSet *pbitSet) {
int offset = getFieldOffset();
int numberFields = getNumberFields();
int next = pbitSet->nextSetBit(offset);
// no more changes or no changes in this structure
if(next<0||next>=offset+numberFields) return;
// entire structure
if(offset==next) {
deserialize(pbuffer, pcontrol);
return;
}
for(int i = 0; i<pImpl->numberFields; i++) {
PVField* pvField = pImpl->pvFields[i];
offset = pvField->getFieldOffset();
numberFields = pvField->getNumberFields();
next = pbitSet->nextSetBit(offset);
// no more changes
if(next<0) return;
// no change in this pvField
if(next>=offset+numberFields) continue;
// deserialize field or fields
if(numberFields==1)
pvField->deserialize(pbuffer, pcontrol);
else
((PVStructure*)pvField)->deserialize(pbuffer, pcontrol,
pbitSet);
}
}
static PVField *findSubField(String fieldName,PVStructure *pvStructure) {
if( fieldName.length()<1) return 0;
String::size_type index = fieldName.find('.');
String name = fieldName;
String restOfName = String();
if(index>0) {
name = fieldName.substr(0, index);
if(fieldName.length()>index) {
restOfName = fieldName.substr(index+1);
}
}
PVFieldPtrArray pvFields = pvStructure->getPVFields();
PVField *pvField = 0;
int numFields = pvStructure->getStructure()->getNumberFields();
for(int i=0; i<numFields; i++) {
PVField *pvf = pvFields[i];
int result = pvf->getField()->getFieldName().compare(name);
if(result==0) {
pvField = pvf;
break;
}
}
if(pvField==0) return 0;
if(restOfName.length()==0) return pvField;
if(pvField->getField()->getType()!=structure) return 0;
return findSubField(restOfName,(PVStructure*)pvField);
}
}}

View File

@@ -1,501 +0,0 @@
/* StandardField.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 <string>
#include <cstdio>
#include <stdexcept>
#include <epicsThread.h>
#include <epicsExit.h>
#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");
// 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);
}
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);
}
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) {
bool gotAlarm = false;
bool gotTimeStamp = false;
bool gotDisplay = false;
bool gotControl = false;
bool gotValueAlarm = false;
int numProp = 0;
if(properties.find("alarm")!=String::npos) { gotAlarm = true; numProp++; }
if(properties.find("timeStamp")!=String::npos) { gotTimeStamp = true; numProp++; }
if(properties.find("display")!=String::npos) { gotDisplay = true; numProp++; }
if(properties.find("control")!=String::npos) { gotControl = true; numProp++; }
if(properties.find("valueAlarm")!=String::npos) { gotValueAlarm = true; numProp++; }
StructureConstPtr valueAlarm;
Type type= field->getType();
while(gotValueAlarm) {
if(type==scalar) {
ScalarConstPtr scalar = static_pointer_cast<const Scalar>(field);
ScalarType scalarType = scalar->getScalarType();
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 pvFloat: valueAlarm = floatAlarmField; break;
case pvDouble: valueAlarm = doubleAlarmField; break;
default:
throw std::logic_error(String("valueAlarm property for illegal type"));
}
break;
}
if(type==structure) {
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
if(structurePtr->getNumberFields()==2) {
FieldConstPtrArray fields = structurePtr->getFields();
FieldConstPtr first = fields[0];
FieldConstPtr second = fields[1];
String nameFirst = first->getFieldName();
String nameSecond = second->getFieldName();
int compareFirst = nameFirst.compare("index");
int compareSecond = nameSecond.compare("choices");
if(compareFirst==0 && compareSecond==0) {
if(first->getType()==scalar
&& second->getType()==scalarArray) {
ScalarConstPtr scalarFirst = static_pointer_cast<const Scalar>(first);
ScalarArrayConstPtr scalarArraySecond =
static_pointer_cast<const ScalarArray>(second);
if(scalarFirst->getScalarType()==pvInt
&& scalarArraySecond->getElementType()==pvString) {
valueAlarm = enumeratedAlarmField;
break;
}
}
}
}
}
throw std::logic_error(String("valueAlarm property for illegal type"));
}
int numFields = numProp+1;
FieldConstPtrArray fields = new FieldConstPtr[numFields];
int next = 0;
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);
}
ScalarConstPtr StandardField::scalar(String fieldName,ScalarType type)
{
return fieldCreate->createScalar(fieldName,type);
}
StructureConstPtr StandardField::scalar(
String fieldName,ScalarType type,String properties)
{
ScalarConstPtr field = fieldCreate->createScalar(valueFieldName,type);
return createProperties(fieldName,field,properties);
}
ScalarArrayConstPtr StandardField::scalarArray(
String fieldName,ScalarType elementType)
{
return fieldCreate->createScalarArray(fieldName,elementType);
}
StructureConstPtr StandardField::scalarArray(
String fieldName,ScalarType elementType, String properties)
{
ScalarArrayConstPtr field = fieldCreate->createScalarArray(
valueFieldName,elementType);
return createProperties(fieldName,field,properties);
}
StructureArrayConstPtr StandardField::structureArray(
String fieldName,StructureConstPtr structure)
{
return fieldCreate->createStructureArray(fieldName,structure);
}
StructureConstPtr StandardField::structureArray(
String fieldName,StructureConstPtr structure,String properties)
{
StructureArrayConstPtr field = fieldCreate->createStructureArray(
valueFieldName,structure);
return createProperties(fieldName,field,properties);
}
StructureConstPtr StandardField::structure(
String fieldName,int numFields,FieldConstPtrArray fields)
{
return fieldCreate->createStructure(fieldName,numFields,fields);
}
StructureConstPtr StandardField::enumerated(String fieldName)
{
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 StandardField::alarm()
{
return alarmField;
}
StructureConstPtr StandardField::timeStamp()
{
return timeStampField;
}
StructureConstPtr StandardField::display()
{
return displayField;
}
StructureConstPtr StandardField::control()
{
return controlField;
}
StructureConstPtr StandardField::booleanAlarm()
{
return booleanAlarmField;
}
StructureConstPtr StandardField::byteAlarm()
{
return byteAlarmField;
}
StructureConstPtr StandardField::shortAlarm()
{
return shortAlarmField;
}
StructureConstPtr StandardField::intAlarm()
{
return intAlarmField;
}
StructureConstPtr StandardField::longAlarm()
{
return longAlarmField;
}
StructureConstPtr StandardField::floatAlarm()
{
return floatAlarmField;
}
StructureConstPtr StandardField::doubleAlarm()
{
return doubleAlarmField;
}
StructureConstPtr StandardField::enumeratedAlarm()
{
return enumeratedAlarmField;
}
void StandardField::init()
{
createAlarm();
createTimeStamp();
createDisplay();
createControl();
createBooleanAlarm();
createByteAlarm();
createShortAlarm();
createIntAlarm();
createLongAlarm();
createFloatAlarm();
createDoubleAlarm();
createEnumeratedAlarm();
}
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;
}
}}

View File

@@ -1,353 +0,0 @@
/* StandardPVField.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 <string>
#include <stdexcept>
#include <epicsThread.h>
#include <epicsExit.h>
#include <pv/lock.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#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(){}
PVScalar * StandardPVField::scalar(PVStructure *parent,
String fieldName,ScalarType type)
{
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);
return pvStructure;
}
PVScalarArray * StandardPVField::scalarArray(PVStructure *parent,
String fieldName,ScalarType elementType)
{
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);
return pvStructure;
}
PVStructureArray * StandardPVField::structureArray(PVStructure *parent,
String fieldName,StructureConstPtr structure)
{
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);
return pvStructure;
}
PVStructure * StandardPVField::enumerated(PVStructure *parent,
String fieldName,StringArray choices,int number)
{
StructureConstPtr field = standardField->enumerated(fieldName);
PVStructure *pvStructure = pvDataCreate->createPVStructure(parent,field);
PVScalarArray *pvScalarArray = pvStructure->getScalarArrayField(
"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::enumerated(PVStructure *parent,
String fieldName,StringArray choices,int number, String 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) {
throw std::logic_error(String("StandardPVField::enumerated"));
}
PVStringArray *pvChoices = static_cast<PVStringArray *>(pvScalarArray);
pvChoices->put(0,number,choices,0);
return pvStructure;
}
PVScalar * StandardPVField::scalarValue(PVStructure *parent,
ScalarType scalarType)
{
ScalarConstPtr field = standardField->scalarValue(scalarType);
return pvDataCreate->createPVScalar(parent,field);
}
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"));
}
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;
}
}}

View File

@@ -1,73 +0,0 @@
/*TypeFunc.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/pvIntrospect.h>
#include <pv/epicsException.h>
#include "dbDefs.h" // for NELEMENTS
namespace epics { namespace pvData {
namespace TypeFunc {
static const char* names[] = {
"scalar", "scalarArray", "structure", "structureArray",
};
const char* name(Type t) {
if (t<int(pvBoolean) || t>int(pvString))
THROW_EXCEPTION2(std::invalid_argument, "logic error unknown Type");
return names[t];
}
void toString(StringBuilder buf,const Type type) {
*buf += name(type);
}
} // namespace TypeFunc
namespace ScalarTypeFunc {
bool isInteger(ScalarType type) {
if(type>=pvByte && type<=pvLong) return true;
return false;
}
bool isNumeric(ScalarType type) {
if(type>=pvByte && type<=pvDouble) return true;
return false;
}
bool isPrimitive(ScalarType type) {
if(type>=pvBoolean && type<=pvDouble) return true;
return false;
}
static const char* names[] = {
"boolean", "byte", "short", "int", "long",
"float", "double", "string",
};
ScalarType getScalarType(String pvalue) {
for(size_t i=0; i<NELEMENTS(names); i++)
if(pvalue==names[i])
return ScalarType(i);
THROW_EXCEPTION2(std::invalid_argument, "error unknown ScalarType");
}
const char* name(ScalarType t) {
if (t<pvBoolean || t>pvString)
THROW_EXCEPTION2(std::invalid_argument, "error unknown ScalarType");
return names[t];
}
void toString(StringBuilder buf,const ScalarType scalarType) {
*buf += name(scalarType);
}
} // namespace ScalarTypeFunc
}}

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,30 +0,0 @@
/* event.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 EVENT_H
#define EVENT_H
#include <memory>
#include <vector>
#include <epicsEvent.h>
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
namespace epics { namespace pvData {
class Event : private NoDefaultMethods {
public:
explicit Event(bool = false);
~Event();
void signal();
bool wait (); /* blocks until full */
bool wait ( double timeOut ); /* false if empty at time out */
bool tryWait (); /* false if empty */
private:
epicsEventId id;
};
}}
#endif /* EVENT_H */

View File

@@ -1,162 +0,0 @@
/* executor.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 <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;
static
Command *shutdown=&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()
{
ExecutorNode shutdownNode(shutdown);
execute(&shutdownNode);
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();
}
}
void ExecutorPvt::run()
{
Lock xx(mutex);
while(true) {
ExecutorListNode * executorListNode = 0;
while(runList.isEmpty()) {
xx.unlock();
moreWork.wait();
xx.lock();
}
executorListNode = runList.removeHead();
if(!executorListNode) continue;
Command *cmd=executorListNode->getObject().command;
if(cmd==shutdown) break;
xx.unlock();
try {
executorListNode->getObject().command->command();
}catch(std::exception& e){
//TODO: feed into logging mechanism
fprintf(stderr, "Executor: Unhandled exception: %s",e.what());
}catch(...){
fprintf(stderr, "Executor: Unhandled exception");
}
xx.lock();
}
stopped.signal();
}
ExecutorNode * ExecutorPvt::createNode(Command *command)
{
Lock xx(mutex);
ExecutorNode *executorNode = new ExecutorNode(command);
executorList.addTail(executorNode->node);
return executorNode;
}
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,37 +0,0 @@
/* executor.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 EXECUTOR_H
#define EXECUTOR_H
#include <memory>
#include <vector>
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
#include <pv/thread.h>
namespace epics { namespace pvData {
// This is created by Executor.createNode and passed to Executor.execute
class ExecutorNode;
class Command {
public:
virtual ~Command(){}
virtual void command() = 0;
};
class Executor : private NoDefaultMethods {
public:
Executor(String threadName,ThreadPriority priority);
~Executor();
ExecutorNode * createNode(Command *command);
void execute(ExecutorNode *node);
private:
class ExecutorPvt *pImpl;
};
}}
#endif /* EXECUTOR_H */

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

@@ -1,52 +0,0 @@
/* lock.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 LOCK_H
#define LOCK_H
#include <stdexcept>
#include <epicsMutex.h>
#include <pv/noDefaultMethods.h>
/* This is based on item 14 of
* Effective C++, Third Edition, Scott Meyers
*/
// TODO reference counting lock to allow recursions
namespace epics { namespace pvData {
typedef epicsMutex Mutex;
class Lock : private NoDefaultMethods {
public:
explicit Lock(Mutex &m)
: mutexPtr(m), locked(true)
{ mutexPtr.lock();}
~Lock(){unlock();}
void lock()
{
if(!locked)
{
mutexPtr.lock();
locked = true;
}
}
void unlock()
{
if(locked)
{
mutexPtr.unlock();
locked=false;
}
}
bool ownsLock() const{return locked;}
private:
Mutex &mutexPtr;
bool locked;
};
}}
#endif /* LOCK_H */

View File

@@ -1,136 +0,0 @@
/* messageQueue.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/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){}
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)
{
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);
}
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();
}
void MessageQueue::release() {
if(pImpl->lastGet==0) return;
pImpl->queue->releaseUsed(pImpl->lastGet);
pImpl->lastGet = 0;
}
bool MessageQueue::put(String message,MessageType messageType,bool replaceLast)
{
MessageElementPtr element = pImpl->queue->getFree();
if(element!=0) {
MessageNodePtr node = element->getObject();
node->message = message;
node->messageType = messageType;
pImpl->lastPut = node;
pImpl->queue->setUsed(element);
return true;
}
pImpl->overrun++;
if(replaceLast) {
MessageNodePtr node = pImpl->lastPut;
node->message = message;
node->messageType = messageType;
}
return false;
}
bool MessageQueue::isEmpty() const
{
int free = pImpl->queue->getNumberFree();
if(free==pImpl->size) return true;
return false;
}
bool MessageQueue::isFull() const
{
if(pImpl->queue->getNumberFree()==0) return true;
return false;
}
int MessageQueue::getClearOverrun()
{
int num = pImpl->overrun;
pImpl->overrun = 0;
return num;
}
}}

View File

@@ -1,48 +0,0 @@
/* messageQueue.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 MESSAGEQUEUE_H
#define MESSAGEQUEUE_H
#include <pv/pvType.h>
#include <pv/requester.h>
#include <pv/noDefaultMethods.h>
namespace epics { namespace pvData {
class MessageNode {
public:
String getMessage() const;
MessageType getMessageType() const;
void setMessageNull();
private:
MessageNode();
~MessageNode();
friend class MessageQueue;
String message;
MessageType messageType;
};
class MessageQueue : private NoDefaultMethods {
public:
MessageQueue(int size);
~MessageQueue();
MessageNode *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;
int getClearOverrun();
private:
class MessageQueuePvt *pImpl;
};
}}
#endif /* MESSAGEQUEUE_H */

View File

@@ -1,54 +0,0 @@
/* queue.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 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 {
public:
T *getObject() { return static_cast<T *>(QueueElementVoid::getObject());}
protected:
QueueElement(T *object) : QueueElementVoid(static_cast<void *>(object)){}
~QueueElement() {}
friend class Queue<T>;
};
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));}
};
}}
#endif /* QUEUE_H */

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 +0,0 @@
/* requester.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 <string>
#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")
};
StringArray messageTypeName = typeName;
}}

View File

@@ -1,33 +0,0 @@
/* requester.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 REQUESTER_H
#define REQUESTER_H
#include <string>
#include <pv/pvType.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class Requester;
enum MessageType {
infoMessage,warningMessage,errorMessage,fatalErrorMessage
};
extern StringArray messageTypeName;
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;
};
}}
#endif /* REQUESTER_H */

View File

@@ -1,61 +0,0 @@
/* serialize.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 SERIALIZE_H
#define SERIALIZE_H
#include <pv/byteBuffer.h>
namespace epics { namespace pvData {
class SerializableControl;
class DeserializableControl;
class Serializable;
class BitSetSerializable;
class SerializableArray;
class BitSet;
class SerializableControl {
public:
virtual ~SerializableControl(){}
virtual void flushSerializeBuffer() =0;
virtual void ensureBuffer(int size) =0;
virtual void alignBuffer(int alignment) =0;
};
class DeserializableControl {
public:
virtual ~DeserializableControl(){}
virtual void ensureData(int size) =0;
virtual void alignData(int alignment) =0;
};
class Serializable {
public:
virtual ~Serializable(){}
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher) const = 0;
virtual void deserialize(ByteBuffer *buffer,
DeserializableControl *flusher) = 0;
};
class BitSetSerializable {
public:
virtual ~BitSetSerializable(){}
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher,BitSet *bitSet) const = 0;
virtual void deserialize(ByteBuffer *buffer,
DeserializableControl *flusher,BitSet *bitSet) = 0;
};
class SerializableArray : virtual public Serializable {
public:
virtual ~SerializableArray(){}
virtual void serialize(ByteBuffer *buffer,
SerializableControl *flusher, int offset, int count) const = 0;
};
}}
#endif /* SERIALIZE_H */

View File

@@ -1,63 +0,0 @@
/* thread.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 THREAD_H
#define THREAD_H
#include <memory>
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
#include <epicsThread.h>
namespace epics { namespace pvData {
enum ThreadPriority {
lowestPriority =epicsThreadPriorityLow,
lowerPriority =epicsThreadPriorityLow + 15,
lowPriority =epicsThreadPriorityMedium - 15,
middlePriority =epicsThreadPriorityMedium,
highPriority =epicsThreadPriorityMedium + 15,
higherPriority =epicsThreadPriorityHigh - 15,
highestPriority =epicsThreadPriorityHigh
};
typedef epicsThreadRunable Runnable;
class Thread : public epicsThread, private NoDefaultMethods {
public:
Thread(String name,
ThreadPriority priority,
Runnable *runnable,
epicsThreadStackSizeClass stkcls=epicsThreadStackSmall)
:epicsThread(*runnable,
name.c_str(),
epicsThreadGetStackSize(stkcls),
priority)
{
this->start();
}
Thread(Runnable &runnable,
String name,
unsigned int stksize,
unsigned int priority=lowestPriority)
:epicsThread(runnable,
name.c_str(),
stksize,
priority)
{
this->start();
}
~Thread()
{
this->exitWait();
}
};
}}
#endif /* THREAD_H */

View File

@@ -1,31 +0,0 @@
/* timeFunction.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 TIMEFUNCTION_H
#define TIMEFUNCTION_H
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
namespace epics { namespace pvData {
class TimeFunctionRequester {
public:
virtual ~TimeFunctionRequester(){}
virtual void function() = 0;
};
class TimeFunction : private NoDefaultMethods {
public:
TimeFunction(TimeFunctionRequester *requester);
~TimeFunction();
double timeCall();
private:
TimeFunctionRequester *requester;
};
}}
#endif /* TIMEFUNCTION_H */

View File

@@ -1,234 +0,0 @@
/* timer.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 <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>
namespace epics { namespace pvData {
PVDATA_REFCOUNT_MONITOR_DEFINE(timerNode);
PVDATA_REFCOUNT_MONITOR_DEFINE(timer);
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),
waitForDone(false),
alive(true),
thread(threadName,priority,this)
{}
void Timer::Pvt::addElement(TimerNode::Pvt &node)
{
TimerListNode *nextNode = timerList.getHead();
if(nextNode==0) {
timerList.addTail(node.timerListNode);
return;
}
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);
return;
}
}
}
TimerNode::TimerNode(TimerCallback &callback)
: pImpl(new Pvt(*this,callback))
{
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(timerNode);
}
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()
{
TimeStamp currentTime;
while(true) {
currentTime.getCurrent();
TimeStamp *timeToRun = 0;
double period = 0.0;
TimerNode::Pvt *nodeToCall = 0;
{
Lock xx(mutex);
if (!alive) break;
TimerListNode *timerListNode = timerList.getHead();
if(timerListNode!=0) {
TimerNode::Pvt *timerNodePvt = &timerListNode->getObject();
timeToRun = &timerNodePvt->timeToRun;
double diff = TimeStamp::diff(
*timeToRun,currentTime);
if(diff<=0.0) {
nodeToCall = timerNodePvt;
timerList.removeHead();
period = timerNodePvt->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;
}
}
}
}
if(nodeToCall!=0) {
nodeToCall->callback->callback();
}
{
Lock xx(mutex);
if(!alive) break;
}
if(timeToRun==0) {
waitForWork.wait();
} else {
double delay = TimeStamp::diff(*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;
}
pImpl->waitForWork.signal();
pImpl->waitForDone.wait();
TimerListNode *node = 0;
while((node = pImpl->timerList.removeHead())!=0) {
node->getObject().callback->timerStopped();
}
PVDATA_REFCOUNT_MONITOR_DESTRUCT(timer);
}
void Timer::scheduleAfterDelay(TimerNode &timerNode,double delay)
{
schedulePeriodic(timerNode,delay,0.0);
}
void Timer::schedulePeriodic(TimerNode &timerNode,double delay,double period)
{
TimerNode::Pvt *timerNodePvt = timerNode.pImpl.get();
if(timerNodePvt->timerListNode.isOnList()) {
throw std::logic_error(String("already queued"));
}
{
Lock xx(pImpl->mutex);
if(!pImpl->alive) {
timerNodePvt->callback->timerStopped();
return;
}
}
TimeStamp *timeStamp = &timerNodePvt->timeToRun;
timeStamp->getCurrent();
*timeStamp += delay;
timerNodePvt->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;
}
if(isFirst) pImpl->waitForWork.signal();
}
}}

View File

@@ -1,59 +0,0 @@
/* timer.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 TIMER_H
#define TIMER_H
#include <memory>
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <pv/pvType.h>
#include <pv/thread.h>
#include <pv/noDefaultMethods.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class Timer;
class TimerCallback {
public:
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;
friend class Timer;
};
class Timer : private NoDefaultMethods {
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;
private:
std::auto_ptr<Pvt> pImpl;
};
}}
#endif /* TIMER_H */

View File

@@ -1,106 +0,0 @@
/* monitor.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 MONITOR_H
#define MONITOR_H
#include <pv/status.h>
#include <pv/destroyable.h>
#include <pv/pvData.h>
#include <pv/sharedPtr.h>
#include <pv/bitSet.h>
namespace epics { namespace pvData {
/**
* Class instance representing monitor element.
* @author mrk
*/
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;
};
/**
* Interface for Monitor.
* @author mrk
*/
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;
};
/**
* 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,
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;
};
}}
#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,108 +0,0 @@
/* alarm.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 <string>
#include <stdexcept>
#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)
{
if(value<0 || value>4) {
throw std::logic_error(String("getSeverity value is illegal"));
}
switch (value) {
case 0: return noAlarm;
case 1: return minorAlarm;
case 2: return majorAlarm;
case 3: return invalidAlarm;
case 4: return undefinedAlarm;
}
throw std::logic_error(String("should never get here"));
}
StringArray AlarmSeverityFunc::getSeverityNames()
{
return severityNames;
}
AlarmSeverity Alarm::getSeverity() const
{
switch(severity) {
case 0: return noAlarm;
case 1: return minorAlarm;
case 2: return majorAlarm;
case 3: return invalidAlarm;
case 4: return undefinedAlarm;
}
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) {
throw std::logic_error(String("getStatus value is illegal"));
}
switch (value) {
case 0: return noStatus;
case 1: return deviceStatus;
case 2: return driverStatus;
case 3: return recordStatus;
case 4: return dbStatus;
case 5: return confStatus;
case 6: return undefinedStatus;
case 7: return clientStatus;
}
throw std::logic_error(String("should never get here"));
}
StringArray AlarmStatusFunc::getStatusNames()
{
return statusNames;
}
AlarmStatus Alarm::getStatus() const
{
switch(status) {
case 0: return noStatus;
case 1: return deviceStatus;
case 2: return driverStatus;
case 3: return recordStatus;
case 4: return dbStatus;
case 5: return confStatus;
case 6: return undefinedStatus;
case 7: return clientStatus;
}
throw std::logic_error(String("should never get here"));
}
}}

View File

@@ -1,54 +0,0 @@
/* alarm.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.
*/
#include <string>
#include <pv/pvType.h>
#ifndef ALARM_H
#define ALARM_H
namespace epics { namespace pvData {
enum AlarmSeverity {
noAlarm,minorAlarm,majorAlarm,invalidAlarm,undefinedAlarm
};
enum AlarmStatus {
noStatus,deviceStatus,driverStatus,recordStatus,
dbStatus,confStatus,undefinedStatus,clientStatus
};
extern const size_t severityCount;
class AlarmSeverityFunc {
public:
static AlarmSeverity getSeverity(int value);
static StringArray getSeverityNames();
};
extern const size_t statusCount;
class AlarmStatusFunc {
public:
static AlarmStatus getStatus(int value);
static StringArray getStatusNames();
};
class Alarm {
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;}
AlarmSeverity getSeverity() const;
void setSeverity(AlarmSeverity value) {severity = value;}
AlarmStatus getStatus() const;
void setStatus(AlarmStatus value) { status = value;}
private:
int32 severity;
int32 status;
String message;
};
}}
#endif /* ALARM_H */

View File

@@ -1,25 +0,0 @@
/* control.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 CONTROL_H
#define CONTROL_H
namespace epics { namespace pvData {
class Control {
public:
Control() : low(0.0), high(0.0) {}
//default constructors and destructor are OK
double getLow() const {return low;}
double getHigh() const {return high;}
void setLow(double value) {low = value;}
void setHigh(double value) {high = value;}
private:
double low;
double high;
};
}}
#endif /* CONTROL_H */

View File

@@ -1,39 +0,0 @@
/* display.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.
*/
#include <string>
#include <pv/pvType.h>
#include <pv/pvData.h>
#ifndef DISPLAY_H
#define DISPLAY_H
namespace epics { namespace pvData {
class Display {
public:
Display()
: description(String("")),format(String("")),units(String("")),
low(0.0),high(0.0) {}
//default constructors and destructor are OK
double getLow() const {return low;}
double getHigh() const{ return high;}
void setLow(double value){low = value;}
void setHigh(double value){high = value;}
String getDescription() const {return description;}
void setDescription(String value) {description = value;}
String getFormat() const {return format;}
void setFormat(String value) {format = value;}
String getUnits() const {return units;}
void setUnits(String value) {units = value;}
private:
String description;
String format;
String units;
double low;
double high;
};
}}
#endif /* DISPLAY_H */

View File

@@ -1,99 +0,0 @@
/* pvAlarm.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 <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvAlarm.h>
namespace epics { namespace pvData {
static String noAlarmFound("No alarm structure found");
static String notAttached("Not attached to an alarm structure");
bool PVAlarm::attach(PVField *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) {
pvField->message(noAlarmFound,errorMessage);
return false;
}
pvSeverity = pvInt;
pvInt = pvStructure->getIntField(String("status"));
if(pvInt==0) {
pvField->message(noAlarmFound,errorMessage);
return false;
}
pvStatus = pvInt;
PVString *pvString = pvStructure->getStringField(String("message"));
if(pvInt==0) {
pvField->message(noAlarmFound,errorMessage);
return false;
}
pvMessage = pvString;
return true;
}
void PVAlarm::detach()
{
pvSeverity = 0;
pvStatus = 0;
pvMessage = 0;
}
bool PVAlarm::isAttached()
{
if(pvSeverity==0 || pvMessage==0) return false;
return true;
}
void PVAlarm::get(Alarm & alarm) const
{
if(pvSeverity==0 || pvMessage==0) {
throw std::logic_error(notAttached);
}
alarm.setSeverity(AlarmSeverityFunc::getSeverity(pvSeverity->get()));
alarm.setStatus(AlarmStatusFunc::getStatus(pvStatus->get()));
alarm.setMessage(pvMessage->get());
}
bool PVAlarm::set(Alarm const & alarm)
{
if(pvSeverity==0 || pvMessage==0) {
throw std::logic_error(notAttached);
}
if(pvSeverity->isImmutable() || pvMessage->isImmutable()) return false;
pvSeverity->put(alarm.getSeverity());
pvStatus->put(alarm.getStatus());
pvMessage->put(alarm.getMessage());
return true;
}
}}

View File

@@ -1,36 +0,0 @@
/* pvAlarm.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 PVALARM_H
#define PVALARM_H
#include <string>
#include <pv/pvType.h>
#include <pv/alarm.h>
#include <pv/pvData.h>
namespace epics { namespace pvData {
class PVAlarm {
public:
PVAlarm() : pvSeverity(0),pvStatus(0),pvMessage(0) {}
//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);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
// set returns false if field is immutable
void get(Alarm & alarm) const;
bool set(Alarm const & alarm);
private:
PVInt *pvSeverity;
PVInt *pvStatus;
PVString *pvMessage;
};
}}
#endif /* PVALARM_H */

View File

@@ -1,90 +0,0 @@
/* pvControl.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 <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvControl.h>
namespace epics { namespace pvData {
static String noControlFound("No control structure found");
static String notAttached("Not attached to an control structure");
bool PVControl::attach(PVField *pvField)
{
PVStructure *pvStructure = 0;
if(pvField->getField()->getFieldName().compare("control")!=0) {
if(pvField->getField()->getFieldName().compare("value")!=0) {
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) {
pvField->message(noControlFound,errorMessage);
return false;
}
pvLow = pvDouble;
pvDouble = pvStructure->getDoubleField(String("limit.high"));
if(pvDouble==0) {
pvLow = 0;
pvField->message(noControlFound,errorMessage);
return false;
}
pvHigh = pvDouble;
return true;
}
void PVControl::detach()
{
pvLow = 0;
pvHigh = 0;
}
bool PVControl::isAttached(){
if(pvLow==0 || pvHigh==0) return false;
return true;
}
void PVControl::get(Control &control) const
{
if(pvLow==0 || pvHigh==0) {
throw std::logic_error(notAttached);
}
control.setLow(pvLow->get());
control.setHigh(pvHigh->get());
}
bool PVControl::set(Control const & control)
{
if(pvLow==0 || pvHigh==0) {
throw std::logic_error(notAttached);
}
if(pvLow->isImmutable() || pvHigh->isImmutable()) return false;
pvLow->put(control.getLow());
pvHigh->put(control.getHigh());
return true;
}
}}

View File

@@ -1,32 +0,0 @@
/* pvControl.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.
*/
#include <pv/control.h>
#include <pv/pvData.h>
#ifndef PVCONTROL_H
#define PVCONTROL_H
namespace epics { namespace pvData {
class PVControl {
public:
PVControl() : pvLow(0),pvHigh(0) {}
//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);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
// set returns false if field is immutable
void get(Control &) const;
bool set(Control const & control);
private:
PVDouble *pvLow;
PVDouble *pvHigh;
};
}}
#endif /* PVCONTROL_H */

View File

@@ -1,119 +0,0 @@
/* pvDisplay.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 <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvDisplay.h>
namespace epics { namespace pvData {
static String noDisplayFound("No display structure found");
static String notAttached("Not attached to an display structure");
bool PVDisplay::attach(PVField *pvField)
{
PVStructure *pvStructure = 0;
if(pvField->getField()->getFieldName().compare("display")!=0) {
if(pvField->getField()->getFieldName().compare("value")!=0) {
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) {
pvField->message(noDisplayFound,errorMessage);
return false;
}
pvFormat = pvStructure->getStringField(String("format"));
if(pvFormat==0) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}
pvUnits = pvStructure->getStringField(String("units"));
if(pvUnits==0) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}
pvLow = pvStructure->getDoubleField(String("limit.low"));
if(pvLow==0) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}
pvHigh = pvStructure->getDoubleField(String("limit.high"));
if(pvHigh==0) {
pvField->message(noDisplayFound,errorMessage);
detach();
return false;
}
return true;
}
void PVDisplay::detach()
{
pvDescription = 0;
pvFormat = 0;
pvUnits = 0;
pvLow = 0;
pvHigh = 0;
}
bool PVDisplay::isAttached() {
if(pvDescription==0 || pvFormat==0 || pvUnits==0 || pvLow==0 || pvHigh==0)
return false;
return true;
}
void PVDisplay::get(Display & display) const
{
if(pvDescription==0 || pvFormat==0 || pvUnits==0 || pvLow==0 || pvHigh==0) {
throw std::logic_error(notAttached);
}
display.setDescription(pvDescription->get());
display.setFormat(pvFormat->get());
display.setUnits(pvUnits->get());
display.setLow(pvLow->get());
display.setHigh(pvHigh->get());
}
bool PVDisplay::set(Display const & display)
{
if(pvDescription==0 || pvFormat==0 || pvUnits==0 || pvLow==0 || pvHigh==0) {
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());
pvLow->put(display.getLow());
pvHigh->put(display.getHigh());
return true;
}
}}

View File

@@ -1,37 +0,0 @@
/* pvDisplay.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.
*/
#include <string>
#include <pv/pvType.h>
#include <pv/pvData.h>
#include <pv/display.h>
#ifndef PVDISPLAY_H
#define PVDISPLAY_H
namespace epics { namespace pvData {
class PVDisplay {
public:
PVDisplay()
: pvDescription(0),pvFormat(),pvUnits(),pvLow(),pvHigh() {}
//default constructors and destructor are OK
//An automatic detach is issued if already attached.
bool attach(PVField *pvField);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
// a set returns false if field is immutable
void get(Display &) const;
bool set(Display const & display);
private:
PVString *pvDescription;
PVString *pvFormat;
PVString *pvUnits;
PVDouble *pvLow;
PVDouble *pvHigh;
};
}}
#endif /* PVDISPLAY_H */

View File

@@ -1,120 +0,0 @@
/* pvEnumerated.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 <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvEnumerated.h>
namespace epics { namespace pvData {
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");
bool PVEnumerated::attach(PVField *pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(notStructure,errorMessage);
return false;
}
PVStructure *pvStructure = static_cast<PVStructure*>(pvField);
PVInt *pvInt = pvStructure->getIntField(String("index"));
if(pvInt==0) {
pvField->message(notEnumerated,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);
return true;
}
void PVEnumerated::detach()
{
pvIndex = 0;
pvChoices = 0;
}
bool PVEnumerated::isAttached() {
if(pvIndex==0 || pvChoices==0) return false;
return true;
}
bool PVEnumerated::setIndex(int32 index)
{
if(pvIndex==0 || pvChoices==0) {
throw std::logic_error(notAttached);
}
if(pvIndex->isImmutable()) return false;
pvIndex->put(index);
return true;
}
int32 PVEnumerated::getIndex()
{
if(pvIndex==0 || pvChoices==0) {
throw std::logic_error(notAttached);
}
return pvIndex->get();
}
String PVEnumerated::getChoice()
{
if(pvIndex==0 || pvChoices==0) {
throw std::logic_error(notAttached);
}
int index = pvIndex->get();
StringArrayData data;
pvChoices->get(0,pvChoices->getLength(),&data);
return data.data[index];
}
bool PVEnumerated::choicesMutable()
{
if(pvIndex==0 || pvChoices==0) {
throw std::logic_error(notAttached);
}
return pvChoices->isImmutable();
}
StringArray PVEnumerated:: getChoices()
{
if(pvIndex==0 || pvChoices==0) {
throw std::logic_error(notAttached);
}
StringArrayData data;
pvChoices->get(0,pvChoices->getLength(),&data);
return data.data;
}
int32 PVEnumerated::getNumberChoices()
{
if(pvIndex==0 || pvChoices==0) {
throw std::logic_error(notAttached);
}
return pvChoices->getLength();
}
bool PVEnumerated:: setChoices(StringArray choices,int32 numberChoices)
{
if(pvIndex==0 || pvChoices==0) {
throw std::logic_error(notAttached);
}
if(pvChoices->isImmutable()) return false;
pvChoices->put(0,numberChoices,choices,0);
return true;
}
}}

View File

@@ -1,39 +0,0 @@
/* pvEnumerated.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.
*/
#include <string>
#include <pv/pvType.h>
#include <pv/pvData.h>
#ifndef PVENUMERATED_H
#define PVENUMERATED_H
namespace epics { namespace pvData {
class PVEnumerated {
public:
PVEnumerated() : pvIndex(0), pvChoices(0) {}
//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);
void detach();
bool isAttached();
// each of the following throws logic_error is not attached to PVField
// a set returns false if field is immutable
bool setIndex(int32 index);
int32 getIndex();
String getChoice();
bool choicesMutable();
StringArray getChoices();
int32 getNumberChoices();
bool setChoices(StringArray choices,int32 numberChoices);
private:
PVInt *pvIndex;
PVStringArray *pvChoices;
};
}}
#endif /* PVENUMERATED_H */

View File

@@ -1,105 +0,0 @@
/* pvTimeStamp.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 <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/timeStamp.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
namespace epics { namespace pvData {
static String noTimeStamp("No timeStamp structure found");
static String notAttached("Not attached to a timeStamp structure");
bool PVTimeStamp::attach(PVField *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) {
pvField->message(noTimeStamp,errorMessage);
return false;
}
// 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);
}
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;
}
void PVTimeStamp::detach()
{
pvSecs = 0;
pvUserTag = 0;
pvNano = 0;
}
bool PVTimeStamp::isAttached() {
if(pvSecs==0 || pvNano==0) return false;
return true;
}
void PVTimeStamp::get(TimeStamp & timeStamp) const
{
if(pvSecs==0 || pvNano==0) {
throw std::logic_error(notAttached);
}
timeStamp.put(pvSecs->get(),pvNano->get());
timeStamp.setUserTag(pvUserTag->get());
}
bool PVTimeStamp::set(TimeStamp const & timeStamp)
{
if(pvSecs==0 || pvNano==0 || pvUserTag==0) {
throw std::logic_error(notAttached);
}
if(pvSecs->isImmutable() || pvNano->isImmutable()) return false;
pvSecs->put(timeStamp.getSecondsPastEpoch());
pvUserTag->put(timeStamp.getUserTag());
pvNano->put(timeStamp.getNanoSeconds());
return true;
}
}}

View File

@@ -1,37 +0,0 @@
/* pvTimeStamp.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.
*/
#include <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/timeStamp.h>
#include <pv/pvData.h>
#ifndef PVTIMESTAMP_H
#define PVTIMESTAMP_H
namespace epics { namespace pvData {
class PVTimeStamp {
public:
PVTimeStamp() : pvSecs(0),pvUserTag(0), pvNano(0) {}
//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);
void detach();
bool isAttached();
// following throw logic_error is not attached to PVField
// a set returns false if field is immutable
void get(TimeStamp &) const;
bool set(TimeStamp const & timeStamp);
private:
PVLong* pvSecs;
PVInt* pvUserTag;
PVInt* pvNano;
};
}}
#endif /* PVTIMESTAMP_H */

View File

@@ -1,66 +0,0 @@
/* timeStamp.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 TIMESTAMP_H
#define TIMESTAMP_H
#include <ctime>
#include "epicsTime.h"
#include <pv/pvType.h>
namespace epics { namespace pvData {
extern int32 milliSecPerSec;
extern int32 microSecPerSec;
extern int32 nanoSecPerSec;
extern int64 posixEpochAtEpicsEpoch;
class TimeStamp {
public:
TimeStamp()
:secondsPastEpoch(0), nanoSeconds(0), userTag(0) {}
TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0,int32 userTag = 0);
//default constructors and destructor are OK
//This class should not be extended
void normalize();
void fromTime_t(const time_t &);
void toTime_t(time_t &) const;
int64 getSecondsPastEpoch() const {return secondsPastEpoch;}
int64 getEpicsSecondsPastEpoch() const {
return secondsPastEpoch - posixEpochAtEpicsEpoch;
}
int32 getNanoSeconds() const {return nanoSeconds;}
int32 getUserTag() const {return userTag;}
void setUserTag(int userTag) {this->userTag = userTag;}
void put(int64 secondsPastEpoch,int32 nanoSeconds = 0) {
this->secondsPastEpoch = secondsPastEpoch;
this->nanoSeconds = nanoSeconds;
normalize();
}
void put(int64 milliseconds);
void getCurrent();
double toSeconds() const ;
bool operator==(TimeStamp const &) const;
bool operator!=(TimeStamp const &) const;
bool operator<=(TimeStamp const &) const;
bool operator< (TimeStamp const &) const;
bool operator>=(TimeStamp const &) const;
bool operator> (TimeStamp const &) const;
static double diff(TimeStamp const & a,TimeStamp const & b);
TimeStamp & operator+=(int64 seconds);
TimeStamp & operator-=(int64 seconds);
TimeStamp & operator+=(double seconds);
TimeStamp & operator-=(double seconds);
int64 getMilliseconds(); // milliseconds since epoch
private:
static int64 diffInt(TimeStamp const &left,TimeStamp const &right );
int64 secondsPastEpoch;
int32 nanoSeconds;
int32 userTag;
};
}}
#endif /* TIMESTAMP_H */

View File

@@ -1,492 +0,0 @@
/* convert.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.
* Author - Marty Kraimer
*/
#ifndef CONVERT_H
#define CONVERT_H
#include <string>
#include <stdexcept>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <vector>
namespace epics { namespace pvData {
bool operator==(PVField&, PVField&);
static inline bool operator!=(PVField& a, PVField& b)
{return !(a==b);}
bool operator==(const Field&, const Field&);
bool operator==(const Scalar&, const Scalar&);
bool operator==(const ScalarArray&, const ScalarArray&);
bool operator==(const Structure&, const Structure&);
bool operator==(const StructureArray&, const StructureArray&);
static inline bool operator!=(const Field& a, const Field& b)
{return !(a==b);}
static inline bool operator!=(const Scalar& a, const Scalar& b)
{return !(a==b);}
static inline bool operator!=(const ScalarArray& a, const ScalarArray& b)
{return !(a==b);}
static inline bool operator!=(const Structure& a, const Structure& b)
{return !(a==b);}
static inline bool operator!=(const StructureArray& a, const StructureArray& b)
{return !(a==b);}
/**
* Convert between numeric types, convert any field to a string,
* or convert from a string to a scalar field.
* <p>Numeric conversions are between scalar numeric types or between arrays of
* 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>
*
* <p>getString converts any supported type to a String.
* Code that implements a PVField interface can implement
* method toString by calling this method.</p>
*
* <p>fromString converts a String to a scalar.
* fromStringArray converts an array of String
* 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 {
public:
Convert();
~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);
/**
* 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(PVField &a,PVField &b);
/**
* 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 * 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);
/**
* Convert from an array of String to a PVScalar
* @param pv The PV.
* @param from The array of String value to convert and put into a PV.
* @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);
/**
* 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);
/**
* Convert from a String to a PVScalarArray.
* The String must be a comma separated set of values optionally enclosed in []
* @param pv The PV.
* @param from The String value to convert and put into a PV.
* @return The number of elements converted.
* @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);
/**
* Convert a PVScalarArray from a String array.
* The array element type must be a scalar.
* @param pv The PV.
* @param offset Starting element in a PV.
* @param length The number of elements to transfer.
* @param from The array of values to put into the PV.
* @param fromOffset Starting element in the source array.
* @return The number of elements converted.
* @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);
/**
* Convert a PVScalarArray to a String array.
* @param pv The PV.
* @param offset Starting element in the PV array.
* @param length Number of elements to convert to the string array.
* @param to String array to receive the converted PV data.
* @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);
/**
* Are from and to valid arguments to copy.
* This first checks of both arguments have the same Type.
* Then calls one of isCopyScalarCompatible,
* isCopyArrayCompatible, or isCopyStructureCompatible.
* @param from The source.
* @param to The destination.
* @return (false,true) is the arguments (are not, are) compatible.
*/
bool isCopyCompatible(FieldConstPtr from, FieldConstPtr to);
/**
* Copy from a PVField to another PVField.
* This calls one on copyScalar, copyArray, copyStructure.
* The two arguments must be compatible.
* @param from The source.
* @param to The destination
* @throws std::invalid_argument if the arguments are not compatible.
*/
void copy(PVField *from,PVField *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().
* If both are scalars the return value is true if any of the following are true.
* <ul>
* <li>Both arguments are numeric.</li>
* <li>Both arguments have the same type.</li>
* <li>Either argument is a string.</li>
* </ul>
* @param from The introspection interface for the from data.
* @param to The introspection interface for the to data..
* @return (false,true) If the arguments (are not, are) compatible.
*/
bool isCopyScalarCompatible(
ScalarConstPtr from, ScalarConstPtr 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);
/**
* Are from and to valid arguments to copyArray.
* The results are like isCopyScalarCompatible except that the tests are made on the elementType.
* @param from The from array.
* @param to The to array.
* @return (false,true) If the arguments (are not, are) compatible.
*/
bool isCopyScalarArrayCompatible(ScalarArrayConstPtr from,
ScalarArrayConstPtr to);
/**
* Convert from a source PV array to a destination PV array.
* @param from The source array.
* @param offset Starting element in the source.
* @param to The destination array.
* @param toOffset Starting element in the array.
* @param length Number of elements to transfer.
* @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);
/**
* Are from and to valid arguments for copyStructure.
* They are only compatible if they have the same Structure description.
* @param from from structure.
* @param to structure.
* @return (false,true) If the arguments (are not, are) compatible.
*/
bool isCopyStructureCompatible(
StructureConstPtr from, StructureConstPtr to);
/**
* Copy from a structure pv to another structure pv.
* NOTE: Only compatible nodes are copied. This means:
* <ul>
* <li>For scalar nodes this means that isCopyScalarCompatible is true.</li>
* <li>For array nodes this means that isCopyArrayCompatible is true.</li>
* <li>For structure nodes this means that isCopyStructureCompatible is true.</li>
* <li>Link nodes are not copied.</li>
* </ul>
* @param from The source.
* @param to The destination.
* @throws std::invalid_argument if the arguments are not compatible.
*/
void copyStructure(PVStructure *from, PVStructure *to);
/**
* Are from and to valid for copyStructureArray.
* @param from The from StructureArray.
* @param to The to StructureArray.
* @return (false,true) If the arguments (are not, are) compatible.
*/
bool isCopyStructureArrayCompatible(
StructureArrayConstPtr from, StructureArrayConstPtr 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);
/**
* Convert a PV to a <byte>.
* @param pv a PV
* @return converted value
*/
int8 toByte(PVScalar *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);
/**
* 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
*/
int32 toInt(PVScalar *pv);
/**
* Convert a PV to an int
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
int64 toLong(PVScalar *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);
/**
* 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);
/**
* Convert a PV to a String
* @param pv a PV
* @return converted value
*/
String toString(PVScalar *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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* Convert a PV array to a byte 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
*/
int toByteArray(PVScalarArray *pv, int offset, int length,
ByteArray to, int toOffset);
/**
* Convert a PV array to a short 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
*/
int toShortArray(PVScalarArray *pv, int offset, int length,
ShortArray to, int toOffset);
/**
* Convert a PV array to an int 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
*/
int toIntArray(PVScalarArray *pv, int offset, int length,
IntArray to, int toOffset);
/**
* Convert a PV array to a long 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
*/
int toLongArray(PVScalarArray *pv, int offset, int length,
LongArray to, int toOffset);
/**
* Convert a PV array to a float 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
*/
int toFloatArray(PVScalarArray *pv, int offset, int length,
FloatArray to, int toOffset);
/**
* Convert a PV array to a double 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
*/
int toDoubleArray(PVScalarArray *pv, int offset, int length,
DoubleArray to, int toOffset);
/**
* Convert a PV array from a byte 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
*/
int fromByteArray(PVScalarArray *pv, int offset, int length,
ByteArray from, int fromOffset);
/**
* Convert a PV array from a short 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
*/
int fromShortArray(PVScalarArray *pv, int offset, int length,
ShortArray from, int fromOffset);
/**
* Convert a PV array from an int 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
*/
int fromIntArray(PVScalarArray *pv, int offset, int length,
IntArray from, int fromOffset);
/**
* Convert a PV array from a long 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
*/
int fromLongArray(PVScalarArray *pv, int offset, int length,
LongArray from, int fromOffset);
/**
* Convert a PV array from a float 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
*/
int fromFloatArray(PVScalarArray *pv, int offset, int length,
FloatArray from, int fromOffset);
/**
* Convert a PV array from a double 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
*/
int fromDoubleArray(PVScalarArray *pv, int offset, int length,
DoubleArray from, int fromOffset);
/**
* Convenience method for implementing toString.
* It generates a newline and inserts blanks at the beginning of the newline.
* @param builder The StringBuilder being constructed.
* @param indentLevel Indent level, Each level is four spaces.
*/
void newLine(StringBuilder buf, int indentLevel);
};
extern Convert * getConvert();
}}
#endif /* CONVERT_H */

View File

@@ -1,855 +0,0 @@
/* pvData.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.
* Author - Marty Kraimer
*/
#ifndef PVDATA_H
#define PVDATA_H
#include <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/pvIntrospect.h>
#include <pv/noDefaultMethods.h>
#include <pv/requester.h>
#include <pv/byteBuffer.h>
#include <pv/serialize.h>
namespace epics { namespace pvData {
class PVAuxInfo;
class PostHandler;
class PVField;
class PVScalar;
class PVScalarArray;
class PVStructure;
class PVStructureArray;
/**
* typedef for a pointer to a PVStructure.
*/
typedef PVStructure * PVStructurePtr;
/**
* typedef for a pointer to a array of pointer to PVStructure.
*/
typedef PVStructurePtr* PVStructurePtrArray;
/**
* typedef for a pointer to a PVField.
*/
typedef PVField* PVFieldPtr;
/**
* typedef for a pointer to a array of pointer to PVField.
*/
typedef PVFieldPtr * PVFieldPtrArray;
/**
* This class provides auxillary information about a PVField.
* Each item is stored as a PVScalar.
* A (key,value) is provided for accessing the items where the key is a String.
*/
class PVAuxInfo : private NoDefaultMethods {
public:
/**
* Constructor
* @param The fields to which the Auxinfo is attached.
*/
PVAuxInfo(PVField *pvField);
/**
* Destructor
*/
~PVAuxInfo();
/**
* Get the PVField to which the Auxinfo is attached.
* @return The fields to which the Auxinfo is attached.
*/
PVField * getPVField();
/**
* Add a new auxiliary item or retrieve the interface to an existing item.
*
* @param key The key.
* @param scalarType The scalrType for the new item being added/
* @return The new PVScalar that has been added to the Auxinfo.
*/
PVScalar * createInfo(String key,ScalarType scalarType);
/**
* Get the number of PVScalars in the Auxinfo.
* @return The number.
*/
int getNumberInfo();
/**
* Get the Auxinfo with the specified key.
* @return The PVScalar or null if it does not exist.
*/
PVScalar * getInfo(String key);
/**
* Get the Auxinfo with the specified index.
* @return The PVScalar or null if it does not exist.
*/
PVScalar * getInfo(int index);
/**
* Convert the Auxinfo to a string and add it to builder.
* @param builder The string builder.
*/
void toString(StringBuilder buf);
/**
* Convert the Auxinfo to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
void toString(StringBuilder buf,int indentLevel);
private:
PVField *pvField;
int lengthInfo;
int numberInfo;
PVScalar **pvInfos; // ptr to array of PVscalar *
friend class PVDataCreate;
};
/**
* This class is implemented by code that calls setPostHander
*/
class PostHandler {
public:
/**
* Destructor
*/
virtual ~PostHandler(){}
/**
* This is called evertime postPut is called for this field.
*/
virtual void postPut() = 0;
};
/**
* PVField is the base class for each PVData field.
* Each PVData field has an interface that extends PVField.
*/
class PVField
: virtual public Serializable,
private NoDefaultMethods
{
public:
POINTER_DEFINITIONS(PVField);
/**
* Destructor
*/
virtual ~PVField();
/**
* Called to report errors associated with the field.
* @param message The message.
* @param messageType The message type.
*/
virtual void message(String message,MessageType messageType) ;
/**
* Register the message requester.
* At most one requester can be registered.
* @param prequester The requester.
*/
virtual void setRequester(Requester *prequester);
/**
* Get offset of the PVField field within top level structure.
* Every field within the PVStructure has a unique offset.
* The top level structure has an offset of 0.
* The first field within the structure has offset equal to 1.
* The other offsets are determined by recursively traversing each structure of the tree.
* @return The offset.
*/
int getFieldOffset() ;
/**
* Get the next offset. If the field is a scalar or array field then this is just offset + 1.
* If the field is a structure it is the offset of the next field after this structure.
* Thus (nextOffset - offset) is always equal to the number of fields within the field.
* @return The offset.
*/
int getNextFieldOffset() ;
/**
* Get the total number of fields in this field.
* This is equal to nextFieldOffset - fieldOffset.
*/
int getNumberFields() ;
/**
* Get the PVAuxInfo interface for the PVField.
* @return The PVAuxInfo interface.
*/
PVAuxInfo * getPVAuxInfo();
/**
* Is the field immutable, i.e. does it not allow changes.
* @return (false,true) if it (is not, is) immutable.
*/
bool isImmutable() ;
/**
* Set the field to be immutable, i. e. it can no longer be modified.
* This is permanent, i.e. once done the field can onot be made mutable.
*/
virtual void setImmutable();
/**
* Get the <i>Field</i> that describes the field.
* @return Field, which is the reflection interface.
*/
FieldConstPtr getField() ;
/**
* Get the parent of this field.
* @return The parent interface or null if this is PVRecord
*/
PVStructure * getParent() ;
/**
* Rename the field name.
* @param newName The new name.
*/
bool renameField(String newName);
/**
* postPut. Called when the field is updated by the implementation.
*/
void postPut() ;
/**
* Set the handler for postPut.
* At most one handler can be set.
* @param postHandler The handler.
*/
void setPostHandler(PostHandler *postHandler);
/**
* Is this field equal to another field.
* @param pv other field
* @return (false,true) if (is not,is) equal.
*/
virtual bool equals(PVField &pv);
/**
* Convert the PVField to a string.
* @param buf buffer for the result
*/
virtual void toString(StringBuilder buf) ;
/**
* Convert the PVField to a string.
* Each line is indented.
* @param buf buffer for the result
* @param indentLevel The indentation level.
*/
virtual void toString(StringBuilder buf,int indentLevel) ;
protected:
PVField(PVStructure *parent,FieldConstPtr field);
void setParent(PVStructure * parent);
private:
void message(String fieldName,String message,MessageType messageType);
class PVFieldPvt *pImpl;
static void computeOffset(PVField *pvField);
static void computeOffset(PVField *pvField,int offset);
friend class PVDataCreate;
friend class PVStructure;
};
/**
* PVScalar is the base class for each scalar field.
*/
class PVScalar : public PVField {
public:
POINTER_DEFINITIONS(PVScalar);
/**
* Destructor
*/
virtual ~PVScalar();
/**
* Get the Scalar introspection interface for the PVScalar.
* @return the interface.
*/
ScalarConstPtr getScalar() ;
protected:
PVScalar(PVStructure *parent,ScalarConstPtr scalar);
};
/**
* Class that holds the data for each posssible scalar type.
*/
template<typename T>
class PVScalarValue : public PVScalar {
public:
POINTER_DEFINITIONS(PVScalarValue);
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
/**
* Destructor
*/
virtual ~PVScalarValue() {}
/**
* Get the value.
* @return The value.
*/
virtual T get() = 0;
/**
* Put a new value into the PVScalar.
* @param The value.
*/
virtual void put(T value) = 0;
protected:
PVScalarValue(PVStructure *parent,ScalarConstPtr scalar)
: PVScalar(parent,scalar) {}
private:
};
/**
* typedefs for the various possible scalar types.
*/
typedef PVScalarValue<bool> PVBoolean;
typedef PVScalarValue<int8> PVByte;
typedef PVScalarValue<int16> PVShort;
typedef PVScalarValue<int32> PVInt;
typedef PVScalarValue<int64> PVLong;
typedef PVScalarValue<float> PVFloat;
typedef PVScalarValue<double> PVDouble;
/**
* PVString is special case, since it implements SerializableArray
*/
class PVString : public PVScalarValue<String>, SerializableArray {
public:
/**
* Destructor
*/
virtual ~PVString() {}
protected:
PVString(PVStructure *parent,ScalarConstPtr scalar)
: PVScalarValue<String>(parent,scalar) {}
};
/**
* PVArray is the base class for all array types, i.e. the scalarArray types and structureArray.
*/
class PVArray : public PVField, public SerializableArray {
public:
POINTER_DEFINITIONS(PVArray);
/**
* Destructor
*/
virtual ~PVArray();
/**
* Get the array length.
* @return The length.
*/
int getLength() const;
/**
* Set the array length.
* @param The length.
*/
void setLength(int length);
/**
* Get the array capacity.
* @return The capacity.
*/
int getCapacity() const;
/**
* Can the capacity be changed.
* @return (false,true) if (can not, can) be changed.
*/
bool isCapacityMutable();
/**
* Set the mutability of the array capacity.
* @return false or true
*/
void setCapacityMutable(bool isMutable);
/**
* Set the array capacity.
* @param The capacity.
*/
virtual void setCapacity(int capacity) = 0;
protected:
PVArray(PVStructure *parent,FieldConstPtr field);
void setCapacityLength(int capacity,int length);
private:
class PVArrayPvt * pImpl;
};
/**
* Class provided by caller of get
*/
template<typename T>
class PVArrayData {
public:
POINTER_DEFINITIONS(PVArrayData);
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
/**
* The data array.
*/
pointer data;
/**
* The offset. This is the offset into the actual array of the first element in data,
*/
int offset;
};
/**
* Base class for a scalarArray.
*/
class PVScalarArray : public PVArray {
public:
POINTER_DEFINITIONS(PVScalarArray);
/**
* Destructor
*/
virtual ~PVScalarArray();
/**
* Get the introspection interface
* @return The interface.
*/
ScalarArrayConstPtr getScalarArray() ;
protected:
PVScalarArray(PVStructure *parent,ScalarArrayConstPtr scalarArray);
private:
};
/**
* This is provided by code that calls get.
*/
typedef PVArrayData<PVStructurePtr> StructureArrayData;
/**
* Data class for a structureArray
*/
class PVStructureArray : public PVArray {
public:
POINTER_DEFINITIONS(PVStructureArray);
/**
* Destructor
*/
virtual ~PVStructureArray() {}
/**
* Get the introspection interface
* @return The interface.
*/
virtual StructureArrayConstPtr getStructureArray() = 0;
/**
* Append new elements to the end of the array.
* @param number The number of elements to add.
* @return the new length of the array.
*/
virtual int append(int number) = 0;
/**
* Remove elements from the array.
* @param offset The offset of the first element to remove.
* @param number The number of elements to remove.
* @return (false,true) if the elements were removed.
*/
virtual bool remove(int offset,int number) = 0;
/**
* Compress. This removes all null elements from the array.
*/
virtual void compress() = 0;
/**
* Get array elements
* @param offset The offset of the first element,
* @param length The number of elements to get.
* @param data The place where the data is placed.
*/
virtual int get(int offset, int length,
StructureArrayData *data) = 0;
/**
* Put data into the array.
* @param offset The offset of the first element,
* @param length The number of elements to get.
* @param from The new values to put into the array.
* @param fromOffset The offset in from.
* @return The number of elements put into the array.
*/
virtual int put(int offset,int length,
PVStructurePtrArray from, int fromOffset) = 0;
/**
* Share data from another source.
* @param value The data to share.
* @param capacity The capacity of the array.
* @param length The length of the array.
*/
virtual void shareData( PVStructurePtrArray value,int capacity,int length) = 0;
protected:
PVStructureArray(PVStructure *parent, StructureArrayConstPtr structureArray)
: PVArray(parent,structureArray) {}
private:
};
class PVStructure : public PVField,public BitSetSerializable {
public:
POINTER_DEFINITIONS(PVStructure);
/**
* Destructor
*/
virtual ~PVStructure();
/**
* Get the introspection interface
* @return The interface.
*/
StructureConstPtr getStructure();
/**
* Get the array of pointers to the subfields in the structure.
* @return The array.
*/
PVFieldPtrArray getPVFields();
/**
* Get the subfield with the specified name.
* @param fieldName The name of the field.
* @return Pointer to the field or null if field does not exist.
*/
PVField *getSubField(String fieldName);
/**
* Get the subfield with the specified offset.
* @param fieldOffset The offset.
* @return Pointer to the field or null if field does not exist.
*/
PVField *getSubField(int fieldOffset);
/**
* Append a field to the structure.
* @param pvField The field to append.
*/
void appendPVField(PVField *pvField);
/**
* Append fields to the structure.
* @param numberFields The number of fields.
* @param pvFields The fields to append.
* @return Pointer to the field or null if field does not exist.
*/
void appendPVFields(int numberFields,PVFieldPtrArray pvFields);
/**
* Remove a field from the structure.
* @param fieldName The name of the field to remove.
*/
void removePVField(String fieldName);
/**
* Get a boolean field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVBoolean *getBooleanField(String fieldName);
/**
* Get a byte field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVByte *getByteField(String fieldName);
/**
* Get a short field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVShort *getShortField(String fieldName);
/**
* Get a int field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVInt *getIntField(String fieldName);
/**
* Get a long field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVLong *getLongField(String fieldName);
/**
* Get a float field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVFloat *getFloatField(String fieldName);
/**
* Get a double field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVDouble *getDoubleField(String fieldName);
/**
* Get a string field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVString *getStringField(String fieldName);
/**
* Get a structure field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVStructure *getStructureField(String fieldName);
/**
* Get a scalarArray field with the specified name.
* @param fieldName The name of the field to get.
* @param elementType The element type.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVScalarArray *getScalarArrayField(
String fieldName,ScalarType elementType);
/**
* Get a structureArray field with the specified name.
* @param fieldName The name of the field to get.
* @return Pointer to the field of null if a field with that name and type does not exist.
*/
PVStructureArray *getStructureArrayField(String fieldName);
/**
* Get the name if this structure extends another structure.
* @return The string which may be null.
*/
String getExtendsStructureName();
/**
* Put the extends name.
* @param extendsStructureName The name.
*/
bool putExtendsStructureName(
String extendsStructureName);
/**
* Serialize.
* @param pbuffer The byte buffer.
* @param pflusher Interface to call when buffer is full.
*/
virtual void serialize(
ByteBuffer *pbuffer,SerializableControl *pflusher) const;
/**
* Deserialize
* @param pbuffer The byte buffer.
* @param pflusher Interface to call when buffer is empty.
*/
virtual void deserialize(
ByteBuffer *pbuffer,DeserializableControl *pflusher);
/**
* Serialize.
* @param pbuffer The byte buffer.
* @param pflusher Interface to call when buffer is full.
* @param pbitSet A bitset the specifies which fields to serialize.
*/
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher,BitSet *pbitSet) const;
/**
* Deserialize
* @param pbuffer The byte buffer.
* @param pflusher Interface to call when buffer is empty.
* @param pbitSet A bitset the specifies which fields to deserialize.
*/
virtual void deserialize(ByteBuffer *pbuffer,
DeserializableControl*pflusher,BitSet *pbitSet);
/**
* Constructor
* @param parent The parent structure.
* @param structure The introspection interface.
*/
PVStructure(PVStructure *parent,StructureConstPtr structure);
/**
* Constructor
* @param parent The parent structure.
* @param structure The introspection interface.
* @param pvFields The array of fields for the structure.
*/
PVStructure(
PVStructure *parent,
StructureConstPtr structure,
PVFieldPtrArray pvFields);
private:
void setParentPvt(PVField *pvField,PVStructure *parent);
class PVStructurePvt * pImpl;
};
template<typename T>
class PVValueArray : public PVScalarArray {
public:
POINTER_DEFINITIONS(PVValueArray);
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef PVArrayData<T> ArrayDataType;
/**
* Destructor
*/
virtual ~PVValueArray() {}
/**
* Get array elements
* @param offset The offset of the first element,
* @param length The number of elements to get.
* @param data The place where the data is placed.
*/
virtual int get(int offset, int length, ArrayDataType *data) = 0;
/**
* Put data into the array.
* @param offset The offset of the first element,
* @param length The number of elements to get.
* @param from The new values to put into the array.
* @param fromOffset The offset in from.
* @return The number of elements put into the array.
*/
virtual int put(int offset,int length, pointer from, int fromOffset) = 0;
/**
* Share data from another source.
* @param value The data to share.
* @param capacity The capacity of the array.
* @param length The length of the array.
*/
virtual void shareData(pointer value,int capacity,int length) = 0;
protected:
PVValueArray(PVStructure *parent,ScalarArrayConstPtr scalar)
: PVScalarArray(parent,scalar) {}
private:
};
/**
* Definitions for the various scalarArray types.
*/
typedef PVArrayData<bool> BooleanArrayData;
typedef PVValueArray<bool> PVBooleanArray;
typedef PVArrayData<int8> ByteArrayData;
typedef PVValueArray<int8> PVByteArray;
typedef PVArrayData<int16> ShortArrayData;
typedef PVValueArray<int16> PVShortArray;
typedef PVArrayData<int32> IntArrayData;
typedef PVValueArray<int32> PVIntArray;
typedef PVArrayData<int64> LongArrayData;
typedef PVValueArray<int64> PVLongArray;
typedef PVArrayData<float> FloatArrayData;
typedef PVValueArray<float> PVFloatArray;
typedef PVArrayData<double> DoubleArrayData;
typedef PVValueArray<double> PVDoubleArray;
typedef PVArrayData<String> StringArrayData;
typedef PVValueArray<String> PVStringArray;
/**
* This is a singlton class for creating data instances.
*/
class PVDataCreate {
public:
/**
* Create a PVField using given Field introspection data.
* @param parent The parent interface.
* @param field The introspection data to be used to create PVField.
* @return The PVField implementation.
*/
PVField *createPVField(PVStructure *parent,
FieldConstPtr field);
/**
* Create a PVField using given a PVField to clone.
* This method calls the appropriate createPVScalar, createPVArray, or createPVStructure.
* @param parent The parent interface.
* @param fieldToClone The field to clone.
* @return The PVField implementation
*/
PVField *createPVField(PVStructure *parent,
String fieldName,PVField * fieldToClone);
/**
* Create an implementation of a scalar field reusing the Scalar introspection interface.
* @param parent The parent.
* @param scalar The introspection interface.
* @return The PVScalar implementation.
*/
PVScalar *createPVScalar(PVStructure *parent,ScalarConstPtr scalar);
/**
* Create an implementation of a scalar field. A Scalar introspection interface is created.
* @param parent The parent interface.
* @param fieldName The field name.
* @param fieldType The field type.
* @return The PVScalar implementation.
*/
PVScalar *createPVScalar(PVStructure *parent,
String fieldName,ScalarType scalarType);
/**
* Create an implementation of a scalar field by cloning an existing PVScalar.
* The new PVScalar will have the same value and auxInfo as the original.
* @param parent The parent interface.
* @param fieldName The field name.
* @param scalarToClone The PVScalar to clone.
* @return The PVScalar implementation.
*/
PVScalar *createPVScalar(PVStructure *parent,
String fieldName,PVScalar * scalarToClone);
/**
* Create an implementation of an array field reusing the Array introspection interface.
* @param parent The parent interface.
* @param array The introspection interface.
* @return The PVScalarArray implementation.
*/
PVScalarArray *createPVScalarArray(PVStructure *parent,
ScalarArrayConstPtr scalarArray);
/**
* Create an implementation for an array field. An Array introspection interface is created.
* @param parent The parent interface.
* @param fieldName The field name.
* @param elementType The element type.
* @return The PVScalarArray implementation.
*/
PVScalarArray *createPVScalarArray(PVStructure *parent,
String fieldName,ScalarType elementType);
/**
* Create an implementation of an array field by cloning an existing PVArray.
* The new PVArray will have the same value and auxInfo as the original.
* @param parent The parent interface.
* @param fieldName The field name.
* @param arrayToClone The PVScalarArray to clone.
* @return The PVScalarArray implementation.
*/
PVScalarArray *createPVScalarArray(PVStructure *parent,
String fieldName,PVScalarArray * scalarArrayToClone);
/**
* Create an implementation of an array with structure elements.
* @param parent The parent interface.
* @param structureArray The introspection interface.
* All elements share the same introspection interface.
* @return The PVStructureArray implementation.
*/
PVStructureArray *createPVStructureArray(PVStructure *parent,
StructureArrayConstPtr structureArray);
/**
* Create implementation for PVStructure.
* @param parent The parent interface.
* @param structure The introspection interface.
* @return The PVStructure implementation
*/
PVStructure *createPVStructure(PVStructure *parent,
StructureConstPtr structure);
/**
* Create implementation for PVStructure.
* @param parent The parent interface.
* @param fieldName The field name.
* @param fields Array of reflection interfaces for the subFields.
* @return The PVStructure implementation
*/
PVStructure *createPVStructure(PVStructure *parent,
String fieldName,int numberFields,FieldConstPtrArray fields);
/**
* Create implementation for PVStructure.
* @param parent The parent interface.
* @param fieldName The field name.
* @param pvFields Array of PVFields
* @return The PVStructure implementation
*/
PVStructure *createPVStructure(PVStructure *parent,
String fieldName,int numberFields,PVFieldPtrArray pvFields);
/**
* Create implementation for PVStructure.
* @param parent The parent interface.
* @param fieldName The field name.
* @param structToClone A structure. Each subfield and any auxInfo is cloned and added to the newly created structure.
* @return The PVStructure implementation.
*/
PVStructure *createPVStructure(PVStructure *parent,
String fieldName,PVStructure *structToClone);
protected:
PVDataCreate();
friend PVDataCreate * getPVDataCreate();
};
/**
* Get the single class that implemnents PVDataCreate
* @param The PVDataCreate factory.
*/
extern PVDataCreate * getPVDataCreate();
}}
#endif /* PVDATA_H */

View File

@@ -1,465 +0,0 @@
/* pvIntrospect.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.
* Author - Marty Kraimer
*/
#ifndef PVINTROSPECT_H
#define PVINTROSPECT_H
#include <string>
#include <stdexcept>
#include <pv/noDefaultMethods.h>
#include <pv/sharedPtr.h>
#include <pv/pvType.h>
namespace epics { namespace pvData {
class Field;
class Scalar;
class ScalarArray;
class Structure;
class StructureArray;
/**
* typedef for a shared pointer to an immutable Field.
*/
typedef std::tr1::shared_ptr<const Field> FieldConstPtr;
/**
* typedef for an array of shared pointer to an immutable Field.
*/
typedef FieldConstPtr * FieldConstPtrArray;
/**
* typedef for a shared pointer to an immutable Scalar.
*/
typedef std::tr1::shared_ptr<const Scalar> ScalarConstPtr;
/**
* typedef for a shared pointer to an immutable ScalarArray.
*/
typedef std::tr1::shared_ptr<const ScalarArray> ScalarArrayConstPtr;
/**
* typedef for a shared pointer to an immutable Structure.
*/
typedef std::tr1::shared_ptr<const Structure> StructureConstPtr;
/**
* typedef for a shared pointer to an immutable StructureArray.
*/
typedef std::tr1::shared_ptr<const StructureArray> StructureArrayConstPtr;
/**
* Definition of support field types.
*/
enum Type {
/**
* The type is scalar. It has a scalarType
*/
scalar,
/**
* The type is scalarArray. Each element is a scalar of the same scalarType.
*/
scalarArray,
/**
* The type is structure.
*/
structure,
/**
* The type is structureArray. Each element is a structure.
*/
structureArray
};
/**
* Convenience functions for Type.
*/
namespace TypeFunc {
/**
* Get a name for the type.
* @param type The type.
* @return The name for the type.
*/
const char* name(Type type);
/**
* Convert the type to a string and add it to builder.
* @param builder The string builder.
* @param type The type.
*/
void toString(StringBuilder builder,const Type type);
};
/**
* Definition of support scalar types.
*/
enum ScalarType {
/**
* The type is boolean, i. e. value can be {@code false} or {@code true}
*/
pvBoolean,
/**
* The type is byte, i. e. a 8 bit signed integer.
*/
pvByte,
/**
* The type is short, i. e. a 16 bit signed integer.
*/
pvShort,
/**
* The type is int, i. e. a 32 bit signed integer.
*/
pvInt,
/**
* The type is long, i. e. a 64 bit signed integer.
*/
pvLong,
/**
* The type is float, i. e. 32 bit IEEE floating point,
*/
pvFloat,
/**
* The type is float, i. e. 64 bit IEEE floating point,
*/
pvDouble,
/**
* The type is string, i. e. a UTF8 character string.
*/
pvString
};
/**
* Convenience functions for ScalarType.
*/
namespace ScalarTypeFunc {
/**
* Is the type an integer, i. e. is it one of byte,...long
* @param scalarType The type.
* @return (false,true) if the scalarType is an integer.
*/
bool isInteger(ScalarType scalarType);
/**
* Is the type numeric, i. e. is it one of byte,...,double
* @param scalarType The type.
* @return (false,true) if the scalarType is a numeric
*/
bool isNumeric(ScalarType scalarType);
/**
* Is the type primitive, i. e. not string
* @param scalarType The type.
* @return (false,true) if the scalarType is primitive.
*/
bool isPrimitive(ScalarType scalarType);
/**
* Get the scalarType for value.
* @param value The name of the scalar type.
* @return The scalarType.
* An exception is thrown if the name is not the name of a scalar type.
*/
ScalarType getScalarType(String value);
/**
* Get a name for the scalarType.
* @param scalarType The type.
* @return The name for the scalarType.
*/
const char* name(ScalarType scalarType);
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param scalarType The type.
*/
void toString(StringBuilder builder,ScalarType scalarType);
};
/**
* This class implements introspection object for field.
*/
class Field : 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;}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder builder) const{toString(builder,0);}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @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);
private:
String m_fieldName;
Type m_type;
friend class StructureArray;
friend class Structure;
friend class PVFieldPvt;
friend class StandardField;
friend class BasePVStructureArray;
friend class FieldCreate;
struct Deleter{void operator()(Field *p){delete p;}};
};
/**
* This class implements introspection object for Scalar.
*/
class Scalar : public Field{
public:
POINTER_DEFINITIONS(Scalar);
/**
* Destructor.
*/
virtual ~Scalar();
typedef Scalar& reference;
typedef const Scalar& const_reference;
/**
* Get the scalarType
* @return the scalarType
*/
ScalarType getScalarType() const {return scalarType;}
/**
* Convert the scalar to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder buf) const{toString(buf,0);}
/**
* Convert the scalar to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel) const;
protected:
Scalar(String fieldName,ScalarType scalarType);
private:
ScalarType scalarType;
friend class FieldCreate;
};
/**
* This class implements introspection object for field.
*/
class ScalarArray : public Field{
public:
POINTER_DEFINITIONS(ScalarArray);
ScalarArray(String fieldName,ScalarType scalarType);
typedef ScalarArray& reference;
typedef const ScalarArray& const_reference;
/**
* Get the scalarType for the elements.
* @return the scalarType
*/
ScalarType getElementType() const {return elementType;}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder buf) const{toString(buf,0);}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel) const;
protected:
/**
* Destructor.
*/
virtual ~ScalarArray();
private:
ScalarType elementType;
friend class FieldCreate;
};
/**
* This class implements introspection object for a structureArray
*/
class StructureArray : public Field{
public:
POINTER_DEFINITIONS(StructureArray);
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.
*/
StructureConstPtr getStructure() const {return pstructure;}
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel=0) const;
protected:
/**
* Constructor.
* @param fieldName The name for the field.
* @param structure The introspection interface for the elements.
*/
StructureArray(String fieldName,StructureConstPtr structure);
/**
* Destructor.
*/
virtual ~StructureArray();
private:
StructureConstPtr pstructure;
friend class FieldCreate;
};
/**
* This class implements introspection object for a structure.
*/
class Structure : public Field {
public:
POINTER_DEFINITIONS(Structure);
/**
* Destructor.
*/
virtual ~Structure();
typedef Structure& reference;
typedef const Structure& const_reference;
/**
* Get the number of immediate subfields in the structure/
* @return The number of fields.
*/
int getNumberFields() const {return numberFields;}
/**
* Get the field for the specified fieldName.
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
*/
FieldConstPtr getField(String fieldName) const;
/**
* 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;
/**
* Get the fields in the structure.
* @return The array of fields.
*/
FieldConstPtrArray getFields() const {return fields;}
/**
* Append a field to the structure.
* @param field The field to append.
*/
void appendField(FieldConstPtr field);
/**
* 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.
*/
void appendFields(int numberFields,FieldConstPtrArray fields);
/**
* Remove a field from the structure.
* @param field The field to remove.
*/
void removeField(int index);
/**
* Convert the structure to a string and add it to builder.
* @param builder The string builder.
*/
virtual void toString(StringBuilder buf) const{toString(buf,0);}
/**
* Convert the structure to a string and add it to builder.
* @param builder The string builder.
* @param indentLevel The number of blanks at the beginning of new lines.
*/
virtual void toString(StringBuilder buf,int indentLevel) const;
protected:
Structure(String fieldName, int numberFields,FieldConstPtrArray fields);
private:
int numberFields;
FieldConstPtrArray fields;
friend class FieldCreate;
};
/**
* This is a singlton class for creating introspection interfaces.
*/
class FieldCreate : NoDefaultMethods {
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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* Create a {@code Structure} field.
* @param fieldName The field name
* @param fields The array of {@code Field}s for the structure.
* @return a {@code Structure} interface for the newly created object.
*/
StructureArrayConstPtr createStructureArray(String fieldName,
StructureConstPtr structure) const;
private:
FieldCreate();
friend FieldCreate * getFieldCreate();
};
/**
* Get the single class that implemnents FieldCreate,
* @param The fieldCreate factory.
*/
extern FieldCreate * getFieldCreate();
}}
#endif /* PVINTROSPECT_H */

View File

@@ -1,102 +0,0 @@
/* pvType.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.
* Author - Marty Kraimer
*/
/* Definitions for the primitive types for pvData.
* It also defines the arrays of the primitive types
*/
#ifndef PVTYPE_H
#define PVTYPE_H
#include <string>
#include <stdint.h>
namespace epics { namespace pvData {
/**
* This is a set of typdefs used by pvData.
*/
/**
* boolean, i.e. can only have the values {@code false} or {@code true}
*/
typedef bool boolean;
/**
* A 8 bit signed integer
*/
typedef int8_t int8;
/**
* A 16 bit signed integer
*/
typedef int16_t int16;
/**
* A 32 bit signed integer
*/
typedef int32_t int32;
/**
* A 64 bit signed integer
*/
typedef int64_t int64;
/**
* A 32 bit unsigned integer
*/
typedef uint32_t uint32;
/**
* A 64 bit unsigned integer
*/
typedef uint64_t uint64;
// float and double are types
/**
* A string
*/
typedef std::string String;
/**
* A boolean array.
*/
typedef bool * BooleanArray;
/**
* A byte array.
*/
typedef int8 * ByteArray;
/**
* A short array.
*/
typedef int16 * ShortArray;
/**
* A int array.
*/
typedef int32 * IntArray;
/**
* A long array.
*/
typedef int64 * LongArray;
/**
* A float array.
*/
typedef float * FloatArray;
/**
* A double array.
*/
typedef double * DoubleArray;
/**
* A string array.
*/
typedef String* StringArray;
/**
* A convenience definition for toString methods
*/
typedef std::string * StringBuilder;
}}
#endif /* PVTYPE_H */

View File

@@ -1,101 +0,0 @@
/* standardField.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.
* Author - Marty Kraimer
*/
#ifndef STANDARDFIELD_H
#define STANDARDFIELD_H
#include <string>
#include <stdexcept>
#include <pv/pvIntrospect.h>
namespace epics { namespace pvData {
/**
* Standard Fields is a class or creating or sharing Field objects for standard fields.
* For each type of standard object two methods are defined:s
* one with no properties and with properties
* 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
* 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:
* {@code
StructureConstPtr example = standardField->scalar(
String("value"),
pvDouble,
String("value,alarm,timeStamp"));
* }
* Will result in a Field definition that has the form: {@code
structure example
double value
structure alarm
structure severity
int index
string[] choices
structure timeStamp
long secondsPastEpoch
int nanoSeconds
* }
* In addition there are methods that create each of the property structures,
* i.e. the methods named: alarm, .... enumeratedAlarm."
*
* StandardField is a singleton class. The class is accessed via the statement: {@code
StandardField *standardField = getStandardField();
* }
*/
class StandardField : private NoDefaultMethods {
public:
StandardField();
~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 alarm();
StructureConstPtr timeStamp();
StructureConstPtr display();
StructureConstPtr control();
StructureConstPtr booleanAlarm();
StructureConstPtr byteAlarm();
StructureConstPtr shortAlarm();
StructureConstPtr intAlarm();
StructureConstPtr longAlarm();
StructureConstPtr floatAlarm();
StructureConstPtr doubleAlarm();
StructureConstPtr enumeratedAlarm();
private:
static void init();
};
extern StandardField * getStandardField();
}}
#endif /* STANDARDFIELD_H */

View File

@@ -1,80 +0,0 @@
/* standardPVField.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.
* Author - Marty Kraimer
*/
#ifndef STANDARDPVFIELD_H
#define STANDARDPVFIELD_H
#include <string>
#include <stdexcept>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
namespace epics { namespace pvData {
/**
* StandardPVField is a class or creating standard data fields.
* Like class StandardField it has two forms of the methods which create a fields:
* one without properties and one with properties.
* The properties are some combination of alarm, timeStamp, control, display, and valueAlarm.
* Just like StandardField there are methods to create the standard properties.
*
* StandardPVField is a singleton class. The class is accessed via the statement: {@code
StandardPVField *standardPVField = getStandardPVField();
* }
*/
class StandardPVField : private NoDefaultMethods {
public:
StandardPVField();
~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);
};
extern StandardPVField * getStandardPVField();
}}
#endif /* STANDARDPVFIELD_H */

View File

@@ -1,77 +0,0 @@
/*bitSetUtil.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 <pv/noDefaultMethods.h>
#include <pv/pvData.h>
#include <pv/bitSetUtil.h>
namespace epics { namespace pvData {
static bool checkBitSetPVField(
PVField *pvField,BitSet *bitSet,int initialOffset)
{
bool atLeastOneBitSet = false;
bool allBitsSet = true;
int offset = initialOffset;
int nbits = pvField->getNumberFields();
if(nbits==1) return bitSet->get(offset);
int nextSetBit = bitSet->nextSetBit(offset);
if(nextSetBit>=(offset+nbits)) return false;
if(bitSet->get(offset)) {
if(nbits>1) {
for(int i=offset+1; i<offset+nbits; i++) bitSet->clear(i);
}
return true;
}
PVStructure *pvStructure = static_cast<PVStructure *>(pvField);
while(offset<initialOffset + nbits) {
PVField *pvSubField = pvStructure->getSubField(offset);
int nbitsNow = pvSubField->getNumberFields();
if(nbitsNow==1) {
if(bitSet->get(offset)) {
atLeastOneBitSet = true;
} else {
allBitsSet = false;
}
offset++;
} else {
offset++;
PVStructure *pvSubStructure = static_cast<PVStructure*>(pvField);
PVFieldPtrArray pvSubStructureFields =
pvSubStructure->getPVFields();
int num = pvSubStructure->getStructure()->getNumberFields();
for(int i=0; i<num; i++) {
PVField *pvSubSubField = pvSubStructureFields[i];
bool result = checkBitSetPVField(pvSubSubField,bitSet,offset);
if(result) {
atLeastOneBitSet = true;
if(!bitSet->get(offset)) {
allBitsSet = false;
}
} else {
allBitsSet = false;
}
offset += pvSubSubField->getNumberFields();
}
}
}
if(allBitsSet) {
if(nbits>1) {
for(int i=initialOffset+1; i<initialOffset+nbits; i++){
bitSet->clear(i);
}
}
bitSet->set(initialOffset);
}
return atLeastOneBitSet;
}
bool BitSetUtil::compress(BitSet *bitSet,PVStructure *pvStructure)
{
return checkBitSetPVField(pvStructure,bitSet,0);
}
}}

View File

@@ -1,21 +0,0 @@
/*bitSetUtil.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 BITSETUTIL_H
#define BITSETUTIL_H
#include <pv/noDefaultMethods.h>
#include <pv/pvData.h>
#include <pv/bitSet.h>
namespace epics { namespace pvData {
class BitSetUtil : private NoDefaultMethods {
public:
static bool compress(BitSet *bitSet,PVStructure *pvStructure);
};
}}
#endif /*BITSETUTIL_H */

24
src/Makefile Normal file
View File

@@ -0,0 +1,24 @@
# Makefile for the pvData library
TOP = ..
include $(TOP)/configure/CONFIG
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
USR_INCLUDES += -I$(INSTALL_LOCATION)/include
PVDATA_SRC = $(TOP)/src
include $(PVDATA_SRC)/misc/Makefile
include $(PVDATA_SRC)/pv/Makefile
include $(PVDATA_SRC)/factory/Makefile
include $(PVDATA_SRC)/property/Makefile
include $(PVDATA_SRC)/copy/Makefile
include $(PVDATA_SRC)/pvMisc/Makefile
include $(PVDATA_SRC)/monitor/Makefile
LIBRARY = pvData
pvData_LIBS += Com
include $(TOP)/configure/RULES

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