762 Commits
3.0.1 ... 8.0.4

Author SHA1 Message Date
Michael Davidsaver
b1c8303870 Update version numbers for release 2021-02-25 09:35:12 -08:00
Michael Davidsaver
a3ef984f4f ci: switch travis -> github 2020-12-20 11:08:29 -08:00
Michael Davidsaver
ca86a63180 update release notes 2020-11-14 13:43:38 -08:00
Michael Davidsaver
07b79693af Deprecate/remove unused buffer alignment tools
ByteBuffer::align() does not work as expected
on some RTEMS targets where malloc() returns
buffers aligned only to 4 bytes.

SerializableControl::alignBuffer() and
DeserializableControl::alignData() are implemented,
but never called, in this module and pvAccessCPP.
ByteBuffer::align() is only needed to implement
these two methods.

Leave non-pure virtual stubs to assist in migration.
2020-11-14 11:07:15 -08:00
Michael Davidsaver
4ef9e18ac6 enable RTEMS CI testing 2020-11-13 20:51:23 -08:00
Michael Davidsaver
320cc3c60b shared_vector_convert<>() fix convert of empty array
Empty arrays can be untyped, but this doesn't matter.
2020-09-29 15:52:49 -07:00
Michael Davidsaver
45d0d76a7f Set next development version 2020-07-26 13:30:34 -07:00
Michael Davidsaver
b2b42d5f8c Update version numbers for release 2020-07-26 13:29:52 -07:00
Michael Davidsaver
90b1f2f6da doc 2020-06-17 14:08:14 -07:00
Michael Davidsaver
2e775ef2fb drop THROW_BASE_EXCEPTION_CAUSE() 2020-06-17 14:08:14 -07:00
Michael Davidsaver
f17d2bbca1 add maybeQuote()
Something for the *NIX gurus
to light their pipes with.
2020-06-17 14:08:14 -07:00
Michael Davidsaver
79b02254c4 update ci-scripts to 3.0.1 2020-06-17 14:06:50 -07:00
Michael Davidsaver
19245ce805 sharedVector extend base_ptr() to VS2013 2020-06-03 10:14:38 -07:00
Andrew Johnson
0fa927afa7 Set next development version 2020-05-28 16:26:00 -05:00
Andrew Johnson
d9b3f98e35 Update version numbers for release 2020-05-28 13:37:15 -05:00
Michael Davidsaver
81e7968230 doc 2020-05-20 14:54:39 -07:00
Michael Davidsaver
06f3b96992 ci-scripts 2.3.2 (with appveyor) 2020-04-27 12:18:16 -07:00
1038182a16 removed empty lines at end of file 2020-04-15 07:53:22 -07:00
60091bfe56 removed spaces at end of line 2020-04-15 07:53:22 -07:00
f4de6dd9b1 replaced tabs with spaces 2020-04-15 07:53:22 -07:00
Michael Davidsaver
3d93a80cce travis switch to ci-scripts 2019-12-20 10:33:03 -08:00
Michael Davidsaver
94eff54fa9 Revert "Properly declare isnan() in C++ testcode"
This reverts commit 07b75e4543.

std:: qualified names not portable until c++11
epicsMath.h changed to ensure that unqualified
names continue to work.
2019-12-19 18:50:33 -08:00
Michael Davidsaver
e9dde4d2f8 update doc 2019-12-13 09:32:42 -08:00
Michael Davidsaver
0a5e22e5b0 testPVData print additional sizes 2019-12-13 09:32:42 -08:00
Michael Davidsaver
3a5cfba4e1 catch exception by ref 2019-12-13 09:32:42 -08:00
Ralph Lange
07b75e4543 Properly declare isnan() in C++ testcode 2019-12-11 13:29:27 +01:00
Michael Davidsaver
e4f150b34f finalize doxygen 2019-11-03 20:03:24 -08:00
Andrew Johnson
ca2ae0d0e7 Incr version and set development flag after release 2019-10-31 17:04:21 -05:00
Andrew Johnson
828506720c Clear development flag for 8.0.1 release 2019-10-31 16:57:41 -05:00
Andrew Johnson
ad712b63f9 Sub-bullets must be indented by at least 2 spaces 2019-10-31 16:52:53 -05:00
Michael Davidsaver
4c3d5a788d release notes for 8.0.1 2019-10-31 10:34:52 -07:00
Michael Davidsaver
df89135455 cleanup 2019-10-11 16:17:49 -07:00
Michael Davidsaver
95d452870c move dedup to most derived
Making virtual calls from a base class dtor is not safe.
2019-10-11 16:17:25 -07:00
Michael Davidsaver
8a82ff9fe4 Revert "dynamic_cast may not be defined during dtor"
This reverts commit dd24b2ad75.
2019-10-11 08:41:30 -07:00
Michael Davidsaver
dd24b2ad75 dynamic_cast may not be defined during dtor 2019-09-30 18:24:13 -07:00
Michael Davidsaver
17fa7a7724 travis matrix build
switch to matrix build to test multiple ubuntu versions
2019-09-23 13:41:23 -07:00
Michael Davidsaver
d01ba94ed7 avoid extraneous copy 2019-09-23 10:14:55 -07:00
Michael Davidsaver
c7c7585950 release notes 2019-09-23 10:14:55 -07:00
Michael Davidsaver
f869936cfd travis drop 3.14 build 2019-09-23 10:14:55 -07:00
Michael Davidsaver
0ad253c6f0 Remove Base 3.14 compatibility 2019-09-23 10:14:55 -07:00
Michael Davidsaver
52d04d5044 note class sizes 2019-09-23 10:14:55 -07:00
Ralph Lange
bff2dc9cd2 rtd-ci: add read-the-docs integration 2019-09-06 11:27:03 +02:00
Andrew Johnson
b903df5d0d Update version number to 8.0.1 DEVELOPMENT 2019-08-13 11:11:57 -05:00
Michael Davidsaver
416d910577 Timer: further attempt to avoid state corruption 2019-07-31 20:13:33 -07:00
Michael Davidsaver
37b7a0708f Timer more alive checks 2019-07-31 19:01:20 -07:00
Michael Davidsaver
6ceaa6adb0 update release notes for 8.0.0 2019-07-24 11:19:30 -07:00
Michael Davidsaver
0447826e7c minor 2019-07-14 19:09:54 -07:00
Michael Davidsaver
3ef60a61a2 always epicsThreadStackBig
On RTEMS at least, c++ code needs the largest
standard stack frame size.
2019-07-08 09:07:09 -07:00
Daniel Damiani
31802a8bde Added additional explicit template instantiations to fix build problems on macos with c+11 2019-07-04 07:09:58 -07:00
Bruno Martins
c2bc77a649 Improve and add new tests for testIntrospect 2019-05-20 16:35:59 -07:00
Bruno Martins
4dd7a18301 Improve docs. Make getFieldT(offset) use vector::at. 2019-05-20 16:35:59 -07:00
Bruno Martins
a29894ee2b getField<T>() fail to compile when T isn't Field or a sub-class 2019-05-20 16:35:59 -07:00
Bruno Martins
2f8ac7f673 Fix tests with expected exceptions for getField(size_t) 2019-05-20 16:35:59 -07:00
Bruno Martins
b050fbbcbe Revert {Structure,Union}::getField to previous behavior 2019-05-20 16:35:59 -07:00
Bruno Martins
caa11605fc Add {Structure,Union}::getFieldT, fix {Structure,Union}::getField 2019-05-20 16:35:59 -07:00
Michael Davidsaver
cfcdd1a3f9 deprecate ByteBuffer::getArray()
in favor of identical ByteBuffer::getBuffer()
2019-05-18 18:21:06 -07:00
Michael Davidsaver
95ff606ba1 quiet (un)signed comparison warning 2019-05-16 10:17:56 -07:00
Michael Davidsaver
4cc9b650c5 getSubField<T>() fail to compile when T isn't PVField or a sub-class 2019-05-16 10:17:56 -07:00
Michael Davidsaver
cd2436342d Revert "Replace display.format with .form and .precision"
This reverts commit 4ffddfa2f6.
2019-05-06 10:40:54 -07:00
Michael Davidsaver
3ae2d09fe3 bump module version after removals 2019-05-01 14:43:33 -07:00
Michael Davidsaver
35b3403de6 remove deprecated pvCopy 2019-05-01 14:18:48 -07:00
Michael Davidsaver
f780ebdf76 remove deprecated localStaticLock 2019-05-01 14:06:33 -07:00
Michael Davidsaver
93f0518b4b Merge remote-tracking branch 'md/display-format'
* md/display-format:
  Replace display.format with .form and .precision
