pvxslibs 1.5.0__cp310-cp310-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvxslibs/__init__.py +0 -0
- pvxslibs/dbd/pvxsIoc.dbd +8 -0
- pvxslibs/include/pvxs/client.h +1094 -0
- pvxslibs/include/pvxs/data.h +948 -0
- pvxslibs/include/pvxs/iochooks.h +170 -0
- pvxslibs/include/pvxs/log.h +148 -0
- pvxslibs/include/pvxs/netcommon.h +82 -0
- pvxslibs/include/pvxs/nt.h +208 -0
- pvxslibs/include/pvxs/server.h +238 -0
- pvxslibs/include/pvxs/sharedArray.h +748 -0
- pvxslibs/include/pvxs/sharedpv.h +121 -0
- pvxslibs/include/pvxs/source.h +290 -0
- pvxslibs/include/pvxs/srvcommon.h +148 -0
- pvxslibs/include/pvxs/unittest.h +327 -0
- pvxslibs/include/pvxs/util.h +354 -0
- pvxslibs/include/pvxs/version.h +97 -0
- pvxslibs/include/pvxs/versionNum.h +6 -0
- pvxslibs/ioc.py +10 -0
- pvxslibs/lib/__init__.py +0 -0
- pvxslibs/lib/event_core_dsoinfo.py +14 -0
- pvxslibs/lib/event_pthread_dsoinfo.py +14 -0
- pvxslibs/lib/libevent_core.so +0 -0
- pvxslibs/lib/libevent_core.so.2.2.0 +0 -0
- pvxslibs/lib/libevent_pthread.so +0 -0
- pvxslibs/lib/libevent_pthread.so.2.2.0 +0 -0
- pvxslibs/lib/libpvxs.so +0 -0
- pvxslibs/lib/libpvxs.so.1.5 +0 -0
- pvxslibs/lib/libpvxsIoc.so +0 -0
- pvxslibs/lib/libpvxsIoc.so.1.5 +0 -0
- pvxslibs/lib/pvxsIoc_dsoinfo.py +14 -0
- pvxslibs/lib/pvxs_dsoinfo.py +14 -0
- pvxslibs/path.py +12 -0
- pvxslibs/test/__init__.py +0 -0
- pvxslibs/test/test_load.py +30 -0
- pvxslibs/version.py +32 -0
- pvxslibs-1.5.0.dist-info/METADATA +44 -0
- pvxslibs-1.5.0.dist-info/RECORD +40 -0
- pvxslibs-1.5.0.dist-info/WHEEL +5 -0
- pvxslibs-1.5.0.dist-info/licenses/LICENSE +26 -0
- pvxslibs-1.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
3
|
+
* pvxs is distributed subject to a Software License Agreement found
|
|
4
|
+
* in file LICENSE that is included with this distribution.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PVXS_IOCHOOKS_H
|
|
7
|
+
#define PVXS_IOCHOOKS_H
|
|
8
|
+
|
|
9
|
+
#include <pvxs/version.h>
|
|
10
|
+
|
|
11
|
+
#if defined(_WIN32) || defined(__CYGWIN__)
|
|
12
|
+
|
|
13
|
+
# if defined(PVXS_IOC_API_BUILDING) && defined(EPICS_BUILD_DLL)
|
|
14
|
+
/* building library as dll */
|
|
15
|
+
# define PVXS_IOC_API __declspec(dllexport)
|
|
16
|
+
# elif !defined(PVXS_IOC_API_BUILDING) && defined(EPICS_CALL_DLL)
|
|
17
|
+
/* calling library in dll form */
|
|
18
|
+
# define PVXS_IOC_API __declspec(dllimport)
|
|
19
|
+
# endif
|
|
20
|
+
|
|
21
|
+
#elif __GNUC__ >= 4
|
|
22
|
+
# define PVXS_IOC_API __attribute__ ((visibility("default")))
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
#ifndef PVXS_IOC_API
|
|
26
|
+
# define PVXS_IOC_API
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
namespace pvxs {
|
|
30
|
+
namespace server {
|
|
31
|
+
class Server;
|
|
32
|
+
}
|
|
33
|
+
namespace ioc {
|
|
34
|
+
|
|
35
|
+
/** Return the singleton Server instance which is setup
|
|
36
|
+
* for use in an IOC process.
|
|
37
|
+
*
|
|
38
|
+
* This Server instance is created during a registrar function,
|
|
39
|
+
* started by the initHookAfterCaServerRunning phase of iocInit().
|
|
40
|
+
* It is stopped and destroyed during an epicsAtExit() hook added
|
|
41
|
+
* during an initHookAfterInitDatabase hook..
|
|
42
|
+
*
|
|
43
|
+
* Any configuration changes via. epicsEnvSet() must be made before registrars are run
|
|
44
|
+
* by \*_registerRecordDeviceDriver(pdbbase).
|
|
45
|
+
*
|
|
46
|
+
* server::SharedPV and server::Source added before iocInit() will be available immediately.
|
|
47
|
+
* Others may be added (or removed) later.
|
|
48
|
+
*
|
|
49
|
+
* @throws std::logic_error if called before instance is created, or after instance is destroyed.
|
|
50
|
+
*
|
|
51
|
+
* @code
|
|
52
|
+
* static void myinitHook(initHookState state) {
|
|
53
|
+
* if(state!=initHookAfterIocBuilt)
|
|
54
|
+
* return;
|
|
55
|
+
*
|
|
56
|
+
* server::SharedPV mypv(...);
|
|
57
|
+
* ioc::server()
|
|
58
|
+
* .addPV("my:pv:name", mypv);
|
|
59
|
+
* }
|
|
60
|
+
* static void myregistrar() {
|
|
61
|
+
* initHookRegister(&myinitHook);
|
|
62
|
+
* }
|
|
63
|
+
* extern "C" {
|
|
64
|
+
* // needs matching "registrar(myregistrar)" in .dbd
|
|
65
|
+
* epicsExportRegistrar(myregistrar);
|
|
66
|
+
* }
|
|
67
|
+
* @endcode
|
|
68
|
+
*/
|
|
69
|
+
PVXS_IOC_API
|
|
70
|
+
server::Server server();
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Load JSON group definition file.
|
|
74
|
+
* This function does not actually parse the given file, but adds it to the list of files to be loaded,
|
|
75
|
+
* at the appropriate time in the startup process.
|
|
76
|
+
*
|
|
77
|
+
* @param jsonFilename the json file containing the group definitions
|
|
78
|
+
* @param macros NULL, or a comma separated list of macro definitions. eg. "KEY=VAL,OTHER=SECOND"
|
|
79
|
+
* @return 0 for success, 1 for failure
|
|
80
|
+
* @since 1.2.0
|
|
81
|
+
*/
|
|
82
|
+
PVXS_IOC_API
|
|
83
|
+
long dbLoadGroup(const char* jsonFilename, const char* macros=nullptr);
|
|
84
|
+
|
|
85
|
+
/** Call just after testdbPrepare()
|
|
86
|
+
*
|
|
87
|
+
* Prepare QSRV for re-test. Optional if testdbPrepare() called only once.
|
|
88
|
+
* Required after subsequent calls.
|
|
89
|
+
* @since 1.2.3
|
|
90
|
+
*/
|
|
91
|
+
PVXS_IOC_API
|
|
92
|
+
void testPrepare();
|
|
93
|
+
|
|
94
|
+
/** Call just before testIocShutdownOk()
|
|
95
|
+
*
|
|
96
|
+
* Shutdown QSRV. Only needed with Base <= 7.0.4 .
|
|
97
|
+
* Since 7.0.4, QSRV shutdown occurs during testIocShutdownOk() .
|
|
98
|
+
* @since 1.2.0
|
|
99
|
+
*/
|
|
100
|
+
PVXS_IOC_API
|
|
101
|
+
void testShutdown();
|
|
102
|
+
|
|
103
|
+
/** Call just after testIocShutdownOk()
|
|
104
|
+
* @since 1.3.0
|
|
105
|
+
*/
|
|
106
|
+
PVXS_IOC_API
|
|
107
|
+
void testAfterShutdown();
|
|
108
|
+
|
|
109
|
+
/** Call just before testdbCleanup()
|
|
110
|
+
* @since 1.3.0
|
|
111
|
+
*/
|
|
112
|
+
PVXS_IOC_API
|
|
113
|
+
void testCleanupPrepare();
|
|
114
|
+
|
|
115
|
+
#if _DOXYGEN_ || EPICS_VERSION_INT >= VERSION_INT(3, 15, 0 ,0)
|
|
116
|
+
|
|
117
|
+
/** Manage Test IOC life-cycle calls.
|
|
118
|
+
*
|
|
119
|
+
* Makes necessary calls to dbUnitTest.h API
|
|
120
|
+
* as well as any added calls needed by PVXS components.
|
|
121
|
+
*
|
|
122
|
+
@code
|
|
123
|
+
* MAIN(mytest) {
|
|
124
|
+
* testPlan(0); // TODO: Set actual number of tests
|
|
125
|
+
* pvxs::testSetup();
|
|
126
|
+
* pvxs::logger_config_env(); // (optional)
|
|
127
|
+
* {
|
|
128
|
+
* TestIOC ioc; // testdbPrepare()
|
|
129
|
+
*
|
|
130
|
+
* // mytestioc.dbd must include pvxsIoc.dbd
|
|
131
|
+
* testdbReadDatabase("mytestioc.dbd", NULL, NULL);
|
|
132
|
+
* mytestioc_registerRecordDeviceDriver(pdbbase);
|
|
133
|
+
* testdbReadDatabase("sometest.db", NULL, NULL);
|
|
134
|
+
*
|
|
135
|
+
* // tests before iocInit()
|
|
136
|
+
*
|
|
137
|
+
* ioc.init();
|
|
138
|
+
*
|
|
139
|
+
* // tests after iocInit()
|
|
140
|
+
*
|
|
141
|
+
* ioc.shutdown(); // (optional) in ~TestIOC if omitted
|
|
142
|
+
* }
|
|
143
|
+
* {
|
|
144
|
+
* ... repeat ...
|
|
145
|
+
* }
|
|
146
|
+
* epicsExitCallAtExits();
|
|
147
|
+
* pvxs::cleanup_for_valgrind();
|
|
148
|
+
* }
|
|
149
|
+
@endcode
|
|
150
|
+
*
|
|
151
|
+
* @since 1.3.0
|
|
152
|
+
*/
|
|
153
|
+
class PVXS_IOC_API TestIOC final {
|
|
154
|
+
bool isRunning = false;
|
|
155
|
+
public:
|
|
156
|
+
TestIOC();
|
|
157
|
+
~TestIOC();
|
|
158
|
+
//! iocInit()
|
|
159
|
+
void init();
|
|
160
|
+
//! iocShutdown()
|
|
161
|
+
void shutdown();
|
|
162
|
+
//! between iocInit() and iocShutdown() ?
|
|
163
|
+
inline
|
|
164
|
+
bool running() const { return isRunning; }
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
#endif // base >= 3.15
|
|
168
|
+
|
|
169
|
+
}} // namespace pvxs::ioc
|
|
170
|
+
#endif // PVXS_IOCHOOKS_H
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
3
|
+
* pvxs is distributed subject to a Software License Agreement found
|
|
4
|
+
* in file LICENSE that is included with this distribution.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PVXS_LOG_H
|
|
7
|
+
#define PVXS_LOG_H
|
|
8
|
+
|
|
9
|
+
#include <atomic>
|
|
10
|
+
|
|
11
|
+
#include <cstddef>
|
|
12
|
+
#include <stdarg.h>
|
|
13
|
+
|
|
14
|
+
#include <compilerDependencies.h>
|
|
15
|
+
#include <errlog.h>
|
|
16
|
+
|
|
17
|
+
#include <pvxs/version.h>
|
|
18
|
+
|
|
19
|
+
// MSVC specific function parameter annotation for printf() spec. validation.
|
|
20
|
+
#ifndef _MSC_VER
|
|
21
|
+
# define _Printf_format_string_
|
|
22
|
+
#elif defined(PVXS_API_BUILDING)
|
|
23
|
+
// Internally, treat some printf() related warnings as errors.
|
|
24
|
+
# pragma warning(error:6302; error:6303; error:6306)
|
|
25
|
+
#endif
|
|
26
|
+
|
|
27
|
+
namespace pvxs {
|
|
28
|
+
|
|
29
|
+
//! Importance of message
|
|
30
|
+
enum struct Level {
|
|
31
|
+
Debug = 50,
|
|
32
|
+
Info = 40,
|
|
33
|
+
Warn = 30,
|
|
34
|
+
Err = 20,
|
|
35
|
+
Crit = 10,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//! A logger
|
|
39
|
+
struct logger {
|
|
40
|
+
//! global name of this logger. Need not be unique
|
|
41
|
+
const char * const name;
|
|
42
|
+
//! Current logging level. See logger_level_set().
|
|
43
|
+
std::atomic<Level> lvl;
|
|
44
|
+
constexpr logger(const char *name) :name(name), lvl{Level(-1)} {}
|
|
45
|
+
|
|
46
|
+
private:
|
|
47
|
+
PVXS_API Level init();
|
|
48
|
+
public:
|
|
49
|
+
|
|
50
|
+
//! @returns true if the logger currently allows a message at level LVL.
|
|
51
|
+
inline bool test(Level lvl) {
|
|
52
|
+
Level cur = this->lvl.load(std::memory_order_relaxed);
|
|
53
|
+
if(cur==Level(-1)) cur = init();
|
|
54
|
+
return cur>=lvl;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
namespace detail {
|
|
59
|
+
|
|
60
|
+
PVXS_API
|
|
61
|
+
const char *log_prep(logger& log, unsigned lvl);
|
|
62
|
+
|
|
63
|
+
PVXS_API
|
|
64
|
+
void _log_printf(unsigned rawlvl, _Printf_format_string_ const char *fmt, ...) EPICS_PRINTF_STYLE(2,3);
|
|
65
|
+
|
|
66
|
+
PVXS_API
|
|
67
|
+
void _log_printf_hex(unsigned rawlvl, _Printf_format_string_ const void *buf, size_t buflen, const char *fmt, ...) EPICS_PRINTF_STYLE(4,5);
|
|
68
|
+
|
|
69
|
+
} // namespace detail
|
|
70
|
+
|
|
71
|
+
//! Define a new logger global.
|
|
72
|
+
//! @param VAR The (static) variable name passed to log_printf() and friends.
|
|
73
|
+
//! @param NAME A name string in "A.B.C" form.
|
|
74
|
+
#define DEFINE_LOGGER(VAR, NAME) static ::pvxs::logger VAR{NAME}
|
|
75
|
+
|
|
76
|
+
PVXS_API
|
|
77
|
+
void xerrlogHexPrintf(const void *buf, size_t buflen);
|
|
78
|
+
|
|
79
|
+
/** Try to log a message at the defined level.
|
|
80
|
+
*
|
|
81
|
+
* Due to portability issues with MSVC, log formats must have at least one argument.
|
|
82
|
+
*
|
|
83
|
+
* @code
|
|
84
|
+
* DEFINE_LOGGER(blah, "myapp.blah");
|
|
85
|
+
* void blahfn(int x) {
|
|
86
|
+
* log_info_printf(blah, "blah happened with %d\n", x);
|
|
87
|
+
* @endcode
|
|
88
|
+
*/
|
|
89
|
+
#define log_printf(LOGGER, LVL, FMT, ...) do{ \
|
|
90
|
+
if(auto _log_prefix = ::pvxs::detail::log_prep(LOGGER, unsigned(LVL))) \
|
|
91
|
+
::pvxs::detail:: _log_printf(unsigned(LVL), "%s " FMT, _log_prefix, __VA_ARGS__); \
|
|
92
|
+
}while(0)
|
|
93
|
+
|
|
94
|
+
/* A note about MSVC (legacy) pre-processor weirdness.
|
|
95
|
+
* Care needs to be taken when expanding nested macros w/ __VA_ARGS__.
|
|
96
|
+
* Expansion of __VA_ARGS__ for the outer macro seems to result in
|
|
97
|
+
* all of the contents, including commas, being treated as a single
|
|
98
|
+
* token. Which won't be split during expansion of the inner macro!
|
|
99
|
+
*
|
|
100
|
+
* #define inner(FMT, ...) printf("%s " FMT, "prefix", __VA_ARGS__)
|
|
101
|
+
* #define outer(...) inner(__VA_ARGS__)
|
|
102
|
+
* outer("%d", 42);
|
|
103
|
+
* expands to
|
|
104
|
+
* printf("%s " "%d", 42, "prefix");
|
|
105
|
+
*
|
|
106
|
+
* The prefix string has jumped to the end because FMT has expanded
|
|
107
|
+
* with all of the arguments of outer(...). Surprise!
|
|
108
|
+
*
|
|
109
|
+
* Thus FMT is explicitly matched in the following "outer" macros.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
#define log_exc_printf(LOGGER, FMT, ...) log_printf(LOGGER, unsigned(::pvxs::Level::Crit)|0x1000, FMT, __VA_ARGS__)
|
|
113
|
+
#define log_crit_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Crit, FMT, __VA_ARGS__)
|
|
114
|
+
#define log_err_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Err, FMT, __VA_ARGS__)
|
|
115
|
+
#define log_warn_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Warn, FMT, __VA_ARGS__)
|
|
116
|
+
#define log_info_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Info, FMT, __VA_ARGS__)
|
|
117
|
+
#define log_debug_printf(LOGGER, FMT, ...) log_printf(LOGGER, ::pvxs::Level::Debug, FMT, __VA_ARGS__)
|
|
118
|
+
|
|
119
|
+
#define log_hex_printf(LOGGER, LVL, BUF, BUFLEN, FMT, ...) do{ \
|
|
120
|
+
if(auto _log_prefix = ::pvxs::detail::log_prep(LOGGER, unsigned(LVL))) \
|
|
121
|
+
::pvxs::detail:: _log_printf_hex(unsigned(LVL), BUF, BUFLEN, "%s " FMT, _log_prefix, __VA_ARGS__);\
|
|
122
|
+
}while(0)
|
|
123
|
+
|
|
124
|
+
//! Set level for a specific logger
|
|
125
|
+
PVXS_API void logger_level_set(const char *name, int lvl);
|
|
126
|
+
inline void logger_level_set(const char *name, Level lvl) {
|
|
127
|
+
logger_level_set(name, int(lvl));
|
|
128
|
+
}
|
|
129
|
+
//! Remove any previously logger configurations.
|
|
130
|
+
//! Does _not_ change any logger::lvl
|
|
131
|
+
//! Use prior to re-applying new configuration.
|
|
132
|
+
PVXS_API void logger_level_clear();
|
|
133
|
+
|
|
134
|
+
/** Configure logging from environment variable **$PVXS_LOG**
|
|
135
|
+
*
|
|
136
|
+
* Value of the form "key=VAL,..."
|
|
137
|
+
*
|
|
138
|
+
* Keys may be literal logger names, or may include '*' wildcards
|
|
139
|
+
* to match multiple loggers. eg. "pvxs.*=DEBUG" will enable
|
|
140
|
+
* all internal log messages.
|
|
141
|
+
*
|
|
142
|
+
* VAL may be one of "CRIT", "ERR", "WARN", "INFO", or "DEBUG"
|
|
143
|
+
*/
|
|
144
|
+
PVXS_API void logger_config_env();
|
|
145
|
+
|
|
146
|
+
} // namespace pvxs
|
|
147
|
+
|
|
148
|
+
#endif // PVXS_LOG_H
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
3
|
+
* pvxs is distributed subject to a Software License Agreement found
|
|
4
|
+
* in file LICENSE that is included with this distribution.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PVXS_NETCOMMON_H
|
|
7
|
+
#define PVXS_NETCOMMON_H
|
|
8
|
+
|
|
9
|
+
#if !defined(PVXS_CLIENT_H) && !defined(PVXS_SERVER_H)
|
|
10
|
+
# error Include <pvxs/client.h> or <pvxs/server.h> Do not include netcommon.h directly
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <list>
|
|
15
|
+
#include <memory>
|
|
16
|
+
|
|
17
|
+
#include <pvxs/version.h>
|
|
18
|
+
|
|
19
|
+
namespace pvxs {
|
|
20
|
+
namespace impl {
|
|
21
|
+
struct Report;
|
|
22
|
+
struct ReportInfo;
|
|
23
|
+
}
|
|
24
|
+
namespace server {
|
|
25
|
+
struct ClientCredentials;
|
|
26
|
+
using impl::Report;
|
|
27
|
+
using impl::ReportInfo;
|
|
28
|
+
}
|
|
29
|
+
namespace client {
|
|
30
|
+
using impl::Report;
|
|
31
|
+
using impl::ReportInfo;
|
|
32
|
+
}
|
|
33
|
+
namespace impl {
|
|
34
|
+
|
|
35
|
+
#ifdef PVXS_EXPERT_API_ENABLED
|
|
36
|
+
|
|
37
|
+
/** Snapshot of information about a client/server
|
|
38
|
+
*
|
|
39
|
+
* cf. pvxs::server::Server::report() and pvxs::client::Context::report()
|
|
40
|
+
*
|
|
41
|
+
* @since 0.2.0
|
|
42
|
+
*/
|
|
43
|
+
struct Report {
|
|
44
|
+
//! Info for a single channel (to a particular PV name on a particular server)
|
|
45
|
+
struct Channel {
|
|
46
|
+
//! Channel name. aka. PV name
|
|
47
|
+
std::string name;
|
|
48
|
+
//! transmit and receive counters in bytes
|
|
49
|
+
size_t tx{}, rx{};
|
|
50
|
+
//! Contextual information (maybe) supplied by the Source
|
|
51
|
+
std::shared_ptr<const ReportInfo> info;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//! Info for a single connection to remote peer
|
|
55
|
+
struct Connection {
|
|
56
|
+
//! peer endpoint (eg. IPv4 address and port)
|
|
57
|
+
std::string peer;
|
|
58
|
+
//! Credentials presented by peer. Only from Server::report()
|
|
59
|
+
std::shared_ptr<const server::ClientCredentials> credentials;
|
|
60
|
+
//! transmit and receive counters in bytes
|
|
61
|
+
size_t tx{}, rx{};
|
|
62
|
+
//! Channels currently connected through this socket
|
|
63
|
+
std::list<Channel> channels;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
//! Currently open sockets
|
|
67
|
+
std::list<Connection> connections;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
struct PVXS_API ReportInfo {
|
|
71
|
+
ReportInfo() = default;
|
|
72
|
+
ReportInfo(const ReportInfo&) = delete;
|
|
73
|
+
ReportInfo& operator=(const ReportInfo&) = delete;
|
|
74
|
+
virtual ~ReportInfo();
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
#endif
|
|
78
|
+
|
|
79
|
+
} // namespace impl
|
|
80
|
+
} // namespace pvxs
|
|
81
|
+
|
|
82
|
+
#endif // PVXS_NETCOMMON_H
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
3
|
+
* pvxs is distributed subject to a Software License Agreement found
|
|
4
|
+
* in file LICENSE that is included with this distribution.
|
|
5
|
+
*/
|
|
6
|
+
#ifndef PVXS_NT_H
|
|
7
|
+
#define PVXS_NT_H
|
|
8
|
+
|
|
9
|
+
#include <memory>
|
|
10
|
+
|
|
11
|
+
#include <pvxs/version.h>
|
|
12
|
+
#include <pvxs/data.h>
|
|
13
|
+
|
|
14
|
+
struct epicsTimeStamp; // epicsTime.h
|
|
15
|
+
|
|
16
|
+
namespace pvxs {
|
|
17
|
+
namespace nt {
|
|
18
|
+
|
|
19
|
+
/** The time_t struct
|
|
20
|
+
*
|
|
21
|
+
* @code
|
|
22
|
+
* // equivalent
|
|
23
|
+
* struct time_t {
|
|
24
|
+
* int64_t secondsPastEpoch;
|
|
25
|
+
* int32_t nanoseconds;
|
|
26
|
+
* int32_t userTag;
|
|
27
|
+
* };
|
|
28
|
+
* @endcode
|
|
29
|
+
* @since 0.1.4
|
|
30
|
+
*/
|
|
31
|
+
struct TimeStamp {
|
|
32
|
+
PVXS_API
|
|
33
|
+
TypeDef build();
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** The alarm_t struct
|
|
37
|
+
*
|
|
38
|
+
* @code
|
|
39
|
+
* // equivalent
|
|
40
|
+
* struct alarm_t {
|
|
41
|
+
* int32_t severity;
|
|
42
|
+
* int32_t status;
|
|
43
|
+
* string message;
|
|
44
|
+
* };
|
|
45
|
+
* @endcode
|
|
46
|
+
* @since 0.1.4
|
|
47
|
+
*/
|
|
48
|
+
struct Alarm {
|
|
49
|
+
PVXS_API
|
|
50
|
+
TypeDef build();
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** A scalar, or array of scalars, and meta-data
|
|
54
|
+
*
|
|
55
|
+
* @code
|
|
56
|
+
* auto def = pvxs::nt::NTScalar{TypeCode::Float64}.build();
|
|
57
|
+
* def += {
|
|
58
|
+
* Member(TypeCode::String, "myspecial"),
|
|
59
|
+
* };
|
|
60
|
+
* auto value = def.create(); // instantiate a Value
|
|
61
|
+
* @endcode
|
|
62
|
+
*/
|
|
63
|
+
struct NTScalar {
|
|
64
|
+
//! Type of the ".value" field.
|
|
65
|
+
TypeCode value;
|
|
66
|
+
//! Include display (range) meta-data
|
|
67
|
+
bool display;
|
|
68
|
+
//! Include control (range) meta-data
|
|
69
|
+
bool control;
|
|
70
|
+
//! Include alarm (range) meta-data
|
|
71
|
+
bool valueAlarm;
|
|
72
|
+
/** Include 'display.form' and 'display.precision' when 'value' is a numeric type
|
|
73
|
+
* @pre requires display=true
|
|
74
|
+
* @since 1.2.0
|
|
75
|
+
*/
|
|
76
|
+
bool form;
|
|
77
|
+
|
|
78
|
+
constexpr
|
|
79
|
+
NTScalar(TypeCode value = TypeCode::Float64,
|
|
80
|
+
bool display = false,
|
|
81
|
+
bool control = false,
|
|
82
|
+
bool valueAlarm = false,
|
|
83
|
+
bool form = false)
|
|
84
|
+
:value(value), display(display), control(control), valueAlarm(valueAlarm), form(form)
|
|
85
|
+
{}
|
|
86
|
+
|
|
87
|
+
//! A TypeDef which can be appended
|
|
88
|
+
PVXS_API
|
|
89
|
+
TypeDef build() const;
|
|
90
|
+
//! Instantiate
|
|
91
|
+
inline Value create() const {
|
|
92
|
+
return build().create();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/** An enumerated value (choice from a list of strings)
|
|
97
|
+
*
|
|
98
|
+
* @since 0.1.5
|
|
99
|
+
*/
|
|
100
|
+
struct NTEnum {
|
|
101
|
+
//! A TypeDef which can be appended
|
|
102
|
+
PVXS_API
|
|
103
|
+
TypeDef build() const;
|
|
104
|
+
//! Instantiate
|
|
105
|
+
inline Value create() const {
|
|
106
|
+
return build().create();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/** Columnar data.
|
|
111
|
+
*
|
|
112
|
+
* Unlike other NT* builders. This create() method returns a Value
|
|
113
|
+
* with the labels field set, and marked. While suitable for an
|
|
114
|
+
* initial value, repeated create() could result in re-sending
|
|
115
|
+
* the same labels array with every update. Users should
|
|
116
|
+
* create() once, and then Value::cloneEmpty() or Value::unmark() for
|
|
117
|
+
* subsequent updates.
|
|
118
|
+
*
|
|
119
|
+
* @since 1.2.3
|
|
120
|
+
*/
|
|
121
|
+
struct PVXS_API NTTable final {
|
|
122
|
+
|
|
123
|
+
NTTable();
|
|
124
|
+
~NTTable();
|
|
125
|
+
|
|
126
|
+
/** Append a column
|
|
127
|
+
*
|
|
128
|
+
* @param code Value type of column
|
|
129
|
+
* @param name Field name of column
|
|
130
|
+
* @param label Display label of column. (defaults to field name)
|
|
131
|
+
* Only used in create().
|
|
132
|
+
* @returns this
|
|
133
|
+
*/
|
|
134
|
+
NTTable& add_column(TypeCode code,
|
|
135
|
+
const char *name,
|
|
136
|
+
const char *label=nullptr);
|
|
137
|
+
|
|
138
|
+
//! A TypeDef which can be appended
|
|
139
|
+
TypeDef build() const;
|
|
140
|
+
//! Instantiate. Also populates labels list.
|
|
141
|
+
Value create() const;
|
|
142
|
+
|
|
143
|
+
struct Pvt;
|
|
144
|
+
private:
|
|
145
|
+
std::shared_ptr<Pvt> pvt;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/** The areaDetector inspired N-dimension array/image container.
|
|
149
|
+
*
|
|
150
|
+
* @code
|
|
151
|
+
* auto def = pvxs::nt::NTNDArray{}.build();
|
|
152
|
+
* auto value = def.create(); // instantiate a Value
|
|
153
|
+
* @endcode
|
|
154
|
+
*/
|
|
155
|
+
struct NTNDArray {
|
|
156
|
+
//! A TypeDef which can be appended
|
|
157
|
+
PVXS_API
|
|
158
|
+
TypeDef build() const;
|
|
159
|
+
//! Instantiate
|
|
160
|
+
inline Value create() const {
|
|
161
|
+
return build().create();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
class PVXS_API NTURI {
|
|
166
|
+
TypeDef _def;
|
|
167
|
+
public:
|
|
168
|
+
NTURI(std::initializer_list<Member> mem);
|
|
169
|
+
|
|
170
|
+
//! A TypeDef which can be appended
|
|
171
|
+
inline
|
|
172
|
+
TypeDef build() const { return _def; }
|
|
173
|
+
|
|
174
|
+
//! Instantiate
|
|
175
|
+
inline Value create() const {
|
|
176
|
+
return build().create();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private:
|
|
180
|
+
template<typename Iter, typename T, typename ...Args>
|
|
181
|
+
static
|
|
182
|
+
void _assign(Iter& cur, const Iter& end, const T& v, Args... args)
|
|
183
|
+
{
|
|
184
|
+
if(cur==end)
|
|
185
|
+
throw std::logic_error("Too many arguments");
|
|
186
|
+
(*cur).template from<T>(v);
|
|
187
|
+
++cur;
|
|
188
|
+
_assign(cur, end, args...);
|
|
189
|
+
}
|
|
190
|
+
template<typename Iter>
|
|
191
|
+
static
|
|
192
|
+
void _assign(Iter& cur, const Iter& end)
|
|
193
|
+
{}
|
|
194
|
+
public:
|
|
195
|
+
|
|
196
|
+
template<typename ...Args>
|
|
197
|
+
Value call(Args... args) const {
|
|
198
|
+
auto val(create());
|
|
199
|
+
auto iterable = val["query"].ichildren();
|
|
200
|
+
auto it = iterable.begin();
|
|
201
|
+
_assign(it, iterable.end(), args...);
|
|
202
|
+
return val;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
}} // namespace pvxs::nt
|
|
207
|
+
|
|
208
|
+
#endif // PVXS_NT_H
|