2019-05-01 14:03:57 -07:00
Michael Davidsaver
6da871fa64 7.1.3 2019-04-17 11:48:01 -07:00
Michael Davidsaver
d53cb0cbc9 doc 2019-04-17 11:47:56 -07:00
Michael Davidsaver
8f0111e482 fix ByteBuffer::putArray() and getArray()
Erroneous mixing of byte and element indexing
introduced by a51b308cc8
2019-04-08 09:46:23 -07:00
Michael Davidsaver
5525119778 test ByteBuffer array operations 2019-04-08 09:46:20 -07:00
Michael Davidsaver
6410600205 testByteBuffer cleanup 2019-04-08 09:46:16 -07:00
Michael Davidsaver
a5d44745d1 cleanup testSharedVector
"using namespace" considered harmful...
2019-04-08 09:46:07 -07:00
Michael Davidsaver
8c275cbc1c 7.1.2 2019-03-18 11:07:20 -07:00
Michael Davidsaver
b79f69231c more doxygen 2019-03-18 10:32:50 -07:00
Michael Davidsaver
ff165595c4 minor doc 2019-03-18 09:28:00 -07:00
Michael Davidsaver
12d851dc6f release notes for 7.1.1 2019-03-18 09:08:08 -07:00
Michael Davidsaver
643f289c23 missing include 2019-03-11 14:55:55 -07:00
Michael Davidsaver
68e74ed1d2 update release notes 2019-03-11 14:08:01 -07:00
Michael Davidsaver
f0ef0965c4 AnyScalar doc 2019-03-11 14:05:10 -07:00
Michael Davidsaver
61ce532fdf cleanup test 2019-03-11 14:05:05 -07:00
Michael Davidsaver
d746e1bfb3 minor 2019-03-11 14:04:53 -07:00
MJGaughran
deccc41b9a Disabled NEED_OLL_FUNCS for Visual Studio 2013+ (#64)
* Disabled NEED_OLL_FUNCS for Visual Studio 2013+

Both _MSC_VER (VC++ compiler version) and EPICS base version should be
checked for strtoll, strtoull definitions.

* NEED_OLL_FUNCS now defined only for VS builds
2019-03-02 11:11:42 -08:00
Michael Davidsaver
4ffddfa2f6 Replace display.format with .form and .precision
Remove instance accessors w/o replacement
as a prelude to deprecation.
2019-01-16 09:06:15 -08:00
Michael Davidsaver
2814c779bd StandardField::getStandardField safety 2019-01-15 21:01:38 -08:00
Michael Davidsaver
4c73607799 cleanup StandardField 2019-01-15 21:01:38 -08:00
Andrew Johnson
d776f6eaf0 Update and unify README.md 2018-12-17 15:00:28 -06:00
Andrew Johnson
706ef01782 Delete ancient and unused examples.zip file 2018-12-17 14:59:23 -06:00
Michael Davidsaver
00c62cbd67 Fix deprecation message w/ gcc < 4.5
Apparently deprecated(msg) is newer than I thought.
2018-11-26 12:05:34 -08:00
Michael Davidsaver
da8f3d6cc7 minor 2018-11-26 10:25:29 -08:00
Michael Davidsaver
0bc95e51c2 7.1.0 2018-11-26 10:20:31 -08:00
Michael Davidsaver
727153e965 deprecate BoundedString, BoundedScalarArray, and FixedScalarArray
https://github.com/epics-base/pvDataCPP/issues/52
2018-11-26 10:13:08 -08:00
Michael Davidsaver
d00f54228d quiet warning, and possible dllimport/export
Seen as a warning on clang, but class/struct
can result in different mangled symbol names
w/ MSVC.
2018-11-07 09:06:58 -08:00
Michael Davidsaver
77c67802a3 printer.cpp extend precision 2018-10-30 17:09:56 -07:00
Michael Davidsaver
7d68d177d7 printer.cpp update time format 2018-10-30 17:02:22 -07:00
Michael Davidsaver
9b20505dcd stream() remove comma in NTTable 2018-10-30 14:33:15 -07:00
Michael Davidsaver
5f93e292b2 testprinter fix plan 2018-10-29 13:12:01 -07:00
Michael Davidsaver
edd3e20f3c format NTEnum 2018-10-29 13:12:01 -07:00
Michael Davidsaver
90cffa60d6 format NTTable as CSV 2018-10-29 13:12:01 -07:00
Michael Davidsaver
6171cd6867 escape and quote PVString(Array)::dumpValue()
Escaping for both.  quote array values,
but not scalar.

Also move remaining template virtuals out of line.
2018-10-29 13:12:01 -07:00
Michael Davidsaver
fa731bf6c3 helper to escape while printing strings 2018-10-29 13:12:01 -07:00
Michael Davidsaver
818fce324c Add PVStructure::stream() 2018-10-29 13:12:01 -07:00
Michael Davidsaver
1bc867e48d update travis-ci 2018-10-29 13:12:01 -07:00
Michael Davidsaver
434b9f7a9f Timer: simply wakeup condition 2018-10-19 13:35:35 -07:00
Michael Davidsaver
f54602dead update doc 2018-10-18 16:43:56 -07:00
Michael Davidsaver
fb546b41c1 rename documentation/*.h -> .dox 2018-10-18 16:43:56 -07:00
Michael Davidsaver
e400d9f5fd Timer reschedule if earlier timer added 2018-10-18 14:44:51 -07:00
Michael Davidsaver
f0fa8a2481 deprecate pvCopy.h 2018-10-16 20:52:50 -07:00
Michael Davidsaver
c3b0b49e3f use FieldBuilder::begin() and Field::build() 2018-10-16 20:52:38 -07:00
Michael Davidsaver
45265b4f9b Add FieldBuilder::begin() and Field::build()
Boilerplate reduction in structure
definition and instanciation.
2018-10-16 20:52:24 -07:00
Michael Davidsaver
aa87a2a23d json print/parse updates
These functions don't create new refs,
so they don't really need to work with shared_ptr.

Fully support printing.

Add option for maskable PVStructure printing.
2018-09-21 10:28:37 -07:00
Michael Davidsaver
5a59b1da75 Status avoid extra copies 2018-09-21 10:28:37 -07:00
Michael Davidsaver
32aa0dd72f drop extractRequestMask()
superceded by PVRequestMapper
2018-09-21 10:27:43 -07:00
mdavidsaver
c1188b16a1 Merge pull request #56 from mdavidsaver/pvrequestmapper
add PVRequestMapper
2018-09-21 10:27:08 -07:00
Michael Davidsaver
a02a60c658 Field::m_hash friends
Avoid additional access of m_hash by FieldCreate::Helper
which has an unclear (though I think correct) friend
relationship with Field.

Attempt to placate old gcc 3.4.4
2018-09-19 11:04:02 -07:00
c5f9f5a2dc link with rt when using clock_gettime() 2018-09-19 10:49:14 -07:00
Michael Davidsaver
342b1bc8ef add PVRequestMapper
utility to having pvRequest .field mangling

Warn if requesting some non-existant fields.
Error if no requested fields exist.

PVRequestMapper mode enum to select between
two "styles" of interpretation.
2018-09-17 09:11:28 -07:00
Michael Davidsaver
64158376f5 PVStructure inline access to member variables 2018-07-31 16:55:15 -07:00
Michael Davidsaver
850d4ff056 PVField::copyUnchecked assert()
Field comparison is now O(0), so do this anyway
to help catch mistakes.
2018-07-31 16:55:15 -07:00
Michael Davidsaver
f0cfe1c85a PVField::copy() avoid duplication with copyUnchecked() 2018-07-31 16:55:15 -07:00
Michael Davidsaver
c8b615b3ee Field initialize m_hash
valgrind complain (rightly) about use of uninitialized
if Structure ctor throws (eg. duplicate field).
~Field will then try to use m_hash before it has been
initialized.  This don't hurt and the subsequent equality
tests prevent any bad behavior.
2018-07-30 14:50:19 -07:00
Michael Davidsaver
c67fdafb43 add pvRequest -> bitmask processing 2018-07-14 15:10:46 -07:00
Michael Davidsaver
f66d277918 msvc 9 compat 2018-07-12 19:05:12 -07:00
Michael Davidsaver
4ef7db20f8 sharePtr.h: adjust apply/llvm compatibility 2018-07-12 15:38:49 -07:00
Michael Davidsaver
e1216dfa76 move PVValueArray dtor out of line
This class has out of line members, and explicit
instanciations.  Move the dtor out of line as
well to maybe avoid emitting duplicate
typeinfo.
2018-07-12 15:38:49 -07:00
Michael Davidsaver
340fa8a7cb Thread accept non-copyable std::function 2018-07-11 16:30:05 -07:00
Michael Davidsaver
a029455466 Thread reftrack 2018-07-11 16:30:04 -07:00
Michael Davidsaver
27f78c430b move Thread out of line 2018-07-11 16:29:50 -07:00
Michael Davidsaver
3d707e5e95 Field de-duplication performance test 2018-07-06 12:01:15 -07:00
Michael Davidsaver
0406a2f614 Field de-duplication
add a global cache of Field instances to
allow O(0) comparison of types.
2018-07-06 12:01:14 -07:00
Michael Davidsaver
a1c0e432ee fix Timer
use after free
2018-06-19 16:32:39 -07:00
Michael Davidsaver
57e57d9e43 de-virtualize PVValueArray<T> methods append(), remove(), and compress()
These were never members of a common base class,
nor overridden by a sub-class.
2018-06-07 09:53:38 -07:00
Michael Davidsaver
e4e4188eaf some more FINAL 2018-06-07 09:53:38 -07:00
Michael Davidsaver
f1553cc90e Move NOMINMAX to configure/CONFIG_SITE
The macro must be defined before MS system headers are
included.

This rev. remove #define NOMINMAX from public headers,
but no public headers use min()/max() and this was
never the correct way to use this macro as by convention
library headers are included after system headers,
which is too late to have an effect.
2018-05-28 11:24:49 -07:00
Michael Davidsaver
997e68c99a remove usage of min()/max() from public headers
Avoids need for #define NOMINMAX w/ MSVC
2018-05-28 10:14:03 -07:00
Michael Davidsaver
25663d9a7b additional EPICS_NOT_COPYABLE
attempt to pacify, or at least clarify, msvc
link error.
2018-05-21 21:02:32 -07:00
Michael Davidsaver
1e55266396 pvUnitTest.h avoid unintended copies
template argument matching doesn't always preserve
rvalue references, so force use of const ref.
2018-05-21 11:21:01 -07:00
Michael Davidsaver
810ae15991 printer.cpp avoid alloc of spaces
No need to allocate a std::string
just to repeat spaces.
2018-05-21 11:21:01 -07:00
Michael Davidsaver
271fec7f5e printer.cpp: clean whitespace 2018-05-21 11:21:01 -07:00
Michael Davidsaver
c43486791e prevent Field/PVField from being copied
I don't think this was ever intended to be possible,
but it was...
2018-05-21 11:19:42 -07:00
Michael Davidsaver
499c03265f update release notes 2018-04-24 13:30:15 -07:00
Michael Davidsaver
7eaa613d4d try to fix dllimport error 2018-04-17 21:13:22 -07:00
Michael Davidsaver
19db72031c shared_vector add missing void swap
swap() of void and const void misses vtype
2018-04-13 12:40:22 -07:00
Michael Davidsaver
671f9cca4b anyscalar.h: move out of line
No reason to believe that inline was helping.
2018-04-08 15:53:21 -07:00
Michael Davidsaver
9ecdb80534 anyscalar.h: remove unnecesary vcast
what was I thinking...
2018-04-08 15:53:21 -07:00
Michael Davidsaver
e973422ee1 anyscalar.h: add ctor from type code and void*
also helper bufferUnsafe() to get storage pointer
or c_str().
2018-04-08 15:53:21 -07:00
Michael Davidsaver
8093c25b72 typeCast.h: allow cast from C string to numeric w/o copy
also re-enable compile test of string to int64 which
was disabled for some reason...
2018-04-08 15:53:21 -07:00
Michael Davidsaver
a7c9c620dd Timer avoid deadlock in timerStopped()
No code actually uses this hook, but lets make
sure nothing bad would happen.
2018-04-08 15:53:21 -07:00
Michael Davidsaver
1e1d94ed73 rework Timer
I'm not sure how I broke it, but I know I don't have the patience
to fix it.  So replacing intrusive list and custom sorting with
std::list and std::list::merge().
2018-04-04 21:03:11 -07:00
Michael Davidsaver
7b8ef390ce add Timer::close()
An aid to orderly shutdown
2018-04-02 15:54:48 -07:00
Michael Davidsaver
87ade13234 Timer cleanup and hide run() 2018-04-02 15:54:48 -07:00
Michael Davidsaver
32abde7f19 redo Timer to avoid data race
run() was accessing this->head w/o locking
2018-04-02 10:54:49 -07:00
Michael Davidsaver
fe413af177 timerTest: redo to avoid time related false positives 2018-04-02 09:34:15 -07:00
Michael Davidsaver
b4cd026fe5 byteBuffer cleanup 2018-03-23 10:05:31 -07:00
Michael Davidsaver
a51b308cc8 ByteBuffer avoid PPC alignment fault 2018-03-19 15:26:40 -07:00
Michael Davidsaver
1c09b42951 ByteBuffer change order of tests for optimized byte swap
Check __clang__ before __GNUC__ as clang
also identifies itself as gcc for compatibility.
2018-03-19 15:26:35 -07:00
Michael Davidsaver
e42bb46563 ByteBuffer collapse some trivial indirection 2018-03-19 15:26:35 -07:00
Michael Davidsaver
a7788f9847 remove rtemsConfig.c
no longer needed.
2018-03-19 09:11:37 -07:00
Michael Davidsaver
b597364419 simpler test harness main() 2018-03-13 18:44:54 -07:00
Andrew Johnson
a9a951d970 Move epicsExit() call into pvDataAllTests()
Needed on VxWorks to display the test summary.
2018-03-13 12:24:59 -05:00
Andrew Johnson
6ac879ec6a Rename vxTestHarness -> pvdTestHarness
Integrate with Michael's similar changes for RTEMS.
2018-03-13 12:24:00 -05:00
Michael Davidsaver
2422ef50b6 rename rtemsTestHarness -> pvdTestHarness
avoid name clash with rtemsTestHarness
from pvAccessCPP
2018-03-12 09:11:44 -07:00
Michael Davidsaver
06dbf96b65 missing test count 2018-03-12 09:11:44 -07:00
Michael Davidsaver
172046e78f Add AnyScalar::clear() 2018-02-21 11:17:49 -08:00
Michael Davidsaver
7e8c49f0a0 don't use shared_ptr::get() for null test
unnecesarily verbose
2018-02-21 11:17:49 -08:00
Michael Davidsaver
f2ad6292f5 cleanup 2018-02-06 13:12:06 -08:00
Michael Davidsaver
337e13b72e pvIntrospect.h mark OVERRIDE/FINAL 2018-02-06 10:12:38 -08:00
Michael Davidsaver
2ab2fc62dc move FINAL/OVERRIDE defs to pvIntrospect.h 2018-02-06 10:12:38 -08:00
Michael Davidsaver
786575c3de a little bit of cleanup and minor opt 2018-02-06 10:02:08 -08:00
Michael Davidsaver
4cca194000 drop *HashFunction
not really implemented
2018-02-06 10:02:08 -08:00
Michael Davidsaver
cd3ead0028 testThread drop dead code 2018-01-05 11:14:59 -08:00
Michael Davidsaver
a239b95ca1 remove previously deprecated executor.h, queue.h and timerFunction.h 2018-01-05 11:14:59 -08:00
Michael Davidsaver
09574c0e82 sharedVector more c++11
support std::move() and construct
from initializer list.
2018-01-05 11:14:59 -08:00
Michael Davidsaver
0b6b01ef83 shared_vector limit MSVC workaround
limit 207efca15c
to MSVC <= 2010.
2018-01-05 11:14:59 -08:00
Andrew Johnson
34145e459b Clean up compiler warnings. 2018-01-04 17:59:09 -06:00
Michael Davidsaver
207efca15c workaround for msvc pickyness
The MSVC STL implementation asserts that
pointer/itertors are not null, even
when they would not be dereferenced
(eg. empty input range).
2018-01-04 11:52:19 -08:00
Michael Davidsaver
3e25c2ea46 fix more printf specs 2018-01-04 11:52:19 -08:00
Michael Davidsaver
2046678caa drop emptyStringtring 2018-01-04 11:52:19 -08:00
Michael Davidsaver
cb7e4e858b clear some warnings 2018-01-04 11:52:19 -08:00
Michael Davidsaver
43ee4b9cb6 thread safe getFieldCreate() and getPVDataCreate()
Fully thread safe and ctor order safe on all targets
(not just c++11).  Never destroyed to avoid global
dtor order issues.
2017-12-28 11:52:47 -06:00
Michael Davidsaver
207c24a4fd deprecate LOCAL_STATIC_LOCK
This construct is fairly useless.
Doesn't prevent ctor ordering problems.
2017-12-28 11:52:47 -06:00
Michael Davidsaver
6465ab3b6d caseUnsafeV use switch instead of jump table
Change from jump table to switch.
reduces code size (~1k of 30k for rtems/mvme3100).
use indexed loop to help gcc vectorizer.

Helpfully won't fail to compile w/ gcc 4.1 (vxworks 6.6/6.7)
2017-12-28 11:52:47 -06:00
Ralph Lange
cf624bc679 jenkins-ci: fix/update CloudBees jobs 2017-12-19 09:08:27 +01:00
Andrew Johnson
df55a776c7 Update version number after tagging release 2017-12-14 18:28:03 -06:00
Andrew Johnson
07afe3887b Reset DEVELOPMENT_FLAG for 7.0.0 release 2017-12-14 18:27:26 -06:00
Andrew Johnson
25434ba84f Insert missing release note entries
Most of these changes were only committed on the release branch and
never pulled onto the master branch. Don't want to lose history.
2017-12-14 18:23:51 -06:00
Michael Davidsaver
9787dbd14f anyscalar.h ensure that storage really is large enough
correct failure on cygwin x86 where apparently
sizeof(double) > sizeof(std::string)
2017-12-11 21:08:59 -06:00
Michael Davidsaver
fd9081c80e minor 2017-12-11 21:08:59 -06:00
Michael Davidsaver
e79c49019d quiet warning 2017-12-11 21:08:59 -06:00
Michael Davidsaver
5bc081a3af skip unnecessary inclusion of localStaticLock.h 2017-12-11 21:08:59 -06:00
Andrew Johnson
5976eb5186 Include <top>/../RELEASE.<host>.local 2017-12-06 20:37:27 -06:00
Andrew Johnson
b194bc05b1 Unify .gitignore files 2017-11-30 12:03:33 -06:00
Andrew Johnson
18207fd79e Use 'make test-results' in travis-build script 2017-11-29 16:36:39 -06:00
Andrew Johnson
7c1e0a51eb Fixes needed for older VxWorks GCC 2017-11-29 16:35:22 -06:00
Ralph Lange
7196658166 jenkins: remove microbench option from CB build 2017-11-15 17:28:05 +01:00
Michael Davidsaver
187fe67ffa fixup debugPtr 2017-11-14 17:13:43 -06:00
Andrew Johnson
7136098c3c Suppress unnecessary deprecation warnings
Disable warnings when compiling the implementations of
deprecated classes and functions.

Removes the unused USAGE_DEPRECATED and USAGE_ERROR macros
from pvData.h which aren't visible outside of it anyway.
2017-11-07 22:19:56 -06:00
Andrew Johnson
7979238029 Let's make timeStamp constants actually const 2017-11-07 11:46:36 -06:00
Michael Davidsaver
fc38dff3b0 testPVData: clarify getSubField() by index on sub-struct 2017-11-07 08:18:12 -06:00
Michael Davidsaver
c590204cf9 add epics::auto_ptr<T> and epics::swap()
Avoid the flood of auto_ptr deprecation warnings
in the common cases of using auto_ptr
to automatically delete.
2017-11-06 12:30:40 -06:00
Michael Davidsaver
284e49c807 add EPICS_NOT_COPYABLE()
More localize (my preference), and avoids
warning spam with windows builds.
2017-11-06 11:29:59 -06:00
Michael Davidsaver
43fcd3d1e2 debugPtr use libCom instead of std::
cross-builds of mingw claim c++11 but don't have std::mutex
2017-11-05 14:49:45 -06:00
Michael Davidsaver
a9f2d7df40 reftrack: remove inline operator[]
Use of class static member 'zero'
in an inline'd method is causing DLL confusion
in dependent modules.
2017-11-02 10:08:07 -05:00
Michael Davidsaver
21a03d2b85 rename configure/CONFIG_PVDATA_VERSION 2017-11-01 11:20:14 -05:00
Michael Davidsaver
f123b8654a update ignore 2017-11-01 09:40:42 -05:00
Michael Davidsaver
51cbe538e8 handle yajl 2.1.0 API changes 2017-10-31 19:34:30 -05:00
Marty Kraimer
e247a2c4eb Merge pull request #48 from mrkraimer/master
pvAlarm, pvTimeStamp, pvControl, pvDisplay: only put to fields that h…
2017-10-17 14:52:54 -04:00
Michael Davidsaver
490b6684ac more createRequest tests 2017-10-17 10:15:00 -05:00
mrkraimer
6fdeadf171 pvAlarm, pvTimeStamp, pvControl, pvDisplay: only put to fields that have changed 2017-10-16 10:00:22 -04:00
Michael Davidsaver
a88d491012 win64 one more time, move explicit instantiations after all definitions. 2017-10-06 11:06:23 +02:00
Michael Davidsaver
fd34d68933 another win64 attempt, explicitly instanciate 2017-10-05 16:24:45 +02:00
Michael Davidsaver
215e3aab7b one more attempt to appease win64 2017-10-05 15:32:31 +02:00
Michael Davidsaver
cd4feb3bab install CONFIG_PVD 2017-10-05 14:02:05 +02:00
Michael Davidsaver
6b0af421dd another attempt to appease msvc win64 2017-10-05 11:24:23 +02:00
Michael Davidsaver
9aeb4f2a96 attempt to fix win64 linking error 2017-10-05 10:39:47 +02:00
Michael Davidsaver
9b1e789e62 PVUnion: get() const propagation, add guess(), and inline trival 2017-09-30 13:43:50 -05:00
Michael Davidsaver
406b163bcc factory methods avoid creating unnecessary temporaries
Avoid some ref. counter activity (still have global mutex...)
2017-09-30 11:09:52 -05:00
Michael Davidsaver
6f2cae95e1 PVField: getParent() const propagation and inline trival 2017-09-30 11:00:37 -05:00
Michael Davidsaver
594a29b2db add PVScalar::putFrom/getAs variants for AnyScalar 2017-09-30 10:04:31 -05:00
Michael Davidsaver
0d12464e30 add AnyScalar 2017-09-29 17:22:43 -05:00
Michael Davidsaver
ccd9ab70ee pvUnitTest.h const-ness 2017-09-29 16:12:01 -05:00
Michael Davidsaver
27f2f87e29 reftrack class Field 2017-09-29 15:30:50 -05:00
Michael Davidsaver
635eb9d36d Status: inline trival and add maximize() w/ shorthand operator |= 2017-09-29 13:37:20 -05:00
Ralph Lange
f3e7f9bb8f travis-ci: consolidate travis configuration 2017-09-28 15:10:49 +02:00
Ralph Lange
2f69665056 travis-ci: fix RTEMS/qemu builds 2017-09-22 16:10:21 +02:00
Michael Davidsaver
559f7bc1b7 travis-ci: remove non-functional RTEMS builds 2017-09-21 16:13:18 -05:00
Michael Davidsaver
693f00caf5 Merge remote-tracking branch 'origin/master'
* origin/master:
  ci: changes for EPICS 7 Base structure

# Conflicts:
#	.travis.yml
2017-09-21 15:07:21 -05:00
Michael Davidsaver
822173979c FieldBuilder::add() ignore exact duplicates 2017-09-21 13:41:11 -05:00
Michael Davidsaver
9bce66f307 FieldBuilder edit union/structureArray/unionArray
Allow appending fields to existing types
to allow structure-like types
2017-09-21 13:41:11 -05:00
Michael Davidsaver
7a71e758b1 pvUnitTest.h multi-line prints 2017-09-21 13:41:11 -05:00
Michael Davidsaver
72fe0ca3e7 minor 2017-09-21 13:41:11 -05:00
Michael Davidsaver
fd0570f0c9 travis-ci fix c++11 builds 2017-09-21 13:41:11 -05:00
Ralph Lange
e0037a0c8b ci: changes for EPICS 7 Base structure 2017-09-21 16:14:02 +02:00
Michael Davidsaver
c7c83282ee parseJSON() more forgiving scalar array handling
Allow eg. to initialize array of integers with [1.0, 2.0]
2017-09-07 15:55:21 -05:00
Michael Davidsaver
8f98d9792b add typemap.h
helper for switch() over DBF or PVD scalar type codes
2017-09-07 15:53:40 -05:00
Michael Davidsaver
111f7bd15e parseJSON() track modified fields 2017-09-07 11:53:54 -05:00
Michael Davidsaver
787af8de18 BitSet building convenience
Allow set()/clear()/flip() to be chained.
Support c++11 initializer lists.
2017-09-07 11:49:07 -05:00
Michael Davidsaver
db6ebfe71b parseJSON() assign union with scalar value 2017-09-06 18:34:00 -05:00
Michael Davidsaver
1cb490039f remove another broken no-arg ctors 2017-08-30 17:55:04 -05:00
Michael Davidsaver
a152a64f1c RefSnapshot operator
move into class definition to hopefully appease MSVC
2017-08-30 17:04:02 -05:00
Michael Davidsaver
08f50e56ac win32 doesn't have ssize_t 2017-08-30 14:20:10 -05:00
Michael Davidsaver
9ae221ca0c apply reftrack to PVField 2017-08-30 11:13:10 -05:00
Michael Davidsaver
aca8da5891 remove broken no-arg ctors
Non-useful bypass of factory which leaves
private pointers undefined (eg. parent field).
2017-08-30 11:11:47 -05:00
Michael Davidsaver
34896560ea add reftrack.h
Add global Reference Counter tracker
2017-08-30 11:11:47 -05:00
Michael Davidsaver
3597fbe382 avoid unnecessary temp shared_ptr
avoid some extra ref. counter operations.
2017-08-16 17:49:17 +02:00
Michael Davidsaver
0b262baf97 fix getSubField() by index 2017-08-16 16:29:06 +02:00
Michael Davidsaver
78b51ebe59 c++98 compatible, but still reduced, number of getSubField() specializations 2017-08-16 11:22:42 +02:00
Michael Davidsaver
08a92468fe PVStructure::getSubField() const propagation 2017-08-15 18:35:54 +02:00
Michael Davidsaver
b84ed964f9 reduce # of PVStructure::getSubField overloads 2017-08-15 18:35:54 +02:00
Michael Davidsaver
8bfe7b6b9d debugPtr compat
Fails for newer RTEMS w/ c++11 but no backtrace()
2017-08-15 18:35:54 +02:00
Michael Davidsaver
dbae173399 don't import/export inline classes 2017-07-18 14:32:42 +02:00
Michael Davidsaver
4d4dbcda4d expose const void* form of PVScalar::putFrom() 2017-07-18 14:28:11 +02:00
Michael Davidsaver
fd4584a49d resolve ambiguity 2017-07-18 11:12:44 +02:00
Michael Davidsaver
ceb9f795cb whitespace: quiet gcc6 indentation warning 2017-07-17 16:25:00 +02:00
Michael Davidsaver
443c254d46 no C99 initializers
because MSVC doesn't support this...
2017-07-17 15:58:04 +02:00
Michael Davidsaver
87fa150ced 3.14 compat 2017-07-13 19:14:52 +02:00
Michael Davidsaver
4cfdb8233f more import/export 2017-07-13 18:49:32 +02:00
Michael Davidsaver
5e42cf76eb import/export fix 2017-07-13 18:35:38 +02:00
Michael Davidsaver
dccf6193da more doc 2017-07-13 18:25:25 +02:00
Michael Davidsaver
ee4fdf3f39 json print/parse from/to PVStructure 2017-07-13 18:02:10 +02:00
Michael Davidsaver
918b7f96db valueBuilder: support scalar array fields 2017-07-12 18:33:20 +02:00
Michael Davidsaver
ef55345665 pvUnitTest: compare array fields 2017-07-12 18:26:43 +02:00
Michael Davidsaver
0a41dbb443 ScalarTypeFunc::allocArray missing export 2017-07-12 15:46:01 +02:00
Michael Davidsaver
934ad32e52 debugPtr import/export 2017-07-12 15:29:34 +02:00
Michael Davidsaver
b582f0f880 createRequest clean message before each run 2017-07-12 15:28:09 +02:00
Michael Davidsaver
face3de44a more doc 2017-07-12 14:29:31 +02:00
Michael Davidsaver
8a7b9d776f requester.h moves to pvAccessCPP 2017-07-12 13:13:44 +02:00
Michael Davidsaver
a8c5d1095d remove MessageQueue 2017-07-12 13:07:36 +02:00
Michael Davidsaver
9fa5028f6c PVStructure::getStructure() avoid creation of temporary
avoid some ref-counter activity
2017-07-07 14:39:25 +02:00
Michael Davidsaver
0de3c089d2 testByteBuffer always test both byte orders 2017-07-07 11:21:00 +02:00
Michael Davidsaver
919bc0138a add pvUnitTest.h 2017-07-06 17:05:30 +02:00
Michael Davidsaver
a0210af5c6 remove unnecessary 'typename' 2017-07-06 13:23:24 +02:00
Michael Davidsaver
888291db9a move destroyable.h to pvAccessCPP 2017-07-05 11:59:22 +02:00
Michael Davidsaver
4fce663795 travis-ci 2017-07-04 15:54:29 +02:00
Michael Davidsaver
fc3384fb95 remove raw html in favor of generated
reformat release notes.
2017-07-04 15:33:43 +02:00
Michael Davidsaver
f9a30ca08e update doc 2017-07-04 15:08:01 +02:00
Michael Davidsaver
cbbe691f70 ValueBuilder dllexport 2017-07-04 12:22:04 +02:00
Michael Davidsaver
afbf0809c3 more travis-ci 2017-07-03 18:36:59 +02:00
Michael Davidsaver
db8d4b4347 fix # of tests 2017-07-03 18:35:57 +02:00
Michael Davidsaver
904ee7dfec travis-ci test mingw/win32 dll/static builds 2017-07-03 18:21:10 +02:00
Michael Davidsaver
bef616632c add ValueBuilder 2017-07-03 17:34:38 +02:00
Michael Davidsaver
1d2e5d182e oops 2017-06-26 19:26:59 +02:00
Michael Davidsaver
568ee1fa85 add debugPtr.h to troubleshoot shared_ptr problems
A wrapper around shared_ptr which tracks backwards references
to help untangle complicated ownership situations (aka. ref loop
waiting to happen).
2017-06-26 15:59:45 +02:00
Michael Davidsaver
66633a7728 test cleanup
remove compile time "debug" flag from from tests.
use testDiag() instead
2017-06-26 15:16:43 +02:00
Michael Davidsaver
18283b44b2 more sharedPtr 2017-06-19 14:15:06 +02:00
Michael Davidsaver
278696b28e more sharedPtr compat 2017-06-15 18:23:20 +02:00
Michael Davidsaver
26efd09d45 doxygen 2017-06-14 17:06:38 +02:00
Michael Davidsaver
ec9aba79ae fix warning about missing override w/ c++11 2017-06-14 16:21:51 +02:00
Michael Davidsaver
07e42d81f4 travis-ci 2017-06-14 14:20:44 +02:00
Michael Davidsaver
d272afc128 fixup sharedPtr 2017-06-14 13:59:02 +02:00
Michael Davidsaver
6cf9fa2208 fix "hides overloaded virtual function" warning 2017-06-14 13:22:06 +02:00
Michael Davidsaver
a72451cdbe Add Destroyable::cleaner to help w/ shared_ptr<> wrapping 2017-06-06 18:38:55 +02:00
Michael Davidsaver
e82489b158 Timer: actually join thread 2017-06-02 11:03:46 +02:00
Michael Davidsaver
e4c7fa6a1c move monitor.h to pvAccessCPP 2017-05-24 17:45:41 -04:00
Michael Davidsaver
48ed24dabf remove no-op monitor.cpp 2017-05-24 16:33:16 -04:00
Michael Davidsaver
9ef060a2f2 remove deprecated monitorPlugin.h 2017-05-24 16:31:26 -04:00
Michael Davidsaver
255c41607f remove deprecated monitorPlugin.h 2017-05-24 16:06:00 -04:00
Michael Davidsaver
22da026888 deprecate unused Queue, MessageQueue, Executor, and TimeFunction 2017-05-15 15:12:28 -04:00
Michael Davidsaver
def0a63008 Queue remove nullElement
avoid potential 0=1 situation.
2017-05-15 14:53:54 -04:00
Michael Davidsaver
6e62e123e8 FieldBuilder allow append to Structure
Helpful to allow a new definition to be created
as an extension of an existing definition.
2017-05-15 12:46:32 -04:00
Michael Davidsaver
262df56024 testFieldBuilder: cleanup 2017-05-12 14:26:18 -04:00
Michael Davidsaver
81cdf071a8 FieldBuilder detect duplicate field names 2017-05-12 13:24:37 -04:00
Michael Davidsaver
c5ce75888e Merge remote-tracking branch 'md/overhaulbytebuf'
* md/overhaulbytebuf:
  overhaul byteBuffer implementation
2017-05-10 15:36:49 -04:00
Michael Davidsaver
fb232896a8 avoid unnecessary globals 2017-05-10 15:00:55 -04:00
Michael Davidsaver
5efa462f19 add c++11 override/final 2017-05-10 15:00:55 -04:00
Michael Davidsaver
225f3ab125 Remove hidden sub-class
collapse Base* and Default* classes
into parents.
2017-05-10 15:00:55 -04:00
Michael Davidsaver
664fbfeb6e pvCopy: remove unnecessary globals 2017-05-07 20:17:26 -04:00
Michael Davidsaver
66f8ca0501 simpler createRequest()
A single function which throws exceptions on error
2017-05-07 20:07:01 -04:00
Michael Davidsaver
e977d63f08 add pvdVersion.h 2017-04-15 17:26:18 -04:00
Michael Davidsaver
08fc3cab38 update testPVUnion 2017-04-15 16:19:23 -04:00
Michael Davidsaver
a01885536c PVUnion fixups
select(int32)

throw for variant w/ other than UNDEFINED_INDEX.
Now same behavior for variant and discriminating,
which is to clear contents.
Fix selector range check.

set(int32)

Fix set(UNDEFINED_INDEX, NULL) for discriminating.
Fix selector range check.
2017-04-15 16:19:23 -04:00
Michael Davidsaver
f7343674ee make PVUnion::UNDEFINED_INDEX const 2017-04-15 16:19:23 -04:00
Michael Davidsaver
fc2adf98ba Status: add helpers
so that

epics::pvData::Status(epics::pvData::Status::STATUSTYPE_WARNING, msg)

can become

epics::pvData::Status::warn(msg)
2017-04-15 16:19:23 -04:00
Michael Davidsaver
a3c57a5077 bitSet: add logical_and()/_or()
Basic logical operations for tests
where a temporary can be avoided.
2017-04-15 16:19:15 -04:00
Michael Davidsaver
28b5dd0163 shared_ptr: further simplify static_shared_vector<>() 2017-04-15 16:06:01 -04:00
Michael Davidsaver
c0b69e4e6f add monitor buffer statistics
to help answer the question of why no monitorEvent()s
are happening.
2017-04-15 16:05:26 -04:00
Michael Davidsaver
a9111d78d3 overhaul byteBuffer implementation
align(n) now fills skipped bytes with '\0'.

align(n,f) to choose a different fill value.

No other changes intended

Use intrinsic byte order swapping builtins for gcc, clang, and msvc.

use assert() to check pre/post conditions.

Remove unused condition macros and unreachable code.

Add tests of byte swapping primitives and
test the correctness of unaligned operations.

add illustrations of flip() and rewind()
2017-04-07 15:09:47 -04:00
Dave Hickin
cc91e22038 testThread: Namespace qualify Thread
Fixes build error with latest RTEMS (Thread ambiguous).
2016-09-16 21:22:33 +01:00
Andrew Johnson
4555f69733 #include <algorithm> required for MSVS 2015 2016-09-14 16:23:32 -05:00
Michael Davidsaver
da8ba56dd1 testTypeCast: mangle values to be printable
print  (u)int8 as integer instead of character
2016-09-07 15:29:58 -04:00
Michael Davidsaver
4d6d5620b0 Revert "testTypeCast: Escape non-printing characters"
This reverts commit f7cad98f3e.
2016-09-07 15:28:48 -04:00
Dave Hickin
f7cad98f3e testTypeCast: Escape non-printing characters 2016-09-07 14:40:16 +01:00
Dave Hickin
d978c4c3bf Fix for MinGW
Fixes #42
2016-09-07 10:45:39 +01:00
Dave Hickin
1c4b7810b1 jenkins: Remove COPYRIGHT from tar 2016-07-22 16:07:35 +01:00
Dave Hickin
a6ec43f81c SHRLIB: Set version to 6.1 2016-07-22 16:05:32 +01:00
Dave Hickin
d258acfc49 SHRLIB: Set version to 6.0 2016-07-22 16:02:21 +01:00
Dave Hickin
d9072402db Update source boilerplate for new LICENSE file 2016-07-22 15:56:43 +01:00
Dave Hickin
1a706e3842 Remove COPYRIGHT file
Copyright is now in LICENSE file
2016-07-22 15:33:50 +01:00
Dave Hickin
a227897504 Update LICENSE to new version 2016-07-22 15:33:20 +01:00
Ralph Lange
0833d68e91 jenkins: fix installE4 logic, add pvCommon dependency 2016-07-22 14:59:48 +02:00
Dave Hickin
99bab6796c Fix windows dynamic build error
Fix error introduced by #40. #include epicsThread.h in timer.cpp
before #defining epicsExportSharedSymbols. Avoids multiply-defined
symbols.
2016-07-20 15:33:20 +01:00
dhickin
0544187057 Merge pull request #40 from anjohnson/master
Resolve github #37 without cacheing epicsExportSharedSymbols
2016-07-20 14:39:25 +01:00
Andrew Johnson
e12e7b4d76 Resolve github #37 without cacheing epicsExportSharedSymbols 2016-07-19 18:40:58 -05:00
Ralph Lange
7609ac6f1e jenkins: fix syntax in local declaration 2016-07-19 22:09:03 +02:00
Ralph Lange
3c946a91e8 jenkins: use install functions, add BRANCH variable to doc script 2016-07-19 22:00:34 +02:00
Ralph Lange
2389ebd87e jenkins: fix CloudBees jobs (paths) 2016-07-12 19:39:50 +02:00
Ralph Lange
90ad497a6f Use environment variables; default Base = 3.15.4; new artifact paths 2016-07-12 15:45:30 +02:00
Ralph Lange
1bb0b6fe03 Use environment variables; new default version of Base 2016-07-12 14:53:21 +02:00
dhickin
c16c1df6fd Merge pull request #39 from dhickin/use_template_getSubField
Replace template getSubField with template version
2016-07-05 15:19:58 +01:00
dhickin
e460641711 Merge pull request #38 from dhickin/getSubField_overload
Add char* overload for non-template getSubField
2016-07-05 15:18:46 +01:00
Dave Hickin
1e980651a9 Use template getSubField when type known
Replace non-template getSubField with template version when PVField is
of a known, derived type.
2016-07-04 17:03:07 +01:00
Dave Hickin
028076e79c Add char* overload for non-template getSubField 2016-07-04 14:59:56 +01:00
dhickin
e5b6a88551 Merge pull request #30 from mdavidsaver/requestermsg
Default implementation for Requester::message()
2016-04-12 16:01:45 +01:00
Andrew Johnson
b18b4f236f Make the PVScalarValue explicit specializations inline
Microsoft's compiler seems to prefer this when building a static library.
2016-04-11 17:16:43 -05:00
Andrew Johnson
605d4e99b9 Remove remaining 'undef epicsExportSharedSymbols' stuff 2016-04-11 15:24:46 -05:00
Andrew Johnson
ad00b6465a Fix VxWorks build, add explanatory comments 2016-04-11 11:33:05 -05:00
dhickin
537ebd05f2 Merge pull request #36 from anjohnson/master
Support for additional Windows targets
2016-04-11 10:06:54 +01:00
Andrew Johnson
2ee8769752 Prevent redefinition of NOMINMAX
While this protection is not strictly necessary here, if someone
does a cut-and-paste into a header file it should be included.
2016-04-06 15:29:30 -05:00
Andrew Johnson
8d7f534d54 VxWorks fix in parseToPOD.cpp 2016-03-28 17:11:25 -05:00
Andrew Johnson
47bb62b051 Disable another useless MSVC warning 2016-03-28 16:41:29 -05:00
Andrew Johnson
50b8213781 Fix NEED_OLL_FUNCS for windows-x64 and Base-3.15 2016-03-28 16:41:29 -05:00
Andrew Johnson
fd1fe53b49 Use the EPICS_DEPRECATED macro from Base.
Neither USAGE_DEPRECATED nor USAGE_ERROR are currently used
in the V4 code-base.
2016-03-28 16:41:28 -05:00
Andrew Johnson
378def0a58 Fix logic for when to define strtoll() and strtoull()
Needed for MinGW and VxWorks when built against Base-3.15
2016-03-28 16:41:28 -05:00
Andrew Johnson
ed5f48b353 EPICS sources use vxWorks for arch-detection 2016-03-28 16:41:28 -05:00
Andrew Johnson
fa6c2c7683 EPICS sources use _MINGW for arch-detection 2016-03-28 16:41:28 -05:00
Andrew Johnson
3fadc9b481 Remove unnecessary includes from epicsException.h
Fix up byteBuffer.h and epicsException.cpp to match.
2016-03-28 16:41:28 -05:00
Andrew Johnson
c3d7fa0d26 Declare explicit specializations
Resolves duplicate symbol build error on MinGW.
2016-03-28 16:41:28 -05:00
Andrew Johnson
5c16357fe2 Don't redefine NOMINMAX (clean up MinGW warnings) 2016-03-28 16:41:28 -05:00
Andrew Johnson
ef2e6079ba Wrap WIN32 #pragma warning(disable) inside push/pop
Exclude from MinGW, G++ doesn't understand these pragmas.
2016-03-28 16:41:28 -05:00
Dave Hickin
18633288fb Documentation: Remove maturity and date comment 2016-03-18 21:48:06 +00:00
Dave Hickin
67daef7bcc Documentation: Remove old versions 2016-03-18 21:43:09 +00:00
Dave Hickin
5eb29dcfc4 Documentation: Change to release-based versioning
Replace dated documentation scheme by one using release version.
2016-03-18 21:41:33 +00:00
Michael Davidsaver
d2fc922ee7 remove unnecessary const_cast 2016-03-18 14:53:24 -04:00
Michael Davidsaver
d35010c1cb Status: remove m_emptyStringtring
No reason to have a global for this.
2016-03-18 14:53:10 -04:00
dhickin
bd4b65225c Merge pull request #28 from mdavidsaver/overhaulbitset
bitSet: macros and vector storage
2016-03-17 14:20:20 +00:00
dhickin
be95a62965 Merge pull request #31 from mdavidsaver/deprecatemonitiorplugin
Deprecate monitorPlugin.h
2016-03-15 14:46:53 +00:00
dhickin
4336d524af Merge pull request #33 from msekoranja/master
Minor Win32 compilation fix
2016-03-07 12:02:03 +00:00
Matej Sekoranja
ae7976fc01 Merge remote-tracking branch 'epics-base/master' 2016-03-06 21:33:43 +01:00
Matej Sekoranja
72f9dc4c7c win32 compilation fix 2016-03-06 21:29:04 +01:00
dhickin
84760648fe Merge pull request #29 from mdavidsaver/fixsharedvector 2016-03-02 13:56:06 +00:00
Michael Davidsaver
b0df40d9a6 testSharedVector more PG locals 2016-03-01 13:25:20 -05:00
Michael Davidsaver
139217914d deprecate monitorPlugin.h 2016-02-26 12:17:12 -05:00
Michael Davidsaver
efa5795193 Default implementation for Requester::message()
This is what many sub-classes do (or should)
so lets prepare to remove some boilerplate.
2016-02-26 12:16:28 -05:00
Michael Davidsaver
4f499aed01 remove PVField::notImplemented
An unused waste of space in every instance...
2016-02-26 12:13:23 -05:00
Michael Davidsaver
a8ba831f5e fix freeze() of shared_vector<void> 2016-02-26 12:13:23 -05:00
Michael Davidsaver
a90405c25a shared_vector update doc 2016-02-26 12:13:23 -05:00
Michael Davidsaver
4546fda8e9 note shared_vector casts which should fail 2016-02-26 12:13:23 -05:00
Michael Davidsaver
b02f771146 shared_vector: vtype lost when freeze/thaw untyped
The vtype code is not copied for freeze/thaw
of shared_vector<void> to/from shared_vector<const void>.
2016-02-26 12:13:23 -05:00
Michael Davidsaver
dc94b26e50 fix static_shared_vector_cast<>() no-op casting
Turns out that Enablers as typically used for
member functions don't work to select
constructors.

Move this selection logic to
struct detail::static_shared_vector_caster<>
to correctly allow no-op casts (eg. void to void).
Previously this would not compile.

Allows PVScalarArray getAs() and putFrom() using
shared_vector<const void>.
2016-02-26 12:13:23 -05:00
Michael Davidsaver
4c32f37ede bitSet: macros and vector storage
use std::vector<uint64> to manage storage.
Make some global variable "constants" into macros.
add swap()
2016-02-18 18:39:32 -05:00
Dave Hickin
336a8b3bc2 Fix win32 deserialization test fail 2016-02-18 18:56:04 +00:00
Dave Hickin
faecea39c8 Merge branch 'master' of github.com:msekoranja/pvDataCPP 2016-02-18 15:35:36 +00:00
Michael Davidsaver
d08d5362be testBitSet: forgot to update test count 2016-02-17 10:53:32 -05:00
Michael Davidsaver
d4292d81f2 BitSet: truncation in or_and
For "this |= set1 & set2" the result size
should be "max(this, min(set1, set2))" while
at present it is "min(set1, set2)" resulting
in truncation if the LHS is longer than the
RHS.
2016-02-17 10:17:21 -05:00
Michael Davidsaver
62893e33e9 testBitSet: demo bug in BitSet::or_and
Incorrect handling of wordsInUse truncates if
RHS (b1 & b2) is shorter than LHS (b3).
2016-02-17 10:17:16 -05:00
Michael Davidsaver
5b07ecbd01 testBitSet more diag output 2016-02-17 10:17:04 -05:00
Ralph Lange
b5c1b9178d jenkins: switch to Base 3.15.3 2016-02-16 10:18:41 +01:00
Matej Sekoranja
65ff7ab1c3 fixed bitSet serialization 2016-02-12 19:35:44 +01:00
Dave Hickin
35fd991fdc Improve directSerialize/Deserialize() documentation
Add explanation of returned values and more description of the methods.
2016-02-11 10:51:43 +00:00
Michael Davidsaver
57e1acba79 add missing epicsShareFunc 2016-02-10 11:22:07 -05:00
Michael Davidsaver
620d351946 current_function.h not executable 2016-02-10 14:43:58 +00:00
Michael Davidsaver
de3c2656ef INC += pv/ 2016-02-10 14:40:29 +00:00
Michael Davidsaver
3b2e9b2485 move all headers to pv/ 2016-02-10 14:40:29 +00:00
dhickin
75a3005d74 Merge pull request #17 from mdavidsaver/sertovector
add serializeToVector()
2016-02-10 14:04:01 +00:00
Michael Davidsaver
448f606054 update comments 2016-02-09 19:17:39 -05:00
Michael Davidsaver
e35c6f29fb add deserializeFrom* helpers 2016-02-05 18:34:16 -05:00
Michael Davidsaver
85a1a48b00 add serializeToVector 2016-01-27 11:25:09 -05:00
dhickin
45427d3202 Merge pull request #21 from mdavidsaver/getfieldnull
getSubField -> getSubFieldT to avoid potential NULL de-ref.
2016-01-26 22:14:53 +00:00
Michael Davidsaver
93c7a05dac remove redundant getSubField 2016-01-25 13:15:15 -05:00
Michael Davidsaver
a34c38c9b9 getSubField -> getSubFieldT to avoid potential NULL de-ref. 2016-01-25 12:12:06 -05:00
Michael Davidsaver
3100b77a1a Merge remote-tracking branch 'origin/master'
* origin/master:
  missing buffer capacity check in PVUnion::serialize
  byteBuffer throw invalid_argument when ctor w/ NULL
  revert incorrect doc string
  byteBuffer check for alloc failure and const
  new Thread::Config
2016-01-25 12:05:32 -05:00
Michael Davidsaver
c8429069a3 SONAME in src/Makefile 2016-01-25 11:49:05 -05:00
Michael Davidsaver
01172217dc Merge remote-tracking branch 'md/threadconfig'
* md/threadconfig:
  new Thread::Config
2015-12-29 18:34:18 -05:00
Michael Davidsaver
14b0e409f2 missing buffer capacity check in PVUnion::serialize
Allows a buffer overflow in PVUnionArray::serialize().
2015-12-28 18:16:01 -05:00
Michael Davidsaver
2107bae8dd set SHRLIB_VERSION 2015-12-18 16:07:09 -05:00
Michael Davidsaver
433676226c byteBuffer throw invalid_argument when ctor w/ NULL 2015-12-17 16:45:56 -05:00
Michael Davidsaver
f0c88234a0 revert incorrect doc string 2015-12-15 10:26:31 -05:00
Michael Davidsaver
393d711e5f byteBuffer check for alloc failure and const
Ensure that bad_alloc is thrown if allocations fail, presently unchecked.

Also add const qualifier where possible.
2015-12-14 13:25:42 -05:00
Michael Davidsaver
cb24bd9c2c Merge remote-tracking branch 'md/validatefieldnames'
* md/validatefieldnames:
  fix testCreateRequest
  field names may not begin with a digit
  fail zero length field names
  validate field names
2015-11-30 20:55:16 -05:00
Michael Davidsaver
abc5c5a374 new Thread::Config 2015-11-23 15:21:21 -05:00
Michael Davidsaver
54c94f181a add global namespace so these macros work anywhere 2015-11-23 15:21:21 -05:00
Michael Davidsaver
6641e7f5d1 fix testCreateRequest
field names may not begin with a digit
2015-11-23 14:33:43 -05:00
Michael Davidsaver
f4a00f2b0f field names may not begin with a digit
Enforce C identifer syntax

[A-Za-z_][A-Za-z0-9_]*
2015-11-23 14:31:27 -05:00
Dave Hickin
05d41f81e4 Minor correction to README 2015-10-15 10:37:12 +01:00
Dave Hickin
fdc289d888 Add new README
Replace out of date HTML README with a new markdown one
2015-10-15 09:16:20 +01:00
Dave Hickin
0a2243e033 Update TODO 2015-10-15 07:46:40 +01:00
Dave Hickin
9d877d764f Doxgen fixes and enhancements
Change &param to @param. Add missing parameter.
Add more doxygen comments in SerializeHelper.
2015-10-15 07:12:42 +01:00
Dave Hickin
f5df29cf34 Doxygen: remove @code when code block not wanted
@code produces a separate code block, rather than just displaying
contents as code.

Mostly replaced use with @c tag when block not wanted.
2015-10-15 06:50:26 +01:00
Dave Hickin
8008823ea5 Fix doxygen warnings 2015-10-14 23:01:28 +01:00
Dave Hickin
6515de4bc0 Add release notes for 5.0 2015-10-08 15:24:14 +01:00
Ralph Lange
8c5f535b79 jenkins: fix CloudBees doc job 2015-09-28 15:29:39 +02:00
Michael Davidsaver
3714be4f16 fail zero length field names 2015-09-24 13:04:49 -04:00
Michael Davidsaver
f24f565e58 validate field names
check for invalid characters in field names (eg '.').

Restrict character set to ascii alpha numeric and '_'.
2015-09-23 15:32:46 -04:00
Ralph Lange
036186fc12 jenkins: adapt doc script to new CloudBees jenkins job 2015-09-14 16:48:15 +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
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
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
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
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
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
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
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
255 changed files with 33738 additions and 41252 deletions

94
.appveyor.yml Normal file
View File

@@ -0,0 +1,94 @@
# .appveyor.yml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
cache:
- C:\Users\appveyor\.tools
#---------------------------------#
# additional packages #
#---------------------------------#
install:
# for the sequencer
- cinst re2c
- cmd: git submodule update --init --recursive
#---------------------------------#
# repository cloning #
#---------------------------------#
init:
# Set autocrlf to make batch files work
- git config --global core.autocrlf true
clone_depth: 50
# Skipping commits affecting only specific files
skip_commits:
files:
- 'documentation/*'
- '**/*.md'
# Build Configurations: dll/static, regular/debug
configuration:
- dynamic
- static
- dynamic-debug
- static-debug
# Environment variables: compiler toolchain, base version, setup file, ...
environment:
# common / default variables for all jobs
SETUP_PATH: .ci-local
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMP: vs2019
BASE: 7.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMP: gcc
BASE: 7.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMP: vs2017
BASE: 7.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMP: vs2019
BASE: 3.15
# Platform: processor architecture
platform:
- x64
#---------------------------------#
# building & testing #
#---------------------------------#
build_script:
- cmd: python .ci/cue.py prepare
- cmd: python .ci/cue.py build
test_script:
- cmd: python .ci/cue.py test
on_finish:
- ps: Get-ChildItem *.tap -Recurse -Force | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
- cmd: python .ci/cue.py build test-results -s
#---------------------------------#
# debugging #
#---------------------------------#
## if you want to connect by remote desktop to a failed build, uncomment these lines
## note that you will need to connect within the usual build timeout limit (60 minutes)
## so you may want to adjust the build matrix above to just build the one of interest
#on_failure:
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
#---------------------------------#
# notifications #
#---------------------------------#
notifications:
- provider: GitHubPullRequest

1
.ci Submodule

Submodule .ci added at ad8dd4a136

6
.ci-local/defaults.set Normal file
View File

@@ -0,0 +1,6 @@
# EPICS Base
BASE_DIRNAME=base
BASE_REPONAME=epics-base
BASE_REPOOWNER=epics-base
BASE_VARNAME=EPICS_BASE
BASE_RECURSIVE=NO

153
.github/workflows/ci-scripts-build.yml vendored Normal file
View File

@@ -0,0 +1,153 @@
# .github/workflows/ci-scripts-build.yml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
# This is YAML - indentation levels are crucial
# Set the 'name:' properties to values that work for you (pvxs)
name: pvData
# Trigger on pushes and PRs to any branch
on:
push:
paths-ignore:
- .appveyor.yml
pull_request:
env:
SETUP_PATH: .ci-local:.ci
EPICS_TEST_IMPRECISE_TIMING: YES
jobs:
build-base:
name: ${{ matrix.base }}/${{ matrix.os }}/${{ matrix.cmp }}/${{ matrix.configuration }}/${{ matrix.wine }}${{ matrix.rtems }}/${{ matrix.extra }}
runs-on: ${{ matrix.os }}
# Set environment variables from matrix parameters
env:
BASE: ${{ matrix.base }}
CMP: ${{ matrix.cmp }}
BCFG: ${{ matrix.configuration }}
WINE: ${{ matrix.wine }}
RTEMS: ${{ matrix.rtems }}
EXTRA: ${{ matrix.extra }}
TEST: ${{ matrix.test }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
cmp: gcc
configuration: default
base: "7.0"
wine: "64"
- os: ubuntu-20.04
cmp: gcc
configuration: static
base: "7.0"
wine: "64"
- os: ubuntu-20.04
cmp: gcc
configuration: default
base: "3.15"
wine: "64"
- os: ubuntu-20.04
cmp: gcc
configuration: static
base: "7.0"
extra: "CMD_CXXFLAGS=-std=c++11"
- os: ubuntu-16.04
cmp: clang
configuration: default
base: "7.0"
- os: ubuntu-20.04
cmp: clang
configuration: default
base: "7.0"
extra: "CMD_CXXFLAGS=-std=c++11"
- os: ubuntu-20.04
cmp: gcc
configuration: default
base: "7.0"
rtems: "4.10"
- os: ubuntu-20.04
cmp: gcc
configuration: default
base: "7.0"
rtems: "4.9"
- os: ubuntu-16.04
cmp: gcc-4.8
utoolchain: true
configuration: default
base: "7.0"
- os: ubuntu-16.04
cmp: gcc-4.9
utoolchain: true
configuration: default
base: "7.0"
- os: ubuntu-20.04
cmp: gcc-8
utoolchain: true
configuration: default
base: "7.0"
- os: ubuntu-20.04
cmp: clang
configuration: default
base: "7.0"
- os: macos-latest
cmp: clang
configuration: default
base: "7.0"
- os: windows-2019
cmp: vs2019
configuration: default
base: "7.0"
- os: windows-2019
cmp: vs2019
configuration: static
base: "7.0"
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Cache Dependencies
uses: actions/cache@v2
with:
path: ~/.cache
key: ${{ matrix.base }}/${{ matrix.os }}/${{ matrix.cmp }}/${{ matrix.configuration }}/${{ matrix.wine }}${{ matrix.rtems }}/${{ matrix.extra }}
- name: Automatic core dump analysis
uses: mdavidsaver/ci-core-dumper@master
- name: "apt-get install"
run: |
sudo apt-get update
sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb
if: runner.os == 'Linux'
- name: "apt-get install ${{ matrix.cmp }}"
run: |
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y install ${{ matrix.cmp }}
if: matrix.utoolchain
- name: Prepare and compile dependencies
run: python .ci/cue.py prepare
- name: Build main module
run: python .ci/cue.py build
- name: Run main module tests
run: python .ci/cue.py test
- name: Collect and show test results
run: python .ci/cue.py test-results

17
.gitignore vendored Normal file
View File

@@ -0,0 +1,17 @@
/cfg/
/bin/
/lib/
/db/
/dbd/
/html/
/include/
/templates/
/configure/*.local
/configure/RELEASE.*
/configure/CONFIG_SITE.*
O.*/
/QtC-*
envPaths
*.orig
*.log
.*.swp

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule ".ci"]
path = .ci
url = https://github.com/epics-base/ci-scripts

View File

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

View File

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

17
.readthedocs.yml Normal file
View File

@@ -0,0 +1,17 @@
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the documentation/ directory with Sphinx
sphinx:
configuration: documentation/conf.py
# Build documentation with MkDocs
#mkdocs:
# configuration: mkdocs.yml
# Optionally build your docs in additional formats such as PDF and ePub
formats: all

View File

@@ -1,12 +0,0 @@
/****************************************************
Copyright (c) 2008 All rights reserved
Copyright (c) 2008 Martin R. Kraimer
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
National Laboratory.
Deutsches Elektronen-Synchroton, Member of the Helmholtz Association,
(DESY), HAMBURG, GERMANY,
BERLINER SPEICHERRING GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H.
(BESSY), BERLIN, GERMANY.
COSYLAB (Control System Laboratory)
(Cosylab) Ljubljana Slovenia
*************************************************** */

2573
Doxyfile

File diff suppressed because it is too large Load Diff

77
LICENSE
View File

@@ -1,12 +1,17 @@
Copyright and License Terms
---------------------------
Copyright (c) 2008 Martin R. Kraimer
Copyright (c) 2006 The University of Chicago, as Operator of Argonne
Copyright (c) 2006-2016 Martin R. Kraimer
Copyright (c) 2006-2016 UChicago Argonne LLC, as Operator of Argonne
National Laboratory.
Copyright (c) 2006 Deutsches Elektronen-Synchroton,
Copyright (c) 2006 Deutsches Elektronen-Synchrotron,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
Copyright (c) 2007 Control System Laboratory,
Copyright (c) 2007-2016 Control System Laboratory,
(COSYLAB) Ljubljana Slovenia
Copyright (c) 2010-2016 Brookhaven Science Associates, as Operator
of Brookhaven National Laboratory
Copyright (c) 2011-2016 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
@@ -31,48 +36,30 @@ OTHER DEALINGS IN THE SOFTWARE.
________________________________________________________________________
This software is in part copyrighted by the University of Chicago (UofC)
Additional Disclaimers
----------------------
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.
This software is copyright in part by these institutions:
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.
* Brookhaven Science Associates, as Operator of Brookhaven
National Laboratory, New York, USA
* Control System Laboratory, Ljubljana, Slovenia
* Deutsches Elektronen-Synchroton, Member of the Helmholtz
Association, Hamburg, Germany
* Diamond Light Source Limited, Didcot, United Kingdom
* Helmholtz-Zentrum Berlin fuer Materialien und Energie m.b.H.,
Berlin, Germany.
* UChicage Argonne LLC, as Operator of Argonne National Laboratory,
Illinois, USA
________________________________________________________________________
In no event shall these institutions 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 advised of the possibility of such damage.
This software is in part copyrighted by the BERLINER SPEICHERRING
GESELLSCHAFT FUER SYNCHROTRONSTRAHLUNG M.B.H. (BESSY), BERLIN, GERMANY.
These institutions 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 these institutions have no obligation to provide
maintenance, support, updates, enhancements, or modifications.
In no event shall BESSY be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
BESSY has been advised of the possibility of such damage.
BESSY specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and BESSY has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________
This software is in part copyrighted by the Deutsches Elektronen-Synchroton,
Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
In no event shall DESY be liable to any party for direct, indirect,
special, incidental, or consequential damages arising out of the use of
this software, its documentation, or any derivatives thereof, even if
DESY has been advised of the possibility of such damage.
DESY specifically disclaims any warranties, including, but not limited
to, the implied warranties of merchantability, fitness for a particular
purpose, and non-infringement. This software is provided on an "as is"
basis, and DESY has no obligation to provide maintenance, support,
updates, enhancements, or modifications.
________________________________________________________________________

View File

@@ -1,12 +1,17 @@
#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
DIRS += examples
examples_DEPEND_DIRS = src
include $(TOP)/configure/RULES_TOP

View File

@@ -1,82 +0,0 @@
<?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 pvData C++</title>
</head>
<body>
<h1 style="text-align: center">EPICS pvData C++<br />
Overview<br />
2010.08.10</h1>
CONTENTS
<hr />
<h2 style="text-align: center">Introduction</h2>
<hr />
<p>This project has the begining of the C++ implementation of pvData. The
following is done:</p>
<dl>
<dt>introspection interfaces</dt>
<dd>The introspection interfaces for clients are described.</dd>
<dt>introspection implementation</dt>
<dd>The following have been implemented: Type, ScalarType, Field,
Scalar</dd>
<dt>test</dt>
<dd>A test of Scalar.</dd>
<dt>As mentioned below there are problems with the current
implementation.</dt>
</dl>
<hr />
<h2 style="text-align: center">Building</h2>
<hr />
<p>The project is structured as an epics base client application. Edit
configure/RELEASE so that it references your EPICS base and then just
type:</p>
<pre> make</pre>
<p>At the top. Then execute the test in the bin directory.</p>
<p>pvDataApp has the following sub directories:</p>
<dl>
<dt>pv</dt>
<dd>pvData.h has the interface descriptions for client code.</dd>
<dt>factory</dt>
<dd>FieldCreateFactory.cpp has the current implementation</dd>
<dt>test</dt>
<dd>Has a test for the current implementation.</dd>
</dl>
<hr />
<h2 style="text-align: center">Questions about Classes</h2>
<hr />
<p>The pure virtual classes defined in pvData.h now work. But there are still
some things that are not so nice. Amoung these are:</p>
<ul>
<li>In FieldCreateFactory.cpp look for "WHY DO I". It asks why the derived
class must also define methods defined in the base class. If it does not
then a compilation error occurs. WHY??? </li>
<li>The toString methods have an argument of "std::string &amp;buf" instead
of "std::string *". Does this seem correct?</li>
<li>Can arguments and return descriptions be defined better?</li>
<li>Is const present everywhere it should be? Remember that introspection
classes are immutable.</li>
<li>The code is NOT thread safe. When we decide for sure what thread/lock
support to choose I will fix this.</li>
</ul>
<p>HELP WILL BE GREATLY APPRECIATED. because I am still coming up to speed
with c++</p>
<hr />
<h2 style="text-align: center">Garbage Collection</h2>
<hr />
<p>Not yet implemented. Lets get class structure correct first.</p>
</body>
</html>

16
README.md Normal file
View File

@@ -0,0 +1,16 @@
# pvaDataCPP
The EPICS **pvData** API provides a set of classes and utilities that form the core of the EPICS PVA implementation.
The pvDataCPP module is a part of the EPICS software toolkit that implements pvData structures as C++ class objects.
## Links
- General information about EPICS can be found at the
[EPICS Controls website](https://epics-controls.org).
- API documentation for this module can be found on its
[Github Pages website](https://epics-base.github.io/pvDataCPP/).
## Building
This module is included as a submodule of a full EPICS 7 release and will be compiled during builds of that software.

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

@@ -0,0 +1,12 @@
# Version number for the PV Data API and shared library
EPICS_PVD_MAJOR_VERSION = 8
EPICS_PVD_MINOR_VERSION = 0
EPICS_PVD_MAINTENANCE_VERSION = 4
# Development flag, set to zero for release versions
EPICS_PVD_DEVELOPMENT_FLAG = 0
# Immediately after a release the MAINTENANCE_VERSION
# will be incremented and the DEVELOPMENT_FLAG set to 1

View File

@@ -1,36 +1,35 @@
# 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>
USR_CPPFLAGS += -DPVD_INTERNAL
ifeq ($(EPICS_TEST_COVERAGE),1)
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local
# MSVC - skip defining min()/max() macros
USR_CPPFLAGS_WIN32 += -DNOMINMAX
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
-include $(TOP)/../CONFIG.local

View File

@@ -2,13 +2,7 @@ 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
CFG += CONFIG_PVDATA_VERSION
TARGETS = $(CONFIG_TARGETS)
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))

View File

@@ -1,25 +1,38 @@
# pvDataCPP RELEASE - Location of external support modules
# RELEASE - Location of external support modules
#
# IF YOU CHANGE this file or any file it includes you must
# subsequently do a "gnumake rebuild" in the application's
# top level directory.
# IF YOU CHANGE ANY PATHS in this file or make API changes to
# any modules it refers to, you should do a "make rebuild" in
# this application's top level directory.
#
# 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.
# The EPICS build process does not check dependencies against
# any files from outside the application, so it is safest to
# rebuild it completely if any modules it depends on change.
#
# 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)
# EPICS V4 Developers: Do not edit the locations in this file!
#
# Create a file RELEASE.local pointing to your EPICS_BASE
# and PVCOMMON build directories, e.g.
# EPICS_BASE = /home/install/epics/base
# PVCOMMON = /home/install/epicsV4/pvCommonCPP
# This file is parsed by both GNUmake and an EPICS Perl script,
# so it may ONLY contain definititions of paths to other support
# modules, variable definitions that are used in module paths,
# and include statements that pull in other RELEASE files.
# Variables may be used before their values have been set.
# Build variables that are NOT used in paths should be set in
# the CONFIG_SITE file.
-include $(TOP)/configure/RELEASE.local
# Variables and paths to dependent modules:
#MODULES = /path/to/modules
#MYMODULE = $(MODULES)/my-module
# If building the EPICS modules individually, set these:
#EPICS_BASE = /path/to/base
# Set RULES here if you want to use build rules from elsewhere:
#RULES = $(MODULES)/build-rules
# These allow developers to override the RELEASE variable settings
# without having to modify the configure/RELEASE file itself.
-include $(TOP)/../RELEASE.local
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
-include $(TOP)/configure/RELEASE.local

3
documentation/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.tag
*.db
html/

2367
documentation/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

16
documentation/Makefile Normal file
View File

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

14
documentation/TODO.md Normal file
View File

@@ -0,0 +1,14 @@
TODO
===========
doxygen
-------
There is a lot of public code that does not have doxygen tags.
valueAlarm
---------
normativeTypes.html describes valueAlarm only for a value field that has type
double.
The implementation also supports all the numeric scalar types.

View File

@@ -0,0 +1,7 @@
.wy-side-nav-search {
background-color: #18334B;
}
.wy-side-nav-search input[type="text"] {
border-color: #18334b;
}

45
documentation/commit-gh.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/sh
set -e -x
# Usage: commit-gh <sub-directory-prefix> <files...>
#
# Creates a commit containing only the files in the sub-directory provided as an argument
#
# Does not disturb the working copy or index
prefix="$1"
shift
# Commit to this branch
BRANCH=refs/heads/gh-pages
# Use the main branch description as the gh-pages commit message
MSG=`git describe --tags --always`
# Scratch space
TDIR=`mktemp -d -p $PWD`
# Automatic cleanup of scratch space
trap 'rm -rf $TDIR' INT TERM QUIT EXIT
export GIT_INDEX_FILE="$TDIR/index"
# Add listed files to a new (empty) index
git update-index --add "$@"
# Write the index into the repo, get tree hash
TREE=`git write-tree --prefix="$prefix"`
echo "TREE $TREE"
git cat-file -p $TREE
# Create a commit with our new tree
# Reference current branch head as parent (if any)
CMT=`git commit-tree -m "$MSG" $TREE`
echo "COMMIT $CMT"
git cat-file -p $CMT
# Update the branch with the new commit tree hash
git update-ref $BRANCH $CMT
echo "Done"

78
documentation/conf.py Normal file
View File

@@ -0,0 +1,78 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'EPICS Documentation'
copyright = '2019, EPICS Controls.'
author = 'EPICS'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.intersphinx',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# Intersphinx links to subprojects
intersphinx_mapping = {
'how-tos': ('https://docs.epics-controls.org/projects/how-tos/en/latest', None),
}
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = [
'css/custom.css',
]
master_doc = 'index'
html_theme_options = {
'logo_only': True,
}
html_logo = "images/EPICS_white_logo_v02.png"
html_extra_path = ['../html']
# -- Run Doxygen ------------------------------------------------------------
import subprocess
subprocess.call('cd ..; mkdir -p html/doxygen; doxygen', shell=True)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

16
documentation/index.rst Normal file
View File

@@ -0,0 +1,16 @@
pvData (C++) Library
====================
.. toctree::
:hidden:
EPICS Website <https://epics-controls.org>
EPICS Documentation Home <https://docs.epics-controls.org>
.. toctree::
:maxdepth: 1
:caption: pvDataCPP
Reference Manual and API Documentation <https://docs.epics-controls.org/projects/pvdata-cpp/en/latest/doxygen>
Source Code Repository on GitHub <https://github.com/epics-base/pvDataCPP>

View File

@@ -0,0 +1,58 @@
#ifndef MAINPAGE_H
#define MAINPAGE_H
/**
@mainpage pvDataCPP documentation
- This module is included in [EPICS Base releases](https://epics-controls.org/resources-and-support/base/) beginning with 7.0.1
- It may also be [Downloaded](https://github.com/epics-base/pvDataCPP/releases) and built separately.
- @htmlonly <a href="modules.html">API components</a> @endhtmlonly
- @ref release_notes
The epics::pvData namespace.
See pv/pvData.h header.
@code
#include <pv/pvData.h>
#include <pv/createRequest.h>
@endcode
- Type description epics::pvData::Field and sub-classes
- Value container epics::pvData::PVField and sub-classes
- POD array handling epics::pvData::shared_vector
- pvRequest parsing epics::pvData::createRequest()
Define a structure type and create a container with default values.
@code
namespace pvd = epics::pvData;
pvd::StructureConstPtr stype(pvd::FieldBuilder::begin()
->add("fld1", pvd::pvInt)
->addNestedStructure("sub")
->add("fld2", pvd::pvString)
->endNested()
->createStructure());
pvd::PVStructuretPtr value(stype->build());
value->getSubFieldT<pvd::PVInt>("fld1")->put(4); // store integer 4. would throw if not pvInt
value->getSubFieldT<pvd::PVScalar>("sub.fld2")->putFrom(4.2); // convert and store string "4.2"
@endcode
is equivalent to the following pseudo-code.
@code
struct stype {
pvd::int32 fld1;
struct {
std::string fld2;
} sub;
};
stype value;
value.fld1 = 4;
value.fld2 = pvd::castUnsafe<std::string>(4.2);
@endcode
*/
#endif /* MAINPAGE_H */

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

View File

@@ -0,0 +1,470 @@
/**
@page release_notes Release Notes
Release 8.1.0 (Feb 2021)
========================
- Incompatible changes
- Remove ByteBuffer::align()
- Compatible changes
- Deprecate SerializableControl::alignBuffer() and DeserializableControl::alignData()
- shared_vector_convert<>() fix convert of empty, untyped, array
Release 8.0.3 (July 2020)
=========================
- Incompatible changes
- Removed THROW_BASE_EXCEPTION_CAUSE() macro which has long ignored its cause.
Any external users should switch to the functionally identical THROW_BASE_EXCEPTION_CAUSE()
- Various printing of functions now conditionally escape strings
including quote '\"' and similar charactors.
Release 8.0.2 (May 2020)
========================
- Changes to documentation and unittests.
No functional changes to library.
Release 8.0.1 (Nov 2019)
==========================
- Incompatible changes
- Requires Base >= 3.15
- Bug fixes
Release 8.0.0 (July 2019)
=========================
- Deprecations
- ByteBuffer::getArray()
- Removals
- pv/localStaticLock.h
- pv/pvCopy.h (see epics::pvData::PVRequestMapper)
- Additions
- Add {Structure,Union}::getFieldT
Release 7.1.3 (Apr 2019)
========================
- Fix for array serialization error to/from big endian.
https://github.com/epics-base/pvDataCPP/issues/65
Release 7.1.2 (Mar 2019)
========================
- 7.1.1 tag pushed prematurely.
Release 7.1.1 (Mar 2019)
========================
- Fixes
- Init order issue with StandardField::getStandardField()
- Build fix for Visual Studio 2013+
Release 7.1.0 (Nov 2018)
========================
- Deprecations
- BoundedString, BoundedScalarArray, and FixedScalarArray will be removed unless they are fixed.
See https://github.com/epics-base/pvDataCPP/issues/52 for discussion.
- pv/localStaticLock.h
- pv/pvCopy.h (see epics::pvData::PVRequestMapper)
- Removals
- Remove previously deprecated executor.h, queue.h and timerFunction.h
- Remove *HashFunction functors to "hash" Field sub-classes which were never fully implemented.
- Fixes
- Make thread safe getFieldCreate() and getPVDataCreate()
- Workaround for MSVC pickyness that iterators be non-NULL, even when not de-referenced.
- Fix alignment fault during (de)serialization on RTEMS/vxWorks.
- Fix epics::pvData::shared_vector::swap() for void specialization.
- Changes in several epics::pvData::Field sub-classes to return const ref. instead of a copy.
- Additions
- epics::pvData::shared_vector add c++11 move and construct for initializer list.
- Add epics::pvData::AnyScalar::clear()
- Add ctor epics::pvData::AnyScalar(ScalarType, const void*) to allow construction from an untyped buffer.
- Add epics::pvData::Timer::close()
- Allow epics::pvData::castUnsafe() from const char* without first allocating a std::string.
- De-duplication of epics::pvData::Field instances is performed using a global hash table.
Identical definitions will share a single instance. Allows O(0) comparision.
- Add epics::pvData::PVRequestMapper to facilitate (partial) copying between PVStructure instances
modified by a pvRequest.
- Add shorthand notations epics::pvData::FieldBuilder::begin() and epics::pvData::Field::build()
Release 7.0.0 (Dec 2017)
========================
- Removals
- Remove requester.h, monitor.h, and destroyable.h.. Migrated to the pvAccessCPP module.
- Previously deprecated monitorPlugin.h is removed.
- Remove pv/messageQueue.h and epics::pvData::MessageQueue
- Deprecate the following utility classes, to be removed in 8.0.
- epics::pvData::Queue
- epics::pvData::Executor
- epics::pvData::TimeFunction
- Additions
- Add pv/pvdVersion.h which is included by pv/pvIntrospect.h
- Add epics::pvData::createRequest() function. Alternative to epics::pvData::CreateRequest class which throws on error.
- epics::pvData::FieldBuilder allow Structure defintion to be changed/appended
- Add epics::pvData::ValueBuilder like FieldBuilder also sets initial values.
- Can also be constructed using an existing PVStructure to allow "editing".
- Add debugPtr.h wrapper with reference tracking to assist in troubleshooting shared_ptr related ref. loops.
- Add @ref pvjson utilities
- Add reftrack @ref pvd_reftrack
- Add header typemap.h to facilitate boilerplate switch() over ScalarType
- Add epics::auto_ptr typedef in help writing code supporting both c++98 and c++11 w/o copious deprecation warnings.
Release 6.0.1
=============
The changes since release 6.0.0 are:
* Fix "Problem building pvDataCPP for win32-x86-mingw" (issue #42)
* In src/misc/bitSet.cpp #include "algorithm" required for MSVS 2015
* In testApp/misc/testTypeCast.cpp print (u)int8 values as integers
* Minor documentation updates
Release 6.0.0 (Aug. 2016)
=======================
The main changes since release 5.0.4 are:
* Linux shared library version added
* Headers have been moved into pv directories
* Bitset functions declared const where possible
* Bitset::swap added
* Requester::message has default implementation
* Serialization/deserialization helpers added
* Non-template getSubField char* overload added
* MonitorPlugin deprecated
* Field name validation performed
* Now builds for Cygwin and MinGW targets
* Fix for debug build issue.
* New license file replaces LICENSE and COPYRIGHT
Shared library version added
----------------------------
Linux shared library version numbers have been added by setting SHRLIB_VERSION
(to 6.0 in this case). So shared object will be libpvData.so.6.0 instead of
libpvData.so.
Headers have been moved into pv directories
-------------------------------------------
E.g. src/property/alarm.h -> src/property/pv/alarm.h
This facilitates using some IDEs such as Qt Creator.
Requester::message has default implementation
---------------------------------------------
Requester::message is no longer pure virtual. Default implementation sends
string to std::cerr.
Serialization/deserialization helpers added
-------------------------------------------
A helper function, serializeToVector, has been added which serializes a
Serializable object into a standard vector of UInt8s.
Similarly a function deserializeFromVector deserializes a standard vector into
a Deserializable object.
A function deserializeFromBuffer deserializes a ByteBuffer into a
Deserializable object.
Field name validation performed
-------------------------------
On creating a Structure or Union the field names are now validated.
Valid characters for a field name are upper or lowercase letters, numbers and
underscores and intial numbers are invalid, i.e. names must be of the form
[A-Za-z_][A-Za-z0-9_]*.
Now builds for Cygwin and MinGW targets
---------------------------------------
Includes cross-compiling MinGW on Linux.
Release 5.0.4
=============
The changes since release 5.0.3 are:
* Fixed bitset serialization (issue #24)
* Fixed truncation in BitSet::or_and (issue #27)
Fixed bitset serialization (issue #24)
--------------------------------------
C++ bitset serialization was not consistent with the C++ deserialization and
Java code in some instances (depending on the endianness of the serializer and
deserializer) when the number of bits was 56-63 modulo 64. C++ serialization
has been fixed.
Fix exposed issue in deserialization on 32-bit platforms which
has also been corrected.
Fixed truncation in BitSet::or_and (issue #27)
----------------------------------------------
If n, n1 and n2 words are used to store the values of the bitsets bitset,
bitset1 and bitset2 respectively then max(n, min(n1,n2)) words are needed
to store bitset.or_(bitset1, bitset2).
Previously min(n1,n2) words were used and the result would be truncated in
some instances. This has been fixed.
Release 5.0.3
=============
The only change since release 5.0.2 is:
Fixed buffer overflow in PVUnion::serialize() (issue #20)
---------------------------------------------------------
A PVUnion whose stored value was null was serialized without checking
whether the buffer had sufficient capacity. This has been fixed by calling
ensureBuffer().
Release 5.0.2 (Sep. 2015)
=========================
The main changes since release 4.0 are:
- Deprecated getXXXField() methods have been removed from PVStructure
- Convert copy methods and equals operators (re)moved
- Convert::copyUnion now always copies between subfields.
- New method getSubFieldT, like getSubField except it throws an exception
- findSubField method removed from PVStructure
- New stream operators for Field and PVField are provided
- New template versions of Structure::getField
- Fixes for static initialisation order issues
- CreateRequest prevents a possible SEGFAULT
Deprecated getXXXField methods have been removed from PVStructure
-------------------------------------------------------------------
The following methods have been removed from PVStructure
- getBooleanField
- getByteField, getShortField, getIntField, getLongField
- getUByteField, getUShortField, getUIntField, getULongField
- getStringField
- getStructureField, getUnionField
- getScalarArrayField, getStructureArrayField, getUnionArrayField
Use template getSubField instead, e.g. use
getSubField< PVInt >(fieldName)
in place of
getIntField(fieldName)
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)
were 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 copy, 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.
New method getSubFieldT, like getSubField except it throws an exception
--------------------
PVStructure has a new template member
getSubFieldT(std::string const &fieldName)
that is like `getSubField()` except that it throws a runtime_error
instead of returning null.
findSubField method removed from PVStructure
--------------------------------------------
This was mainly used in the implementation of getSubField. With a change to
the latter, findSubField was removed.
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 struc, PVStructurePtr pv)
{
if(struc) {
cout << *struc << endl;
} else {
cout << "nullptr\n"
}
if(pv) {
cout << *.struc << endl;
} else {
cout << "nullptr\n"
}
}
Now it can be done as follows:
void print(StructureConstPtr struc, PVStructurePtr pv)
{
cout << struc << endl;
cout << pv << endl;
}
New template version of Structure::getField
--------------------------------------------
A new template getField method has been added to Structure
template<typename FT >
std::tr1::shared_ptr< const FT > getField(std::string const &fieldName) const
Can be used, for example, as follows:
StructurePtr tsStruc = struc->getField<Structure>("timeStamp");
Fixes for static initialisation order issues
--------------------------------------------
Certain static builds (in particular Windows builds) of applications using
pvData had issues due to PVStructure::DEFAULT_ID being used before being initialised. This has been fixed.
CreateRequest change
--------------------
createRequest could cause a SEGFAULT if passed a bad argument.
This has been changed so the it returns a null pvStructure
and provides an error.
Release 4.0.3
=============
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 hysteresis 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:
- *variant union* The field can have any type.
- *union* 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
*/

14
examples/Makefile Normal file
View File

@@ -0,0 +1,14 @@
# Makefile for the examples
# make sure they compile
TOP = ..
include $(TOP)/configure/CONFIG
PROD_LIBS += pvData Com
TESTPROD_HOST += unittest
unittest_SRCS += unittest.cpp
include $(TOP)/configure/RULES

30
examples/unittest.cpp Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright information and license terms for this software can be
* found in the file LICENSE that is included with the distribution
*/
/* c++ unittest skeleton */
#include <stdexcept>
#include <testMain.h>
#include <pv/pvUnitTest.h>
#include <pv/epicsException.h>
namespace {
void testCase1() {
testEqual(1+1, 2);
}
} // namespace
MAIN(testUnitTest)
{
testPlan(1);
try {
testCase1();
}catch(std::exception& e){
PRINT_EXCEPTION(e); // print stack trace if thrown with THROW_EXCEPTION()
testAbort("Unhandled exception: %s", e.what());
}
return testDone();
}

View File

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

View File

@@ -4,10 +4,33 @@
# 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>
# Author: Ralph Lange <ralph.lange@gmx.de>
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
# Copyright (C) 2014-2016 ITER Organization.
# All rights reserved. Use is subject to license terms.
installTool () {
local module=$1
local version=$2
wget -nv https://openepics.ci.cloudbees.com/job/${module}-${version}_Build/lastSuccessfulBuild/artifact/${module,,}-${version}.CB-dist.tar.gz
tar -xzf ${module,,}-${version}.CB-dist.tar.gz
}
installE4 () {
local module=$1
local branch=$2
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
tar -xzf ${module}.CB-dist.tar.gz
}
###########################################
# Defaults for EPICS Base
DEFAULT_BASE=3.15.4
BASE=${BASE:-${DEFAULT_BASE}}
###########################################
# Fetch and unpack dependencies
@@ -17,10 +40,8 @@ rm -fr ${STUFF}
mkdir -p ${STUFF}
cd ${STUFF}
wget -nv https://openepics.ci.cloudbees.com/job/Base-3.14.12.3_Build/lastSuccessfulBuild/artifact/baseR3.14.12.3.CB-dist.tar.gz
wget -nv https://openepics.ci.cloudbees.com/job/Doxygen-1.8.3_Build/lastSuccessfulBuild/artifact/doxygen-1.8.3.CB-dist.tar.gz
tar -xzf baseR3.14.12.3.CB-dist.tar.gz
tar -xzf doxygen-1.8.3.CB-dist.tar.gz
installTool Boost 1.61.0
installTool Base ${BASE}
###########################################
# Build
@@ -37,21 +58,13 @@ EPICS_BASE=${EPICS_BASE}
EOF
make distclean all
doxygen
###########################################
# Test
for t in bin/linux-x86_64/test*; do
$t
done
make runtests
###########################################
# Create distribution
# Create cache
tar czf pvData.CB-dist.tar.gz lib include COPYRIGHT LICENSE
###########################################
# Publish documentation
rsync -aP --delete -e ssh documentation epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/pvDataCPP/tip
tar czf pvData.CB-dist.tar.gz lib include cfg LICENSE

66
jenkins/cloudbees_doc Normal file
View File

@@ -0,0 +1,66 @@
# 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-2016 ITER Organization.
# All rights reserved. Use is subject to license terms.
installTool () {
local module=$1
local version=$2
wget -nv https://openepics.ci.cloudbees.com/job/${module}-${version}_Build/lastSuccessfulBuild/artifact/${module,,}-${version}.CB-dist.tar.gz
tar -xzf ${module,,}-${version}.CB-dist.tar.gz
}
installE4 () {
local module=$1
local branch=$2
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
tar -xzf ${module}.CB-dist.tar.gz
}
###########################################
# Defaults for EPICS Base and parameters
BASE=3.15.4
PUBLISH=${PUBLISH:-NO}
BRANCH=${BRANCH:-master}
###########################################
# Fetch and unpack dependencies
export STUFF=/tmp/stuff
rm -fr ${STUFF}
mkdir -p ${STUFF}
cd ${STUFF}
installTool Doxygen 1.8.11
###########################################
# Generate
cd ${WORKSPACE}
installE4 pvData ${BRANCH}
export PATH=${STUFF}/bin:${PATH}
doxygen
###########################################
# Publish
if [ "${PUBLISH}" != "NO" ]; 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}/
rsync -aqP --delete -e ssh documentation epics-jenkins@web.sourceforge.net:/home/project-web/epics-pvdata/htdocs/docbuild/pvDataCPP/${PUBLISH}/
fi

View File

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

View File

@@ -1,99 +0,0 @@
TOP = ..
include $(TOP)/configure/CONFIG
PVDATA = $(TOP)/pvDataApp/
SRC_DIRS += $(PVDATA)/misc
INC += noDefaultMethods.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 += timeFunction.h
INC += timer.h
INC += queue.h
INC += messageQueue.h
INC += destroyable.h
INC += status.h
INC += sharedPtr.h
INC += localStaticLock.h
LIBSRCS += byteBuffer.cpp
LIBSRCS += bitSet.cpp
LIBSRCS += epicsException.cpp
LIBSRCS += requester.cpp
LIBSRCS += serializeHelper.cpp
LIBSRCS += event.cpp
LIBSRCS += executor.cpp
LIBSRCS += timeFunction.cpp
LIBSRCS += timer.cpp
LIBSRCS += status.cpp
LIBSRCS += messageQueue.cpp
LIBSRCS += localStaticLock.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 += FieldCreateFactory.cpp
LIBSRCS += PVAuxInfoImpl.cpp
LIBSRCS += PVField.cpp
LIBSRCS += PVScalar.cpp
LIBSRCS += PVArray.cpp
LIBSRCS += PVScalarArray.cpp
LIBSRCS += PVStructure.cpp
LIBSRCS += PVStructureArray.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
LIBRARY = pvData
pvData_LIBS += Com
include $(TOP)/configure/RULES

View File

@@ -1,108 +0,0 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mes
*/
#include <pv/convert.h>
#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();
}
bool operator==(const ScalarArray& a, const ScalarArray& b)
{
if(&a==&b)
return true;
return a.getElementType()==b.getElementType();
}
bool operator==(const Structure& a, const Structure& b)
{
if(&a==&b)
return true;
if (a.getID()!=b.getID())
return false;
size_t nflds=a.getNumberFields();
if (b.getNumberFields()!=nflds)
return false;
// std::equals does not work, since FieldConstPtrArray is an array of shared_pointers
FieldConstPtrArray af = a.getFields();
FieldConstPtrArray bf = b.getFields();
for (size_t i = 0; i < nflds; i++)
if (*(af[i].get()) != *(bf[i].get()))
return false;
StringArray an = a.getFieldNames();
StringArray bn = b.getFieldNames();
return std::equal( an.begin(), an.end(), bn.begin() );
}
bool operator==(const StructureArray& a, const StructureArray& b)
{
return *(a.getStructure().get())==*(b.getStructure().get());
}
namespace nconvert {
} // namespace nconvert
}} // namespace epics::pvData

File diff suppressed because it is too large Load Diff

View File

@@ -1,563 +0,0 @@
/*FieldCreateFactory.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/lock.h>
#include <pv/pvIntrospect.h>
#include <pv/convert.h>
#include <pv/factory.h>
#include <pv/serializeHelper.h>
using std::tr1::static_pointer_cast;
using std::size_t;
namespace epics { namespace pvData {
static DebugLevel debugLevel = lowDebug;
static void newLine(StringBuilder buffer, int indentLevel)
{
*buffer += "\n";
for(int i=0; i<indentLevel; i++) *buffer += " ";
}
Field::Field(Type type)
: m_fieldType(type)
{
}
Field::~Field() {
}
void Field::toString(StringBuilder /*buffer*/,int /*indentLevel*/) const{
}
// TODO move all these to a header file
struct ScalarHashFunction {
size_t operator() (const Scalar& scalar) const { return scalar.getScalarType(); }
};
struct ScalarArrayHashFunction {
size_t operator() (const ScalarArray& scalarArray) const { return 0x10 | scalarArray.getElementType(); }
};
struct StructureHashFunction {
size_t operator() (const Structure& /*structure*/) const { return 0; }
// TODO
// final int PRIME = 31;
// return PRIME * Arrays.hashCode(fieldNames) + Arrays.hashCode(fields);
};
struct StructureArrayHashFunction {
size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); }
};
Scalar::Scalar(ScalarType scalarType)
: Field(scalar),scalarType(scalarType){}
Scalar::~Scalar(){}
void Scalar::toString(StringBuilder buffer,int /*indentLevel*/) const{
*buffer += getID();
}
String Scalar::getID() const
{
static const String idScalarLUT[] = {
"boolean", // pvBoolean
"byte", // pvByte
"short", // pvShort
"int", // pvInt
"long", // pvLong
"ubyte", // pvUByte
"ushort", // pvUShort
"uint", // pvUInt
"ulong", // pvULong
"float", // pvFloat
"double", // pvDouble
"string" // pvString
};
return idScalarLUT[scalarType];
}
int8 Scalar::getTypeCodeLUT() const
{
static const int8 typeCodeLUT[] = {
0x00, // pvBoolean
0x20, // pvByte
0x21, // pvShort
0x22, // pvInt
0x23, // pvLong
0x28, // pvUByte
0x29, // pvUShort
0x2A, // pvUInt
0x2B, // pvULong
0x42, // pvFloat
0x43, // pvDouble
0x60 // pvString
};
return typeCodeLUT[scalarType];
}
void Scalar::serialize(ByteBuffer *buffer, SerializableControl *control) const {
control->ensureBuffer(1);
buffer->putByte(getTypeCodeLUT());
}
void Scalar::deserialize(ByteBuffer */*buffer*/, DeserializableControl */*control*/) {
// must be done via FieldCreate
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
static String emptyString;
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
{
// to optimize default (non-empty) IDs optimization
// empty IDs are not allowed
String id = structure->getID();
if (id == Structure::DEFAULT_ID) // TODO slow comparison
SerializeHelper::serializeString(emptyString, buffer, control);
else
SerializeHelper::serializeString(id, buffer, control);
FieldConstPtrArray const & fields = structure->getFields();
StringArray const & fieldNames = structure->getFieldNames();
std::size_t len = fields.size();
SerializeHelper::writeSize(len, buffer, control);
for (std::size_t i = 0; i < len; i++)
{
SerializeHelper::serializeString(fieldNames[i], buffer, control);
control->cachedSerialize(fields[i], buffer);
}
}
static StructureConstPtr deserializeStructureField(const FieldCreate* fieldCreate, ByteBuffer* buffer, DeserializableControl* control)
{
String id = SerializeHelper::deserializeString(buffer, control);
const std::size_t size = SerializeHelper::readSize(buffer, control);
FieldConstPtrArray fields; fields.reserve(size);
StringArray fieldNames; fieldNames.reserve(size);
for (std::size_t i = 0; i < size; i++)
{
fieldNames.push_back(SerializeHelper::deserializeString(buffer, control));
fields.push_back(control->cachedDeserialize(buffer));
}
if (id.empty())
return fieldCreate->createStructure(fieldNames, fields);
else
return fieldCreate->createStructure(id, fieldNames, fields);
}
ScalarArray::ScalarArray(ScalarType elementType)
: Field(scalarArray),elementType(elementType){}
ScalarArray::~ScalarArray() {}
int8 ScalarArray::getTypeCodeLUT() const
{
static const int8 typeCodeLUT[] = {
0x00, // pvBoolean
0x20, // pvByte
0x21, // pvShort
0x22, // pvInt
0x23, // pvLong
0x28, // pvUByte
0x29, // pvUShort
0x2A, // pvUInt
0x2B, // pvULong
0x42, // pvFloat
0x43, // pvDouble
0x60 // pvString
};
return typeCodeLUT[elementType];
}
const String ScalarArray::getIDScalarArrayLUT() const
{
static const String idScalarArrayLUT[] = {
"boolean[]", // pvBoolean
"byte[]", // pvByte
"short[]", // pvShort
"int[]", // pvInt
"long[]", // pvLong
"ubyte[]", // pvUByte
"ushort[]", // pvUShort
"uint[]", // pvUInt
"ulong[]", // pvULong
"float[]", // pvFloat
"double[]", // pvDouble
"string[]" // pvString
};
return idScalarArrayLUT[elementType];
}
String ScalarArray::getID() const
{
return getIDScalarArrayLUT();
}
void ScalarArray::toString(StringBuilder buffer,int /*indentLevel*/) const{
*buffer += getID();
}
void ScalarArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
control->ensureBuffer(1);
buffer->putByte(0x10 | getTypeCodeLUT());
}
void ScalarArray::deserialize(ByteBuffer */*buffer*/, DeserializableControl */*control*/) {
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
StructureArray::StructureArray(StructureConstPtr const & structure)
: Field(structureArray),pstructure(structure)
{
}
StructureArray::~StructureArray() {
if(debugLevel==highDebug) printf("~StructureArray\n");
}
String StructureArray::getID() const
{
return pstructure->getID() + "[]";
}
void StructureArray::toString(StringBuilder buffer,int indentLevel) const {
*buffer += getID();
newLine(buffer,indentLevel + 1);
pstructure->toString(buffer,indentLevel + 1);
}
void StructureArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
control->ensureBuffer(1);
buffer->putByte(0x90);
control->cachedSerialize(pstructure, buffer);
}
void StructureArray::deserialize(ByteBuffer */*buffer*/, DeserializableControl */*control*/) {
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
String Structure::DEFAULT_ID = "structure";
Structure::Structure (
StringArray const & fieldNames,
FieldConstPtrArray const & infields,
String const & inid)
: Field(structure),
fieldNames(fieldNames),
fields(infields),
id(inid)
{
if(inid.empty()) {
throw std::invalid_argument("id is empty");
}
if(fieldNames.size()!=fields.size()) {
throw std::invalid_argument("fieldNames.size()!=fields.size()");
}
size_t number = fields.size();
for(size_t i=0; i<number; i++) {
String name = fieldNames[i];
if(name.size()<1) {
throw std::invalid_argument("fieldNames has a zero length string");
}
// look for duplicates
for(size_t j=i+1; j<number; j++) {
String otherName = fieldNames[j];
int result = name.compare(otherName);
if(result==0) {
String message("duplicate fieldName ");
message += name;
throw std::invalid_argument(message);
}
}
}
}
Structure::~Structure() { }
String Structure::getID() const
{
return id;
}
FieldConstPtr Structure::getField(String const & fieldName) const {
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(fieldNames[i]);
if(result==0) return pfield;
}
return FieldConstPtr();
}
size_t Structure::getFieldIndex(String const &fieldName) const {
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(fieldNames[i]);
if(result==0) return i;
}
return -1;
}
void Structure::toString(StringBuilder buffer,int indentLevel) const{
*buffer += getID();
toStringCommon(buffer,indentLevel+1);
}
void Structure::toStringCommon(StringBuilder buffer,int indentLevel) const{
newLine(buffer,indentLevel);
size_t numberFields = fields.size();
for(size_t i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
*buffer += pfield->getID() + " " + fieldNames[i];
switch(pfield->getType()) {
case scalar:
case scalarArray:
break;
case structure:
{
Field const *xxx = pfield.get();
Structure const *pstruct = static_cast<Structure const*>(xxx);
pstruct->toStringCommon(buffer,indentLevel + 1);
break;
}
case structureArray:
newLine(buffer,indentLevel +1);
pfield->toString(buffer,indentLevel +1);
break;
}
if(i<numberFields-1) newLine(buffer,indentLevel);
}
}
void Structure::serialize(ByteBuffer *buffer, SerializableControl *control) const {
control->ensureBuffer(1);
buffer->putByte(0x80);
serializeStructureField(this, buffer, control);
}
void Structure::deserialize(ByteBuffer */*buffer*/, DeserializableControl */*control*/) {
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
}
ScalarConstPtr FieldCreate::createScalar(ScalarType scalarType) const
{
// TODO use singleton instance
ScalarConstPtr scalar(new Scalar(scalarType), Field::Deleter());
return scalar;
}
ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
{
// TODO use singleton instance
ScalarArrayConstPtr scalarArray(new ScalarArray(elementType), Field::Deleter());
return scalarArray;
}
StructureConstPtr FieldCreate::createStructure (
StringArray const & fieldNames,FieldConstPtrArray const & fields) const
{
StructureConstPtr structure(
new Structure(fieldNames,fields), Field::Deleter());
return structure;
}
StructureConstPtr FieldCreate::createStructure (
String const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const
{
StructureConstPtr structure(
new Structure(fieldNames,fields,id), Field::Deleter());
return structure;
}
StructureArrayConstPtr FieldCreate::createStructureArray(
StructureConstPtr const & structure) const
{
StructureArrayConstPtr structureArray(
new StructureArray(structure), Field::Deleter());
return structureArray;
}
StructureConstPtr FieldCreate::appendField(
StructureConstPtr const & structure,
String const & fieldName,
FieldConstPtr const & field) const
{
StringArray oldNames = structure->getFieldNames();
FieldConstPtrArray oldFields = structure->getFields();
size_t oldLen = oldNames.size();
StringArray newNames(oldLen+1);
FieldConstPtrArray newFields(oldLen+1);
for(size_t i = 0; i<oldLen; i++) {
newNames[i] = oldNames[i];
newFields[i] = oldFields[i];
}
newNames[oldLen] = fieldName;
newFields[oldLen] = field;
return createStructure(structure->getID(),newNames,newFields);
}
StructureConstPtr FieldCreate::appendFields(
StructureConstPtr const & structure,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const
{
StringArray oldNames = structure->getFieldNames();
FieldConstPtrArray oldFields = structure->getFields();
size_t oldLen = oldNames.size();
size_t extra = fieldNames.size();
StringArray newNames(oldLen+extra);
FieldConstPtrArray newFields(oldLen+extra);
for(size_t i = 0; i<oldLen; i++) {
newNames[i] = oldNames[i];
newFields[i] = oldFields[i];
}
for(size_t i = 0; i<extra; i++) {
newNames[oldLen +i] = fieldNames[i];
newFields[oldLen +i] = fields[i];
}
return createStructure(structure->getID(),newNames,newFields);
}
static int decodeScalar(int8 code)
{
static const int integerLUT[] =
{
pvByte, // 8-bits
pvShort, // 16-bits
pvInt, // 32-bits
pvLong, // 64-bits
-1,
-1,
-1,
-1,
pvUByte, // unsigned 8-bits
pvUShort, // unsigned 16-bits
pvUInt, // unsigned 32-bits
pvULong, // unsigned 64-bits
-1,
-1,
-1,
-1
};
static const int floatLUT[] =
{
-1, // reserved
-1, // 16-bits
pvFloat, // 32-bits
pvDouble, // 64-bits
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1
};
// bits 7-5
switch (code >> 5)
{
case 0: return pvBoolean;
case 1: return integerLUT[code & 0x0F];
case 2: return floatLUT[code & 0x0F];
case 3: return pvString;
default: return -1;
}
}
FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl* control) const
{
control->ensureData(1);
int8 code = buffer->getByte();
if (code == -1)
return FieldConstPtr();
int typeCode = code & 0xE0;
bool notArray = ((code & 0x10) == 0);
if (notArray)
{
if (typeCode < 0x80)
{
// Type type = Type.scalar;
int scalarType = decodeScalar(code);
if (scalarType == -1)
throw std::invalid_argument("invalid scalar type encoding");
return FieldConstPtr(new Scalar(static_cast<ScalarType>(scalarType)), Field::Deleter());
}
else if (typeCode == 0x80)
{
// Type type = Type.structure;
return deserializeStructureField(this, buffer, control);
}
else
throw std::invalid_argument("invalid type encoding");
}
else // array
{
if (typeCode < 0x80)
{
// Type type = Type.scalarArray;
int scalarType = decodeScalar(code);
if (scalarType == -1)
throw std::invalid_argument("invalid scalarArray type encoding");
return FieldConstPtr(new ScalarArray(static_cast<ScalarType>(scalarType)), Field::Deleter());
}
else if (typeCode == 0x80)
{
// Type type = Type.structureArray;
StructureConstPtr elementStructure = std::tr1::static_pointer_cast<const Structure>(control->cachedDeserialize(buffer));
return FieldConstPtr(new StructureArray(elementStructure), Field::Deleter());
}
else
throw std::invalid_argument("invalid type encoding");
}
}
FieldCreatePtr FieldCreate::getFieldCreate()
{
LOCAL_STATIC_LOCK;
static FieldCreatePtr fieldCreate;
static Mutex mutex;
Lock xx(mutex);
if(fieldCreate.get()==0) fieldCreate = FieldCreatePtr(new FieldCreate());
return fieldCreate;
}
FieldCreate::FieldCreate(){}
FieldCreatePtr getFieldCreate() {
return FieldCreate::getFieldCreate();
}
}}

View File

@@ -1,105 +0,0 @@
/*PVArray.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/pvData.h>
#include <pv/factory.h>
using std::size_t;
namespace epics { namespace pvData {
class PVArrayPvt {
public:
PVArrayPvt() : length(0),capacity(0),capacityMutable(true)
{}
size_t length;
size_t capacity;
bool capacityMutable;
};
PVArray::PVArray(FieldConstPtr const & field)
: PVField(field),pImpl(new PVArrayPvt())
{ }
PVArray::~PVArray()
{
delete pImpl;
}
void PVArray::setImmutable()
{
pImpl->capacityMutable = false;
PVField::setImmutable();
}
size_t PVArray::getLength() const {return pImpl->length;}
size_t PVArray::getCapacity() const {return pImpl->capacity;}
static String fieldImmutable("field is immutable");
void PVArray::setLength(size_t length) {
if(length==pImpl->length) return;
if(PVField::isImmutable()) {
PVField::message(fieldImmutable,errorMessage);
return;
}
if(length>pImpl->capacity) this->setCapacity(length);
if(length>pImpl->capacity) length = pImpl->capacity;
pImpl->length = length;
}
void PVArray::setCapacityLength(size_t capacity,size_t length) {
pImpl->capacity = capacity;
pImpl->length = length;
}
bool PVArray::isCapacityMutable() const
{
if(PVField::isImmutable()) {
return false;
}
return pImpl->capacityMutable;
}
void PVArray::setCapacityMutable(bool isMutable)
{
if(isMutable && PVField::isImmutable()) {
PVField::message(fieldImmutable,errorMessage);
return;
}
pImpl->capacityMutable = isMutable;
}
static String capacityImmutable("capacity is immutable");
void PVArray::setCapacity(size_t capacity) {
if(PVField::isImmutable()) {
PVField::message(fieldImmutable,errorMessage);
return;
}
if(pImpl->capacityMutable==false) {
PVField::message(capacityImmutable,errorMessage);
return;
}
pImpl->capacity = capacity;
}
std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array)
{
return array.dumpValue(manip.stream, manip.index);
}
}}

View File

@@ -1,84 +0,0 @@
/*PVAuxInfo.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/noDefaultMethods.h>
#include <pv/pvData.h>
#include <pv/convert.h>
#include <pv/factory.h>
#include <pv/lock.h>
namespace epics { namespace pvData {
PVAuxInfo::PVAuxInfo(PVField * pvField)
: pvField(pvField),
pvInfos(std::map<String,std::tr1::shared_ptr<PVScalar> > ())
{
}
PVAuxInfo::~PVAuxInfo()
{
}
PVField * PVAuxInfo::getPVField() {
return pvField;
}
PVScalarPtr PVAuxInfo::createInfo(String const & key,ScalarType scalarType)
{
PVInfoIter iter = pvInfos.find(key);
if(iter!=pvInfos.end()) {
String message = key.c_str();
message += " already exists ";
pvField->message(message,errorMessage);
return nullPVScalar;
}
PVScalarPtr pvScalar = getPVDataCreate()->createPVScalar(scalarType);
pvInfos.insert(PVInfoPair(key,pvScalar));
return pvScalar;
}
PVScalarPtr PVAuxInfo::getInfo(String const & key)
{
PVInfoIter iter;
iter = pvInfos.find(key);
if(iter==pvInfos.end()) return nullPVScalar;
return iter->second;
}
PVAuxInfo::PVInfoMap & PVAuxInfo::getInfoMap()
{
return pvInfos;
}
void PVAuxInfo::toString(StringBuilder buf)
{
PVAuxInfo::toString(buf,0);
}
void PVAuxInfo::toString(StringBuilder buf,int indentLevel)
{
if(pvInfos.size()<=0) return;
ConvertPtr convert = getConvert();
convert->newLine(buf,indentLevel);
*buf += "auxInfo";
for(PVInfoIter iter = pvInfos.begin(); iter!= pvInfos.end(); ++iter) {
convert->newLine(buf,indentLevel+1);
PVFieldPtr value = iter->second;
value->toString(buf,indentLevel + 1);
}
}
}}

View File

@@ -1,715 +0,0 @@
/*PVDataCreateFactory.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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>
using std::tr1::static_pointer_cast;
using std::size_t;
using std::min;
namespace epics { namespace pvData {
/** 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(ScalarConstPtr const & scalar);
virtual ~BasePVScalar();
virtual T get() const ;
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(ScalarConstPtr const & scalar)
: PVScalarValue<T>(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() const { return value;}
template<typename T>
void BasePVScalar<T>::put(T val)
{
value = val;
PVField::postPut();
}
template<typename T>
void BasePVScalar<T>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const {
pflusher->ensureBuffer(sizeof(T));
pbuffer->put(value);
}
template<typename T>
void BasePVScalar<T>::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pflusher)
{
pflusher->ensureData(sizeof(T));
value = pbuffer->GET(T);
}
typedef BasePVScalar<boolean> BasePVBoolean;
typedef BasePVScalar<int8> BasePVByte;
typedef BasePVScalar<int16> BasePVShort;
typedef BasePVScalar<int32> BasePVInt;
typedef BasePVScalar<int64> BasePVLong;
typedef BasePVScalar<uint8> BasePVUByte;
typedef BasePVScalar<uint16> BasePVUShort;
typedef BasePVScalar<uint32> BasePVUInt;
typedef BasePVScalar<uint64> BasePVULong;
typedef BasePVScalar<float> BasePVFloat;
typedef BasePVScalar<double> BasePVDouble;
// 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(ScalarConstPtr const & scalar);
virtual ~BasePVString();
virtual String get() const ;
virtual void put(String val);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const;
virtual void deserialize(ByteBuffer *pbuffer,
DeserializableControl *pflusher);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, size_t offset, size_t count) const;
private:
String value;
};
BasePVString::BasePVString(ScalarConstPtr const & scalar)
: PVString(scalar),value()
{}
BasePVString::~BasePVString() {}
String BasePVString::get() const { return value;}
void BasePVString::put(String val)
{
value = val;
postPut();
}
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, size_t offset, size_t count) const
{
// check bounds
const size_t length = /*(value == null) ? 0 :*/ value.length();
/*if (offset < 0) offset = 0;
else*/ if (offset > length) offset = length;
//if (count < 0) count = length;
const size_t 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* pointer;
typedef const T* const_pointer;
typedef std::vector<T> vector;
typedef const std::vector<T> const_vector;
typedef std::tr1::shared_ptr<vector> shared_vector;
DefaultPVArray(ScalarArrayConstPtr const & scalarArray);
virtual ~DefaultPVArray();
virtual void setCapacity(size_t capacity);
virtual void setLength(size_t length);
virtual size_t get(size_t offset, size_t length, PVArrayData<T> &data) ;
virtual size_t put(size_t offset,size_t length, const_pointer from,
size_t fromOffset);
virtual void shareData(
std::tr1::shared_ptr<std::vector<T> > const & value,
std::size_t capacity,
std::size_t length);
virtual pointer get() ;
virtual pointer get() const ;
virtual vector const & getVector() { return *value.get(); }
virtual shared_vector const & getSharedVector(){return value;};
// from Serializable
virtual void serialize(ByteBuffer *pbuffer,SerializableControl *pflusher) const;
virtual void deserialize(ByteBuffer *pbuffer,DeserializableControl *pflusher);
virtual void serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, size_t offset, size_t count) const;
private:
shared_vector value;
};
template<typename T>
T *DefaultPVArray<T>::get()
{
std::vector<T> *vec = value.get();
T *praw = &((*vec)[0]);
return praw;
}
template<typename T>
T *DefaultPVArray<T>::get() const
{
std::vector<T> *vec = value.get();
T *praw = &((*vec)[0]);
return praw;
}
template<typename T>
DefaultPVArray<T>::DefaultPVArray(ScalarArrayConstPtr const & scalarArray)
: PVValueArray<T>(scalarArray),
value(std::tr1::shared_ptr<std::vector<T> >(new std::vector<T>()))
{ }
template<typename T>
DefaultPVArray<T>::~DefaultPVArray()
{ }
template<typename T>
void DefaultPVArray<T>::setCapacity(size_t capacity)
{
if(PVArray::getCapacity()==capacity) return;
if(!PVArray::isCapacityMutable()) {
std::string message("not capacityMutable");
PVField::message(message, errorMessage);
return;
}
size_t length = PVArray::getLength();
if(length>capacity) length = capacity;
size_t oldCapacity = PVArray::getCapacity();
if(oldCapacity>capacity) {
std::vector<T> array;
array.reserve(capacity);
array.resize(length);
T * from = get();
for (size_t i=0; i<length; i++) array[i] = from[i];
value->swap(array);
} else {
value->reserve(capacity);
}
PVArray::setCapacityLength(capacity,length);
}
template<typename T>
void DefaultPVArray<T>::setLength(size_t length)
{
if(PVArray::getLength()==length) return;
size_t capacity = PVArray::getCapacity();
if(length>capacity) {
if(!PVArray::isCapacityMutable()) {
std::string message("not capacityMutable");
PVField::message(message, errorMessage);
return;
}
setCapacity(length);
}
value->resize(length);
PVArray::setCapacityLength(capacity,length);
}
template<typename T>
size_t DefaultPVArray<T>::get(size_t offset, size_t len, PVArrayData<T> &data)
{
size_t n = len;
size_t length = this->getLength();
if(offset+len > length) {
n = length-offset;
//if(n<0) n = 0;
}
data.data = *value.get();
data.offset = offset;
return n;
}
template<typename T>
size_t DefaultPVArray<T>::put(size_t offset,size_t len,
const_pointer from,size_t fromOffset)
{
if(PVField::isImmutable()) {
PVField::message("field is immutable",errorMessage);
return 0;
}
T * pvalue = get();
if(from==pvalue) return len;
if(len<1) return 0;
size_t length = this->getLength();
size_t capacity = this->getCapacity();
if(offset+len > length) {
size_t newlength = offset + len;
if(newlength>capacity) {
setCapacity(newlength);
newlength = this->getCapacity();
len = newlength - offset;
if(len<=0) return 0;
}
length = newlength;
setLength(length);
}
pvalue = get();
for(size_t i=0;i<len;i++) {
pvalue[i+offset] = from[i+fromOffset];
}
this->setLength(length);
this->postPut();
return len;
}
template<typename T>
void DefaultPVArray<T>::shareData(
std::tr1::shared_ptr<std::vector<T> > const & sharedValue,
std::size_t capacity,
std::size_t length)
{
value = sharedValue;
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) {
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
// alignment if (size>0) { pcontrol->ensureData(sizeof(T)-1); pbuffer->align(sizeof(T)); }
//if(size>=0) {
// prepare array, if necessary
if(size>this->getCapacity()) this->setCapacity(size);
// set new length
this->setLength(size);
// try to avoid deserializing from the buffer
// this is only possible if we do not need to do endian-swapping
if (!pbuffer->reverse<T>())
if (pcontrol->directDeserialize(pbuffer, (char*)(get()), size, sizeof(T)))
{
// inform about the change?
PVField::postPut();
return;
}
// retrieve value from the buffer
size_t i = 0;
T * pvalue = get();
while(true) {
/*
size_t maxIndex = min(size-i, (int)(pbuffer->getRemaining()/sizeof(T)))+i;
for(; i<maxIndex; i++)
value[i] = pbuffer->get<T>();
*/
size_t maxCount = min(size-i, (pbuffer->getRemaining()/sizeof(T)));
pbuffer->getArray(pvalue+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;
}
// inform about the change?
PVField::postPut();
//}
// TODO null arrays (size == -1) not supported
}
template<typename T>
void DefaultPVArray<T>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, size_t offset, size_t count) const {
// cache
size_t length = this->getLength();
// check bounds
/*if(offset<0)
offset = 0;
else*/ if(offset>length) offset = length;
//if(count<0) count = length;
size_t maxCount = length-offset;
if(count>maxCount) count = maxCount;
// write
SerializeHelper::writeSize(count, pbuffer, pflusher);
//if (count == 0) return; pcontrol->ensureData(sizeof(T)-1); pbuffer->align(sizeof(T));
// try to avoid copying into the buffer
// this is only possible if we do not need to do endian-swapping
if (!pbuffer->reverse<T>())
if (pflusher->directSerialize(pbuffer, (const char*)(get()+offset), count, sizeof(T)))
return;
size_t end = offset+count;
size_t i = offset;
T * pvalue = const_cast<T *>(get());
while(true) {
/*
size_t maxIndex = min<int>(end-i, (int)(pbuffer->getRemaining()/sizeof(T)))+i;
for(; i<maxIndex; i++)
pbuffer->put<T>(value[i]);
*/
size_t maxCount = min<int>(end-i, (int)(pbuffer->getRemaining()/sizeof(T)));
pbuffer->putArray(pvalue+i, maxCount);
i += maxCount;
if(i<end)
pflusher->flushSerializeBuffer();
else
break;
}
}
// specializations for String
template<>
void DefaultPVArray<String>::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
//if(size>=0) {
// prepare array, if necessary
if(size>getCapacity()) setCapacity(size);
// set new length
setLength(size);
// retrieve value from the buffer
String * pvalue = get();
for(size_t i = 0; i<size; i++) {
pvalue[i] = SerializeHelper::deserializeString(pbuffer,
pcontrol);
}
// inform about the change?
postPut();
//}
// TODO null arrays (size == -1) not supported
}
template<>
void DefaultPVArray<String>::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, size_t offset, size_t count) const {
size_t length = getLength();
// check bounds
/*if(offset<0)
offset = 0;
else*/ if(offset>length) offset = length;
//if(count<0) count = length;
size_t maxCount = length-offset;
if(count>maxCount) count = maxCount;
// write
SerializeHelper::writeSize(count, pbuffer, pflusher);
size_t end = offset+count;
String * pvalue = get();
for(size_t i = offset; i<end; i++) {
SerializeHelper::serializeString(pvalue[i], pbuffer, pflusher);
}
}
typedef DefaultPVArray<boolean> DefaultPVBooleanArray;
typedef DefaultPVArray<int8> BasePVByteArray;
typedef DefaultPVArray<int16> BasePVShortArray;
typedef DefaultPVArray<int32> BasePVIntArray;
typedef DefaultPVArray<int64> BasePVLongArray;
typedef DefaultPVArray<uint8> BasePVUByteArray;
typedef DefaultPVArray<uint16> BasePVUShortArray;
typedef DefaultPVArray<uint32> BasePVUIntArray;
typedef DefaultPVArray<uint64> BasePVULongArray;
typedef DefaultPVArray<float> BasePVFloatArray;
typedef DefaultPVArray<double> BasePVDoubleArray;
typedef DefaultPVArray<String> BasePVStringArray;
// Factory
PVDataCreate::PVDataCreate()
: fieldCreate(getFieldCreate())
{ }
PVFieldPtr PVDataCreate::createPVField(FieldConstPtr const & field)
{
switch(field->getType()) {
case scalar: {
ScalarConstPtr xx = static_pointer_cast<const Scalar>(field);
return createPVScalar(xx);
}
case scalarArray: {
ScalarArrayConstPtr xx = static_pointer_cast<const ScalarArray>(field);
return createPVScalarArray(xx);
}
case structure: {
StructureConstPtr xx = static_pointer_cast<const Structure>(field);
return createPVStructure(xx);
}
case structureArray: {
StructureArrayConstPtr xx = static_pointer_cast<const StructureArray>(field);
return createPVStructureArray(xx);
}
}
throw std::logic_error("PVDataCreate::createPVField should never get here");
}
PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone)
{
switch(fieldToClone->getField()->getType()) {
case scalar:
{
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(fieldToClone);
return createPVScalar(pvScalar);
}
case scalarArray:
{
PVScalarArrayPtr pvScalarArray
= static_pointer_cast<PVScalarArray>(fieldToClone);
return createPVScalarArray(pvScalarArray);
}
case structure:
{
PVStructurePtr pvStructure
= static_pointer_cast<PVStructure>(fieldToClone);
StringArray const & fieldNames = pvStructure->getStructure()->getFieldNames();
PVFieldPtrArray pvFieldPtrArray = pvStructure->getPVFields();
return createPVStructure(fieldNames,pvFieldPtrArray);
}
case structureArray:
{
PVStructureArrayPtr from
= static_pointer_cast<PVStructureArray>(fieldToClone);
StructureArrayConstPtr structureArray = from->getStructureArray();
PVStructureArrayPtr to = createPVStructureArray(
structureArray);
getConvert()->copyStructureArray(from, to);
return to;
}
}
throw std::logic_error("PVDataCreate::createPVField should never get here");
}
PVScalarPtr PVDataCreate::createPVScalar(ScalarConstPtr const & scalar)
{
ScalarType scalarType = scalar->getScalarType();
switch(scalarType) {
case pvBoolean:
return PVScalarPtr(new BasePVBoolean(scalar));
case pvByte:
return PVScalarPtr(new BasePVByte(scalar));
case pvShort:
return PVScalarPtr(new BasePVShort(scalar));
case pvInt:
return PVScalarPtr(new BasePVInt(scalar));
case pvLong:
return PVScalarPtr(new BasePVLong(scalar));
case pvUByte:
return PVScalarPtr(new BasePVUByte(scalar));
case pvUShort:
return PVScalarPtr(new BasePVUShort(scalar));
case pvUInt:
return PVScalarPtr(new BasePVUInt(scalar));
case pvULong:
return PVScalarPtr(new BasePVULong(scalar));
case pvFloat:
return PVScalarPtr(new BasePVFloat(scalar));
case pvDouble:
return PVScalarPtr(new BasePVDouble(scalar));
case pvString:
return PVScalarPtr(new BasePVString(scalar));
}
throw std::logic_error("PVDataCreate::createPVScalar should never get here");
}
PVScalarPtr PVDataCreate::createPVScalar(ScalarType scalarType)
{
ScalarConstPtr scalar = fieldCreate->createScalar(scalarType);
return createPVScalar(scalar);
}
PVScalarPtr PVDataCreate::createPVScalar(PVScalarPtr const & scalarToClone)
{
ScalarType scalarType = scalarToClone->getScalar()->getScalarType();
PVScalarPtr pvScalar = createPVScalar(scalarType);
getConvert()->copyScalar(scalarToClone, pvScalar);
PVAuxInfoPtr from = scalarToClone->getPVAuxInfo();
PVAuxInfoPtr to = pvScalar->getPVAuxInfo();
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
String key = iter->first;
PVScalarPtr pvFrom = iter->second;
ScalarConstPtr scalar = pvFrom->getScalar();
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
getConvert()->copyScalar(pvFrom,pvTo);
}
return pvScalar;
}
PVScalarArrayPtr PVDataCreate::createPVScalarArray(
ScalarArrayConstPtr const & scalarArray)
{
switch(scalarArray->getElementType()) {
case pvBoolean:
return PVScalarArrayPtr(new DefaultPVBooleanArray(scalarArray));
case pvByte:
return PVScalarArrayPtr(new BasePVByteArray(scalarArray));
case pvShort:
return PVScalarArrayPtr(new BasePVShortArray(scalarArray));
case pvInt:
return PVScalarArrayPtr(new BasePVIntArray(scalarArray));
case pvLong:
return PVScalarArrayPtr(new BasePVLongArray(scalarArray));
case pvUByte:
return PVScalarArrayPtr(new BasePVUByteArray(scalarArray));
case pvUShort:
return PVScalarArrayPtr(new BasePVUShortArray(scalarArray));
case pvUInt:
return PVScalarArrayPtr(new BasePVUIntArray(scalarArray));
case pvULong:
return PVScalarArrayPtr(new BasePVULongArray(scalarArray));
case pvFloat:
return PVScalarArrayPtr(new BasePVFloatArray(scalarArray));
case pvDouble:
return PVScalarArrayPtr(new BasePVDoubleArray(scalarArray));
case pvString:
return PVScalarArrayPtr(new BasePVStringArray(scalarArray));
}
throw std::logic_error("PVDataCreate::createPVScalarArray should never get here");
}
PVScalarArrayPtr PVDataCreate::createPVScalarArray(
ScalarType elementType)
{
ScalarArrayConstPtr scalarArray = fieldCreate->createScalarArray(elementType);
return createPVScalarArray(scalarArray);
}
PVScalarArrayPtr PVDataCreate::createPVScalarArray(
PVScalarArrayPtr const & arrayToClone)
{
PVScalarArrayPtr pvArray = createPVScalarArray(
arrayToClone->getScalarArray()->getElementType());
getConvert()->copyScalarArray(arrayToClone,0, pvArray,0,arrayToClone->getLength());
PVAuxInfoPtr from = arrayToClone->getPVAuxInfo();
PVAuxInfoPtr to = pvArray->getPVAuxInfo();
PVAuxInfo::PVInfoMap & map = from->getInfoMap();
for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) {
String key = iter->first;
PVScalarPtr pvFrom = iter->second;
ScalarConstPtr scalar = pvFrom->getScalar();
PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType());
getConvert()->copyScalar(pvFrom,pvTo);
}
return pvArray;
}
PVStructureArrayPtr PVDataCreate::createPVStructureArray(
StructureArrayConstPtr const & structureArray)
{
return PVStructureArrayPtr(new PVStructureArray(structureArray));
}
PVStructurePtr PVDataCreate::createPVStructure(
StructureConstPtr const & structure)
{
return PVStructurePtr(new PVStructure(structure));
}
PVStructurePtr PVDataCreate::createPVStructure(
StringArray const & fieldNames,PVFieldPtrArray const & pvFields)
{
size_t num = fieldNames.size();
FieldConstPtrArray fields(num);
for (size_t i=0;i<num;i++) fields[i] = pvFields[i]->getField();
StructureConstPtr structure = fieldCreate->createStructure(fieldNames,fields);
PVStructurePtr pvStructure(new PVStructure(structure,pvFields));
return pvStructure;
}
PVStructurePtr PVDataCreate::createPVStructure(PVStructurePtr const & structToClone)
{
FieldConstPtrArray field;
if(structToClone==0) {
FieldConstPtrArray fields(0);
StringArray fieldNames(0);
StructureConstPtr structure = fieldCreate->createStructure(fieldNames,fields);
return PVStructurePtr(new PVStructure(structure));
}
StructureConstPtr structure = structToClone->getStructure();
PVStructurePtr pvStructure(new PVStructure(structure));
getConvert()->copyStructure(structToClone,pvStructure);
return pvStructure;
}
PVDataCreatePtr PVDataCreate::getPVDataCreate()
{
static PVDataCreatePtr pvDataCreate;
static Mutex mutex;
Lock xx(mutex);
if(pvDataCreate.get()==0) pvDataCreate = PVDataCreatePtr(new PVDataCreate());
return pvDataCreate;
}
PVDataCreatePtr getPVDataCreate() {
return PVDataCreate::getPVDataCreate();
}
}}

View File

@@ -1,296 +0,0 @@
/*PVField.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/lock.h>
#include <pv/pvData.h>
#include <pv/factory.h>
#include <pv/convert.h>
using std::tr1::const_pointer_cast;
using std::size_t;
namespace epics { namespace pvData {
PVField::PVField(FieldConstPtr field)
: notImplemented("not implemented"),
parent(NULL),field(field),
fieldOffset(0), nextFieldOffset(0),
immutable(false),
convert(getConvert())
{
}
PVField::~PVField()
{ }
void PVField::message(
String message,
MessageType messageType,
String fullFieldName)
{
if(parent!=NULL) {
if(fullFieldName.length()>0) {
fullFieldName = fieldName + '.' + fullFieldName;
} else {
fullFieldName = fieldName;
}
parent->message(message,messageType,fullFieldName);
return;
}
message = fullFieldName + " " + message;
if(requester) {
requester->message(message,messageType);
} else {
printf("%s %s %s\n",
getMessageTypeName(messageType).c_str(),
fieldName.c_str(),
message.c_str());
}
}
void PVField::message(String message,MessageType messageType)
{
PVField::message(message,messageType,"");
}
String PVField::getFieldName() const
{
return fieldName;
}
void PVField::setRequester(RequesterPtr const &req)
{
if(parent!=NULL) {
throw std::logic_error(
"PVField::setRequester only legal for top level structure");
}
if(requester.get()!=NULL) {
if(requester.get()==req.get()) return;
throw std::logic_error(
"PVField::setRequester requester is already present");
}
requester = req;
}
size_t PVField::getFieldOffset() const
{
if(nextFieldOffset==0) computeOffset(this);
return fieldOffset;
}
size_t PVField::getNextFieldOffset() const
{
if(nextFieldOffset==0) computeOffset(this);
return nextFieldOffset;
}
size_t PVField::getNumberFields() const
{
if(nextFieldOffset==0) computeOffset(this);
return (nextFieldOffset - fieldOffset);
}
PVAuxInfoPtr & PVField::getPVAuxInfo(){
if(pvAuxInfo.get()==NULL) {
pvAuxInfo = PVAuxInfoPtr(new PVAuxInfo(this));
}
return pvAuxInfo;
}
bool PVField::isImmutable() const {return immutable;}
void PVField::setImmutable() {immutable = true;}
const FieldConstPtr & PVField::getField() const {return field;}
PVStructure *PVField::getParent() const {return parent;}
void PVField::replacePVField(const PVFieldPtr & newPVField)
{
if(parent==NULL) {
throw std::logic_error("no parent");
}
PVFieldPtrArray pvFields = parent->getPVFields();
StructureConstPtr structure = parent->getStructure();
StringArray fieldNames = structure->getFieldNames();
for(size_t i=0; i<fieldNames.size(); i++) {
if(newPVField->getFieldName().compare(fieldNames[i]) == 0) {
pvFields[i] = newPVField;
return;
}
}
throw std::logic_error("Did not find field in parent");
}
void PVField::replaceField(FieldConstPtr &xxx)
{
field = xxx;
}
void PVField::renameField(String const & newName)
{
if(parent==NULL) {
throw std::logic_error("no parent");
}
std::tr1::shared_ptr<Structure> parentStructure = const_pointer_cast<Structure>(
parent->getStructure());
PVFieldPtrArray pvFields = parent->getPVFields();
for(size_t i=0; i<pvFields.size(); i++) {
if(pvFields[i].get()==this) {
parentStructure->renameField(i,newName);
fieldName = newName;
return;
}
}
throw std::logic_error("Did not find field in parent");
}
void PVField::postPut()
{
if(postHandler.get()!=NULL) postHandler->postPut();
}
void PVField::setPostHandler(PostHandlerPtr const &handler)
{
if(postHandler.get()!=NULL) {
if(postHandler.get()==handler.get()) return;
throw std::logic_error(
"PVField::setPostHandler a postHandler is already registered");
}
postHandler = handler;
}
void PVField::setParentAndName(PVStructure * xxx,String const & name)
{
parent = xxx;
fieldName = name;
}
bool PVField::equals(PVField &pv)
{
return convert->equals(*this,pv);
}
void PVField::toString(StringBuilder buf)
{
toString(buf,0);
}
void PVField::toString(StringBuilder buf,int indentLevel)
{
convert->getString(buf,this,indentLevel);
if(pvAuxInfo.get()!=NULL) pvAuxInfo->toString(buf,indentLevel);
}
std::ostream& operator<<(std::ostream& o, const PVField& f)
{
std::ostream& ro = f.dumpValue(o);
// TODO I do not want to call getPVAuxInfo() since it lazily creates a new instance of it
//if (f.pvAuxInfo.get()!=NULL) ro << *(f.pvAuxInfo.get());
return ro;
};
namespace format
{
std::ostream& operator<<(std::ostream& os, indent_level const& indent)
{
indent_value(os) = indent.level;
return os;
}
std::ostream& operator<<(std::ostream& os, indent const&)
{
long il = indent_value(os);
std::size_t spaces = static_cast<std::size_t>(il) * 4;
return os << std::string(spaces, ' ');
}
array_at_internal operator<<(std::ostream& str, array_at const& manip)
{
return array_at_internal(manip.index, str);
}
};
void PVField::computeOffset(const PVField * pvField) {
const PVStructure * pvTop = pvField->getParent();
if(pvTop==NULL) {
if(pvField->getField()->getType()!=structure) {
PVField *xxx = const_cast<PVField *>(pvField);
xxx->fieldOffset = 0;
xxx->nextFieldOffset = 1;
return;
}
pvTop = static_cast<const PVStructure *>(pvField);
} else {
while(pvTop->getParent()!=NULL) pvTop = pvTop->getParent();
}
int offset = 0;
int nextOffset = 1;
PVFieldPtrArray pvFields = pvTop->getPVFields();
for(size_t i=0; i < pvTop->getStructure()->getNumberFields(); i++) {
offset = nextOffset;
PVField *pvField = pvFields[i].get();
FieldConstPtr field = pvField->getField();
switch(field->getType()) {
case scalar:
case scalarArray:
case structureArray:{
nextOffset++;
pvField->fieldOffset = offset;
pvField->nextFieldOffset = nextOffset;
break;
}
case structure: {
pvField->computeOffset(pvField,offset);
nextOffset = pvField->getNextFieldOffset();
}
}
}
PVField *top = (PVField *)pvTop;
PVField *xxx = const_cast<PVField *>(top);
xxx->fieldOffset = 0;
xxx->nextFieldOffset = nextOffset;
}
void PVField::computeOffset(const PVField * pvField,size_t offset) {
int beginOffset = offset;
int nextOffset = offset + 1;
const PVStructure *pvStructure = static_cast<const PVStructure *>(pvField);
const PVFieldPtrArray pvFields = pvStructure->getPVFields();
for(size_t i=0; i < pvStructure->getStructure()->getNumberFields(); i++) {
offset = nextOffset;
PVField *pvSubField = pvFields[i].get();
FieldConstPtr field = pvSubField->getField();
switch(field->getType()) {
case scalar:
case scalarArray:
case structureArray: {
nextOffset++;
pvSubField->fieldOffset = offset;
pvSubField->nextFieldOffset = nextOffset;
break;
}
case structure: {
pvSubField->computeOffset(pvSubField,offset);
nextOffset = pvSubField->getNextFieldOffset();
}
}
}
PVField *xxx = const_cast<PVField *>(pvField);
xxx->fieldOffset = beginOffset;
xxx->nextFieldOffset = nextOffset;
}
}}

View File

@@ -1,42 +0,0 @@
/*PVScalar.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/pvData.h>
#include <pv/factory.h>
using std::tr1::static_pointer_cast;
namespace epics { namespace pvData {
PVScalar::~PVScalar() {}
PVScalar::PVScalar(ScalarConstPtr const & scalar)
: PVField(scalar) {}
const ScalarConstPtr PVScalar::getScalar() const
{
return static_pointer_cast<const Scalar>(PVField::getField());
}
template<>
std::ostream& PVScalarValue<int8>::dumpValue(std::ostream& o) const
{
return o << static_cast<int>(get());
}
template<>
std::ostream& PVScalarValue<uint8>::dumpValue(std::ostream& o) const
{
return o << static_cast<unsigned int>(get());
}
}}

View File

@@ -1,732 +0,0 @@
/*PVStructure.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <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::size_t;
namespace epics { namespace pvData {
PVFieldPtr PVStructure::nullPVField;
PVBooleanPtr PVStructure::nullPVBoolean;
PVBytePtr PVStructure::nullPVByte;
PVShortPtr PVStructure::nullPVShort;
PVIntPtr PVStructure::nullPVInt;
PVLongPtr PVStructure::nullPVLong;
PVUBytePtr PVStructure::nullPVUByte;
PVUShortPtr PVStructure::nullPVUShort;
PVUIntPtr PVStructure::nullPVUInt;
PVULongPtr PVStructure::nullPVULong;
PVFloatPtr PVStructure::nullPVFloat;
PVDoublePtr PVStructure::nullPVDouble;
PVStringPtr PVStructure::nullPVString;
PVStructurePtr PVStructure::nullPVStructure;
PVStructureArrayPtr PVStructure::nullPVStructureArray;
PVScalarArrayPtr PVStructure::nullPVScalarArray;
static PVFieldPtr findSubField(
String const &fieldName,
const PVStructure *pvStructure);
PVStructure::PVStructure(StructureConstPtr const & structurePtr)
: PVField(structurePtr),
structurePtr(structurePtr),
extendsStructureName("")
{
size_t numberFields = structurePtr->getNumberFields();
FieldConstPtrArray fields = structurePtr->getFields();
StringArray fieldNames = structurePtr->getFieldNames();
// PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
pvFields.reserve(numberFields);
PVDataCreatePtr pvDataCreate = getPVDataCreate();
for(size_t i=0; i<numberFields; i++) {
pvFields.push_back(pvDataCreate->createPVField(fields[i]));
}
for(size_t i=0; i<numberFields; i++) {
pvFields[i]->setParentAndName(this,fieldNames[i]);
}
}
PVStructure::PVStructure(StructureConstPtr const & structurePtr,
PVFieldPtrArray const & pvs
)
: PVField(structurePtr),
structurePtr(structurePtr),
extendsStructureName("")
{
size_t numberFields = structurePtr->getNumberFields();
StringArray fieldNames = structurePtr->getFieldNames();
pvFields.reserve(numberFields);
for(size_t i=0; i<numberFields; i++) {
pvFields.push_back(pvs[i]);
}
for(size_t i=0; i<numberFields; i++) {
pvFields[i]->setParentAndName(this,fieldNames[i]);
}
}
PVStructure::~PVStructure()
{
}
void PVStructure::setImmutable()
{
size_t numFields = pvFields.size();
for(size_t i=0; i<numFields; i++) {
PVFieldPtr pvField = pvFields[i];
pvField->setImmutable();
}
PVField::setImmutable();
}
StructureConstPtr PVStructure::getStructure() const
{
return structurePtr;
}
const PVFieldPtrArray & PVStructure::getPVFields() const
{
return pvFields;
}
PVFieldPtr PVStructure::getSubField(String const &fieldName) const
{
return findSubField(fieldName,this);
}
PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const
{
if(fieldOffset<=getFieldOffset()) {
return nullPVField;
}
if(fieldOffset>getNextFieldOffset()) return nullPVField;
size_t numFields = pvFields.size();
for(size_t i=0; i<numFields; i++) {
PVFieldPtr pvField = pvFields[i];
if(pvField->getFieldOffset()==fieldOffset) return pvFields[i];
if(pvField->getNextFieldOffset()<=fieldOffset) continue;
if(pvField->getField()->getType()==structure) {
PVStructure *pvStructure = static_cast<PVStructure *>(pvField.get());
return pvStructure->getSubField(fieldOffset);
}
}
throw std::logic_error("PVStructure.getSubField: Logic error");
}
void PVStructure::fixParentStructure()
{
PVStructure *parent = getParent();
if(parent==NULL) return;
StructureConstPtr parentStructure = parent->structurePtr;
String fieldName = getFieldName();
size_t index = parentStructure->getFieldIndex(fieldName);
StringArray const &fieldNames = parentStructure->getFieldNames();
size_t num = fieldNames.size();
FieldConstPtrArray fields(num);
FieldConstPtrArray const & oldFields = parentStructure->getFields();
for(size_t i=0; i< num; i++) {
if(i==index) {
fields[i] = structurePtr;
} else {
fields[i] = oldFields[i];
}
}
FieldConstPtr field = getFieldCreate()->createStructure(
parentStructure->getID(),fieldNames,fields);
parent->replaceField(field);
parent->fixParentStructure();
}
void PVStructure::appendPVField(
String const &fieldName,
PVFieldPtr const & pvField)
{
size_t origLength = pvFields.size();
size_t newLength = origLength+1;
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
xxx->push_back(pvField);
FieldConstPtr field = getFieldCreate()->appendField(
structurePtr,fieldName,pvField->getField());
replaceField(field);
structurePtr = static_pointer_cast<const Structure>(field);
StringArray fieldNames = structurePtr->getFieldNames();
for(size_t i=0; i<newLength; i++) {
pvFields[i]->setParentAndName(this,fieldNames[i]);
}
fixParentStructure();
}
void PVStructure::appendPVFields(
StringArray const & fieldNames,
PVFieldPtrArray const & pvFields)
{
size_t origLength = this->pvFields.size();
size_t extra = fieldNames.size();
if(extra==0) return;
size_t newLength = origLength + extra;
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&this->pvFields);
xxx->reserve(newLength);
for(size_t i=0; i<extra; i++) {
xxx->push_back(pvFields[i]);
}
FieldConstPtrArray fields;
fields.reserve(extra);
for(size_t i=0; i<extra; i++) fields.push_back(pvFields[i]->getField());
FieldConstPtr field = getFieldCreate()->appendFields(
structurePtr,fieldNames,fields);
replaceField(field);
structurePtr = static_pointer_cast<const Structure>(field);
StringArray names = structurePtr->getFieldNames();
for(size_t i=0; i<newLength; i++) {
(*xxx)[i]->setParentAndName(this,names[i]);
}
fixParentStructure();
}
void PVStructure::removePVField(String const &fieldName)
{
PVFieldPtr pvField = getSubField(fieldName);
if(pvField.get()==NULL) {
String message("removePVField ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return;
}
size_t origLength = pvFields.size();
size_t newLength = origLength - 1;
PVFieldPtrArray const & origPVFields = pvFields;
FieldConstPtrArray origFields = structurePtr->getFields();
PVFieldPtrArray newPVFields;
newPVFields.reserve(newLength);
StringArray newFieldNames;
newFieldNames.reserve(newLength);
FieldConstPtrArray fields;
fields.reserve(newLength);
for(size_t i=0; i<origLength; i++) {
if(origPVFields[i]!=pvField) {
newFieldNames.push_back(origPVFields[i]->getFieldName());
newPVFields.push_back(origPVFields[i]);
fields.push_back(origFields[i]);
}
}
PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields);
xxx->swap(newPVFields);
FieldConstPtr field = getFieldCreate()->createStructure(
structurePtr->getID(),newFieldNames,fields);
replaceField(field);
structurePtr = static_pointer_cast<const Structure>(field);
StringArray fieldNames = structurePtr->getFieldNames();
for(size_t i=0; i<newLength; i++) {
pvFields[i]->setParentAndName(this,fieldNames[i]);
}
}
PVBooleanPtr PVStructure::getBooleanField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVBoolean;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvBoolean) {
return std::tr1::static_pointer_cast<PVBoolean>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type boolean ";
this->message(message, errorMessage);
return nullPVBoolean;
}
PVBytePtr PVStructure::getByteField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVByte;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvByte) {
return std::tr1::static_pointer_cast<PVByte>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type byte ";
this->message(message, errorMessage);
return nullPVByte;
}
PVShortPtr PVStructure::getShortField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVShort;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvShort) {
return std::tr1::static_pointer_cast<PVShort>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type short ";
this->message(message, errorMessage);
return nullPVShort;
}
PVIntPtr PVStructure::getIntField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVInt;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvInt) {
return std::tr1::static_pointer_cast<PVInt>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type int ";
this->message(message, errorMessage);
return nullPVInt;
}
PVLongPtr PVStructure::getLongField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVLong;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvLong) {
return std::tr1::static_pointer_cast<PVLong>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type long ";
this->message(message, errorMessage);
return nullPVLong;
}
PVUBytePtr PVStructure::getUByteField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVUByte;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvUByte) {
return std::tr1::static_pointer_cast<PVUByte>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type byte ";
this->message(message, errorMessage);
return nullPVUByte;
}
PVUShortPtr PVStructure::getUShortField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVUShort;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvUShort) {
return std::tr1::static_pointer_cast<PVUShort>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type short ";
this->message(message, errorMessage);
return nullPVUShort;
}
PVUIntPtr PVStructure::getUIntField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVUInt;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvUInt) {
return std::tr1::static_pointer_cast<PVUInt>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type int ";
this->message(message, errorMessage);
return nullPVUInt;
}
PVULongPtr PVStructure::getULongField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVULong;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvULong) {
return std::tr1::static_pointer_cast<PVULong>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type long ";
this->message(message, errorMessage);
return nullPVULong;
}
PVFloatPtr PVStructure::getFloatField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVFloat;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvFloat) {
return std::tr1::static_pointer_cast<PVFloat>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type float ";
this->message(message, errorMessage);
return nullPVFloat;
}
PVDoublePtr PVStructure::getDoubleField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVDouble;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvDouble) {
return std::tr1::static_pointer_cast<PVDouble>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type double ";
this->message(message, errorMessage);
return nullPVDouble;
}
PVStringPtr PVStructure::getStringField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVString;
}
if(pvField->getField()->getType()==scalar) {
ScalarConstPtr pscalar = static_pointer_cast<const Scalar>(
pvField->getField());
if(pscalar->getScalarType()==pvString) {
return std::tr1::static_pointer_cast<PVString>(pvField);
}
}
String message("fieldName ");
message += fieldName + " does not have type string ";
this->message(message, errorMessage);
return nullPVString;
}
PVStructurePtr PVStructure::getStructureField(String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVStructure;
}
if(pvField->getField()->getType()==structure) {
return std::tr1::static_pointer_cast<PVStructure>(pvField);
}
String message("fieldName ");
message += fieldName + " does not have type structure ";
this->message(message, errorMessage);
return nullPVStructure;
}
PVScalarArrayPtr PVStructure::getScalarArrayField(
String const &fieldName,ScalarType elementType)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVScalarArray;
}
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 nullPVScalarArray;
}
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 nullPVScalarArray;
}
return std::tr1::static_pointer_cast<PVScalarArray>(pvField);
}
PVStructureArrayPtr PVStructure::getStructureArrayField(
String const &fieldName)
{
PVFieldPtr pvField = findSubField(fieldName,this);
if(pvField.get()==NULL) {
String message("fieldName ");
message += fieldName + " does not exist";
this->message(message, errorMessage);
return nullPVStructureArray;
}
if(pvField->getField()->getType()==structureArray) {
return std::tr1::static_pointer_cast<PVStructureArray>(pvField);
}
String message("fieldName ");
message += fieldName + " does not have type structureArray ";
this->message(message, errorMessage);
return nullPVStructureArray;
}
String PVStructure::getExtendsStructureName() const
{
return extendsStructureName;
}
bool PVStructure::putExtendsStructureName(
String const &xxx)
{
if(extendsStructureName.length()!=0) return false;
extendsStructureName = xxx;
return true;
}
void PVStructure::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const {
size_t fieldsSize = pvFields.size();
for(size_t i = 0; i<fieldsSize; i++)
pvFields[i]->serialize(pbuffer, pflusher);
}
void PVStructure::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
size_t fieldsSize = pvFields.size();
for(size_t i = 0; i<fieldsSize; i++)
pvFields[i]->deserialize(pbuffer, pcontrol);
}
void PVStructure::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, BitSet *pbitSet) const {
PVStructure* nonConstThis = const_cast<PVStructure*>(this);
size_t numberFields = nonConstThis->getNumberFields();
size_t offset = nonConstThis->getFieldOffset();
int32 next = pbitSet->nextSetBit(offset);
// no more changes or no changes in this structure
if(next<0||next>=static_cast<int32>(offset+numberFields)) return;
// entire structure
if(static_cast<int32>(offset)==next) {
serialize(pbuffer, pflusher);
return;
}
size_t fieldsSize = pvFields.size();
for(size_t i = 0; i<fieldsSize; i++) {
PVFieldPtr pvField = pvFields[i];
offset = pvField->getFieldOffset();
int32 inumberFields = pvField->getNumberFields();
next = pbitSet->nextSetBit(offset);
// no more changes
if(next<0) return;
// no change in this pvField
if(next>=static_cast<int32>(offset+inumberFields)) continue;
// serialize field or fields
if(inumberFields==1) {
pvField->serialize(pbuffer, pflusher);
} else {
PVStructurePtr pvStructure = std::tr1::static_pointer_cast<PVStructure>(pvField);
pvStructure->serialize(pbuffer, pflusher, pbitSet);
}
}
}
void PVStructure::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol, BitSet *pbitSet) {
size_t offset = getFieldOffset();
size_t numberFields = getNumberFields();
int32 next = pbitSet->nextSetBit(offset);
// no more changes or no changes in this structure
if(next<0||next>=static_cast<int32>(offset+numberFields)) return;
// entire structure
if(static_cast<int32>(offset)==next) {
deserialize(pbuffer, pcontrol);
return;
}
size_t fieldsSize = pvFields.size();
for(size_t i = 0; i<fieldsSize; i++) {
PVFieldPtr pvField = pvFields[i];
offset = pvField->getFieldOffset();
int32 inumberFields = pvField->getNumberFields();
next = pbitSet->nextSetBit(offset);
// no more changes
if(next<0) return;
// no change in this pvField
if(next>=static_cast<int32>(offset+inumberFields)) continue;
// deserialize field or fields
if(inumberFields==1) {
pvField->deserialize(pbuffer, pcontrol);
} else {
PVStructurePtr pvStructure = std::tr1::static_pointer_cast<PVStructure>(pvField);
pvStructure->deserialize(pbuffer, pcontrol, pbitSet);
}
}
}
static PVFieldPtr findSubField(
String const & fieldName,
PVStructure const *pvStructure)
{
if( fieldName.length()<1) return PVFieldPtr();
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();
PVFieldPtr pvField;
size_t numFields = pvStructure->getStructure()->getNumberFields();
for(size_t i=0; i<numFields; i++) {
pvField = pvFields[i];
size_t result = pvField->getFieldName().compare(name);
if(result==0) {
if(restOfName.length()==0) return pvFields[i];
if(pvField->getField()->getType()!=structure) return PVFieldPtr();
PVStructurePtr pvStructure =
std::tr1::static_pointer_cast<PVStructure>(pvField);
return findSubField(restOfName,pvStructure.get());
}
}
return PVFieldPtr();
}
std::ostream& PVStructure::dumpValue(std::ostream& o) const
{
o << format::indent() << getStructure()->getID() << ' ' << getFieldName();
String extendsName = getExtendsStructureName();
if(extendsName.length()>0) {
o << " extends " << extendsName;
}
o << std::endl;
{
format::indent_scope s(o);
PVFieldPtrArray const & fieldsData = getPVFields();
if (fieldsData.size() != 0) {
size_t length = getStructure()->getNumberFields();
for(size_t i=0; i<length; i++) {
PVFieldPtr fieldField = fieldsData[i];
Type type = fieldField->getField()->getType();
if (type == scalar || type == scalarArray)
o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl;
else
o << *(fieldField.get());
}
}
}
return o;
}
}}

View File

@@ -1,276 +0,0 @@
/*PVStructureArray.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/pvData.h>
#include <pv/convert.h>
#include <pv/factory.h>
#include <pv/serializeHelper.h>
using std::tr1::static_pointer_cast;
using std::size_t;
namespace epics { namespace pvData {
PVStructureArray::PVStructureArray(StructureArrayConstPtr const & structureArray)
: PVArray(structureArray),
structureArray(structureArray),
value(std::tr1::shared_ptr<PVStructurePtrArray>(new PVStructurePtrArray()))
{
}
size_t PVStructureArray::append(size_t number)
{
size_t currentLength = getLength();
size_t newLength = currentLength + number;
setCapacity(newLength);
setLength(newLength);
StructureConstPtr structure = structureArray->getStructure();
PVStructurePtrArray *to = value.get();
for(size_t i=currentLength; i<newLength; i++) {
(*to)[i] =getPVDataCreate()->createPVStructure(structure);
}
return newLength;
}
bool PVStructureArray::remove(size_t offset,size_t number)
{
size_t length = getLength();
if(offset+number>length) return false;
PVStructurePtrArray vec = *value.get();
for(size_t i = offset; i+number < length; i++) {
vec[i] = vec[i + number];
}
size_t newLength = length - number;
setCapacityLength(newLength,newLength);
return true;
}
void PVStructureArray::compress() {
size_t length = getCapacity();
size_t newLength = 0;
PVStructurePtrArray vec = *value.get();
for(size_t i=0; i<length; i++) {
if(vec[i].get()!=NULL) {
newLength++;
continue;
}
// find first non 0
size_t notNull = 0;
for(size_t j=i+1;j<length;j++) {
if(vec[j].get()!=NULL) {
notNull = j;
break;
}
}
if(notNull!=0) {
vec[i] = vec[notNull];
vec[notNull].reset();
newLength++;
continue;
}
break;
}
setCapacityLength(newLength,newLength);
}
void PVStructureArray::setCapacity(size_t capacity) {
if(getCapacity()==capacity) return;
if(!isCapacityMutable()) {
std::string message("not capacityMutable");
PVField::message(message, errorMessage);
return;
}
size_t length = getLength();
if(length>capacity) length = capacity;
size_t oldCapacity = getCapacity();
if(oldCapacity>capacity) {
PVStructurePtrArray array;
array.reserve(capacity);
array.resize(length);
PVStructurePtr * from = get();
for (size_t i=0; i<length; i++) array[i] = from[i];
value->swap(array);
} else {
value->reserve(capacity);
}
setCapacityLength(capacity,length);
}
void PVStructureArray::setLength(size_t length) {
if(PVArray::getLength()==length) return;
size_t capacity = PVArray::getCapacity();
if(length>capacity) {
if(!PVArray::isCapacityMutable()) {
std::string message("not capacityMutable");
PVField::message(message, errorMessage);
return;
}
setCapacity(length);
}
value->resize(length);
PVArray::setCapacityLength(capacity,length);
}
StructureArrayConstPtr PVStructureArray::getStructureArray() const
{
return structureArray;
}
size_t PVStructureArray::get(
size_t offset, size_t len, StructureArrayData &data)
{
size_t n = len;
size_t length = getLength();
if(offset+len > length) {
n = length - offset;
//if(n<0) n = 0;
}
data.data = *value.get();
data.offset = offset;
return n;
}
size_t PVStructureArray::put(size_t offset,size_t len,
const_vector const & from, size_t fromOffset)
{
if(isImmutable()) {
message(String("field is immutable"), errorMessage);
return 0;
}
if(&from==value.get()) return 0;
if(len<1) return 0;
size_t length = getLength();
size_t capacity = getCapacity();
if(offset+len > length) {
size_t newlength = offset + len;
if(newlength>capacity) {
setCapacity(newlength);
capacity = getCapacity();
newlength = capacity;
len = newlength - offset;
if(len<=0) return 0;
}
length = newlength;
setLength(length);
}
PVStructurePtrArray *to = value.get();
StructureConstPtr structure = structureArray->getStructure();
for(size_t i=0; i<len; i++) {
PVStructurePtr frompv = from[i+fromOffset];
if(frompv.get()!=NULL) {
if(frompv->getStructure()!=structure) {
throw std::invalid_argument(String(
"Element is not a compatible structure"));
}
}
(*to)[i+offset] = frompv;
}
postPut();
setLength(length);
return len;
}
void PVStructureArray::shareData(
std::tr1::shared_ptr<std::vector<PVStructurePtr> > const & sharedValue,
std::size_t capacity,
std::size_t length)
{
value = sharedValue;
setCapacityLength(capacity,length);
}
void PVStructureArray::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher) const {
serialize(pbuffer, pflusher, 0, getLength());
}
void PVStructureArray::deserialize(ByteBuffer *pbuffer,
DeserializableControl *pcontrol) {
size_t size = SerializeHelper::readSize(pbuffer, pcontrol);
//if(size>=0) {
// prepare array, if necessary
if(size>getCapacity()) setCapacity(size);
setLength(size);
PVStructurePtrArray *pvArray = value.get();
for(size_t i = 0; i<size; i++) {
pcontrol->ensureData(1);
size_t temp = pbuffer->getByte();
if(temp==0) {
(*pvArray)[i].reset();
}
else {
if((*pvArray)[i].get()==NULL) {
StructureConstPtr structure = structureArray->getStructure();
(*pvArray)[i] = getPVDataCreate()->createPVStructure(structure);
}
(*pvArray)[i]->deserialize(pbuffer, pcontrol);
}
}
postPut();
//}
}
void PVStructureArray::serialize(ByteBuffer *pbuffer,
SerializableControl *pflusher, size_t offset, size_t count) const {
// cache
size_t length = getLength();
// check bounds
/*if(offset<0)
offset = 0;
else*/ if(offset>length) offset = length;
//if(count<0) count = length;
size_t maxCount = length-offset;
if(count>maxCount) count = maxCount;
PVStructurePtrArray pvArray = *value.get();
// write
SerializeHelper::writeSize(count, pbuffer, pflusher);
for(size_t i = 0; i<count; i++) {
if(pbuffer->getRemaining()<1) pflusher->flushSerializeBuffer();
PVStructurePtr pvStructure = pvArray[i+offset];
if(pvStructure.get()==NULL) {
pbuffer->putByte(0);
}
else {
pbuffer->putByte(1);
pvStructure->serialize(pbuffer, pflusher);
}
}
}
std::ostream& PVStructureArray::dumpValue(std::ostream& o) const
{
o << format::indent() << getStructureArray()->getID() << ' ' << getFieldName() << std::endl;
size_t length = getLength();
if (length > 0)
{
format::indent_scope s(o);
for (size_t i = 0; i < length; i++)
dumpValue(o, i);
}
return o;
}
std::ostream& PVStructureArray::dumpValue(std::ostream& o, std::size_t index) const
{
PVStructurePtrArray pvArray = *value.get();
PVStructurePtr pvStructure = pvArray[index];
return o << *(pvStructure.get());
return o;
}
}}

View File

@@ -1,643 +0,0 @@
/* StandardField.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <string>
#include <cstdio>
#include <stdexcept>
#include <epicsThread.h>
#include <epicsExit.h>
#include <pv/lock.h>
#include <pv/pvIntrospect.h>
#include <pv/standardField.h>
using std::tr1::static_pointer_cast;
namespace epics { namespace pvData {
StandardField::StandardField()
: fieldCreate(getFieldCreate()),
notImplemented("not implemented"),
valueFieldName("value")
{}
void StandardField::init()
{
createAlarm();
createTimeStamp();
createDisplay();
createControl();
createBooleanAlarm();
createByteAlarm();
createShortAlarm();
createIntAlarm();
createLongAlarm();
createUByteAlarm();
createUShortAlarm();
createUIntAlarm();
createULongAlarm();
createFloatAlarm();
createDoubleAlarm();
createEnumeratedAlarm();
}
StandardField::~StandardField(){}
StructureConstPtr StandardField::createProperties(String id,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==epics::pvData::scalar || type==epics::pvData::scalarArray) {
ScalarType scalarType = (type==epics::pvData::scalar) ?
static_pointer_cast<const Scalar>(field)->getScalarType() :
static_pointer_cast<const ScalarArray>(field)->getElementType();
switch(scalarType) {
case pvBoolean: valueAlarm = booleanAlarmField; break;
case pvByte: valueAlarm = byteAlarmField; break;
case pvShort: valueAlarm = shortAlarmField; break;
case pvInt: valueAlarm = intAlarmField; break;
case pvLong: valueAlarm = longAlarmField; break;
case pvUByte: valueAlarm = ubyteAlarmField; break;
case pvUShort: valueAlarm = ushortAlarmField; break;
case pvUInt: valueAlarm = uintAlarmField; break;
case pvULong: valueAlarm = ulongAlarmField; break;
case pvFloat: valueAlarm = floatAlarmField; break;
case pvDouble: valueAlarm = doubleAlarmField; break;
case pvString:
throw std::logic_error(String("valueAlarm property not supported for pvString"));
}
break;
}
if(type==structure) {
StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field);
StringArray names = structurePtr->getFieldNames();
if(names.size()==2) {
FieldConstPtrArray fields = structurePtr->getFields();
FieldConstPtr first = fields[0];
FieldConstPtr second = fields[1];
String nameFirst = names[0];
String nameSecond = names[1];
int compareFirst = nameFirst.compare("index");
int compareSecond = nameSecond.compare("choices");
if(compareFirst==0 && compareSecond==0) {
if(first->getType()==epics::pvData::scalar
&& second->getType()==epics::pvData::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"));
}
size_t numFields = numProp+1;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
int next = 0;
names[0] = "value";
fields[next++] = field;
if(gotAlarm) {
names[next] = "alarm";
fields[next++] = alarmField;
}
if(gotTimeStamp) {
names[next] = "timeStamp";
fields[next++] = timeStampField;
}
if(gotDisplay) {
names[next] = "display";
fields[next++] = displayField;
}
if(gotControl) {
names[next] = "control";
fields[next++] = controlField;
}
if(gotValueAlarm) {
names[next] = "valueAlarm";
fields[next++] = valueAlarm;
}
return fieldCreate->createStructure(id,names,fields);
}
void StandardField::createAlarm() {
size_t num = 3;
FieldConstPtrArray fields(num);
StringArray names(num);
names[0] = "severity";
names[1] = "status";
names[2] = "message";
fields[0] = fieldCreate->createScalar(pvInt);
fields[1] = fieldCreate->createScalar(pvInt);
fields[2] = fieldCreate->createScalar(pvString);
alarmField = fieldCreate->createStructure("alarm_t",names,fields);
}
void StandardField::createTimeStamp() {
size_t num = 3;
FieldConstPtrArray fields(num);
StringArray names(num);
names[0] = "secondsPastEpoch";
names[1] = "nanoSeconds";
names[2] = "userTag";
fields[0] = fieldCreate->createScalar(pvLong);
fields[1] = fieldCreate->createScalar(pvInt);
fields[2] = fieldCreate->createScalar(pvInt);
timeStampField = fieldCreate->createStructure("time_t",names,fields);
}
void StandardField::createDisplay() {
size_t num = 5;
FieldConstPtrArray fields(num);
StringArray names(num);
names[0] = "limitLow";
names[1] = "limitHigh";
names[2] = "description";
names[3] = "format";
names[4] = "units";
fields[0] = fieldCreate->createScalar(pvDouble);
fields[1] = fieldCreate->createScalar(pvDouble);
fields[2] = fieldCreate->createScalar(pvString);
fields[3] = fieldCreate->createScalar(pvString);
fields[4] = fieldCreate->createScalar(pvString);
displayField = fieldCreate->createStructure("display_t",names,fields);
}
void StandardField::createControl() {
size_t num = 3;
FieldConstPtrArray fields(num);
StringArray names(num);
names[0] = "limitLow";
names[1] = "limitHigh";
names[2] = "minStep";
fields[0] = fieldCreate->createScalar(pvDouble);
fields[1] = fieldCreate->createScalar(pvDouble);
fields[2] = fieldCreate->createScalar(pvDouble);
controlField = fieldCreate->createStructure("control_t",names,fields);
}
void StandardField::createBooleanAlarm() {
size_t numFields = 4;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "falseSeverity";
names[2] = "trueSeverity";
names[3] = "changeStateSeverity";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvInt);
fields[2] = fieldCreate->createScalar(pvInt);
fields[3] = fieldCreate->createScalar(pvInt);
booleanAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createByteAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvByte);
fields[2] = fieldCreate->createScalar(pvByte);
fields[3] = fieldCreate->createScalar(pvByte);
fields[4] = fieldCreate->createScalar(pvByte);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvByte);
byteAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createShortAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvShort);
fields[2] = fieldCreate->createScalar(pvShort);
fields[3] = fieldCreate->createScalar(pvShort);
fields[4] = fieldCreate->createScalar(pvShort);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvShort);
shortAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createIntAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvInt);
fields[2] = fieldCreate->createScalar(pvInt);
fields[3] = fieldCreate->createScalar(pvInt);
fields[4] = fieldCreate->createScalar(pvInt);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvInt);
intAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createLongAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvLong);
fields[2] = fieldCreate->createScalar(pvLong);
fields[3] = fieldCreate->createScalar(pvLong);
fields[4] = fieldCreate->createScalar(pvLong);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvLong);
longAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createUByteAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvUByte);
fields[2] = fieldCreate->createScalar(pvUByte);
fields[3] = fieldCreate->createScalar(pvUByte);
fields[4] = fieldCreate->createScalar(pvUByte);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvUByte);
ubyteAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createUShortAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvUShort);
fields[2] = fieldCreate->createScalar(pvUShort);
fields[3] = fieldCreate->createScalar(pvUShort);
fields[4] = fieldCreate->createScalar(pvUShort);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvUShort);
ushortAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createUIntAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvUInt);
fields[2] = fieldCreate->createScalar(pvUInt);
fields[3] = fieldCreate->createScalar(pvUInt);
fields[4] = fieldCreate->createScalar(pvUInt);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvUInt);
uintAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createULongAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvULong);
fields[2] = fieldCreate->createScalar(pvULong);
fields[3] = fieldCreate->createScalar(pvULong);
fields[4] = fieldCreate->createScalar(pvULong);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvULong);
ulongAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createFloatAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvFloat);
fields[2] = fieldCreate->createScalar(pvFloat);
fields[3] = fieldCreate->createScalar(pvFloat);
fields[4] = fieldCreate->createScalar(pvFloat);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvFloat);
floatAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createDoubleAlarm() {
size_t numFields = 10;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "lowAlarmLimit";
names[2] = "lowWarningLimit";
names[3] = "highWarningLimit";
names[4] = "highAlarmLimit";
names[5] = "lowAlarmSeverity";
names[6] = "lowWarningSeverity";
names[7] = "highWarningSeverity";
names[8] = "highAlarmSeverity";
names[9] = "hystersis";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalar(pvDouble);
fields[2] = fieldCreate->createScalar(pvDouble);
fields[3] = fieldCreate->createScalar(pvDouble);
fields[4] = fieldCreate->createScalar(pvDouble);
fields[5] = fieldCreate->createScalar(pvInt);
fields[6] = fieldCreate->createScalar(pvInt);
fields[7] = fieldCreate->createScalar(pvInt);
fields[8] = fieldCreate->createScalar(pvInt);
fields[9] = fieldCreate->createScalar(pvDouble);
doubleAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
void StandardField::createEnumeratedAlarm() {
size_t numFields = 3;
FieldConstPtrArray fields(numFields);
StringArray names(numFields);
names[0] = "active";
names[1] = "stateSeverity";
names[2] = "changeStateSeverity";
fields[0] = fieldCreate->createScalar(pvBoolean);
fields[1] = fieldCreate->createScalarArray(pvInt);
fields[2] = fieldCreate->createScalar(pvInt);
enumeratedAlarmField = fieldCreate->createStructure("valueAlarm_t",names,fields);
}
StructureConstPtr StandardField::scalar(
ScalarType type,String const &properties)
{
ScalarConstPtr field = fieldCreate->createScalar(type); // scalar_t
return createProperties("uri:ev4:nt/2012/pwd:NTScalar",field,properties);
}
StructureConstPtr StandardField::scalarArray(
ScalarType elementType, String const &properties)
{
ScalarArrayConstPtr field = fieldCreate->createScalarArray(elementType); // scalar_t[]
return createProperties("uri:ev4:nt/2012/pwd:NTScalarArray",field,properties);
}
StructureConstPtr StandardField::structureArray(
StructureConstPtr const & structure,String const &properties)
{
StructureArrayConstPtr field = fieldCreate->createStructureArray(
structure);
return createProperties("uri:ev4:nt/2012/pwd:NTAny",field,properties);
}
StructureConstPtr StandardField::enumerated()
{
size_t num = 2;
FieldConstPtrArray fields(num);
StringArray names(num);
names[0] = "index";
names[1] = "choices";
fields[0] = fieldCreate->createScalar(pvInt);
fields[1] = fieldCreate->createScalarArray(pvString);
return fieldCreate->createStructure("enum_t",names,fields);
// NOTE: if this method is used to get NTEnum wihtout properties the ID will be wrong!
}
StructureConstPtr StandardField::enumerated(String const &properties)
{
StructureConstPtr field = enumerated(); // enum_t
return createProperties("uri:ev4:nt/2012/pwd:NTEnum",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::ubyteAlarm()
{
return ubyteAlarmField;
}
StructureConstPtr StandardField::shortAlarm()
{
return shortAlarmField;
}
StructureConstPtr StandardField::ushortAlarm()
{
return ushortAlarmField;
}
StructureConstPtr StandardField::intAlarm()
{
return intAlarmField;
}
StructureConstPtr StandardField::uintAlarm()
{
return uintAlarmField;
}
StructureConstPtr StandardField::longAlarm()
{
return longAlarmField;
}
StructureConstPtr StandardField::ulongAlarm()
{
return ulongAlarmField;
}
StructureConstPtr StandardField::floatAlarm()
{
return floatAlarmField;
}
StructureConstPtr StandardField::doubleAlarm()
{
return doubleAlarmField;
}
StructureConstPtr StandardField::enumeratedAlarm()
{
return enumeratedAlarmField;
}
StandardFieldPtr StandardField::getStandardField()
{
static StandardFieldPtr standardFieldCreate;
static Mutex mutex;
Lock xx(mutex);
if(standardFieldCreate.get()==0)
{
standardFieldCreate = StandardFieldPtr(new StandardField());
standardFieldCreate->init();
}
return standardFieldCreate;
}
StandardFieldPtr getStandardField() {
return StandardField::getStandardField();
}
}}

View File

@@ -1,83 +0,0 @@
/*TypeFunc.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <pv/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<=pvULong) return true;
return false;
}
bool isUInteger(ScalarType type) {
if(type>=pvUByte && type<=pvULong) 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",
"ubyte", "ushort", "uint", "ulong",
"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,18 +0,0 @@
/*factory.h*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef FACTORY_H
#define FACTORY_H
namespace epics { namespace pvData {
enum DebugLevel{noDebug,lowDebug,highDebug};
}}
#endif /*FACTORY_H */

View File

@@ -1,400 +0,0 @@
/* bitSet.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mes
*/
#include "string.h"
#include "stdio.h"
#include <pv/bitSet.h>
#include <pv/lock.h>
#include <pv/serializeHelper.h>
namespace epics { namespace pvData {
BitSet::shared_pointer BitSet::create(uint32 nbits)
{
return BitSet::shared_pointer(new BitSet(nbits));
}
BitSet::BitSet() : words(0), wordsLength(0), wordsInUse(0) {
initWords(BITS_PER_WORD);
}
BitSet::BitSet(uint32 nbits) : words(0), wordsLength(0), wordsInUse(0) {
initWords(nbits);
}
BitSet::~BitSet() {
delete[] words;
}
void BitSet::initWords(uint32 nbits) {
uint32 length = (nbits <= 0) ? 1 : wordIndex(nbits-1) + 1;
if (words) delete[] words;
words = new uint64[length];
memset(words, 0, sizeof(uint64)*length);
wordsLength = length;
}
void BitSet::recalculateWordsInUse() {
// wordsInUse is unsigned
if (wordsInUse == 0)
return;
// Traverse the bitset until a used word is found
int32 i;
for (i = (int32)wordsInUse-1; i >= 0; i--)
if (words[i] != 0)
break;
wordsInUse = i+1; // The new logical size
}
void BitSet::ensureCapacity(uint32 wordsRequired) {
if (wordsLength < wordsRequired) {
// create and copy
uint64* newwords = new uint64[wordsRequired];
memset(newwords, 0, sizeof(uint64)*wordsRequired);
memcpy(newwords, words, sizeof(uint64)*wordsLength);
if (words) delete[] words;
words = newwords;
wordsLength = wordsRequired;
}
}
void BitSet::expandTo(uint32 wordIndex) {
uint32 wordsRequired = wordIndex+1;
if (wordsInUse < wordsRequired) {
ensureCapacity(wordsRequired);
wordsInUse = wordsRequired;
}
}
void BitSet::flip(uint32 bitIndex) {
uint32 wordIdx = wordIndex(bitIndex);
expandTo(wordIdx);
words[wordIdx] ^= (((uint64)1) << (bitIndex % BITS_PER_WORD));
recalculateWordsInUse();
}
void BitSet::set(uint32 bitIndex) {
uint32 wordIdx = wordIndex(bitIndex);
expandTo(wordIdx);
words[wordIdx] |= (((uint64)1) << (bitIndex % BITS_PER_WORD));
}
void BitSet::clear(uint32 bitIndex) {
uint32 wordIdx = wordIndex(bitIndex);
if (wordIdx >= wordsInUse)
return;
words[wordIdx] &= ~(((uint64)1) << (bitIndex % BITS_PER_WORD));
recalculateWordsInUse();
}
void BitSet::set(uint32 bitIndex, bool value) {
if (value)
set(bitIndex);
else
clear(bitIndex);
}
bool BitSet::get(uint32 bitIndex) const {
uint32 wordIdx = wordIndex(bitIndex);
return ((wordIdx < wordsInUse)
&& ((words[wordIdx] & (((uint64)1) << (bitIndex % BITS_PER_WORD))) != 0));
}
void BitSet::clear() {
while (wordsInUse > 0)
words[--wordsInUse] = 0;
}
uint32 BitSet::numberOfTrailingZeros(uint64 i) {
// HD, Figure 5-14
uint32 x, y;
if (i == 0) return 64;
uint32 n = 63;
y = (uint32)i; if (y != 0) { n = n -32; x = y; } else x = (uint32)(i>>32);
y = x <<16; if (y != 0) { n = n -16; x = y; }
y = x << 8; if (y != 0) { n = n - 8; x = y; }
y = x << 4; if (y != 0) { n = n - 4; x = y; }
y = x << 2; if (y != 0) { n = n - 2; x = y; }
return n - ((x << 1) >> 31);
}
uint32 BitSet::bitCount(uint64 i) {
// HD, Figure 5-14
i = i - ((i >> 1) & 0x5555555555555555LL);
i = (i & 0x3333333333333333LL) + ((i >> 2) & 0x3333333333333333LL);
i = (i + (i >> 4)) & 0x0f0f0f0f0f0f0f0fLL;
i = i + (i >> 8);
i = i + (i >> 16);
i = i + (i >> 32);
return (uint32)(i & 0x7f);
}
int32 BitSet::nextSetBit(uint32 fromIndex) const {
uint32 u = wordIndex(fromIndex);
if (u >= wordsInUse)
return -1;
uint64 word = words[u] & (WORD_MASK << (fromIndex % BITS_PER_WORD));
while (true) {
if (word != 0)
return (u * BITS_PER_WORD) + numberOfTrailingZeros(word);
if (++u == wordsInUse)
return -1;
word = words[u];
}
}
int32 BitSet::nextClearBit(uint32 fromIndex) const {
// Neither spec nor implementation handle bitsets of maximal length.
uint32 u = wordIndex(fromIndex);
if (u >= wordsInUse)
return fromIndex;
uint64 word = ~words[u] & (WORD_MASK << (fromIndex % BITS_PER_WORD));
while (true) {
if (word != 0)
return (u * BITS_PER_WORD) + numberOfTrailingZeros(word);
if (++u == wordsInUse)
return wordsInUse * BITS_PER_WORD;
word = ~words[u];
}
}
bool BitSet::isEmpty() const {
return (wordsInUse == 0);
}
uint32 BitSet::cardinality() const {
uint32 sum = 0;
for (uint32 i = 0; i < wordsInUse; i++)
sum += bitCount(words[i]);
return sum;
}
uint32 BitSet::size() const {
return wordsLength * BITS_PER_WORD;
}
BitSet& BitSet::operator&=(const BitSet& set) {
while (wordsInUse > set.wordsInUse)
words[--wordsInUse] = 0;
// Perform logical AND on words in common
for (uint32 i = 0; i < wordsInUse; i++)
words[i] &= set.words[i];
recalculateWordsInUse();
return *this;
}
BitSet& BitSet::operator|=(const BitSet& set) {
uint32 wordsInCommon;
if (wordsInUse < set.wordsInUse) {
wordsInCommon = wordsInUse;
//ensureCapacity(set.wordsInUse);
//wordsInUse = set.wordsInUse;
}
else
wordsInCommon = set.wordsInUse;
// Perform logical OR on words in common
uint32 i = 0;
for (; i < wordsInCommon; i++)
words[i] |= set.words[i];
// TODO what to do if BitSets are not the same size !!!
// recalculateWordsInUse() is not needed
return *this;
}
BitSet& BitSet::operator^=(const BitSet& set) {
uint32 wordsInCommon;
if (wordsInUse < set.wordsInUse) {
wordsInCommon = wordsInUse;
//ensureCapacity(set.wordsInUse);
//wordsInUse = set.wordsInUse;
}
else
wordsInCommon = set.wordsInUse;
// Perform logical XOR on words in common
uint32 i = 0;
for (; i < wordsInCommon; i++)
words[i] ^= set.words[i];
// TODO what to do if BitSets are not the same size !!!
recalculateWordsInUse();
return *this;
}
BitSet& BitSet::operator-=(const BitSet& set) {
uint32 wordsInCommon;
if (wordsInUse < set.wordsInUse) {
wordsInCommon = wordsInUse;
//ensureCapacity(set.wordsInUse);
//wordsInUse = set.wordsInUse;
}
else
wordsInCommon = set.wordsInUse;
// Perform logical (a & !b) on words in common
uint32 i = 0;
for (; i < wordsInCommon; i++)
words[i] &= ~set.words[i];
recalculateWordsInUse();
return *this;
}
BitSet& BitSet::operator=(const BitSet &set) {
// Check for self-assignment!
if (this == &set)
return *this;
// we ensure that words array size is adequate (and not wordsInUse to ensure capacity to the future)
if (wordsLength < set.wordsLength)
{
if (words) delete[] words;
words = new uint64[set.wordsLength];
wordsLength = set.wordsLength;
}
memcpy(words, set.words, sizeof(uint64)*set.wordsInUse);
wordsInUse = set.wordsInUse;
return *this;
}
void BitSet::or_and(const BitSet& set1, const BitSet& set2) {
uint32 inUse = (set1.wordsInUse < set2.wordsInUse) ? set1.wordsInUse : set2.wordsInUse;
ensureCapacity(inUse);
wordsInUse = inUse;
// Perform logical AND on words in common
for (uint32 i = 0; i < inUse; i++)
words[i] |= (set1.words[i] & set2.words[i]);
// recalculateWordsInUse()...
}
bool BitSet::operator==(const BitSet &set) const
{
if (this == &set)
return true;
if (wordsInUse != set.wordsInUse)
return false;
// Check words in use by both BitSets
for (uint32 i = 0; i < wordsInUse; i++)
if (words[i] != set.words[i])
return false;
return true;
}
bool BitSet::operator!=(const BitSet &set) const
{
return !(*this == set);
}
void BitSet::toString(StringBuilder buffer, int /*indentLevel*/) const
{
*buffer += '{';
int32 i = nextSetBit(0);
char tmp[30];
if (i != -1) {
sprintf(tmp,"%d",(int)i); *buffer += tmp;
for (i = nextSetBit(i+1); i >= 0; i = nextSetBit(i+1)) {
int32 endOfRun = nextClearBit(i);
do { *buffer += ", "; sprintf(tmp,"%d",(int)i); *buffer += tmp; } while (++i < endOfRun);
}
}
*buffer += '}';
}
void BitSet::serialize(ByteBuffer* buffer, SerializableControl* flusher) const {
uint32 n = wordsInUse;
if (n == 0) {
SerializeHelper::writeSize(0, buffer, flusher);
return;
}
uint32 len = 8 * (n-1);
for (uint64 x = words[n - 1]; x != 0; x >>= 8)
len++;
SerializeHelper::writeSize(len, buffer, flusher);
flusher->ensureBuffer(len);
for (uint32 i = 0; i < n - 1; i++)
buffer->putLong(words[i]);
for (uint64 x = words[n - 1]; x != 0; x >>= 8)
buffer->putByte((int8) (x & 0xff));
}
void BitSet::deserialize(ByteBuffer* buffer, DeserializableControl* control) {
uint32 bytes = SerializeHelper::readSize(buffer, control); // in bytes
wordsInUse = (bytes + 7) / 8;
if (wordsInUse > wordsLength)
{
if (words) delete[] words;
words = new uint64[wordsInUse];
wordsLength = wordsInUse;
}
if (wordsInUse == 0)
return;
control->ensureData(bytes);
uint32 i = 0;
uint32 longs = bytes / 8;
while (i < longs)
words[i++] = buffer->getLong();
for (uint32 j = i; j < wordsInUse; j++)
words[j] = 0;
for (uint32 remaining = (bytes - longs * 8), j = 0; j < remaining; j++)
words[i] |= (buffer->getByte() & 0xffL) << (8 * j);
}
}};

View File

@@ -1,8 +0,0 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mes
*/

View File

@@ -1,902 +0,0 @@
/* byteBuffer.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mse
*/
#ifndef BYTEBUFFER_H
#define BYTEBUFFER_H
#include <string>
#include <pv/pvType.h>
#include <epicsEndian.h>
#include <string.h>
#include <pv/epicsException.h>
namespace epics {
namespace pvData {
/*
TODO can be used:
MS Visual C++:
You include intrin.h and call the following functions:
For 16 bit numbers:
unsigned short _byteswap_ushort(unsigned short value);
For 32 bit numbers:
unsigned long _byteswap_ulong(unsigned long value);
For 64 bit numbers:
unsigned __int64 _byteswap_uint64(unsigned __int64 value);
*/
/*
For floats and doubles it's more difficult as with plain integers as these may or not may be in the host machines byte-order.
You can get little-endian floats on big-endian machines and vice versa.
*/
#define GCC_VERSION_SINCE(major, minor, patchlevel) \
(defined(__GNUC__) && !defined(__INTEL_COMPILER) && \
((__GNUC__ > (major)) || \
(__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \
(__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel))))
#if GCC_VERSION_SINCE(4,3,0)
#define swap32(x) __builtin_bswap32(x)
#define swap64(x) __builtin_bswap64(x)
#define __byte_swap16(x) \
(((x) >> 8) | \
((x) << 8))
static inline uint16_t
swap16(uint16_t _x)
{
return (__byte_swap16(_x));
}
#else
#define __byte_swap16(x) \
(((x) >> 8) | \
((x) << 8))
#define __byte_swap32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
#define __byte_swap64(x) \
(((x) >> 56) | \
(((x) >> 40) & 0xff00) | \
(((x) >> 24) & 0xff0000) | \
(((x) >> 8) & 0xff000000) | \
(((x) << 8) & ((uint64_t)0xff << 32)) | \
(((x) << 24) & ((uint64_t)0xff << 40)) | \
(((x) << 40) & ((uint64_t)0xff << 48)) | \
(((x) << 56)))
static inline uint16_t
swap16(uint16_t _x)
{
return (__byte_swap16(_x));
}
static inline uint32_t
swap32(uint32_t _x)
{
return (__byte_swap32(_x));
}
static inline uint64_t
swap64(uint64_t _x)
{
return (__byte_swap64(_x));
}
#endif
template<typename T>
inline T swap(T val) { return val; } // not valid
template<>
inline int16 swap(int16 val)
{
return swap16(val);
}
template<>
inline int32 swap(int32 val)
{
return swap32(val);
}
template<>
inline int64 swap(int64 val)
{
return swap64(val);
}
template<>
inline float swap(float val)
{
union {
int32 i;
float f;
} conv;
conv.f = val;
conv.i = swap32(conv.i);
return conv.f;
}
template<>
inline double swap(double val)
{
union {
int64 i;
double d;
} conv;
conv.d = val;
conv.i = swap64(conv.i);
return conv.d;
}
#define is_aligned(POINTER, BYTE_COUNT) \
(((std::ptrdiff_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)
/*template <bool ENDIANESS_SUPPORT = false,
bool UNALIGNED_ACCESS = false,
bool ADAPTIVE_ACCESS = true,
bool USE_INLINE_MEMCPY = true>*/
#define ENDIANESS_SUPPORT true
#define UNALIGNED_ACCESS true
#define ADAPTIVE_ACCESS true
#define USE_INLINE_MEMCPY true
#if defined (__GNUC__) && (__GNUC__ < 3)
#define GET(T) get((T*)0)
#else
#define GET(T) get<T>()
#endif
/**
* This class implements {@code Bytebuffer} that is like the {@code java.nio.ByteBuffer}.
* <p>A {@code BitSet} is not safe for multithreaded use without
* external synchronization.
*
* Based on Java implementation.
*/
class ByteBuffer
{
public:
/**
* Constructor.
*
* @param size The number of bytes.
* @param byteOrder The byte order.
* Must be one of EPICS_BYTE_ORDER,EPICS_ENDIAN_LITTLE,EPICS_ENDIAN_BIG,
*/
ByteBuffer(std::size_t size, int byteOrder = EPICS_BYTE_ORDER) :
_buffer(0), _size(size),
_reverseEndianess(byteOrder != EPICS_BYTE_ORDER),
_reverseFloatEndianess(byteOrder != EPICS_FLOAT_WORD_ORDER)
{
_buffer = (char*)malloc(size);
clear();
}
/**
* Destructor
*/
~ByteBuffer()
{
if (_buffer) free(_buffer);
}
/**
* Set the byte order.
*
* @param byteOrder The byte order.
* Must be one of EPICS_BYTE_ORDER,EPICS_ENDIAN_LITTLE,EPICS_ENDIAN_BIG,
*/
inline void setEndianess(int byteOrder)
{
_reverseEndianess = (byteOrder != EPICS_BYTE_ORDER);
_reverseFloatEndianess = (byteOrder != EPICS_FLOAT_WORD_ORDER);
}
/**
* Get the raw buffer data.
* @return the raw buffer data.
*/
inline const char* getBuffer()
{
return _buffer;
}
/**
* Makes a buffer ready for a new sequence of channel-read or relative put operations:
* It sets the limit to the capacity and the position to zero.
*/
inline void clear()
{
_position = _buffer;
_limit = _buffer + _size;
}
/**
* Makes a buffer ready for a new sequence of channel-write or relative get operations:
* It sets the limit to the current position and then sets the position to zero.
*/
inline void flip() {
_limit = _position;
_position = _buffer;
}
/**
* Makes a buffer ready for re-reading the data that it already contains:
* It leaves the limit unchanged and sets the position to zero.
*/
inline void rewind() {
_position = _buffer;
}
/**
* Returns the current position.
* @return The current position in the raw data.
*/
inline std::size_t getPosition()
{
return (std::size_t)(((std::ptrdiff_t)(const void *)_position) - ((std::ptrdiff_t)(const void *)_buffer));
}
/**
* Sets the buffer position.
* If the mark is defined and larger than the new position then it is discarded.
*
* @param pos The offset into the raw buffer.
* The new position value; must be no larger than the current limit
*/
inline void setPosition(std::size_t pos)
{
_position = _buffer + pos;
}
/**
* Returns this buffer's limit.
*
* @return The offset into the raw buffer.
*/
inline std::size_t getLimit()
{
return (std::size_t)(((std::ptrdiff_t)(const void *)_limit) - ((std::ptrdiff_t)(const void *)_buffer));
}
/**
* Sets this buffer's limit.
* If the position is larger than the new limit then it is set to the new limit.s
* If the mark is defined and larger than the new limit then it is discarded.
*
* @param limit The new position value;
* must be no larger than the current limit
*/
inline void setLimit(std::size_t limit)
{
_limit = _buffer + limit;
}
/**
* Returns the number of elements between the current position and the limit.
*
* @return The number of elements remaining in this buffer.
*/
inline std::size_t getRemaining()
{
return (std::size_t)(((std::ptrdiff_t)(const void *)_limit) - ((std::ptrdiff_t)(const void *)_position));
}
/**
* Returns The size, i.e. capacity of the raw data buffer in bytes.
*
* @return The size of the raw data buffer.
*/
inline std::size_t getSize()
{
return _size;
}
/**
* Put the value into the raw buffer as a byte stream in the current byte order.
*
* @param value The value to be put into the byte buffer.
*/
template<typename T>
inline void put(T value);
/**
* Put the value into the raw buffer at the specified index as a byte stream in the current byte order.
*
* @param index Offset in the byte buffer.
* @param value The value to be put into the byte buffer.
*/
template<typename T>
inline void put(std::size_t index, T value);
/**
* Get the new object from the byte buffer. The item MUST have type {@code T}.
* The position is adjusted based on the type.
*
* @return The object.
*/
#if defined (__GNUC__) && (__GNUC__ < 3)
template<typename T>
inline T get(const T*);
#else
template<typename T>
inline T get();
#endif
/**
* Get the new object from the byte buffer at the specified index.
* The item MUST have type {@code T}.
* The position is adjusted based on the type.
*
* @param index The location in the byte buffer.
* @return The object.
*/
template<typename T>
inline T get(std::size_t index);
/**
* Put a sub-array of bytes into the byte buffer.
* The position is increased by the count.
*
* @param src The source array.
* @param offset The starting position within src.
* @param count The number of bytes to put into the byte buffer,
*/
inline void put(const char* src, std::size_t src_offset, std::size_t count) {
//if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer overflow");
memcpy(_position, src + src_offset, count);
_position += count;
}
/**
* Get a sub-array of bytes from the byte buffer.
* The position is increased by the count.
*
* @param dest The destination array.
* @param offset The starting position within src.
* @param count The number of bytes to put into the byte buffer,
*/
inline void get(char* dest, std::size_t dest_offset, std::size_t count) {
//if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer overflow");
memcpy(dest + dest_offset, _position, count);
_position += count;
}
/**
* Put an array of type {@code T} into the byte buffer.
* The position is adjusted.
*
* @param values The input array.
* @param count The number of elements.
*/
template<typename T>
inline void putArray(T* values, std::size_t count);
/**
* Get an array of type {@code T} from the byte buffer.
* The position is adjusted.
*
* @param values The destination array.
* @param count The number of elements.
*/
template<typename T>
inline void getArray(T* values, std::size_t count);
/**
* Is the byte order the EPICS_BYTE_ORDER
* @return (false,true) if (is, is not) the EPICS_BYTE_ORDER
*/
template<typename T>
inline bool reverse()
{
return _reverseEndianess;
}
/**
* Adjust position so that it is aligned to the specified size.
* Size MUST be a power of 2.
* @param size The alignment requirement.
*/
inline void align(std::size_t size)
{
const std::size_t k = size - 1;
_position = (char*)((((std::ptrdiff_t)(const void *)_position) + k) & ~(k));
}
/**
* Put a boolean value into the byte buffer.
*
* @param value The value.
*/
inline void putBoolean( bool value) { put< int8>(value ? 1 : 0); }
/**
* Put a byte value into the byte buffer.
*
* @param value The value.
*/
inline void putByte ( int8 value) { put< int8>(value); }
/**
* Put a short value into the byte buffer.
*
* @param value The value.
*/
inline void putShort ( int16 value) { put< int16>(value); }
/**
* Put an int value into the byte buffer.
*
* @param value The value.
*/
inline void putInt ( int32 value) { put< int32>(value); }
/**
* Put a long value into the byte buffer.
*
* @param value The value.
*/
inline void putLong ( int64 value) { put< int64>(value); }
/**
* Put a float value into the byte buffer.
*
* @param value The value.
*/
inline void putFloat ( float value) { put< float>(value); }
/**
* Put a double value into the byte buffer.
*
* @param value The value.
*/
inline void putDouble (double value) { put<double>(value); }
/**
* Put a boolean value into the byte buffer at the specified index.
*
* @param index The offset in the byte buffer,
* @param value The value.
*/
inline void putBoolean(std::size_t index, bool value) { put< int8>(index, value); }
/**
* Put a byte value into the byte buffer at the specified index.
*
* @param index The offset in the byte buffer,
* @param value The value.
*/
inline void putByte (std::size_t index, int8 value) { put< int8>(index, value); }
/**
* Put a short value into the byte buffer at the specified index.
*
* @param index The offset in the byte buffer,
* @param value The value.
*/
inline void putShort (std::size_t index, int16 value) { put< int16>(index, value); }
/**
* Put an int value into the byte buffer at the specified index.
*
* @param index The offset in the byte buffer,
* @param value The value.
*/
inline void putInt (std::size_t index, int32 value) { put< int32>(index, value); }
/**
* Put a long value into the byte buffer at the specified index.
*
* @param index The offset in the byte buffer,
* @param value The value.
*/
inline void putLong (std::size_t index, int64 value) { put< int64>(index, value); }
/**
* Put a float value into the byte buffer at the specified index.
*
* @param index The offset in the byte buffer,
* @param value The value.
*/
inline void putFloat (std::size_t index, float value) { put< float>(index, value); }
/**
* Put a double value into the byte buffer at the specified index.
*
* @param index The offset in the byte buffer,
* @param value The value.
*/
inline void putDouble (std::size_t index, double value) { put<double>(index, value); }
/**
* Get a boolean value from the byte buffer.
*
* @return The value.
*/
inline bool getBoolean() { return GET( int8) != 0; }
/**
* Get a byte value from the byte buffer.
*
* @return The value.
*/
inline int8 getByte () { return GET( int8); }
/**
* Get a short value from the byte buffer.
*
* @return The value.
*/
inline int16 getShort () { return GET( int16); }
/**
* Get a int value from the byte buffer.
*
* @return The value.
*/
inline int32 getInt () { return GET( int32); }
/**
* Get a long value from the byte buffer.
*
* @return The value.
*/
inline int64 getLong () { return GET( int64); }
/**
* Get a float value from the byte buffer.
*
* @return The value.
*/
inline float getFloat () { return GET( float); }
/**
* Get a double value from the byte buffer.
*
* @return The value.
*/
inline double getDouble () { return GET(double); }
/**
* Get a boolean value from the byte buffer at the specified index.
*
* @param index The offset in the byte buffer.
* @return The value.
*/
inline bool getBoolean(std::size_t index) { return get< int8>(index) != 0; }
/**
* Get a byte value from the byte buffer at the specified index.
*
* @param index The offset in the byte buffer.
* @return The value.
*/
inline int8 getByte (std::size_t index) { return get< int8>(index); }
/**
* Get a short value from the byte buffer at the specified index.
*
* @param index The offset in the byte buffer.
* @return The value.
*/
inline int16 getShort (std::size_t index) { return get< int16>(index); }
/**
* Get an int value from the byte buffer at the specified index.
*
* @param index The offset in the byte buffer.
* @return The value.
*/
inline int32 getInt (std::size_t index) { return get< int32>(index); }
/**
* Get a long value from the byte buffer at the specified index.
*
* @param index The offset in the byte buffer.
* @return The value.
*/
inline int64 getLong (std::size_t index) { return get< int64>(index); }
/**
* Get a float value from the byte buffer at the specified index.
*
* @param index The offset in the byte buffer.
* @return The value.
*/
inline float getFloat (std::size_t index) { return get< float>(index); }
/**
* Get a boolean value from the byte buffer at the specified index.
*
* @param double The offset in the byte buffer.
* @return The value.
*/
inline double getDouble (std::size_t index) { return get<double>(index); }
// TODO remove
inline const char* getArray()
{
return _buffer;
}
private:
char* _buffer;
char* _position;
char* _limit;
std::size_t _size;
bool _reverseEndianess;
bool _reverseFloatEndianess;
};
template<>
inline bool ByteBuffer::reverse<bool>()
{
return false;
}
template<>
inline bool ByteBuffer::reverse<int8>()
{
return false;
}
template<>
inline bool ByteBuffer::reverse<uint8>()
{
return false;
}
template<>
inline bool ByteBuffer::reverse<float>()
{
return _reverseFloatEndianess;
}
template<>
inline bool ByteBuffer::reverse<double>()
{
return _reverseFloatEndianess;
}
// the following methods must come after the specialized reverse<>() methods to make pre-gcc3 happy
template<typename T>
inline void ByteBuffer::put(T value)
{
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
if (sizeof(T) == 1)
{
*(_position++) = (int8)value;
return;
}
if (ENDIANESS_SUPPORT && reverse<T>())
{
value = swap<T>(value);
}
if (UNALIGNED_ACCESS)
{
// NOTE: some CPU handle unaligned access pretty good (e.g. x86)
*((T*)_position) = value;
_position += sizeof(T);
}
else
{
// NOTE: this check and branching does not always payoff
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
{
*((T*)_position) = value;
_position += sizeof(T);
}
else
{
if (USE_INLINE_MEMCPY)
{
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
memcpy(_position, &value, sizeof(T));
_position += sizeof(T);
}
else
{
// NOTE: compiler should optimize this and unroll the loop
for (size_t i = 0; i < sizeof(T); i++)
_position[i] = ((char*)&value)[i];
_position += sizeof(T);
}
}
}
}
template<typename T>
inline void ByteBuffer::put(std::size_t index, T value)
{
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
if (sizeof(T) == 1)
{
*(_buffer + index) = (int8)value;
return;
}
if (ENDIANESS_SUPPORT && reverse<T>())
{
value = swap<T>(value);
}
if (UNALIGNED_ACCESS)
{
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
*((T*)(_buffer + index)) = value;
}
else
{
// NOTE: this check and branching does not always payoff
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
{
*((T*)(_buffer + index)) = value;
}
else
{
if (USE_INLINE_MEMCPY)
{
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
memcpy(_buffer + index, &value, sizeof(T));
}
else
{
// NOTE: compiler should optimize this and unroll the loop
char *p = _buffer + index;
for (size_t i = 0; i < sizeof(T); i++)
p[i] = ((char*)&value)[i];
}
}
}
}
#if defined (__GNUC__) && (__GNUC__ < 3)
template<typename T>
inline T ByteBuffer::get(const T*)
#else
template<typename T>
inline T ByteBuffer::get()
#endif
{
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
if (sizeof(T) == 1)
{
return (int8)(*(_position++));
}
T value;
if (UNALIGNED_ACCESS)
{
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
value = *((T*)_position);
_position += sizeof(T);
}
else
{
// NOTE: this check and branching does not always payoff
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
{
value = *((T*)_position);
_position += sizeof(T);
}
else
{
if (USE_INLINE_MEMCPY)
{
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
memcpy(&value, _position, sizeof(T));
_position += sizeof(T);
}
else
{
// NOTE: compiler should optimize this and unroll the loop
for (size_t i = 0; i < sizeof(T); i++)
((char*)&value)[i] = _position[i];
_position += sizeof(T);
}
}
}
if (ENDIANESS_SUPPORT && reverse<T>())
{
value = swap<T>(value);
}
return value;
}
template<typename T>
inline T ByteBuffer::get(std::size_t index)
{
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
if (sizeof(T) == 1)
{
return (int8)(*(_buffer + index));
}
T value;
if (UNALIGNED_ACCESS)
{
// NOTE: some CPU handle unaligned access preety good (e.g. x86)
value = *((T*)(_buffer + index));
}
else
{
// NOTE: this check and branching does not always payoff
if (ADAPTIVE_ACCESS && is_aligned(_position, sizeof(T)))
{
value = *((T*)(_buffer + index));
}
else
{
if (USE_INLINE_MEMCPY)
{
// NOTE: it turns out that this compiler can optimize this with inline code, e.g. gcc
memcpy(&value, _buffer + index, sizeof(T));
}
else
{
// NOTE: compiler should optimize this and unroll the loop
char* p = _buffer + index;
for (size_t i = 0; i < sizeof(T); i++)
((char*)&value)[i] = p[i];
}
}
}
if (ENDIANESS_SUPPORT && reverse<T>())
{
value = swap<T>(value);
}
return value;
}
template<typename T>
inline void ByteBuffer::putArray(T* values, std::size_t count)
{
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
if (sizeof(T) == 1)
{
put((const char*)values, 0, count);
return;
}
T* start = (T*)_position;
size_t n = sizeof(T)*count;
// we require aligned arrays...
memcpy(_position, values, n);
_position += n;
// ... so that we can be fast changing endianess
if (ENDIANESS_SUPPORT && reverse<T>())
{
for (std::size_t i = 0; i < count; i++)
{
*start = swap<T>(*start);
start++;
}
}
}
template<typename T>
inline void ByteBuffer::getArray(T* values, std::size_t count)
{
// this avoids int8 specialization, compiler will take care if optimization, -O2 or more
if (sizeof(T) == 1)
{
get((char*)values, 0, count);
return;
}
T* start = (T*)values;
size_t n = sizeof(T)*count;
// we require aligned arrays...
memcpy(values, _position, n);
_position += n;
// ... so that we can be fast changing endianess
if (ENDIANESS_SUPPORT && reverse<T>())
{
for (std::size_t i = 0; i < count; i++)
{
*start = swap<T>(*start);
start++;
}
}
}
}
}
#endif /* BYTEBUFFER_H */

View File

@@ -1,38 +0,0 @@
/* destroyable.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mse
*/
#ifndef DESTROYABLE_H
#define DESTROYABLE_H
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
/**
* Instance declaring destroy method.
* @author mse
*/
class Destroyable {
public:
POINTER_DEFINITIONS(Destroyable);
/**
* Destroy this instance.
*/
virtual void destroy() = 0;
protected:
/**
* Do not allow delete on this instance and derived classes, destroy() must be used instead.
*/
virtual ~Destroyable() {};
};
}}
#endif /* DESTROYABLE_H */

View File

@@ -1,38 +0,0 @@
/* event.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef EVENT_H
#define EVENT_H
#include <memory>
#include <vector>
#include <epicsEvent.h>
#include <pv/pvType.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class Event;
typedef std::tr1::shared_ptr<Event> EventPtr;
class Event {
public:
POINTER_DEFINITIONS(Event);
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;
String alreadyOn;
};
}}
#endif /* EVENT_H */

View File

@@ -1,90 +0,0 @@
/* executor.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <pv/executor.h>
namespace epics { namespace pvData {
// special instance to stop the executor thread
class ExecutorShutdown : public Command {
virtual void command();
};
void ExecutorShutdown::command()
{
}
static
std::tr1::shared_ptr<Command> shutdown(new ExecutorShutdown());
Executor::Executor(String threadName,ThreadPriority priority)
: thread(threadName,priority,this)
{
}
Executor::~Executor()
{
execute(shutdown);
stopped.wait();
// The thread signals 'stopped' while still holding
// the lock. By taking it we wait for the run() function
// to actually return
Lock xx(mutex);
head.reset();
tail.reset();
}
void Executor::run()
{
Lock xx(mutex);
while(true) {
while(head.get()==NULL) {
xx.unlock();
moreWork.wait();
xx.lock();
}
CommandPtr command = head;
if(command.get()==NULL) continue;
if(command.get()==shutdown.get()) break;
xx.unlock();
try {
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();
}
void Executor::execute(CommandPtr const & command)
{
Lock xx(mutex);
command->next.reset();
if(head.get()==NULL) {
head = command;
moreWork.signal();
return;
}
if(tail.get()==NULL) return;
tail->next = command;
}
}}

View File

@@ -1,53 +0,0 @@
/* executor.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef EXECUTOR_H
#define EXECUTOR_H
#include <memory>
#include <pv/pvType.h>
#include <pv/lock.h>
#include <pv/event.h>
#include <pv/thread.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class Command;
class Executor;
typedef std::tr1::shared_ptr<Command> CommandPtr;
typedef std::tr1::shared_ptr<Executor> ExecutorPtr;
class Command {
public:
POINTER_DEFINITIONS(Command);
virtual ~Command(){}
virtual void command() = 0;
private:
CommandPtr next;
friend class Executor;
};
class Executor : public Runnable{
public:
POINTER_DEFINITIONS(Executor);
Executor(String threadName,ThreadPriority priority);
~Executor();
void execute(CommandPtr const &node);
virtual void run();
private:
CommandPtr head;
CommandPtr tail;
epics::pvData::Mutex mutex;
epics::pvData::Event moreWork;
epics::pvData::Event stopped;
epics::pvData::Thread thread;
};
}}
#endif /* EXECUTOR_H */

View File

@@ -1,39 +0,0 @@
/* localStaticLock.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mse
*/
#include <pv/localStaticLock.h>
static int nifty_counter;
static epics::pvData::Mutex* g_localStaticInitMutex;
epics::pvData::Mutex& getLocalStaticInitMutex()
{
return *g_localStaticInitMutex;
}
// The counter is initialized at load-time, i.e., before any of the static objects are initialized.
MutexInitializer::MutexInitializer ()
{
if (0 == nifty_counter++)
{
// Initialize static members.
g_localStaticInitMutex = new epics::pvData::Mutex();
}
}
MutexInitializer::~MutexInitializer ()
{
if (0 == --nifty_counter)
{
// Clean-up.
delete g_localStaticInitMutex;
}
}

View File

@@ -1,31 +0,0 @@
/* localStaticLock.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mse
*/
#ifndef LOCALSTATICLOCK_H
#define LOCALSTATICLOCK_H
#include <pv/lock.h>
extern epics::pvData::Mutex& getLocalStaticInitMutex();
#if defined(__GNUC__) && __GNUC__ >= 4
// noop
#define LOCAL_STATIC_LOCK
#else
#define LOCAL_STATIC_LOCK epics::pvData::Lock localStaticInitMutexLock(getLocalStaticInitMutex());
#endif
static class MutexInitializer {
public:
MutexInitializer ();
~MutexInitializer ();
} localStaticMutexInitializer; // Note object here in the header.
#endif /* LOCALSTATICLOCK_H */

View File

@@ -1,111 +0,0 @@
/* messageQueue.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <string>
#include <pv/messageQueue.h>
namespace epics { namespace pvData {
MessageNode::MessageNode()
: messageType(infoMessage)
{}
String MessageNode::getMessage() const
{
return message;
}
MessageType MessageNode::getMessageType() const
{
return messageType;
}
MessageQueuePtr MessageQueue::create(int size)
{
MessageNodePtrArray nodeArray;
nodeArray.reserve(size);
for(int i=0; i<size; i++) {
nodeArray.push_back(
MessageNodePtr(new MessageNode()));
}
return std::tr1::shared_ptr<MessageQueue>(new MessageQueue(nodeArray));
}
MessageQueue::MessageQueue(MessageNodePtrArray &data)
: Queue<MessageNode>(data),
overrun(0)
{ }
MessageQueue::~MessageQueue()
{
}
MessageNodePtr &MessageQueue::get() {
if(getNumberUsed()==0) return nullNode;
lastGet = getUsed();
return lastGet;
}
void MessageQueue::release() {
if(lastGet.get()==NULL) return;
releaseUsed(lastGet);
lastGet.reset();
}
bool MessageQueue::put(String message,MessageType messageType,bool replaceLast)
{
MessageNodePtr node = getFree();
if(node.get()!= NULL) {
node->message = message;
node->messageType = messageType;
lastPut = node;
setUsed(node);
return true;
}
overrun++;
if(replaceLast) {
node = lastPut;
node->message = message;
node->messageType = messageType;
return true;
}
return false;
}
bool MessageQueue::isEmpty()
{
int free = getNumberFree();
if(free==capacity()) return true;
return false;
}
bool MessageQueue::isFull()
{
if(getNumberFree()==0) return true;
return false;
}
int MessageQueue::getClearOverrun()
{
int num = overrun;
overrun = 0;
return num;
}
MessageQueuePtr createMessageQueue(int size)
{
MessageNodePtrArray nodeArray;
nodeArray.reserve(size);
for(int i=0; i<size; i++) {
nodeArray.push_back(
MessageNodePtr(new MessageNode()));
}
return std::tr1::shared_ptr<MessageQueue>(new MessageQueue(nodeArray));
}
}}

View File

@@ -1,65 +0,0 @@
/* messageQueue.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef MESSAGEQUEUE_H
#define MESSAGEQUEUE_H
#include <memory>
#include <vector>
#include <cstddef>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/requester.h>
#include <pv/queue.h>
namespace epics { namespace pvData {
class MessageNode;
class MessageQueue;
typedef std::tr1::shared_ptr<MessageNode> MessageNodePtr;
typedef std::vector<MessageNodePtr> MessageNodePtrArray;
typedef std::tr1::shared_ptr<MessageQueue> MessageQueuePtr;
class MessageNode {
public:
MessageNode();
String getMessage() const;
MessageType getMessageType() const;
private:
String message;
MessageType messageType;
friend class MessageQueue;
};
class MessageQueue : public Queue<MessageNode> {
public:
POINTER_DEFINITIONS(MessageQueue);
static MessageQueuePtr create(int size);
MessageQueue(MessageNodePtrArray &nodeArray);
virtual ~MessageQueue();
MessageNodePtr &get();
// must call release before next get
void release();
// return (false,true) if message (was not, was) put into queue
bool put(String message,MessageType messageType,bool replaceLast);
bool isEmpty() ;
bool isFull() ;
int getClearOverrun();
private:
MessageNodePtr nullNode;
MessageNodePtr lastGet;
MessageNodePtr lastPut;
uint32 overrun;
};
}}
#endif /* MESSAGEQUEUE_H */

View File

@@ -1,30 +0,0 @@
/* noDefaultMethods.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef NO_DEFAULT_METHODS_H
#define NO_DEFAULT_METHODS_H
namespace epics { namespace pvData {
/* This is based on Item 6 of
* Effective C++, Third Edition, Scott Meyers
*/
class NoDefaultMethods {
protected:
// allow by derived objects
NoDefaultMethods(){};
~NoDefaultMethods(){}
private:
// do not implment
NoDefaultMethods(const NoDefaultMethods&);
NoDefaultMethods & operator=(const NoDefaultMethods &);
};
}}
#endif /* NO_DEFAULT_METHODS_H */

View File

@@ -1,131 +0,0 @@
/* queue.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <vector>
#include <cstddef>
#include <stdexcept>
#include <pv/sharedPtr.h>
#ifndef QUEUE_H
#define QUEUE_H
namespace epics { namespace pvData {
template <typename T>
class Queue
{
public:
POINTER_DEFINITIONS(Queue);
typedef std::tr1::shared_ptr<T> queueElementPtr;
typedef std::vector<queueElementPtr> queueElementPtrArray;
Queue(queueElementPtrArray &);
virtual ~Queue();
void clear();
int capacity();
int getNumberFree();
int getNumberUsed();
queueElementPtr & getFree();
void setUsed(queueElementPtr const &element);
queueElementPtr & getUsed();
void releaseUsed(queueElementPtr const &element);
private:
queueElementPtr nullElement;
queueElementPtrArray elements;
int size;
int numberFree;
int numberUsed;
int nextGetFree;
int nextSetUsed;
int nextGetUsed;
int nextReleaseUsed;
};
template <typename T>
Queue<T>::Queue(std::vector<queueElementPtr> &xxx)
: size(xxx.size()),
numberFree(size),
numberUsed(0),
nextGetFree(0),
nextSetUsed(0),
nextGetUsed(0),
nextReleaseUsed(0)
{
elements.swap(xxx);
}
template <typename T>
Queue<T>::~Queue(){}
template <typename T>
int Queue<T>::capacity(){return size;}
template <typename T>
int Queue<T>::getNumberFree(){return numberFree;}
template <typename T>
int Queue<T>::getNumberUsed(){return numberUsed;}
template <typename T>
void Queue<T>::clear()
{
numberFree = size;
numberUsed = 0;
nextGetFree = 0;
nextSetUsed = 0;
nextGetUsed = 0;
nextReleaseUsed = 0;
}
template <typename T>
std::tr1::shared_ptr<T> & Queue<T>::getFree()
{
if(numberFree==0) return nullElement;
numberFree--;
int ind = nextGetFree;
std::tr1::shared_ptr<T> queueElement = elements[nextGetFree++];
if(nextGetFree>=size) nextGetFree = 0;
return elements[ind];
}
template <typename T>
void Queue<T>::setUsed(std::tr1::shared_ptr<T> const &element)
{
if(element!=elements[nextSetUsed++]) {
throw std::logic_error("not correct queueElement");
}
numberUsed++;
if(nextSetUsed>=size) nextSetUsed = 0;
}
template <typename T>
std::tr1::shared_ptr<T> & Queue<T>::getUsed()
{
if(numberUsed==0) return nullElement;
int ind = nextGetUsed;
std::tr1::shared_ptr<T> queueElement = elements[nextGetUsed++];
if(nextGetUsed>=size) nextGetUsed = 0;
return elements[ind];
}
template <typename T>
void Queue<T>::releaseUsed(std::tr1::shared_ptr<T> const &element)
{
if(element!=elements[nextReleaseUsed++]) {
throw std::logic_error(
"not queueElement returned by last call to getUsed");
}
if(nextReleaseUsed>=size) nextReleaseUsed = 0;
numberUsed--;
numberFree++;
}
}}
#endif /* QUEUE_H */

View File

@@ -1,34 +0,0 @@
/* requester.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <string>
#include <cstdio>
#include <pv/lock.h>
#include <pv/requester.h>
namespace epics { namespace pvData {
const size_t messageTypeCount = 4;
static StringArray messageTypeName(messageTypeCount);
String getMessageTypeName(MessageType messageType)
{
static Mutex mutex;
Lock xx(mutex);
if(messageTypeName[0].size()==0) {
messageTypeName[0] = "info";
messageTypeName[1] = "warning";
messageTypeName[2] = "error";
messageTypeName[3] = "fatalError";
}
return messageTypeName[messageType];
}
}}

View File

@@ -1,36 +0,0 @@
/* requester.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef REQUESTER_H
#define REQUESTER_H
#include <string>
#include <pv/pvType.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class Requester;
typedef std::tr1::shared_ptr<Requester> RequesterPtr;
enum MessageType {
infoMessage,warningMessage,errorMessage,fatalErrorMessage
};
extern String getMessageTypeName(MessageType messageType);
extern const size_t messageTypeCount;
class Requester {
public:
POINTER_DEFINITIONS(Requester);
virtual ~Requester(){}
virtual String getRequesterName() = 0;
virtual void message(String const & message,MessageType messageType) = 0;
};
}}
#endif /* REQUESTER_H */

View File

@@ -1,72 +0,0 @@
/* serialize.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef SERIALIZE_H
#define SERIALIZE_H
#include <pv/byteBuffer.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class SerializableControl;
class DeserializableControl;
class Serializable;
class BitSetSerializable;
class SerializableArray;
class BitSet;
class Field;
class SerializableControl {
public:
virtual ~SerializableControl(){}
virtual void flushSerializeBuffer() =0;
virtual void ensureBuffer(std::size_t size) =0;
virtual void alignBuffer(std::size_t alignment) =0;
virtual bool directSerialize(ByteBuffer *existingBuffer, const char* toSerialize,
std::size_t elementCount, std::size_t elementSize) = 0;
virtual void cachedSerialize(std::tr1::shared_ptr<const Field> const & field, ByteBuffer* buffer) = 0;
};
class DeserializableControl {
public:
virtual ~DeserializableControl(){}
virtual void ensureData(std::size_t size) =0;
virtual void alignData(std::size_t alignment) =0;
virtual bool directDeserialize(ByteBuffer *existingBuffer, char* deserializeTo,
std::size_t elementCount, std::size_t elementSize) = 0;
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer) = 0;
};
class Serializable {
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, std::size_t offset, std::size_t count) const = 0;
};
}}
#endif /* SERIALIZE_H */

View File

@@ -1,82 +0,0 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author Michael DavidSaver
*/
#ifndef SHAREDPTR_H
#define SHAREDPTR_H
/*
* Pulls in the std::tr1 namespace with the following names
*
* class shared_ptr
* class weak_ptr
* class bad_weak_ptr
* function static_pointer_cast;
* function dynamic_pointer_cast
* function const_pointer_cast
* function swap
* function get_deleter
* function enable_shared_from_this
*/
// where should we look?
#if defined(__GNUC__) && __GNUC__>=4 && !defined(__vxworks)
// GCC >=4.0.0
# define SHARED_FROM_TR1
#elif defined(_MSC_VER) && (_MSC_VER>1500 || defined(_HAS_TR1))
// MSVC > 2008, or 2008 w/ SP1
# define SHARED_FROM_TR1
#else
# define SHARED_FROM_BOOST
#endif
#if defined(_MSC_VER) && (_MSC_VER>=1600)
// MSVC 2010 has it in <memory>
# undef SHARED_FROM_BOOST
# undef SHARED_FROM_TR1
#endif
// go and get it
#if defined(SHARED_FROM_TR1)
# include <tr1/memory>
#elif defined(SHARED_FROM_BOOST)
#if defined(__GNUC__) && __GNUC__ < 3
#define BOOST_EXCEPTION_DISABLE
#define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif
# include <boost/tr1/memory.hpp>
#else
// eventually...
# include <memory>
#endif
// cleanup
#ifdef SHARED_FROM_TR1
# undef SHARED_FROM_TR1
#endif
#ifdef SHARED_FROM_BOOST
# undef SHARED_FROM_BOOST
#endif
#define POINTER_DEFINITIONS(clazz) \
typedef std::tr1::shared_ptr<clazz> shared_pointer; \
typedef std::tr1::shared_ptr<const clazz> const_shared_pointer; \
typedef std::tr1::weak_ptr<clazz> weak_pointer; \
typedef std::tr1::weak_ptr<const clazz> const_weak_pointer;
#endif // SHAREDPTR_H

View File

@@ -1,138 +0,0 @@
/*pvData.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <pv/status.h>
#include <pv/epicsException.h>
#include <pv/serializeHelper.h>
namespace epics { namespace pvData {
const char* Status::StatusTypeName[] = { "OK", "WARNING", "ERROR", "FATAL" };
epics::pvData::String Status::m_emptyString;
Status Status::Ok;
//PVDATA_REFCOUNT_MONITOR_DEFINE(status);
Status::Status() :
m_statusType(STATUSTYPE_OK)
{
}
Status::Status(StatusType type, String const & message) :
m_statusType(type), m_message(message)
{
if (type == STATUSTYPE_OK)
throw std::invalid_argument("type == STATUSTYPE_OK");
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
}
Status::Status(StatusType type, String const & message, String const & stackDump) :
m_statusType(type), m_message(message), m_stackDump(stackDump)
{
if (type == STATUSTYPE_OK)
throw std::invalid_argument("type == STATUSTYPE_OK");
//PVDATA_REFCOUNT_MONITOR_CONSTRUCT(status);
}
Status::~Status() {
//PVDATA_REFCOUNT_MONITOR_DESTRUCT(status);
}
Status::StatusType Status::getType() const
{
return m_statusType;
}
epics::pvData::String Status::getMessage() const
{
return m_message;
}
epics::pvData::String Status::getStackDump() const
{
return m_stackDump;
}
bool Status::isOK() const
{
return (m_statusType == STATUSTYPE_OK);
}
bool Status::isSuccess() const
{
return (m_statusType == STATUSTYPE_OK || m_statusType == STATUSTYPE_WARNING);
}
void Status::serialize(ByteBuffer *buffer, SerializableControl *flusher) const
{
flusher->ensureBuffer(1);
if (m_statusType == STATUSTYPE_OK)
{
// special code for okStatus (optimization)
buffer->putByte((int8)-1);
}
else
{
buffer->putByte((int8)m_statusType);
SerializeHelper::serializeString(m_message, buffer, flusher);
SerializeHelper::serializeString(m_stackDump, buffer, flusher);
}
}
void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
{
flusher->ensureData(1);
int8 typeCode = buffer->getByte();
if (typeCode == (int8)-1)
{
// in most of the cases status will be OK, we statistically optimize
if (m_statusType != STATUSTYPE_OK)
{
m_statusType = STATUSTYPE_OK;
m_message = m_stackDump = m_emptyString;
}
}
else
{
m_statusType = (StatusType)typeCode;
m_message = SerializeHelper::deserializeString(buffer, flusher);
m_stackDump = SerializeHelper::deserializeString(buffer, flusher);
}
}
String Status::toString() const
{
String str;
toString(&str, 0);
return str;
}
void Status::toString(StringBuilder buffer, int /*indentLevel*/) const
{
*buffer += "Status [type=";
*buffer += StatusTypeName[m_statusType];
if (!m_message.empty())
{
*buffer += ", message=";
*buffer += m_message;
}
if (!m_stackDump.empty())
{
*buffer += ", stackDump=";
*buffer += '\n';
*buffer += m_stackDump;
}
*buffer += ']';
}
}}

View File

@@ -1,110 +0,0 @@
/* status.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mse
*/
#ifndef STATUS_H
#define STATUS_H
#include <pv/serialize.h>
#include <pv/byteBuffer.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
/**
* Status.
* @author mse
*/
class Status : public epics::pvData::Serializable {
public:
POINTER_DEFINITIONS(Status);
/**
* Status type enum.
*/
enum StatusType {
/** Operation completed successfully. */
STATUSTYPE_OK,
/** Operation completed successfully, but there is a warning message. */
STATUSTYPE_WARNING,
/** Operation failed due to an error. */
STATUSTYPE_ERROR,
/** Operation failed due to an unexpected error. */
STATUSTYPE_FATAL
};
static const char* StatusTypeName[];
static Status Ok;
/**
* Creates OK status; STATUSTYPE_OK, empty message and stackDump.
*/
Status();
/**
* Create non-OK status.
*/
Status(StatusType type, epics::pvData::String const & message);
/**
* Create non-OK status.
*/
Status(StatusType type, epics::pvData::String const & message, epics::pvData::String const & stackDump);
~Status();
/**
* Get status type.
* @return status type, non-<code>null</code>.
*/
StatusType getType() const;
/**
* Get error message describing an error. Required if error status.
* @return error message.
*/
epics::pvData::String getMessage() const;
/**
* Get stack dump where error (exception) happened. Optional.
* @return stack dump.
*/
epics::pvData::String getStackDump() const;
/**
* Convenient OK test. Same as <code>(getType() == StatusType.OK)</code>.
* NOTE: this will return <code>false</code> on WARNING message although operation succeeded.
* To check if operation succeeded, use <code>isSuccess</code>.
* @return OK status.
* @see #isSuccess()
*/
bool isOK() const;
/**
* Check if operation succeeded.
* @return operation success status.
*/
bool isSuccess() const;
String toString() const;
void toString(StringBuilder buffer, int indentLevel = 0) const;
void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
private:
static epics::pvData::String m_emptyString;
StatusType m_statusType;
String m_message;
String m_stackDump;
};
}}
#endif /* STATUS_H */

View File

@@ -1,66 +0,0 @@
/* thread.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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,49 +0,0 @@
/* timeFunction.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <pv/pvType.h>
#include <pv/timeStamp.h>
#include <pv/timeFunction.h>
namespace epics { namespace pvData {
TimeFunction::TimeFunction(TimeFunctionRequesterPtr const &requester)
: requester(requester) {}
TimeFunction::~TimeFunction() {}
double TimeFunction::timeCall()
{
TimeStamp startTime;
TimeStamp endTime;
double perCall = 0.0;
long ntimes = 1;
while(true) {
startTime.getCurrent();
for(long i=0; i<ntimes; i++) requester->function();
endTime.getCurrent();
double diff = TimeStamp::diff(endTime,startTime);
if(diff>=1.0) {
perCall = diff/(double)ntimes;
break;
}
ntimes *= 2;
}
return perCall;
}
}}

View File

@@ -1,41 +0,0 @@
/* timeFunction.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef TIMEFUNCTION_H
#define TIMEFUNCTION_H
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class TimeFunctionRequester;
class TimeFunction;
typedef std::tr1::shared_ptr<TimeFunctionRequester> TimeFunctionRequesterPtr;
typedef std::tr1::shared_ptr<TimeFunction> TimeFunctionPtr;
class TimeFunctionRequester {
public:
POINTER_DEFINITIONS(TimeFunctionRequester);
virtual ~TimeFunctionRequester(){}
virtual void function() = 0;
};
class TimeFunction {
public:
POINTER_DEFINITIONS(TimeFunction);
TimeFunction(TimeFunctionRequesterPtr const & requester);
~TimeFunction();
double timeCall();
private:
TimeFunctionRequesterPtr requester;
};
}}
#endif /* TIMEFUNCTION_H */

View File

@@ -1,214 +0,0 @@
/* timer.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdexcept>
#include <pv/timer.h>
#include <pv/convert.h>
namespace epics { namespace pvData {
TimerCallback::TimerCallback()
: period(0.0),
onList(false)
{
}
Timer::Timer(String threadName,ThreadPriority priority)
: waitForWork(false),
waitForDone(false),
alive(true),
thread(threadName,priority,this)
{}
void Timer::addElement(TimerCallbackPtr const & timerCallback)
{
timerCallback->onList = true;
if(head.get()==NULL) {
head = timerCallback;
timerCallback->next.reset();
return;
}
TimerCallbackPtr nextNode(head);
TimerCallbackPtr prevNode;
while(true) {
if(timerCallback->timeToRun < nextNode->timeToRun) {
if(prevNode.get()!=NULL) {
prevNode->next = timerCallback;
} else {
head = timerCallback;
}
timerCallback->next = nextNode;
return;
}
if(nextNode->next.get()==NULL) {
nextNode->next = timerCallback;
timerCallback->next.reset();
return;
}
prevNode = nextNode;
nextNode = nextNode->next;
}
}
void Timer::cancel(TimerCallbackPtr const &timerCallback)
{
Lock xx(mutex);
if(!timerCallback->onList) return;
TimerCallbackPtr nextNode(head);
TimerCallbackPtr prevNode;
while(true) {
if(nextNode.get()==timerCallback.get()) {
if(prevNode.get()!=NULL) {
prevNode->next = timerCallback->next;
} else {
head = timerCallback->next;
}
timerCallback->next.reset();
timerCallback->onList = false;
return;
}
prevNode = nextNode;
nextNode = nextNode->next;
}
throw std::logic_error(String(""));
}
bool Timer::isScheduled(TimerCallbackPtr const &timerCallback)
{
Lock xx(mutex);
return timerCallback->onList;
}
void Timer::run()
{
TimeStamp currentTime;
while(true) {
double period = 0.0;
TimerCallbackPtr nodeToCall;
{
Lock xx(mutex);
currentTime.getCurrent();
if (!alive) break;
TimerCallbackPtr timerCallback = head;
if(timerCallback.get()!=NULL) {
double diff = TimeStamp::diff(
timerCallback->timeToRun,currentTime);
if(diff<=0.0) {
nodeToCall = timerCallback;
nodeToCall->onList = false;
head = head->next;
period = timerCallback->period;
if(period>0.0) {
timerCallback->timeToRun += period;
addElement(timerCallback);
}
timerCallback = head;
}
}
}
if(nodeToCall.get()!=NULL) {
nodeToCall->callback();
}
{
Lock xx(mutex);
if(!alive) break;
}
if(head.get()==NULL) {
waitForWork.wait();
} else {
double delay = TimeStamp::diff(head->timeToRun,currentTime);
waitForWork.wait(delay);
}
}
waitForDone.signal();
}
Timer::~Timer() {
{
Lock xx(mutex);
alive = false;
}
waitForWork.signal();
waitForDone.wait();
TimerCallbackPtr timerCallback;
while(true) {
timerCallback = head;
if(head.get()==NULL) break;
head->timerStopped();
head = timerCallback->next;
timerCallback->next.reset();
timerCallback->onList = false;
}
}
void Timer::scheduleAfterDelay(
TimerCallbackPtr const &timerCallback,
double delay)
{
schedulePeriodic(timerCallback,delay,0.0);
}
void Timer::schedulePeriodic(
TimerCallbackPtr const &timerCallback,
double delay,
double period)
{
if(isScheduled(timerCallback)) {
throw std::logic_error(String("already queued"));
}
{
Lock xx(mutex);
if(!alive) {
timerCallback->timerStopped();
return;
}
}
TimeStamp timeStamp;
timeStamp.getCurrent();
timeStamp += delay;
timerCallback->timeToRun.getCurrent();
timerCallback->timeToRun += delay;
timerCallback->period = period;
bool isFirst = false;
{
Lock xx(mutex);
addElement(timerCallback);
if(timerCallback.get()==head.get()) isFirst = true;
}
if(isFirst) waitForWork.signal();
}
void Timer::toString(StringBuilder builder)
{
Lock xx(mutex);
if(!alive) return;
TimeStamp currentTime;
TimerCallbackPtr nodeToCall(head);
currentTime.getCurrent();
while(true) {
if(nodeToCall.get()==NULL) return;
TimeStamp timeToRun = nodeToCall->timeToRun;
double period = nodeToCall->period;
double diff = TimeStamp::diff(timeToRun,currentTime);
char buffer[50];
sprintf(buffer,"timeToRun %f period %f\n",diff,period);
*builder += buffer;
nodeToCall = nodeToCall->next;
}
}
}}

View File

@@ -1,75 +0,0 @@
/* timer.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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/timeStamp.h>
#include <pv/event.h>
#include <pv/lock.h>
#include <pv/sharedPtr.h>
namespace epics { namespace pvData {
class TimerCallback;
class Timer;
typedef std::tr1::shared_ptr<TimerCallback> TimerCallbackPtr;
typedef std::tr1::shared_ptr<Timer> TimerPtr;
class TimerCallback {
public:
POINTER_DEFINITIONS(TimerCallback);
TimerCallback();
virtual ~TimerCallback(){}
virtual void callback() = 0;
virtual void timerStopped() = 0;
private:
TimerCallbackPtr next;
TimeStamp timeToRun;
double period;
bool onList;
friend class Timer;
};
class Timer : public Runnable {
public:
POINTER_DEFINITIONS(Timer);
Timer(String threadName, ThreadPriority priority);
virtual ~Timer();
virtual void run();
void scheduleAfterDelay(
TimerCallbackPtr const &timerCallback,
double delay);
void schedulePeriodic(
TimerCallbackPtr const &timerCallback,
double delay,
double period);
void cancel(TimerCallbackPtr const &timerCallback);
bool isScheduled(TimerCallbackPtr const &timerCallback);
void toString(StringBuilder builder);
private:
void addElement(TimerCallbackPtr const &timerCallback);
TimerCallbackPtr head;
Mutex mutex;
Event waitForWork;
Event waitForDone;
bool alive;
Thread thread;
};
}}
#endif /* TIMER_H */

View File

@@ -1,109 +0,0 @@
/* monitor.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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 MonitorElement;
typedef std::tr1::shared_ptr<MonitorElement> MonitorElementPtr;
typedef std::vector<MonitorElementPtr> MonitorElementPtrArray;
class Monitor;
typedef std::tr1::shared_ptr<Monitor> MonitorPtr;
/**
* Class instance representing monitor element.
* @author mrk
*/
class MonitorElement {
public:
POINTER_DEFINITIONS(MonitorElement);
MonitorElement(){}
MonitorElement(PVStructurePtr const & pvStructurePtr)
: pvStructurePtr(pvStructurePtr),
changedBitSet(BitSet::create(pvStructurePtr->getNumberFields())),
overrunBitSet(BitSet::create(pvStructurePtr->getNumberFields()))
{}
PVStructurePtr pvStructurePtr;
BitSet::shared_pointer changedBitSet;
BitSet::shared_pointer overrunBitSet;
};
/**
* Interface for Monitor.
* @author mrk
*/
class Monitor : public Destroyable{
public:
POINTER_DEFINITIONS(Monitor);
virtual ~Monitor(){}
/**
* 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 MonitorElementPtr poll() = 0;
/**
* Release a MonitorElement that was returned by poll.
* @param monitorElement
*/
virtual void release(MonitorElementPtr const & monitorElement) = 0;
};
/**
* Requester for ChannelMonitor.
* @author mrk
*/
class MonitorRequester : public virtual Requester {
public:
POINTER_DEFINITIONS(MonitorRequester);
virtual ~MonitorRequester(){}
/**
* The client and server have both completed the createMonitor request.
* @param status Completion status.
* @param monitor The monitor
* @param structure The structure defining the data.
*/
virtual void monitorConnect(Status const & status,
MonitorPtr const & monitor, StructureConstPtr const & structure) = 0;
/**
* A monitor event has occurred.
* The requester must call Monitor.poll to get data.
* @param monitor The monitor.
*/
virtual void monitorEvent(MonitorPtr const & monitor) = 0;
/**
* The data source is no longer available.
* @param monitor The monitor.
*/
virtual void unlisten(MonitorPtr const & monitor) = 0;
};
}}
#endif /* MONITOR_H */

View File

@@ -1,57 +0,0 @@
/* alarm.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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 StringArrayPtr getSeverityNames();
};
extern const size_t statusCount;
class AlarmStatusFunc {
public:
static AlarmStatus getStatus(int value);
static StringArrayPtr 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 const &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,31 +0,0 @@
/* control.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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;}
double getMinStep() const {return minStep;}
void setLow(double value) {low = value;}
void setHigh(double value) {high = value;}
void setMinStep(double value) {minStep = value;}
private:
double low;
double high;
double minStep;
};
}}
#endif /* CONTROL_H */

View File

@@ -1,42 +0,0 @@
/* display.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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 const & value) {description = value;}
String getFormat() const {return format;}
void setFormat(String const & value) {format = value;}
String getUnits() const {return units;}
void setUnits(String const & value) {units = value;}
private:
String description;
String format;
String units;
double low;
double high;
};
}}
#endif /* DISPLAY_H */

View File

@@ -1,41 +0,0 @@
/* pvAlarm.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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() {}
//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(PVFieldPtr const & 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:
PVIntPtr pvSeverity;
PVIntPtr pvStatus;
PVStringPtr pvMessage;
static String noAlarmFound;
static String notAttached;
};
}}
#endif /* PVALARM_H */

View File

@@ -1,75 +0,0 @@
/* pvControl.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/pvControl.h>
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
String PVControl::noControlFound("No control structure found");
String PVControl::notAttached("Not attached to an control structure");
bool PVControl::attach(PVFieldPtr const & pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(noControlFound,errorMessage);
return false;
}
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
pvLow = pvStructure->getDoubleField("limitLow");
if(pvLow.get()==NULL) {
pvField->message(noControlFound,errorMessage);
return false;
}
pvHigh = pvStructure->getDoubleField(String("limitHigh"));
if(pvHigh.get()==NULL) {
pvLow.reset();
pvField->message(noControlFound,errorMessage);
return false;
}
return true;
}
void PVControl::detach()
{
pvLow.reset();
pvHigh.reset();
}
bool PVControl::isAttached(){
if(pvLow.get()==NULL) return false;
return true;
}
void PVControl::get(Control &control) const
{
if(pvLow.get()==NULL) {
throw std::logic_error(notAttached);
}
control.setLow(pvLow->get());
control.setHigh(pvHigh->get());
}
bool PVControl::set(Control const & control)
{
if(pvLow.get()==NULL) {
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,37 +0,0 @@
/* pvControl.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <pv/control.h>
#include <pv/pvData.h>
#ifndef PVCONTROL_H
#define PVCONTROL_H
namespace epics { namespace pvData {
class PVControl {
public:
PVControl(){}
//default constructors and destructor are OK
//returns (false,true) if pvField(isNot, is valid enumerated structure
//An automatic detach is issued if already attached.
bool attach(PVFieldPtr const & 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:
PVDoublePtr pvLow;
PVDoublePtr pvHigh;
static String noControlFound;
static String notAttached;
};
}}
#endif /* PVCONTROL_H */

View File

@@ -1,41 +0,0 @@
/* pvDisplay.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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() {}
//default constructors and destructor are OK
//An automatic detach is issued if already attached.
bool attach(PVFieldPtr const & 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:
static String noDisplayFound;
static String notAttached;
PVStringPtr pvDescription;
PVStringPtr pvFormat;
PVStringPtr pvUnits;
PVDoublePtr pvLow;
PVDoublePtr pvHigh;
};
}}
#endif /* PVDISPLAY_H */

View File

@@ -1,44 +0,0 @@
/* pvEnumerated.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <string>
#include <pv/pvType.h>
#include <pv/pvData.h>
#ifndef PVENUMERATED_H
#define PVENUMERATED_H
namespace epics { namespace pvData {
class PVEnumerated {
public:
PVEnumerated() {}
//default constructors and destructor are OK
//This class should not be extended
//returns (false,true) if pvField(isNot, is valid enumerated structure
//An automatic detach is issued if already attached.
bool attach(PVFieldPtr const & 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();
StringArrayPtr const & getChoices();
int32 getNumberChoices();
bool setChoices(StringArray & choices);
private:
static String notFound;
static String notAttached;
PVIntPtr pvIndex;
PVStringArrayPtr pvChoices;
};
}}
#endif /* PVENUMERATED_H */

View File

@@ -1,82 +0,0 @@
/* pvTimeStamp.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#include <string>
#include <stdexcept>
#include <pv/pvType.h>
#include <pv/timeStamp.h>
#include <pv/pvData.h>
#include <pv/pvTimeStamp.h>
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
String PVTimeStamp::noTimeStamp("No timeStamp structure found");
String PVTimeStamp::notAttached("Not attached to a timeStamp structure");
bool PVTimeStamp::attach(PVFieldPtr const & pvField)
{
if(pvField->getField()->getType()!=structure) {
pvField->message(noTimeStamp,errorMessage);
return false;
}
PVStructurePtr xxx = static_pointer_cast<PVStructure>(pvField);
PVStructure* pvStructure = xxx.get();
while(true) {
PVLongPtr pvLong = pvStructure->getLongField("secondsPastEpoch");
if(pvLong.get()!=NULL) {
pvSecs = pvLong;
pvNano = pvStructure->getIntField("nanoSeconds");
pvUserTag = pvStructure->getIntField("userTag");
}
if(pvSecs.get()!=NULL
&& pvNano.get()!=NULL
&& pvUserTag.get()!=NULL) return true;
detach();
// look up the tree for a timeSyamp
pvStructure = pvStructure->getParent();
if(pvStructure==NULL) break;
}
return false;
}
void PVTimeStamp::detach()
{
pvSecs.reset();
pvUserTag.reset();
pvNano.reset();
}
bool PVTimeStamp::isAttached() {
if(pvSecs.get()==NULL) return false;
return true;
}
void PVTimeStamp::get(TimeStamp & timeStamp) const
{
if(pvSecs.get()==NULL) {
throw std::logic_error(notAttached);
}
timeStamp.put(pvSecs->get(),pvNano->get());
timeStamp.setUserTag(pvUserTag->get());
}
bool PVTimeStamp::set(TimeStamp const & timeStamp)
{
if(pvSecs.get()==NULL) {
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,42 +0,0 @@
/* pvTimeStamp.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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(){}
//default constructors and destructor are OK
//This class should not be extended
//returns (false,true) if pvField(isNot, is valid timeStamp structure
bool attach(PVFieldPtr const & 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:
static String noTimeStamp;
static String notAttached;
PVLongPtr pvSecs;
PVIntPtr pvUserTag;
PVIntPtr pvNano;
};
}}
#endif /* PVTIMESTAMP_H */

View File

@@ -1,69 +0,0 @@
/* timeStamp.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#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,768 +0,0 @@
/* convert.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* Author - Marty Kraimer
*/
/**
* @author mrk
*/
#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,
* pvUByte, pvUShort, pvUInt, pvULong,
* pvFloat, or pvDouble.</p>
*
* <p>getString converts any supported type to a String.
* Code that implements a PVField interface should implement
* method toString by calling this method.</p>
*
* <p>fromString converts a String to a scalar.
* fromStringArray converts an array of Strings
* to a pvArray, which must have a scaler element type.
* A scalar field is a numeric field or pvBoolean or pvString.</p>
* <p>All from methods put data into a PVField, e.g. from means where the PVField gets it's data.</p>
*/
class Convert;
typedef std::tr1::shared_ptr<Convert> ConvertPtr;
class Convert {
public:
static ConvertPtr getConvert();
~Convert();
/**
* Get the full fieldName for the pvField.
* @param builder The builder that will have the result.
* @param pvField The pvField.
*/
void getFullName(StringBuilder buf,PVFieldPtr const & pvField);
/**
* Do fields have the same definition.
*
* @param First field
* @param Second field
* @return (false, true) if the fields (are not, are) the same.
*/
bool equals(PVFieldPtr const &a,PVFieldPtr const &b);
/**
* Do fields have the same definition.
*
* @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,PVFieldPtr const & pvField,int indentLevel);
/**
* Convert a PVField to a string.
* param buf buffer for the result
* @param pv The PVField to convert to a string.
* If the PVField is a structure or array be prepared for a very long string.
*/
void getString(StringBuilder buf,PVFieldPtr const & pvField);
/**
* Convert a PVField to a string.
* @param buf buffer for the result
* @param pv a PVField to convert to a string.
* If a PVField is a structure or array be prepared for a very long string.
* @param indentLevel indentation level
*/
void getString(StringBuilder buf,PVField const * pvField,int indentLevel);
/**
* Convert a PVField to a string.
* param buf buffer for the result
* @param pv The PVField to convert to a string.
* If the PVField is a structure or array be prepared for a very long string.
*/
void getString(StringBuilder buf,PVField const * pvField);
/**
* Convert from an array of String to a PVScalar
* @param pv The PV.
* @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.
*/
std::size_t fromString(
PVStructurePtr const &pv,
StringArray const & from,
std::size_t fromStartIndex = 0);
/**
* Convert from a String to a PVScalar
* @param pv The PV.
* @param from The String value to convert and put into a PV.
* @throws std::logic_error if the String does not have a valid value.
*/
void fromString(PVScalarPtr const & pv, String const & from);
/**
* Convert from a String to a PVScalarArray.
* The String must be a comma separated set of values optionally enclosed in []
* @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.
*/
std::size_t fromString(PVScalarArrayPtr const & 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.
*/
std::size_t fromStringArray(
PVScalarArrayPtr const & pv,
std::size_t offset, std::size_t length,
StringArray const & from,
std::size_t fromOffset);
/**
* Convert a PVScalarArray to a String array.
* @param pv The PV.
* @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.
*/
std::size_t toStringArray(PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
StringArray & to,
std::size_t toOffset);
/**
* Are from and to valid arguments to copy.
* This first checks of both arguments have the same Type.
* 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 const & from, FieldConstPtr const & 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(PVFieldPtr const & from, PVFieldPtr const & to);
/**
* Are from and to valid arguments to copyScalar.
* false will be returned if either argument is not a scalar as defined by Type.isScalar().
* 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 const & from,
ScalarConstPtr const & to);
/**
* Copy from a scalar pv to another scalar pv.
* @param from the source.
* @param to the destination.
* @throws std::invalid_argument if the arguments are not compatible.
*/
void copyScalar(PVScalarPtr const & from, PVScalarPtr const & to);
/**
* Are from and to valid arguments to copyArray.
* The results are like isCopyScalarCompatible except that the tests are made on the elementType.
* @param from The from array.
* @param to The to array.
* @return (false,true) If the arguments (are not, are) compatible.
*/
bool isCopyScalarArrayCompatible(
ScalarArrayConstPtr const & from,
ScalarArrayConstPtr const & 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.
*/
std::size_t copyScalarArray(
PVScalarArrayPtr const & from,
std::size_t offset,
PVScalarArrayPtr const & to,
std::size_t toOffset,
std::size_t length);
/**
* Are from and to valid arguments for copyStructure.
* They are only compatible if they have the same Structure description.
* @param from from structure.
* @param to structure.
* @return (false,true) If the arguments (are not, are) compatible.
*/
bool isCopyStructureCompatible(
StructureConstPtr const & from, StructureConstPtr const & 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(PVStructurePtr const & from, PVStructurePtr const & 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 const & from, StructureArrayConstPtr const & to);
/**
* Copy from a structure array to another structure array.
* @param from The source array.
* @param to The destination array.
*/
void copyStructureArray(
PVStructureArrayPtr const & from, PVStructureArrayPtr const & to);
/**
* Convert a PV to a <byte>.
* @param pv a PV
* @return converted value
*/
int8 toByte(PVScalarPtr const & pv);
/**
* Convert a PV to a short.
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
int16 toShort(PVScalarPtr const & pv);
/**
* Convert a PV to a int.
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
int32 toInt(PVScalarPtr const & pv);
/**
* Convert a PV to an long
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
int64 toLong(PVScalarPtr const & pv);
/**
* Convert a PV to a ubyte.
* @param pv a PV
* @return converted value
*/
uint8 toUByte(PVScalarPtr const & pv);
/**
* Convert a PV to a ushort.
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
uint16 toUShort(PVScalarPtr const & pv);
/**
* Convert a PV to a uint.
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
uint32 toUInt(PVScalarPtr const & pv);
/**
* Convert a PV to an ulong
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
uint64 toULong(PVScalarPtr const & pv);
/**
* Convert a PV to a float
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
float toFloat(PVScalarPtr const & pv);
/**
* Convert a PV to a double
* @param pv a PV
* @return converted value
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
double toDouble(PVScalarPtr const & pv);
/**
* Convert a PV to a String
* @param pv a PV
* @return converted value
*/
String toString(PVScalarPtr const & pv);
/**
* Convert a PV from a byte
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromByte(PVScalarPtr const & pv,int8 from);
/**
* Convert a PV from a short
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromShort(PVScalarPtr const & pv,int16 from);
/**
* Convert a PV from an int
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromInt(PVScalarPtr const & pv, int32 from);
/**
* Convert a PV from a long
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromLong(PVScalarPtr const & pv, int64 from);
/**
* Convert a PV from a ubyte
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromUByte(PVScalarPtr const & pv,uint8 from);
/**
* Convert a PV from a ushort
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromUShort(PVScalarPtr const & pv,uint16 from);
/**
* Convert a PV from an uint
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromUInt(PVScalarPtr const & pv, uint32 from);
/**
* Convert a PV from a ulong
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromULong(PVScalarPtr const & pv, uint64 from);
/**
* Convert a PV from a float
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromFloat(PVScalarPtr const & pv, float from);
/**
* Convert a PV from a double
* @param pv a PV
* @param from value to put into PV
* @throws std::invalid_argument if the Type is not a numeric scalar
*/
void fromDouble(PVScalarPtr const & 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
*/
std::size_t toByteArray(PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
int8* to,
std::size_t toOffset);
/**
* Convert a PV array to a short array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toShortArray(PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
int16* to,
std::size_t toOffset);
/**
* Convert a PV array to an int array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toIntArray(PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
int32* to,
std::size_t toOffset);
/**
* Convert a PV array to a long array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toLongArray(PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
int64* to,
std::size_t toOffset);
/**
* Convert a PV array to a ubyte array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toUByteArray(PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
uint8* to,
std::size_t toOffset);
/**
* Convert a PV array to a ushort array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toUShortArray(PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
uint16* to,
std::size_t toOffset);
/**
* Convert a PV array to an uint array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toUIntArray(
PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
uint32* to,
std::size_t toOffset);
/**
* Convert a PV array to a ulong array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toULongArray(
PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
uint64* to,
std::size_t toOffset);
/**
* Convert a PV array to a float array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toFloatArray(
PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
float* to,
std::size_t toOffset);
/**
* Convert a PV array to a double array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param to where to put the PV data
* @param toOffset starting element in the array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t toDoubleArray(
PVScalarArrayPtr const & pv,
std::size_t offset,
std::size_t length,
double* to, std::size_t
toOffset);
/**
* Convert a PV array from a byte array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromByteArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const int8* from, std::size_t fromOffset);
std::size_t fromByteArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const ByteArray & from, std::size_t fromOffset);
/**
* Convert a PV array from a short array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromShortArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const int16* from, std::size_t fromOffset);
std::size_t fromShortArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const ShortArray & from, std::size_t fromOffset);
/**
* Convert a PV array from an int array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromIntArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const int32* from, std::size_t fromOffset);
std::size_t fromIntArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const IntArray & from, std::size_t fromOffset);
/**
* Convert a PV array from a long array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromLongArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const int64* from, std::size_t fromOffset);
std::size_t fromLongArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const LongArray & from, std::size_t fromOffset);
/**
* Convert a PV array from a ubyte array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromUByteArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const uint8* from, std::size_t fromOffset);
std::size_t fromUByteArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const UByteArray & from, std::size_t fromOffset);
/**
* Convert a PV array from a ushort array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromUShortArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const uint16* from, std::size_t fromOffset);
std::size_t fromUShortArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const UShortArray & from, std::size_t fromOffset);
/**
* Convert a PV array from an uint array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromUIntArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const uint32* from, std::size_t fromOffset);
std::size_t fromUIntArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const UIntArray & from, std::size_t fromOffset);
/**
* Convert a PV array from a ulong array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromULongArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const uint64* from, std::size_t fromOffset);
std::size_t fromULongArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const ULongArray & from, std::size_t fromOffset);
/**
* Convert a PV array from a float array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromFloatArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const float* from, std::size_t fromOffset);
std::size_t fromFloatArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const FloatArray & from, std::size_t fromOffset);
/**
* Convert a PV array from a double array.
* @param pv a PV
* @param offset starting element in a PV
* @param length number of elements to transfer
* @param from value to put into PV
* @param fromOffset starting element in the source array
* @return number of elements converted
* @throws std::invalid_argument if the element type is not numeric
*/
std::size_t fromDoubleArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const double* from, std::size_t fromOffset);
std::size_t fromDoubleArray(
PVScalarArrayPtr & pv, std::size_t offset, std::size_t length,
const DoubleArray & from, std::size_t fromOffset);
/**
* Convenience method for implementing toString.
* It generates a newline and inserts blanks at the beginning of the newline.
* @param builder The StringBuilder being constructed.
* @param indentLevel Indent level, Each level is four spaces.
*/
void newLine(StringBuilder buf, int indentLevel);
private:
Convert();
PVDataCreatePtr pvDataCreate;
String trueString;
String falseString;
String illegalScalarType;
};
extern ConvertPtr getConvert();
}}
#endif /* CONVERT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,559 +0,0 @@
/* pvIntrospect.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk and Michael Davidsaver
*/
#ifndef PVINTROSPECT_H
#define PVINTROSPECT_H
#include <string>
#include <stdexcept>
#include <pv/noDefaultMethods.h>
#include <pv/pvType.h>
#include <pv/byteBuffer.h>
#include <pv/serialize.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 std::vector<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 unsigned byte, i. e. a 8 bit unsigned integer.
*/
pvUByte,
/**
* The type is unsigned short, i. e. a 16 bit unsigned integer.
*/
pvUShort,
/**
* The type is unsigned int, i. e. a 32 bit unsigned integer.
*/
pvUInt,
/**
* The type is unsigned long, i. e. a 64 bit unsigned integer.
*/
pvULong,
/**
* The type is float, i. e. 32 bit IEEE floating point,
*/
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,...ulong
* @param scalarType The type.
* @return (false,true) if the scalarType is an integer.
*/
bool isInteger(ScalarType scalarType);
/**
* Is the type an unsigned integer, i. e. is it one of ubyte,...ulong
* @param scalarType The type.
* @return (false,true) if the scalarType is an integer.
*/
bool isUInteger(ScalarType scalarType);
/**
* Is the type numeric, i. e. is it one of byte,...,double
* @param scalarType The type.
* @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 const &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 :
virtual public Serializable,
public std::tr1::enable_shared_from_this<Field> {
public:
POINTER_DEFINITIONS(Field);
/**
* Destructor.
*/
virtual ~Field();
/**
* Get the field type.
* @return The type.
*/
Type getType() const{return m_fieldType;}
/**
* Get the identification string.
* @return The identification string, can be empty.
*/
virtual String getID() const = 0;
/**
* Convert the scalarType to a string and add it to builder.
* @param builder The string builder.
*/
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;
protected:
/**
* Constructor
* @param fieldName The field type.
*/
Field(Type type);
private:
Type m_fieldType;
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;
virtual String getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
Scalar(ScalarType scalarType);
private:
int8 getTypeCodeLUT() const;
ScalarType scalarType;
friend class FieldCreate;
};
/**
* This class implements introspection object for field.
*/
class ScalarArray : public Field{
public:
POINTER_DEFINITIONS(ScalarArray);
typedef ScalarArray& reference;
typedef const ScalarArray& const_reference;
/**
* Constructor
* @param scalarType The scalarType for the field.
*/
ScalarArray(ScalarType scalarType);
/**
* Get the scalarType for the elements.
* @return the scalarType
*/
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;
virtual String getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
/**
* Destructor.
*/
virtual ~ScalarArray();
private:
int8 getTypeCodeLUT() const;
const String getIDScalarArrayLUT() const;
ScalarType elementType;
friend class FieldCreate;
};
/**
* This class implements introspection object for a structureArray
*/
class StructureArray : public Field{
public:
POINTER_DEFINITIONS(StructureArray);
typedef StructureArray& reference;
typedef const StructureArray& const_reference;
/**
* 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;
virtual String getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
/**
* Constructor.
* @param structure The introspection interface for the elements.
*/
StructureArray(StructureConstPtr const & 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);
/**
* Default structure ID.
*/
static epics::pvData::String DEFAULT_ID;
/**
* 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.
*/
std::size_t getNumberFields() const {return fieldNames.size();}
/**
* Get the field for the specified fieldName.
* @param fieldName The name of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
*/
FieldConstPtr getField(String const &fieldName) const;
/**
* Get the field for the specified fieldName.
* @param fieldName The index of the field to get;
* @return The introspection interface.
* This will hold a null pointer if the field is not in the structure.
*/
FieldConstPtr getField(std::size_t index) const {return fields[index];}
/**
* Get the field index for the specified fieldName.
* @return The introspection interface.
* This will be -1 if the field is not in the structure.
*/
std::size_t getFieldIndex(String const &fieldName) const;
/**
* Get the fields in the structure.
* @return The array of fields.
*/
FieldConstPtrArray const & getFields() const {return fields;}
/**
* Get the names of the fields in the structure.
* @return The array of fieldNames.
*/
StringArray const & getFieldNames() const {return fieldNames;}
void renameField(std::size_t fieldIndex,String const & newName)
{fieldNames[fieldIndex] = newName;}
/**
* Get the name of the field with the specified index;
* @param fieldIndex The index of the desired field.
* @return The fieldName.
*/
String getFieldName(std::size_t fieldIndex){return fieldNames[fieldIndex];}
/**
* Convert the structure to a string and add it to builder.
* @param builder The string builder.
*/
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;
virtual String getID() const;
virtual void serialize(ByteBuffer *buffer, SerializableControl *control) const;
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *control);
protected:
Structure(StringArray const & fieldNames, FieldConstPtrArray const & fields, String const & id = DEFAULT_ID);
private:
void toStringCommon(StringBuilder buf,int indentLevel) const;
StringArray fieldNames;
FieldConstPtrArray fields;
String id;
friend class FieldCreate;
};
/**
* This is a singlton class for creating introspection interfaces.
*/
class FieldCreate;
typedef std::tr1::shared_ptr<FieldCreate> FieldCreatePtr;
class FieldCreate {
public:
static FieldCreatePtr getFieldCreate();
/**
* Create a {@code ScalarField}.
* @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(ScalarType scalarType) const;
/**
* Create an {@code Array} field.
* @param elementType The {@code scalarType} for array elements
* @return An {@code Array} Interface for the newly created object.
*/
ScalarArrayConstPtr createScalarArray(ScalarType elementType) const;
/**
* Create an {@code Array} field that is has element type <i>Structure</i>
* @param fieldName The field name
* @param elementStructure The {@code Structure} for each array element.
* @return An {@code Array} Interface for the newly created object.
*/
StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const;
/**
* Create a {@code Structure} field.
* @param fieldNames The array of {@code fieldNames} for the structure.
* @param fields The array of {@code fields} for the structure.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr createStructure (
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Create a {@code Structure} field with identification string.
* @param id The identification string for the structure.
* @param fieldNames The array of {@code fieldNames} for the structure.
* @param fields The array of {@code fields} for the structure.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr createStructure (
String const & id,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Append a field to a structure.
* @param structure The structure to which the field is appended.
* @param fieldName The name of the field.
* @param field The field.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr appendField(
StructureConstPtr const & structure,
String const & fieldName, FieldConstPtr const & field) const;
/**
* Append fields to a structure.
* @param structure The structure to which the fields appended.
* @param fieldName The names of the fields.
* @param field The fields.
* @return a {@code Structure} interface for the newly created object.
*/
StructureConstPtr appendFields(
StructureConstPtr const & structure,
StringArray const & fieldNames,
FieldConstPtrArray const & fields) const;
/**
* Deserialize {@code Field} instance from given byte buffer.
* @param buffer Buffer containing serialized {@code Field} instance.
* @param control Deserialization control instance.
* @return a deserialized {@code Field} instance.
*/
FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
private:
FieldCreate();
};
/**
* Get the single class that implemnents FieldCreate,
* @param The fieldCreate factory.
*/
extern FieldCreatePtr getFieldCreate();
}}
#endif /* PVINTROSPECT_H */

View File

@@ -1,452 +0,0 @@
/* pvType.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
/* 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 <vector>
#ifdef __vxworks
typedef int intptr_t;
typedef unsigned int uintptr_t;
#define INT64_MAX (0x7fffffffffffffffLL)
#define UINT64_MAX (0xffffffffffffffffLL)
#else
#include <stdint.h>
#endif
#include <pv/sharedPtr.h>
#include <pv/localStaticLock.h>
namespace epics { namespace pvData {
/**
* This is a set of typdefs used by pvData.
*/
/**
* boolean, i.e. can only have the values {@code false} or {@code true}
*/
typedef uint8_t 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 8 bit unsigned integer
*/
typedef uint8_t uint8;
/**
* A 16 bit unsigned integer
*/
typedef uint16_t uint16;
/**
* 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 std::vector<uint8> BooleanArray;
typedef std::tr1::shared_ptr<BooleanArray> BooleanArrayPtr;
/* get is same is ubyte*/
typedef std::vector<uint8>::iterator BooleanArray_iterator;
typedef std::vector<uint8>::const_iterator BooleanArray_const_iterator;
/**
* A byte array.
*/
typedef std::vector<int8> ByteArray;
typedef std::tr1::shared_ptr<ByteArray> ByteArrayPtr;
inline int8 * get(ByteArray &value)
{
return &value[0];
}
inline int8 const * get(ByteArray const &value)
{
return static_cast<int8 const *>(&value[0]);
}
inline int8 * get(ByteArrayPtr &value)
{
return get(*value.get());
}
inline int8 const * get(ByteArrayPtr const &value)
{
return get(*value.get());
}
inline ByteArray & getVector(ByteArrayPtr &value)
{
return *value.get();
}
inline ByteArray const & getVector(ByteArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int8>::iterator ByteArray_iterator;
typedef std::vector<int8>::const_iterator ByteArray_const_iterator;
/**
* A short array.
*/
typedef std::vector<int16> ShortArray;
typedef std::tr1::shared_ptr<ShortArray> ShortArrayPtr;
inline int16 * get(ShortArray &value)
{
return &value[0];
}
inline int16 const * get(ShortArray const &value)
{
return static_cast<int16 const *>(&value[0]);
}
inline int16 * get(ShortArrayPtr &value)
{
return get(*value.get());
}
inline int16 const * get(ShortArrayPtr const &value)
{
return get(*value.get());
}
inline ShortArray & getVector(ShortArrayPtr &value)
{
return *value.get();
}
inline ShortArray const & getVector(ShortArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int16>::iterator ShortArray_iterator;
typedef std::vector<int16>::const_iterator ShortArray_const_iterator;
/**
* A int array.
*/
typedef std::vector<int32> IntArray;
typedef std::tr1::shared_ptr<IntArray> IntArrayPtr;
inline int32 * get(IntArray &value)
{
return &value[0];
}
inline int32 const * get(IntArray const &value)
{
return static_cast<int32 const *>(&value[0]);
}
inline int32 * get(IntArrayPtr &value)
{
return get(*value.get());
}
inline int32 const * get(IntArrayPtr const &value)
{
return get(*value.get());
}
inline IntArray & getVector(IntArrayPtr &value)
{
return *value.get();
}
inline IntArray const & getVector(IntArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int32>::iterator IntArray_iterator;
typedef std::vector<int32>::const_iterator IntArray_const_iterator;
/**
* A long array.
*/
typedef std::vector<int64> LongArray;
typedef std::tr1::shared_ptr<LongArray> LongArrayPtr;
inline int64 * get(LongArray &value)
{
return &value[0];
}
inline int64 const * get(LongArray const &value)
{
return static_cast<int64 const *>(&value[0]);
}
inline int64 * get(LongArrayPtr &value)
{
return get(*value.get());
}
inline int64 const * get(LongArrayPtr const &value)
{
return get(*value.get());
}
inline LongArray & getVector(LongArrayPtr &value)
{
return *value.get();
}
inline LongArray const & getVector(LongArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<int64>::iterator LongArray_iterator;
typedef std::vector<int64>::const_iterator LongArray_const_iterator;
/**
* An unsigned byte array.
*/
typedef std::vector<uint8> UByteArray;
typedef std::tr1::shared_ptr<UByteArray> UByteArrayPtr;
inline uint8 * get(UByteArray &value)
{
return &value[0];
}
inline uint8 const * get(UByteArray const &value)
{
return static_cast<uint8 const *>(&value[0]);
}
inline uint8 * get(UByteArrayPtr &value)
{
return get(*value.get());
}
inline uint8 const * get(UByteArrayPtr const &value)
{
return get(*value.get());
}
inline UByteArray & getVector(UByteArrayPtr &value)
{
return *value.get();
}
inline UByteArray const & getVector(UByteArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint8>::iterator UByteArray_iterator;
typedef std::vector<uint8>::const_iterator UByteArray_const_iterator;
/**
* An unsigned short array.
*/
typedef std::vector<uint16> UShortArray;
typedef std::tr1::shared_ptr<UShortArray> UShortArrayPtr;
inline uint16 * get(UShortArray &value)
{
return &value[0];
}
inline uint16 const * get(UShortArray const &value)
{
return static_cast<uint16 const *>(&value[0]);
}
inline uint16 * get(UShortArrayPtr &value)
{
return get(*value.get());
}
inline uint16 const * get(UShortArrayPtr const &value)
{
return get(*value.get());
}
inline UShortArray & getVector(UShortArrayPtr &value)
{
return *value.get();
}
inline UShortArray const & getVector(UShortArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint16>::iterator UShortArray_iterator;
typedef std::vector<uint16>::const_iterator UShortArray_const_iterator;
/**
* An unsigned int array.
*/
typedef std::vector<uint32> UIntArray;
typedef std::tr1::shared_ptr<UIntArray> UIntArrayPtr;
inline uint32 * get(UIntArray &value)
{
return &value[0];
}
inline uint32 const * get(UIntArray const &value)
{
return static_cast<uint32 const *>(&value[0]);
}
inline uint32 * get(UIntArrayPtr &value)
{
return get(*value.get());
}
inline uint32 const * get(UIntArrayPtr const &value)
{
return get(*value.get());
}
inline UIntArray & getVector(UIntArrayPtr &value)
{
return *value.get();
}
inline UIntArray const & getVector(UIntArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint32>::iterator UIntArray_iterator;
typedef std::vector<uint32>::const_iterator UIntArray_const_iterator;
/**
* An unsigned long array.
*/
typedef std::vector<uint64> ULongArray;
typedef std::tr1::shared_ptr<ULongArray> ULongArrayPtr;
inline uint64 * get(ULongArray &value)
{
return &value[0];
}
inline uint64 const * get(ULongArray const &value)
{
return static_cast<uint64 const *>(&value[0]);
}
inline uint64 * get(ULongArrayPtr &value)
{
return get(*value.get());
}
inline uint64 const * get(ULongArrayPtr const &value)
{
return get(*value.get());
}
inline ULongArray & getVector(ULongArrayPtr &value)
{
return *value.get();
}
inline ULongArray const & getVector(ULongArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<uint64>::iterator ULongArray_iterator;
typedef std::vector<uint64>::const_iterator ULongArray_const_iterator;
/**
* A float array.
*/
typedef std::vector<float> FloatArray;
typedef std::tr1::shared_ptr<FloatArray> FloatArrayPtr;
inline float * get(FloatArray &value)
{
return &value[0];
}
inline float const * get(FloatArray const &value)
{
return static_cast<float const *>(&value[0]);
}
inline float * get(FloatArrayPtr &value)
{
return get(*value.get());
}
inline float const * get(FloatArrayPtr const &value)
{
return get(*value.get());
}
inline FloatArray & getVector(FloatArrayPtr &value)
{
return *value.get();
}
inline FloatArray const & getVector(FloatArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<float>::iterator FloatArray_iterator;
typedef std::vector<float>::const_iterator FloatArray_const_iterator;
/**
* A double array.
*/
typedef std::vector<double> DoubleArray;
typedef std::tr1::shared_ptr<DoubleArray> DoubleArrayPtr;
inline double * get(DoubleArray &value)
{
return &value[0];
}
inline double const * get(DoubleArray const &value)
{
return static_cast<double const *>(&value[0]);
}
inline double * get(DoubleArrayPtr &value)
{
return get(*value.get());
}
inline double const * get(DoubleArrayPtr const &value)
{
return get(*value.get());
}
inline DoubleArray & getVector(DoubleArrayPtr &value)
{
return *value.get();
}
inline DoubleArray const & getVector(DoubleArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<double>::iterator DoubleArray_iterator;
typedef std::vector<double>::const_iterator DoubleArray_const_iterator;
/**
* A string array.
*/
typedef std::vector<String> StringArray;
typedef std::tr1::shared_ptr<StringArray> StringArrayPtr;
inline String * get(StringArray &value)
{
return &value[0];
}
inline String const * get(StringArray const &value)
{
return static_cast<String const *>(&value[0]);
}
inline String * get(StringArrayPtr &value)
{
return get(*value.get());
}
inline String const * get(StringArrayPtr const &value)
{
return get(*value.get());
}
inline StringArray & getVector(StringArrayPtr &value)
{
return *value.get();
}
inline StringArray const & getVector(StringArrayPtr const &value)
{
return *value.get();
}
typedef std::vector<String>::iterator StringArray_iterator;
typedef std::vector<String>::const_iterator StringArray_const_iterator;
/**
* A convenience definition for toString methods
*/
typedef String * StringBuilder;
}}
#endif /* PVTYPE_H */

View File

@@ -1,130 +0,0 @@
/* standardField.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* Author - Marty Kraimer
*/
/**
* @author mrk
*/
#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.
* 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
int severity
int status
string message
structure timeStamp
long secondsPastEpoch
int nanoSeconds
int userTag
* }
* In addition there are methods that create each of the property structures,
* i.e. the methods named: alarm, .... enumeratedAlarm."
*
* StandardField is a singleton class. The class is accessed via the statement: {@code
StandardField *standardField = getStandardField();
* }
*/
class StandardField;
typedef std::tr1::shared_ptr<StandardField> StandardFieldPtr;
class StandardField {
public:
static StandardFieldPtr getStandardField();
~StandardField();
StructureConstPtr scalar(ScalarType type,String const & properties);
StructureConstPtr scalarArray(ScalarType elementType, String const & properties);
StructureConstPtr structureArray(StructureConstPtr const & structure,String const & properties);
StructureConstPtr enumerated();
StructureConstPtr enumerated(String const & properties);
StructureConstPtr alarm();
StructureConstPtr timeStamp();
StructureConstPtr display();
StructureConstPtr control();
StructureConstPtr booleanAlarm();
StructureConstPtr byteAlarm();
StructureConstPtr ubyteAlarm();
StructureConstPtr shortAlarm();
StructureConstPtr ushortAlarm();
StructureConstPtr intAlarm();
StructureConstPtr uintAlarm();
StructureConstPtr longAlarm();
StructureConstPtr ulongAlarm();
StructureConstPtr floatAlarm();
StructureConstPtr doubleAlarm();
StructureConstPtr enumeratedAlarm();
private:
StandardField();
void init();
StructureConstPtr createProperties(String id,FieldConstPtr field,String properties);
FieldCreatePtr fieldCreate;
String notImplemented;
String valueFieldName;
StructureConstPtr alarmField;
StructureConstPtr timeStampField;
StructureConstPtr displayField;
StructureConstPtr controlField;
StructureConstPtr booleanAlarmField;
StructureConstPtr byteAlarmField;
StructureConstPtr shortAlarmField;
StructureConstPtr intAlarmField;
StructureConstPtr longAlarmField;
StructureConstPtr ubyteAlarmField;
StructureConstPtr ushortAlarmField;
StructureConstPtr uintAlarmField;
StructureConstPtr ulongAlarmField;
StructureConstPtr floatAlarmField;
StructureConstPtr doubleAlarmField;
StructureConstPtr enumeratedAlarmField;
void createAlarm();
void createTimeStamp();
void createDisplay();
void createControl();
void createBooleanAlarm();
void createByteAlarm();
void createShortAlarm();
void createIntAlarm();
void createLongAlarm();
void createUByteAlarm();
void createUShortAlarm();
void createUIntAlarm();
void createULongAlarm();
void createFloatAlarm();
void createDoubleAlarm();
void createEnumeratedAlarm();
friend StandardFieldPtr getStandardField();
};
extern StandardFieldPtr getStandardField();
}}
#endif /* STANDARDFIELD_H */

View File

@@ -1,54 +0,0 @@
/* standardPVField.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mrk
*/
#ifndef STANDARDPVFIELD_H
#define STANDARDPVFIELD_H
#include <string>
#include <stdexcept>
#include <pv/pvIntrospect.h>
#include <pv/pvData.h>
#include <pv/standardField.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;
typedef std::tr1::shared_ptr<StandardPVField> StandardPVFieldPtr;
class StandardPVField : private NoDefaultMethods {
public:
static StandardPVFieldPtr getStandardPVField();
~StandardPVField();
PVStructurePtr scalar(ScalarType type,String const & properties);
PVStructurePtr scalarArray(ScalarType elementType, String const & properties);
PVStructurePtr structureArray(StructureConstPtr const &structure,String const & properties);
PVStructurePtr enumerated(StringArray const &choices);
PVStructurePtr enumerated(StringArray const &choices, String const & properties);
private:
StandardPVField();
StandardFieldPtr standardField;
FieldCreatePtr fieldCreate;
PVDataCreatePtr pvDataCreate;
String notImplemented;
};
extern StandardPVFieldPtr getStandardPVField();
}}
#endif /* STANDARDPVFIELD_H */

View File

@@ -1,24 +0,0 @@
/*bitSetUtil.h*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvData is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/**
* @author mes
*/
#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(BitSetPtr const &bitSet,PVStructurePtr const &pvStructure);
};
}}
#endif /*BITSETUTIL_H */

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