Compare commits
847 Commits
2.0-BETA
...
c6bd63efce
| Author | SHA1 | Date | |
|---|---|---|---|
| c6bd63efce | |||
|
|
f66492ce4b | ||
|
|
e069c699e9 | ||
|
|
8963b2dba1 | ||
|
|
9ec9a526f5 | ||
|
|
b4114589ff | ||
| 6689c9ce1f | |||
|
|
0c1773f25d | ||
|
|
d0ff9a9592 | ||
|
|
bf36070860 | ||
|
|
5552773e5e | ||
|
|
b3a1077270 | ||
| 2be3bc40e0 | |||
|
|
1c5f75bcd6 | ||
|
|
2455039594 | ||
|
|
f47676c225 | ||
|
|
0881e0ed86 | ||
|
|
e457b60b30 | ||
|
|
a6746f8161 | ||
| 7c10c29c33 | |||
|
|
144f0228cc | ||
|
|
7300e6b0bd | ||
|
|
0ef8a36172 | ||
|
|
c0be043aaf | ||
| 4c9b294e2b | |||
|
|
dd74289eaf | ||
|
|
3da69257a0 | ||
|
|
13e4e577bb | ||
|
|
5387face45 | ||
|
|
eac2a8e70f | ||
|
|
04fcb7e38f | ||
|
|
45018a2163 | ||
|
|
b7ad4478a4 | ||
|
|
c16f19c80e | ||
|
|
87018882d1 | ||
| 3efc4e3fd8 | |||
| 2547514abb | |||
| 763e39d435 | |||
| 155e8f078e | |||
|
|
9447eacbd2 | ||
|
|
0b424a71ec | ||
|
|
45671faaea | ||
|
|
016d1154fc | ||
|
|
f3911d5831 | ||
|
|
93e90c5a04 | ||
|
|
8039c75b3e | ||
|
|
a647c8b174 | ||
| 865840ec0c | |||
|
|
d3b4976ea2 | ||
|
|
b1c8303870 | ||
|
|
a3ef984f4f | ||
|
|
ca86a63180 | ||
|
|
07b79693af | ||
|
|
4ef9e18ac6 | ||
|
|
320cc3c60b | ||
|
|
45d0d76a7f | ||
|
|
b2b42d5f8c | ||
|
|
90b1f2f6da | ||
|
|
2e775ef2fb | ||
|
|
f17d2bbca1 | ||
|
|
79b02254c4 | ||
|
|
19245ce805 | ||
|
|
0fa927afa7 | ||
|
|
d9b3f98e35 | ||
|
|
81e7968230 | ||
|
|
06f3b96992 | ||
| 1038182a16 | |||
| 60091bfe56 | |||
| f4de6dd9b1 | |||
|
|
3d93a80cce | ||
|
|
94eff54fa9 | ||
|
|
e9dde4d2f8 | ||
|
|
0a5e22e5b0 | ||
|
|
3a5cfba4e1 | ||
|
|
07b75e4543 | ||
|
|
e4f150b34f | ||
|
|
ca2ae0d0e7 | ||
|
|
828506720c | ||
|
|
ad712b63f9 | ||
|
|
4c3d5a788d | ||
|
|
df89135455 | ||
|
|
95d452870c | ||
|
|
8a82ff9fe4 | ||
|
|
dd24b2ad75 | ||
|
|
17fa7a7724 | ||
|
|
d01ba94ed7 | ||
|
|
c7c7585950 | ||
|
|
f869936cfd | ||
|
|
0ad253c6f0 | ||
|
|
52d04d5044 | ||
|
|
bff2dc9cd2 | ||
|
|
b903df5d0d | ||
|
|
416d910577 | ||
|
|
37b7a0708f | ||
|
|
6ceaa6adb0 | ||
|
|
0447826e7c | ||
|
|
3ef60a61a2 | ||
|
|
31802a8bde | ||
|
|
c2bc77a649 | ||
|
|
4dd7a18301 | ||
|
|
a29894ee2b | ||
|
|
2f8ac7f673 | ||
|
|
b050fbbcbe | ||
|
|
caa11605fc | ||
|
|
cfcdd1a3f9 | ||
|
|
95ff606ba1 | ||
|
|
4cc9b650c5 | ||
|
|
cd2436342d | ||
|
|
3ae2d09fe3 | ||
|
|
35b3403de6 | ||
|
|
f780ebdf76 | ||
|
|
93f0518b4b | ||
|
|
6da871fa64 | ||
|
|
d53cb0cbc9 | ||
|
|
8f0111e482 | ||
|
|
5525119778 | ||
|
|
6410600205 | ||
|
|
a5d44745d1 | ||
|
|
8c275cbc1c | ||
|
|
b79f69231c | ||
|
|
ff165595c4 | ||
|
|
12d851dc6f | ||
|
|
643f289c23 | ||
|
|
68e74ed1d2 | ||
|
|
f0ef0965c4 | ||
|
|
61ce532fdf | ||
|
|
d746e1bfb3 | ||
|
|
deccc41b9a | ||
|
|
4ffddfa2f6 | ||
|
|
2814c779bd | ||
|
|
4c73607799 | ||
|
|
d776f6eaf0 | ||
|
|
706ef01782 | ||
|
|
00c62cbd67 | ||
|
|
da8f3d6cc7 | ||
|
|
0bc95e51c2 | ||
|
|
727153e965 | ||
|
|
d00f54228d | ||
|
|
77c67802a3 | ||
|
|
7d68d177d7 | ||
|
|
9b20505dcd | ||
|
|
5f93e292b2 | ||
|
|
edd3e20f3c | ||
|
|
90cffa60d6 | ||
|
|
6171cd6867 | ||
|
|
fa731bf6c3 | ||
|
|
818fce324c | ||
|
|
1bc867e48d | ||
|
|
434b9f7a9f | ||
|
|
f54602dead | ||
|
|
fb546b41c1 | ||
|
|
e400d9f5fd | ||
|
|
f0fa8a2481 | ||
|
|
c3b0b49e3f | ||
|
|
45265b4f9b | ||
|
|
aa87a2a23d | ||
|
|
5a59b1da75 | ||
|
|
32aa0dd72f | ||
|
|
c1188b16a1 | ||
|
|
a02a60c658 | ||
| c5f9f5a2dc | |||
|
|
342b1bc8ef | ||
|
|
64158376f5 | ||
|
|
850d4ff056 | ||
|
|
f0cfe1c85a | ||
|
|
c8b615b3ee | ||
|
|
c67fdafb43 | ||
|
|
f66d277918 | ||
|
|
4ef7db20f8 | ||
|
|
e1216dfa76 | ||
|
|
340fa8a7cb | ||
|
|
a029455466 | ||
|
|
27f78c430b | ||
|
|
3d707e5e95 | ||
|
|
0406a2f614 | ||
|
|
a1c0e432ee | ||
|
|
57e57d9e43 | ||
|
|
e4e4188eaf | ||
|
|
f1553cc90e | ||
|
|
997e68c99a | ||
|
|
25663d9a7b | ||
|
|
1e55266396 | ||
|
|
810ae15991 | ||
|
|
271fec7f5e | ||
|
|
c43486791e | ||
|
|
499c03265f | ||
|
|
7eaa613d4d | ||
|
|
19db72031c | ||
|
|
671f9cca4b | ||
|
|
9ecdb80534 | ||
|
|
e973422ee1 | ||
|
|
8093c25b72 | ||
|
|
a7c9c620dd | ||
|
|
1e1d94ed73 | ||
|
|
7b8ef390ce | ||
|
|
87ade13234 | ||
|
|
32abde7f19 | ||
|
|
fe413af177 | ||
|
|
b4cd026fe5 | ||
|
|
a51b308cc8 | ||
|
|
1c09b42951 | ||
|
|
e42bb46563 | ||
|
|
a7788f9847 | ||
|
|
b597364419 | ||
|
|
a9a951d970 | ||
|
|
6ac879ec6a | ||
|
|
2422ef50b6 | ||
|
|
06dbf96b65 | ||
|
|
172046e78f | ||
|
|
7e8c49f0a0 | ||
|
|
f2ad6292f5 | ||
|
|
337e13b72e | ||
|
|
2ab2fc62dc | ||
|
|
786575c3de | ||
|
|
4cca194000 | ||
|
|
cd3ead0028 | ||
|
|
a239b95ca1 | ||
|
|
09574c0e82 | ||
|
|
0b6b01ef83 | ||
|
|
34145e459b | ||
|
|
207efca15c | ||
|
|
3e25c2ea46 | ||
|
|
2046678caa | ||
|
|
cb7e4e858b | ||
|
|
43ee4b9cb6 | ||
|
|
207c24a4fd | ||
|
|
6465ab3b6d | ||
|
|
cf624bc679 | ||
|
|
df55a776c7 | ||
|
|
07afe3887b | ||
|
|
25434ba84f | ||
|
|
9787dbd14f | ||
|
|
fd9081c80e | ||
|
|
e79c49019d | ||
|
|
5bc081a3af | ||
|
|
5976eb5186 | ||
|
|
b194bc05b1 | ||
|
|
18207fd79e | ||
|
|
7c1e0a51eb | ||
|
|
7196658166 | ||
|
|
187fe67ffa | ||
|
|
7136098c3c | ||
|
|
7979238029 | ||
|
|
fc38dff3b0 | ||
|
|
c590204cf9 | ||
|
|
284e49c807 | ||
|
|
43fcd3d1e2 | ||
|
|
a9f2d7df40 | ||
|
|
21a03d2b85 | ||
|
|
f123b8654a | ||
|
|
51cbe538e8 | ||
|
|
e247a2c4eb | ||
|
|
490b6684ac | ||
|
|
6fdeadf171 | ||
|
|
a88d491012 | ||
|
|
fd34d68933 | ||
|
|
215e3aab7b | ||
|
|
cd4feb3bab | ||
|
|
6b0af421dd | ||
|
|
9aeb4f2a96 | ||
|
|
9b1e789e62 | ||
|
|
406b163bcc | ||
|
|
6f2cae95e1 | ||
|
|
594a29b2db | ||
|
|
0d12464e30 | ||
|
|
ccd9ab70ee | ||
|
|
27f2f87e29 | ||
|
|
635eb9d36d | ||
|
|
f3e7f9bb8f | ||
|
|
2f69665056 | ||
|
|
559f7bc1b7 | ||
|
|
693f00caf5 | ||
|
|
822173979c | ||
|
|
9bce66f307 | ||
|
|
7a71e758b1 | ||
|
|
72fe0ca3e7 | ||
|
|
fd0570f0c9 | ||
|
|
e0037a0c8b | ||
|
|
c7c83282ee | ||
|
|
8f98d9792b | ||
|
|
111f7bd15e | ||
|
|
787af8de18 | ||
|
|
db6ebfe71b | ||
|
|
1cb490039f | ||
|
|
a152a64f1c | ||
|
|
08f50e56ac | ||
|
|
9ae221ca0c | ||
|
|
aca8da5891 | ||
|
|
34896560ea | ||
|
|
3597fbe382 | ||
|
|
0b262baf97 | ||
|
|
78b51ebe59 | ||
|
|
08a92468fe | ||
|
|
b84ed964f9 | ||
|
|
8bfe7b6b9d | ||
|
|
dbae173399 | ||
|
|
4d4dbcda4d | ||
|
|
fd4584a49d | ||
|
|
ceb9f795cb | ||
|
|
443c254d46 | ||
|
|
87fa150ced | ||
|
|
4cfdb8233f | ||
|
|
5e42cf76eb | ||
|
|
dccf6193da | ||
|
|
ee4fdf3f39 | ||
|
|
918b7f96db | ||
|
|
ef55345665 | ||
|
|
0a41dbb443 | ||
|
|
934ad32e52 | ||
|
|
b582f0f880 | ||
|
|
face3de44a | ||
|
|
8a7b9d776f | ||
|
|
a8c5d1095d | ||
|
|
9fa5028f6c | ||
|
|
0de3c089d2 | ||
|
|
919bc0138a | ||
|
|
a0210af5c6 | ||
|
|
888291db9a | ||
|
|
4fce663795 | ||
|
|
fc3384fb95 | ||
|
|
f9a30ca08e | ||
|
|
cbbe691f70 | ||
|
|
afbf0809c3 | ||
|
|
db8d4b4347 | ||
|
|
904ee7dfec | ||
|
|
bef616632c | ||
|
|
1d2e5d182e | ||
|
|
568ee1fa85 | ||
|
|
66633a7728 | ||
|
|
18283b44b2 | ||
|
|
278696b28e | ||
|
|
26efd09d45 | ||
|
|
ec9aba79ae | ||
|
|
07e42d81f4 | ||
|
|
d272afc128 | ||
|
|
6cf9fa2208 | ||
|
|
a72451cdbe | ||
|
|
e82489b158 | ||
|
|
e4c7fa6a1c | ||
|
|
48ed24dabf | ||
|
|
9ef060a2f2 | ||
|
|
255c41607f | ||
|
|
22da026888 | ||
|
|
def0a63008 | ||
|
|
6e62e123e8 | ||
|
|
262df56024 | ||
|
|
81cdf071a8 | ||
|
|
c5ce75888e | ||
|
|
fb232896a8 | ||
|
|
5efa462f19 | ||
|
|
225f3ab125 | ||
|
|
664fbfeb6e | ||
|
|
66f8ca0501 | ||
|
|
e977d63f08 | ||
|
|
08fc3cab38 | ||
|
|
a01885536c | ||
|
|
f7343674ee | ||
|
|
fc2adf98ba | ||
|
|
a3c57a5077 | ||
|
|
28b5dd0163 | ||
|
|
c0b69e4e6f | ||
|
|
a9111d78d3 | ||
|
|
cc91e22038 | ||
|
|
4555f69733 | ||
|
|
da8ba56dd1 | ||
|
|
4d6d5620b0 | ||
|
|
f7cad98f3e | ||
|
|
d978c4c3bf | ||
|
|
1c4b7810b1 | ||
|
|
a6ec43f81c | ||
|
|
d258acfc49 | ||
|
|
d9072402db | ||
|
|
1a706e3842 | ||
|
|
a227897504 | ||
|
|
0833d68e91 | ||
|
|
99bab6796c | ||
|
|
0544187057 | ||
|
|
e12e7b4d76 | ||
|
|
7609ac6f1e | ||
|
|
3c946a91e8 | ||
|
|
2389ebd87e | ||
|
|
90ad497a6f | ||
|
|
1bb0b6fe03 | ||
|
|
c16c1df6fd | ||
|
|
e460641711 | ||
|
|
1e980651a9 | ||
|
|
028076e79c | ||
|
|
e5b6a88551 | ||
|
|
b18b4f236f | ||
|
|
605d4e99b9 | ||
|
|
ad00b6465a | ||
|
|
537ebd05f2 | ||
|
|
2ee8769752 | ||
|
|
8d7f534d54 | ||
|
|
47bb62b051 | ||
|
|
50b8213781 | ||
|
|
fd1fe53b49 | ||
|
|
378def0a58 | ||
|
|
ed5f48b353 | ||
|
|
fa6c2c7683 | ||
|
|
3fadc9b481 | ||
|
|
c3d7fa0d26 | ||
|
|
5c16357fe2 | ||
|
|
ef2e6079ba | ||
|
|
18633288fb | ||
|
|
67daef7bcc | ||
|
|
5eb29dcfc4 | ||
|
|
d2fc922ee7 | ||
|
|
d35010c1cb | ||
|
|
bd4b65225c | ||
|
|
be95a62965 | ||
|
|
4336d524af | ||
|
|
ae7976fc01 | ||
|
|
72f9dc4c7c | ||
|
|
84760648fe | ||
|
|
b0df40d9a6 | ||
|
|
139217914d | ||
|
|
efa5795193 | ||
|
|
4f499aed01 | ||
|
|
a8ba831f5e | ||
|
|
a90405c25a | ||
|
|
4546fda8e9 | ||
|
|
b02f771146 | ||
|
|
dc94b26e50 | ||
|
|
4c32f37ede | ||
|
|
336a8b3bc2 | ||
|
|
faecea39c8 | ||
|
|
d08d5362be | ||
|
|
d4292d81f2 | ||
|
|
62893e33e9 | ||
|
|
5b07ecbd01 | ||
|
|
b5c1b9178d | ||
|
|
65ff7ab1c3 | ||
|
|
35fd991fdc | ||
|
|
57e1acba79 | ||
|
|
620d351946 | ||
|
|
de3c2656ef | ||
|
|
3b2e9b2485 | ||
|
|
75a3005d74 | ||
|
|
448f606054 | ||
|
|
e35c6f29fb | ||
|
|
85a1a48b00 | ||
|
|
45427d3202 | ||
|
|
93c7a05dac | ||
|
|
a34c38c9b9 | ||
|
|
3100b77a1a | ||
|
|
c8429069a3 | ||
|
|
01172217dc | ||
|
|
14b0e409f2 | ||
|
|
2107bae8dd | ||
|
|
433676226c | ||
|
|
f0c88234a0 | ||
|
|
393d711e5f | ||
|
|
cb24bd9c2c | ||
|
|
abc5c5a374 | ||
|
|
54c94f181a | ||
|
|
6641e7f5d1 | ||
|
|
f4a00f2b0f | ||
|
|
05d41f81e4 | ||
|
|
fdc289d888 | ||
|
|
0a2243e033 | ||
|
|
9d877d764f | ||
|
|
f5df29cf34 | ||
|
|
8008823ea5 | ||
|
|
6515de4bc0 | ||
|
|
8c5f535b79 | ||
|
|
3714be4f16 | ||
|
|
f24f565e58 | ||
|
|
036186fc12 | ||
|
|
d3853bd4e9 | ||
|
|
7253bac48a | ||
|
|
973fbeeba5 | ||
|
|
f22cefba97 | ||
|
|
a5abc37b17 | ||
|
|
b95fa7be56 | ||
|
|
f6cf87a52d | ||
|
|
51f36b2281 | ||
|
|
ddebd494c6 | ||
|
|
d0a8d2b1cd | ||
|
|
1731a0daf6 | ||
|
|
3487b3ee9e | ||
|
|
5834efb709 | ||
|
|
52bc6d060d | ||
|
|
35ca5f3aed | ||
|
|
ac2b6ea8db | ||
|
|
9827caa3e3 | ||
|
|
ebe2d6196c | ||
|
|
e4689dd3f8 | ||
|
|
1dba611b8e | ||
|
|
97cbea6f4d | ||
|
|
d9963b0631 | ||
|
|
8418303ce2 | ||
|
|
40952df965 | ||
|
|
4f2c51c480 | ||
|
|
fd31a0d6b0 | ||
|
|
9ad725a272 | ||
|
|
2b6172ba63 | ||
|
|
c521f9299d | ||
|
|
1e646f8df1 | ||
|
|
b5a436c1b7 | ||
|
|
4f25c7a3ea | ||
|
|
eadb8ff65b | ||
|
|
6a80e941a0 | ||
|
|
7fc9b42b3a | ||
|
|
0d857999bf | ||
|
|
8ba71b048e | ||
|
|
e07f6c1703 | ||
|
|
e4f38121d2 | ||
|
|
255ee3f151 | ||
|
|
e72dbaabe1 | ||
|
|
b39662450f | ||
|
|
98da0c0bec | ||
|
|
45dde325fd | ||
|
|
2967a8f798 | ||
|
|
d4bdc73948 | ||
|
|
37c2f6bb17 | ||
|
|
a8e4d749e3 | ||
|
|
3df16ee449 | ||
|
|
332c2f959b | ||
|
|
a1b89c9a3b | ||
|
|
d6921fdac0 | ||
|
|
4cb3c22221 | ||
|
|
cc1536b6e1 | ||
|
|
92a178cbf9 | ||
|
|
fbebce0a49 | ||
|
|
b13bb9819a | ||
|
|
bb505b8ed9 | ||
|
|
cf030bc711 | ||
|
|
6cb95c5cfc | ||
|
|
a277a4fdd5 | ||
|
|
388799d39d | ||
|
|
4acf7edf95 | ||
|
|
e39346d51e | ||
|
|
5ae6de4f1d | ||
|
|
e0f1427af7 | ||
|
|
69297bdb58 | ||
|
|
0fa2f2c2ff | ||
|
|
9efce46fff | ||
|
|
c356ecb402 | ||
|
|
4c6887e7ec | ||
|
|
6d338cab15 | ||
|
|
354fdd412f | ||
|
|
f3f6141e6a | ||
|
|
f2b43b704c | ||
|
|
de1478d7ba | ||
|
|
b9592eeb8c | ||
|
|
6a62f9c082 | ||
|
|
2e4a8b2e23 | ||
|
|
c5112ffa11 | ||
|
|
7b9fda4e81 | ||
|
|
278e531806 | ||
|
|
047de40642 | ||
|
|
4e671a1c21 | ||
|
|
f36c8ce280 | ||
|
|
e77f2c91d7 | ||
|
|
82b0d5ce5f | ||
|
|
6117035863 | ||
|
|
c86e31ad99 | ||
|
|
f506fe1c0e | ||
|
|
554dc06eda | ||
|
|
80e1dfd142 | ||
|
|
6db5cf60dc | ||
|
|
63d181a0ac | ||
|
|
73c4896cce | ||
|
|
5b1b5ab904 | ||
|
|
80a537bc4c | ||
|
|
2a8a1d3736 | ||
|
|
61fbfa0684 | ||
|
|
f06a6bfe7b | ||
|
|
587f81f511 | ||
|
|
435ca63d1b | ||
|
|
64bb660f44 | ||
|
|
8bf24de0b3 | ||
|
|
943ea633a4 | ||
|
|
b1d5f7d7e5 | ||
|
|
188b94ce19 | ||
|
|
515282abfe | ||
|
|
efbdb722e7 | ||
|
|
e980823294 | ||
|
|
3692f4fb3c | ||
|
|
3e645f3c79 | ||
|
|
6127763302 | ||
|
|
19a181b38f | ||
|
|
2818b0384c | ||
|
|
36faf8c2ea | ||
|
|
a208171250 | ||
|
|
b8a2b7cff6 | ||
|
|
2a08cbc1a0 | ||
|
|
62bc6c1fb1 | ||
|
|
1098650421 | ||
|
|
15d85c2f87 | ||
|
|
16fb3f0339 | ||
|
|
37f6dff065 | ||
|
|
baf8832fc9 | ||
|
|
b558e11ede | ||
|
|
103cdabff1 | ||
|
|
57e33c8f7d | ||
|
|
da0f65c2d3 | ||
|
|
6535c075f3 | ||
|
|
f3c0b9544c | ||
|
|
3609fd4745 | ||
|
|
622e140622 | ||
|
|
a4954c3825 | ||
|
|
b6e1b9c203 | ||
|
|
34a35c2658 | ||
|
|
90b7c9a17c | ||
|
|
c72297020b | ||
|
|
f07b601dce | ||
|
|
63c62a2aae | ||
|
|
6888a9d340 | ||
|
|
72bf9f76a3 | ||
|
|
c0c6213c7c | ||
|
|
652ef4bc82 | ||
|
|
c6eed12139 | ||
|
|
1132e25072 | ||
|
|
879e3a2b67 | ||
|
|
6ec207141f | ||
|
|
45c657ce79 | ||
|
|
888dc11c03 | ||
|
|
5e3159f800 | ||
|
|
570ec97eda | ||
|
|
09c75823e6 | ||
|
|
50c8c3b0bd | ||
|
|
3fb44312c7 | ||
|
|
67bdf2ab8b | ||
|
|
a56ed44e74 | ||
|
|
3c912c3812 | ||
|
|
0ceb87eee1 | ||
|
|
6510c10884 | ||
|
|
89da38cfa4 | ||
|
|
82b5d0e50b | ||
|
|
bb8789a9ad | ||
|
|
20345ab0dd | ||
|
|
d5dfb3de0c | ||
|
|
88aabb41e7 | ||
|
|
897059303d | ||
|
|
0b7607cf04 | ||
|
|
4a512f47de | ||
|
|
76a54d38e4 | ||
|
|
b9b03940a2 | ||
|
|
8370a97866 | ||
|
|
b659c77dbb | ||
|
|
e45b842a6c | ||
|
|
c2f22a4ad8 | ||
|
|
cb15a8676b | ||
|
|
32ba6d444b | ||
|
|
95b7a04041 | ||
|
|
d81ef64799 | ||
|
|
19269735ae | ||
|
|
f7957c8ea5 | ||
|
|
1e40797bc4 | ||
|
|
ad66f8af73 | ||
|
|
d436e61bdb | ||
|
|
c71e62746d | ||
|
|
d5b0ad5d80 | ||
|
|
34f2d7bc9a | ||
|
|
fb7f1b622b | ||
|
|
4a992e6e1c | ||
|
|
9593de8c0f | ||
|
|
8205be5220 | ||
|
|
39c43c4c02 | ||
|
|
8a9fa956e0 | ||
|
|
06e9c533e3 | ||
|
|
5bdcaf43db | ||
|
|
df1d13a155 | ||
|
|
6e7b19b090 | ||
|
|
279b73a477 | ||
|
|
74239303b3 | ||
|
|
134f390a5f | ||
|
|
8aa26b78bb | ||
|
|
301038664e | ||
|
|
ccad38f2db | ||
|
|
29dee42d34 | ||
|
|
f9135c81de | ||
|
|
9400635fd9 | ||
|
|
4102deceb3 | ||
|
|
86306740be | ||
|
|
8e63fc8b25 | ||
|
|
3219bd0307 | ||
|
|
bdb4430bb6 | ||
|
|
a574dbf89b | ||
|
|
47178370d5 | ||
|
|
ac67fddbcb | ||
|
|
e97fab3107 | ||
|
|
fee6f03ec2 | ||
|
|
1aff2ec112 | ||
|
|
57b3e9a8b2 | ||
|
|
35dad272eb | ||
|
|
d40c41048d | ||
|
|
03f59c94b4 | ||
|
|
87718f1c82 | ||
|
|
cbf7b69ef0 | ||
|
|
c56c976a22 | ||
|
|
3579d17a05 | ||
|
|
0f17bd23c7 | ||
|
|
db10bed951 | ||
|
|
071806f12b | ||
|
|
9cd7008efe | ||
|
|
14dc098761 | ||
|
|
8c6a895b19 | ||
|
|
01b8e69e4b | ||
|
|
11e91ac3fa | ||
|
|
70380b9a43 | ||
|
|
fa7a44f5b3 | ||
|
|
fb0329c0b5 | ||
|
|
c3d04fdd08 | ||
|
|
ebb0c97c51 | ||
|
|
aabe0f3594 | ||
|
|
7c21bf7aa1 | ||
|
|
de70d90603 | ||
|
|
31be738c10 | ||
|
|
759d268af0 | ||
|
|
f21811eb6a | ||
|
|
c643509c7e | ||
|
|
0860f8e6f9 | ||
|
|
e96b447e37 | ||
|
|
0eecd3b1fe | ||
|
|
b5b6ae100d | ||
|
|
8fd9bf10e5 | ||
|
|
9ac030169a | ||
|
|
569bd3b681 | ||
|
|
45bb461c32 | ||
|
|
105c3185f7 | ||
|
|
5565e4e30c | ||
|
|
70ae281f45 | ||
|
|
b518efd196 | ||
|
|
6e3a344caa | ||
|
|
2e3cbed520 | ||
|
|
5e2e7c81a6 | ||
|
|
cff59487ae | ||
|
|
cdcbfe7378 | ||
|
|
0c4ef8f079 | ||
|
|
c0e9dcff21 | ||
|
|
79eeb0fa2a | ||
|
|
46feb86a99 | ||
|
|
74f68c47d3 | ||
|
|
3c7a738ffc | ||
|
|
22d4a53d65 | ||
|
|
d319e2ed7b | ||
|
|
2cb07a8490 | ||
|
|
6900d4bbec | ||
|
|
73450bdbc7 | ||
|
|
776ff49ed2 | ||
|
|
00da6c88ae | ||
|
|
986f036d20 | ||
|
|
5699c43b74 | ||
|
|
b58b97a916 | ||
|
|
5f52f14094 | ||
|
|
5f8fa26bf3 | ||
|
|
a5c835cfeb | ||
|
|
ec6b67ffad | ||
|
|
3de28e3cef | ||
|
|
d2a649f5fa | ||
|
|
23d5aab1e8 | ||
|
|
cf8c6718dd | ||
|
|
b0c8249562 | ||
|
|
8cb0b1a7d6 | ||
|
|
7f9745c8d1 | ||
|
|
4e749cc8be | ||
|
|
70c9a7c18f | ||
|
|
11e2ee19ea | ||
|
|
a4cfab1242 | ||
|
|
be4738f59c | ||
|
|
b63c3da565 | ||
|
|
0b89f08d09 | ||
|
|
ac53153bea | ||
|
|
bc3187a3f6 | ||
|
|
4294710d9e | ||
|
|
476f18332a | ||
|
|
82a33460cf | ||
|
|
3b6268a4fc | ||
|
|
41425b3fa1 | ||
|
|
a964e3668d | ||
|
|
57804494ef | ||
|
|
9039a10c9a | ||
|
|
9e865bc37d | ||
|
|
54ee8bf7a0 | ||
|
|
629c8346d2 | ||
|
|
1bf2ff430a | ||
|
|
69be072a07 | ||
|
|
a2ca21a1a6 | ||
|
|
572c02bf6e | ||
|
|
80777b293f | ||
|
|
3c08834377 | ||
|
|
eeae12e3d4 | ||
|
|
992ac73068 | ||
|
|
e843779555 | ||
|
|
5f4ca240b4 | ||
|
|
79cd374f16 | ||
|
|
b137b32fc6 | ||
|
|
3cd2bfdef0 | ||
|
|
461dbdf0f8 | ||
|
|
9e8a6b6304 | ||
|
|
fd5ea89340 | ||
|
|
1d1d2b31cd | ||
|
|
d75656dad7 | ||
|
|
f0aa2fe0e0 | ||
|
|
ae847aea2b | ||
|
|
00ac5bf64f | ||
|
|
61e8024c65 | ||
|
|
ee5a370c01 | ||
|
|
659ce13e98 | ||
|
|
a7fde21300 | ||
|
|
a6bfab2d74 | ||
|
|
e948af1851 | ||
|
|
2062cc5d10 | ||
|
|
e85d10c6d9 | ||
|
|
0e0ab66d45 | ||
|
|
f2635c7fdc | ||
|
|
4d92bbe541 | ||
|
|
e6e1434fc1 | ||
|
|
5e689f94f4 | ||
|
|
c1b6d26b8e | ||
|
|
f72c5dba84 | ||
|
|
704007092c | ||
|
|
2f8c434429 | ||
|
|
b0c57e7ae3 | ||
|
|
0e57391b4d | ||
|
|
7ff1a93e72 | ||
|
|
d7eada7216 | ||
|
|
c435f71592 | ||
|
|
0dd6f01ef6 | ||
|
|
cd95b75563 | ||
|
|
4122e772c1 | ||
|
|
2fbe99909c | ||
|
|
d4f3d6209c | ||
|
|
641a51aa4f | ||
|
|
67afe84593 | ||
|
|
66f7c90c51 | ||
|
|
959117c391 | ||
| 5e810c704f | |||
|
|
675243061d | ||
|
|
246825d672 | ||
|
|
aa1a67d6c1 | ||
|
|
97b1848ba3 | ||
|
|
c4f6132aca | ||
|
|
a0de4f126f | ||
|
|
a8a96def97 | ||
|
|
eaddc30def | ||
|
|
aa17639e20 | ||
|
|
58d7ad494b | ||
|
|
2895f48bd6 | ||
|
|
8f6ea47501 | ||
|
|
3eb6237343 | ||
|
|
cb19940fa7 | ||
|
|
4bc7e9c8fe | ||
|
|
18ba24156c |
113
.appveyor.yml
Normal file
113
.appveyor.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
# .appveyor.yml for use with EPICS Base ci-scripts
|
||||
# (see: https://github.com/epics-base/ci-scripts)
|
||||
|
||||
# This is YAML - indentation levels are crucial
|
||||
|
||||
#---------------------------------#
|
||||
# build cache #
|
||||
#---------------------------------#
|
||||
# The AppVeyor cache allowance is way too small (1GB per account across all
|
||||
# projects, branches and jobs) to be used for the dependency builds.
|
||||
|
||||
cache:
|
||||
- C:\Users\appveyor\.tools
|
||||
|
||||
#---------------------------------#
|
||||
# repository cloning #
|
||||
#---------------------------------#
|
||||
|
||||
init:
|
||||
# Set autocrlf to make batch files work
|
||||
- cmd: git config --global core.autocrlf true
|
||||
|
||||
clone_depth: 5
|
||||
|
||||
#---------------------------------#
|
||||
# build matrix configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# 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
|
||||
EPICS_TEST_IMPRECISE_TIMING: YES
|
||||
BASE: 7.0
|
||||
|
||||
matrix:
|
||||
- CMP: vs2019
|
||||
BASE: 3.15
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
- CMP: vs2019
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
- CMP: vs2017
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
- CMP: vs2015
|
||||
- CMP: gcc
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
# TODO: static linking w/ readline isn't working. Bypass auto-detect
|
||||
COMMANDLINE_LIBRARY: EPICS
|
||||
|
||||
# Platform: processor architecture
|
||||
platform: x64
|
||||
|
||||
# Matrix configuration: exclude sets of jobs
|
||||
matrix:
|
||||
exclude:
|
||||
# MinGW debug builds use the same libraries, unlike VS
|
||||
- configuration: dynamic-debug
|
||||
CMP: gcc
|
||||
- configuration: static-debug
|
||||
CMP: gcc
|
||||
|
||||
#---------------------------------#
|
||||
# building & testing #
|
||||
#---------------------------------#
|
||||
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive
|
||||
- cmd: pip install git+https://github.com/mdavidsaver/ci-core-dumper#egg=ci-core-dumper
|
||||
- cmd: python .ci/cue.py prepare
|
||||
|
||||
build_script:
|
||||
- cmd: python .ci/cue.py build
|
||||
|
||||
test_script:
|
||||
- cmd: python -m ci_core_dumper install
|
||||
- cmd: python .ci/cue.py -T 20M test
|
||||
|
||||
on_finish:
|
||||
- ps: Get-ChildItem *.tap -Recurse -Force | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||
- cmd: python .ci/cue.py -T 5M test-results
|
||||
|
||||
on_failure:
|
||||
- cmd: python -m ci_core_dumper report
|
||||
|
||||
#---------------------------------#
|
||||
# debugging #
|
||||
#---------------------------------#
|
||||
|
||||
## To connect by remote desktop to a failed build, uncomment the lines below.
|
||||
## You must connect within the usual build timeout limit (60 minutes),
|
||||
## so adjust the build matrix above to just build the config 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: Email
|
||||
to:
|
||||
- core-talk@aps.anl.gov
|
||||
on_build_success: false
|
||||
- provider: GitHubPullRequest
|
||||
1
.ci
Submodule
1
.ci
Submodule
Submodule .ci added at 20f8e05393
6
.ci-local/defaults.set
Normal file
6
.ci-local/defaults.set
Normal 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
|
||||
301
.github/workflows/ci-scripts-build.yml
vendored
Normal file
301
.github/workflows/ci-scripts-build.yml
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
# .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
|
||||
|
||||
# Workflow name, shared by all branches
|
||||
|
||||
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
|
||||
EPICS_TEST_TIMEOUT: 300 # 5 min
|
||||
|
||||
jobs:
|
||||
native:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
# Set environment variables from matrix parameters
|
||||
env:
|
||||
# NB: PVA modules build against both BASE 7.0 and 3.15
|
||||
BASE: ${{ matrix.base }}
|
||||
CMP: ${{ matrix.cmp }}
|
||||
BCFG: ${{ matrix.configuration }}
|
||||
CI_CROSS_TARGETS: ${{ matrix.cross }}
|
||||
EXTRA: ${{ matrix.extra }}
|
||||
TEST: ${{ matrix.test }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Job names also name artifacts, character limitations apply
|
||||
include:
|
||||
- name: "7.0 Ub gcc c++20 Werror"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
# Turn all warnings into errors,
|
||||
# except for those we could not fix (yet).
|
||||
# Remove respective -Wno-error=... flag once it is fixed.
|
||||
extra: "CMD_CXXFLAGS=-std=c++20
|
||||
CMD_CPPFLAGS='-fdiagnostics-color
|
||||
-fstack-protector-strong
|
||||
-Wformat
|
||||
-Werror
|
||||
-Werror=format-security
|
||||
-Wno-error=deprecated-declarations
|
||||
-Wno-error=stringop-truncation
|
||||
-Wno-error=restrict
|
||||
-Wno-error=sizeof-pointer-memaccess
|
||||
-Wno-error=nonnull
|
||||
-Wno-error=dangling-pointer
|
||||
-Wno-error=format-overflow
|
||||
-Wno-error=stringop-overread
|
||||
-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3'
|
||||
CMD_LDFLAGS=-Wl,-z,relro"
|
||||
|
||||
- name: "7.0 Ub gcc C++11, static"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
|
||||
- name: "7.0 Ub gcc u-char"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
extra: "CMD_CFLAGS=-funsigned-char CMD_CXXFLAGS=-funsigned-char"
|
||||
|
||||
- name: "7.0 Ub clang"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: clang
|
||||
configuration: default
|
||||
|
||||
- name: "7.0 Ub clang C++11"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: clang
|
||||
configuration: default
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
|
||||
- name: "7.0 MacOS clang"
|
||||
base: "7.0"
|
||||
os: macos-latest
|
||||
cmp: clang
|
||||
configuration: default
|
||||
|
||||
# Cross builds
|
||||
|
||||
- name: "3.15 Ub-22 gcc + MinGW"
|
||||
base: "3.15"
|
||||
os: ubuntu-22.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "windows-x64-mingw"
|
||||
|
||||
- name: "7.0 Ub gcc + linux-aarch64"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "linux-aarch64"
|
||||
|
||||
- name: "7.0 Ub gcc + linux-arm gnueabi"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "linux-arm@arm-linux-gnueabi"
|
||||
|
||||
- name: "7.0 Ub gcc + linux-arm gnueabihf"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "linux-arm@arm-linux-gnueabihf"
|
||||
|
||||
- name: "7.0 Ub gcc + MinGW"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "windows-x64-mingw"
|
||||
|
||||
- name: "7.0 Ub gcc + MinGW, static"
|
||||
base: "7.0"
|
||||
os: ubuntu-latest
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
cross: "windows-x64-mingw"
|
||||
|
||||
- name: "7.0 Ub-22 gcc + RT-4.9 pc386"
|
||||
base: "7.0"
|
||||
os: ubuntu-22.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-pc386-qemu@4.9"
|
||||
|
||||
- name: "7.0 Ub-22 gcc + RT-4.10 pc386"
|
||||
base: "7.0"
|
||||
os: ubuntu-22.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-pc386-qemu@4.10"
|
||||
test: NO
|
||||
|
||||
- name: "7.0 Ub-22 gcc + RT-5.1 pc686"
|
||||
base: "7.0"
|
||||
os: ubuntu-22.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-pc686-qemu@5"
|
||||
|
||||
- name: "7.0 Ub-22 gcc + RT-5.1 beatnik,zynq_a9,uC5282"
|
||||
base: "7.0"
|
||||
os: ubuntu-22.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-beatnik@5:RTEMS-xilinx_zynq_a9_qemu@5:RTEMS-uC5282@5"
|
||||
test: NO
|
||||
|
||||
# Windows builds
|
||||
|
||||
- name: "7.0 Win-22 MSC-22"
|
||||
base: "7.0"
|
||||
os: windows-2022
|
||||
cmp: vs2022
|
||||
configuration: default
|
||||
|
||||
- name: "7.0 Win-22 MSC-22 static"
|
||||
base: "7.0"
|
||||
os: windows-2022
|
||||
cmp: vs2022
|
||||
configuration: static
|
||||
|
||||
- name: "7.0 Win-22 MSC-22 debug"
|
||||
base: "7.0"
|
||||
os: windows-2022
|
||||
cmp: vs2022
|
||||
configuration: debug
|
||||
extra: "CMD_CXXFLAGS=-analyze"
|
||||
|
||||
- name: "7.0 Win-22 MinGW"
|
||||
base: "7.0"
|
||||
os: windows-2022
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Automatic core dumper 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: 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 -T 60M test
|
||||
- name: Upload tapfiles Artifact
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tapfiles ${{ matrix.name }}
|
||||
path: '**/O.*/*.tap'
|
||||
if-no-files-found: ignore
|
||||
- name: Collect and show test results
|
||||
if: ${{ always() }}
|
||||
run: python .ci/cue.py -T 5M test-results
|
||||
|
||||
docker:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
# Set environment variables from matrix parameters
|
||||
env:
|
||||
BASE: ${{ matrix.base }}
|
||||
CMP: ${{ matrix.cmp }}
|
||||
BCFG: ${{ matrix.configuration }}
|
||||
EXTRA: ${{ matrix.extra }}
|
||||
TEST: ${{ matrix.test }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Job names also name artifacts, character limitations apply
|
||||
include:
|
||||
- name: "7.0 CentOS-8 gcc"
|
||||
base: "7.0"
|
||||
image: centos:8
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
|
||||
- name: "7.0 Rocky-9 gcc"
|
||||
base: "7.0"
|
||||
image: rockylinux:9
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
|
||||
- name: "7.0 Fedora-33 gcc"
|
||||
base: "7.0"
|
||||
image: fedora:33
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
|
||||
- name: "7.0 Fedora gcc"
|
||||
base: "7.0"
|
||||
image: fedora:latest
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
|
||||
steps:
|
||||
- name: "Fix repo URLs on CentOS-8"
|
||||
# centos:8 is frozen, repos are in the vault
|
||||
if: matrix.image=='centos:8'
|
||||
run: |
|
||||
sed -i -e "s|mirrorlist=|#mirrorlist=|" \
|
||||
-e "s|#baseurl=http://mirror|baseurl=http://vault|" \
|
||||
/etc/yum.repos.d/CentOS-Linux-{BaseOS,AppStream,Extras,Plus}.repo
|
||||
- name: "Redhat setup"
|
||||
run: |
|
||||
dnf -y install python3 gdb make perl gcc-c++ glibc-devel readline-devel ncurses-devel perl-devel perl-Test-Simple
|
||||
git --version || dnf -y install git
|
||||
python3 --version
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Automatic core dumper analysis
|
||||
uses: mdavidsaver/ci-core-dumper@master
|
||||
- name: Prepare and compile dependencies
|
||||
run: python3 .ci/cue.py prepare
|
||||
- name: Build main module
|
||||
run: python3 .ci/cue.py build
|
||||
- name: Run main module tests
|
||||
run: python3 .ci/cue.py -T 20M test
|
||||
- name: Upload tapfiles Artifact
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tapfiles ${{ matrix.name }}
|
||||
path: '**/O.*/*.tap'
|
||||
if-no-files-found: ignore
|
||||
- name: Collect and show test results
|
||||
if: ${{ always() }}
|
||||
run: python3 .ci/cue.py -T 5M test-results
|
||||
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal 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
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule ".ci"]
|
||||
path = .ci
|
||||
url = https://github.com/epics-base/ci-scripts
|
||||
@@ -1,9 +0,0 @@
|
||||
QtC-pvData.creator.user
|
||||
bin
|
||||
lib
|
||||
doc
|
||||
include
|
||||
documentation/html
|
||||
./O.*
|
||||
configure/RELEASE.local
|
||||
configure/CONFIG_SITE.local
|
||||
6
.hgtags
6
.hgtags
@@ -1,6 +0,0 @@
|
||||
459f10877e5628241704f31437b4cbd342df0798 test1
|
||||
6e8a22d01e824702088195c08bf50bfb6f293de5 1.0-BETA
|
||||
d29d84f4c3f389f2accd497185b106c8541f95c9 1.1-SNAPSHOT
|
||||
a29729ca0ecd60b66f2d997031d97911377e44a7 marchtest
|
||||
9c59737f56e71aef641b70d0f72aa768fd7f8414 1.0.1-BETA
|
||||
4559c3de0cb4e3420e26272817f58bab005063ec 1.1-BETA
|
||||
17
.readthedocs.yml
Normal file
17
.readthedocs.yml
Normal 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
|
||||
12
COPYRIGHT
12
COPYRIGHT
@@ -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
|
||||
*************************************************** */
|
||||
77
LICENSE
77
LICENSE
@@ -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.
|
||||
________________________________________________________________________
|
||||
|
||||
17
Makefile
17
Makefile
@@ -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
|
||||
|
||||
|
||||
|
||||
82
README.html
82
README.html
@@ -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 &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
16
README.md
Normal 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.
|
||||
@@ -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
|
||||
|
||||
|
||||
12
configure/CONFIG_PVDATA_VERSION
Normal file
12
configure/CONFIG_PVDATA_VERSION
Normal 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 = 8
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
EPICS_PVD_DEVELOPMENT_FLAG = 1
|
||||
|
||||
# Immediately after a release the MAINTENANCE_VERSION
|
||||
# will be incremented and the DEVELOPMENT_FLAG set to 1
|
||||
@@ -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
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -1,27 +1,38 @@
|
||||
#RELEASE Location of external products
|
||||
# RELEASE - Location of external support modules
|
||||
#
|
||||
# IF YOU MAKE ANY CHANGES to this file you MUST at least run
|
||||
# "gnumake" in this directory afterwards; you usually need
|
||||
# to run "gnumake rebuild" in the application's top level
|
||||
# directory each time this file is changed.
|
||||
# IF YOU CHANGE 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.
|
||||
#
|
||||
# NOTE: The build does not check dependencies against files
|
||||
# that are outside this application, thus you should run
|
||||
# "gnumake distclean install" in the top directory each time
|
||||
# EPICS_BASE, SNCSEQ, or any other external module defined
|
||||
# in the RELEASE file is rebuilt.
|
||||
# The 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/target specific settings can be specified in files named
|
||||
# Host- or target-specific settings can be given in files named
|
||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
# RELEASE.Common.$(T_A)
|
||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
#
|
||||
# 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.
|
||||
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
# Variables and paths to dependent modules:
|
||||
#MODULES = /path/to/modules
|
||||
#MYMODULE = $(MODULES)/my-module
|
||||
|
||||
# Create a file RELEASE.local containing the
|
||||
# location of your EPICS_BASE, e.g.
|
||||
# EPICS_BASE=/home/install/epics/base
|
||||
# If building the EPICS modules individually, set these:
|
||||
#EPICS_BASE = /path/to/base
|
||||
|
||||
-include $(TOP)/configure/RELEASE.local
|
||||
# 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
3
documentation/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.tag
|
||||
*.db
|
||||
html/
|
||||
2367
documentation/Doxyfile
Normal file
2367
documentation/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
16
documentation/Makefile
Normal file
16
documentation/Makefile
Normal 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
14
documentation/TODO.md
Normal 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.
|
||||
7
documentation/_static/css/custom.css
Normal file
7
documentation/_static/css/custom.css
Normal 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
45
documentation/commit-gh.sh
Executable 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
78
documentation/conf.py
Normal 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)
|
||||
BIN
documentation/images/EPICS_white_logo_v02.png
Normal file
BIN
documentation/images/EPICS_white_logo_v02.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
16
documentation/index.rst
Normal file
16
documentation/index.rst
Normal 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>
|
||||
58
documentation/mainpage.dox
Normal file
58
documentation/mainpage.dox
Normal 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
491
documentation/release_notes.dox
Normal file
491
documentation/release_notes.dox
Normal file
@@ -0,0 +1,491 @@
|
||||
/**
|
||||
|
||||
@page release_notes Release Notes
|
||||
|
||||
Release 8.0.7 (Dec 2025)
|
||||
========================
|
||||
|
||||
- Compatible changes
|
||||
- Allow epics::pvData::Timer to be cancelled during callback execution.
|
||||
- Clang compiler warnings cleaned up.
|
||||
- Limit periodic timers to one catch-up after missing many events.
|
||||
|
||||
Release 8.0.6 (Dec 2023)
|
||||
========================
|
||||
|
||||
- Compatible changes
|
||||
- Actually enable JSON-5 output in PVStructure::Formatter::JSON when available.
|
||||
- Fix unaligned access issues for some ARM/Linux targets.
|
||||
|
||||
Release 8.0.5 (Sep 2022)
|
||||
========================
|
||||
|
||||
- Compatible changes
|
||||
- Internal changes to use the YAJL API for generating JSON and JSON-5 output.
|
||||
|
||||
Release 8.0.4 (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
14
examples/Makefile
Normal 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
30
examples/unittest.cpp
Normal 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();
|
||||
}
|
||||
70
jenkins/cloudbees_build
Normal file
70
jenkins/cloudbees_build
Normal file
@@ -0,0 +1,70 @@
|
||||
# pvData C++ implementation
|
||||
# Jenkins @ Cloudbees build script
|
||||
#
|
||||
# Jenkins invokes scripts with the "-ex" option. So the build is considered a failure
|
||||
# if any of the commands exits with a non-zero exit code.
|
||||
#
|
||||
# Author: Ralph Lange <ralph.lange@gmx.de>
|
||||
# Copyright (C) 2013 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH
|
||||
# Copyright (C) 2014-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
|
||||
|
||||
export STUFF=/tmp/stuff
|
||||
|
||||
rm -fr ${STUFF}
|
||||
mkdir -p ${STUFF}
|
||||
cd ${STUFF}
|
||||
|
||||
installTool Boost 1.61.0
|
||||
installTool Base ${BASE}
|
||||
|
||||
###########################################
|
||||
# Build
|
||||
|
||||
cd ${WORKSPACE}
|
||||
|
||||
export EPICS_BASE=${STUFF}
|
||||
export EPICS_HOST_ARCH=$(${EPICS_BASE}/startup/EpicsHostArch)
|
||||
export LD_LIBRARY_PATH=${EPICS_BASE}/lib/${EPICS_HOST_ARCH}
|
||||
export PATH=${STUFF}/bin:${PATH}
|
||||
|
||||
cat > configure/RELEASE.local << EOF
|
||||
EPICS_BASE=${EPICS_BASE}
|
||||
EOF
|
||||
|
||||
make distclean all
|
||||
|
||||
###########################################
|
||||
# Test
|
||||
|
||||
make runtests
|
||||
|
||||
###########################################
|
||||
# Create cache
|
||||
|
||||
tar czf pvData.CB-dist.tar.gz lib include cfg LICENSE
|
||||
66
jenkins/cloudbees_doc
Normal file
66
jenkins/cloudbees_doc
Normal 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
|
||||
@@ -1,101 +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
|
||||
|
||||
@@ -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
@@ -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];
|
||||
}
|
||||
|
||||
const int8 Scalar::getTypeCodeLUT() const
|
||||
{
|
||||
static const int8 typeCodeLUT[] = {
|
||||
0x00, // pvBoolean
|
||||
0x20, // pvByte
|
||||
0x21, // pvShort
|
||||
0x22, // pvInt
|
||||
0x23, // pvLong
|
||||
0x28, // pvUByte
|
||||
0x29, // pvUShort
|
||||
0x2A, // pvUInt
|
||||
0x2B, // pvULong
|
||||
0x42, // pvFloat
|
||||
0x43, // pvDouble
|
||||
0x60 // pvString
|
||||
};
|
||||
return typeCodeLUT[scalarType];
|
||||
}
|
||||
|
||||
|
||||
void Scalar::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte(getTypeCodeLUT());
|
||||
}
|
||||
|
||||
void Scalar::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
// must be done via FieldCreate
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
static String emptyString;
|
||||
|
||||
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
|
||||
{
|
||||
// to optimize default (non-empty) IDs optimization
|
||||
// empty IDs are not allowed
|
||||
String id = structure->getID();
|
||||
if (id == Structure::DEFAULT_ID) // TODO slow comparison
|
||||
SerializeHelper::serializeString(emptyString, buffer, control);
|
||||
else
|
||||
SerializeHelper::serializeString(id, buffer, control);
|
||||
|
||||
FieldConstPtrArray const & fields = structure->getFields();
|
||||
StringArray const & fieldNames = structure->getFieldNames();
|
||||
std::size_t len = fields.size();
|
||||
SerializeHelper::writeSize(len, buffer, control);
|
||||
for (std::size_t i = 0; i < len; i++)
|
||||
{
|
||||
SerializeHelper::serializeString(fieldNames[i], buffer, control);
|
||||
control->cachedSerialize(fields[i], buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static StructureConstPtr deserializeStructureField(const FieldCreate* fieldCreate, ByteBuffer* buffer, DeserializableControl* control)
|
||||
{
|
||||
String id = SerializeHelper::deserializeString(buffer, control);
|
||||
const std::size_t size = SerializeHelper::readSize(buffer, control);
|
||||
FieldConstPtrArray fields; fields.reserve(size);
|
||||
StringArray fieldNames; fieldNames.reserve(size);
|
||||
for (std::size_t i = 0; i < size; i++)
|
||||
{
|
||||
fieldNames.push_back(SerializeHelper::deserializeString(buffer, control));
|
||||
fields.push_back(control->cachedDeserialize(buffer));
|
||||
}
|
||||
|
||||
if (id.empty())
|
||||
return fieldCreate->createStructure(fieldNames, fields);
|
||||
else
|
||||
return fieldCreate->createStructure(id, fieldNames, fields);
|
||||
}
|
||||
|
||||
ScalarArray::ScalarArray(ScalarType elementType)
|
||||
: Field(scalarArray),elementType(elementType){}
|
||||
|
||||
ScalarArray::~ScalarArray() {}
|
||||
|
||||
const int8 ScalarArray::getTypeCodeLUT() const
|
||||
{
|
||||
static const int8 typeCodeLUT[] = {
|
||||
0x00, // pvBoolean
|
||||
0x20, // pvByte
|
||||
0x21, // pvShort
|
||||
0x22, // pvInt
|
||||
0x23, // pvLong
|
||||
0x28, // pvUByte
|
||||
0x29, // pvUShort
|
||||
0x2A, // pvUInt
|
||||
0x2B, // pvULong
|
||||
0x42, // pvFloat
|
||||
0x43, // pvDouble
|
||||
0x60 // pvString
|
||||
};
|
||||
return typeCodeLUT[elementType];
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,100 +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;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}}
|
||||
@@ -1,687 +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;}
|
||||
|
||||
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;}
|
||||
|
||||
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);
|
||||
// if (size>0) { pcontrol->ensureData(sizeof(T)-1); pbuffer->align(sizeof(T)); }
|
||||
if(size>=0) {
|
||||
// prepare array, if necessary
|
||||
if(size>this->getCapacity()) this->setCapacity(size);
|
||||
// set new length
|
||||
this->setLength(size);
|
||||
// retrieve value from the buffer
|
||||
size_t i = 0;
|
||||
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(get()+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));
|
||||
size_t end = offset+count;
|
||||
size_t i = offset;
|
||||
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)));
|
||||
T * pvalue = const_cast<T *>(get());
|
||||
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();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,279 +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!=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& PVField::dumpValue(std::ostream& o) const
|
||||
{
|
||||
// default implementation
|
||||
// each PVField class should implement it to avoid switch statement
|
||||
// and string reallocation
|
||||
String tmp;
|
||||
convert->getString(&tmp,this,0);
|
||||
return o << tmp;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const PVField& f) { return f.dumpValue(o); };
|
||||
|
||||
void PVField::computeOffset(const PVField * pvField) {
|
||||
const PVStructure * pvTop = pvField->getParent();
|
||||
if(pvTop==NULL) {
|
||||
if(pvField->getField()->getType()!=structure) {
|
||||
PVField *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;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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());
|
||||
}
|
||||
}}
|
||||
@@ -1,705 +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();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,253 +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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -1,642 +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) {
|
||||
ScalarConstPtr scalar = static_pointer_cast<const Scalar>(field);
|
||||
ScalarType scalarType = scalar->getScalarType();
|
||||
switch(scalarType) {
|
||||
case pvBoolean: valueAlarm = booleanAlarmField; break;
|
||||
case pvByte: valueAlarm = byteAlarmField; break;
|
||||
case pvShort: valueAlarm = shortAlarmField; break;
|
||||
case pvInt: valueAlarm = intAlarmField; break;
|
||||
case pvLong: valueAlarm = longAlarmField; break;
|
||||
case 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();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}};
|
||||
@@ -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
|
||||
*/
|
||||
@@ -1,884 +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<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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -1,55 +0,0 @@
|
||||
/* lock.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 LOCK_H
|
||||
#define LOCK_H
|
||||
#include <stdexcept>
|
||||
#include <epicsMutex.h>
|
||||
#include <pv/noDefaultMethods.h>
|
||||
/* This is based on item 14 of
|
||||
* Effective C++, Third Edition, Scott Meyers
|
||||
*/
|
||||
|
||||
// TODO reference counting lock to allow recursions
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
typedef epicsMutex Mutex;
|
||||
|
||||
class Lock : private NoDefaultMethods {
|
||||
public:
|
||||
explicit Lock(Mutex &m)
|
||||
: mutexPtr(m), locked(true)
|
||||
{ mutexPtr.lock();}
|
||||
~Lock(){unlock();}
|
||||
void lock()
|
||||
{
|
||||
if(!locked)
|
||||
{
|
||||
mutexPtr.lock();
|
||||
locked = true;
|
||||
}
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
if(locked)
|
||||
{
|
||||
mutexPtr.unlock();
|
||||
locked=false;
|
||||
}
|
||||
}
|
||||
bool ownsLock() const{return locked;}
|
||||
private:
|
||||
Mutex &mutexPtr;
|
||||
bool locked;
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
#endif /* LOCK_H */
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 &element);
|
||||
queueElementPtr & getUsed();
|
||||
void releaseUsed(queueElementPtr &element);
|
||||
private:
|
||||
queueElementPtr nullElement;
|
||||
queueElementPtrArray elements;
|
||||
int size;
|
||||
int numberFree;
|
||||
int numberUsed;
|
||||
int nextGetFree;
|
||||
int nextSetUsed;
|
||||
int nextGetUsed;
|
||||
int nextReleaseUsed;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Queue<T>::Queue(std::vector<queueElementPtr> &xxx)
|
||||
: size(xxx.size()),
|
||||
numberFree(size),
|
||||
numberUsed(0),
|
||||
nextGetFree(0),
|
||||
nextSetUsed(0),
|
||||
nextGetUsed(0),
|
||||
nextReleaseUsed(0)
|
||||
{
|
||||
elements.swap(xxx);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Queue<T>::~Queue(){}
|
||||
|
||||
template <typename T>
|
||||
int Queue<T>::capacity(){return size;}
|
||||
|
||||
template <typename T>
|
||||
int Queue<T>::getNumberFree(){return numberFree;}
|
||||
|
||||
template <typename T>
|
||||
int Queue<T>::getNumberUsed(){return numberUsed;}
|
||||
|
||||
template <typename T>
|
||||
void Queue<T>::clear()
|
||||
{
|
||||
numberFree = size;
|
||||
numberUsed = 0;
|
||||
nextGetFree = 0;
|
||||
nextSetUsed = 0;
|
||||
nextGetUsed = 0;
|
||||
nextReleaseUsed = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::tr1::shared_ptr<T> & Queue<T>::getFree()
|
||||
{
|
||||
if(numberFree==0) return nullElement;
|
||||
numberFree--;
|
||||
int ind = nextGetFree;
|
||||
std::tr1::shared_ptr<T> queueElement = elements[nextGetFree++];
|
||||
if(nextGetFree>=size) nextGetFree = 0;
|
||||
return elements[ind];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Queue<T>::setUsed(std::tr1::shared_ptr<T> &element)
|
||||
{
|
||||
if(element!=elements[nextSetUsed++]) {
|
||||
throw std::logic_error("not correct queueElement");
|
||||
}
|
||||
numberUsed++;
|
||||
if(nextSetUsed>=size) nextSetUsed = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::tr1::shared_ptr<T> & Queue<T>::getUsed()
|
||||
{
|
||||
if(numberUsed==0) return nullElement;
|
||||
int ind = nextGetUsed;
|
||||
std::tr1::shared_ptr<T> queueElement = elements[nextGetUsed++];
|
||||
if(nextGetUsed>=size) nextGetUsed = 0;
|
||||
return elements[ind];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Queue<T>::releaseUsed(std::tr1::shared_ptr<T> &element)
|
||||
{
|
||||
if(element!=elements[nextReleaseUsed++]) {
|
||||
throw std::logic_error(
|
||||
"not queueElement returned by last call to getUsed");
|
||||
}
|
||||
if(nextReleaseUsed>=size) nextReleaseUsed = 0;
|
||||
numberUsed--;
|
||||
numberFree++;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
#endif /* QUEUE_H */
|
||||
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -1,68 +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 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 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 */
|
||||
@@ -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
|
||||
@@ -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 += ']';
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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:
|
||||
const 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:
|
||||
const 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 */
|
||||
@@ -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 */
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -1,80 +0,0 @@
|
||||
/*bitSetUtil.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/noDefaultMethods.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/bitSetUtil.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static bool checkBitSetPVField(
|
||||
PVField *pvField,BitSet *bitSet,int32 initialOffset)
|
||||
{
|
||||
bool atLeastOneBitSet = false;
|
||||
bool allBitsSet = true;
|
||||
int32 offset = initialOffset;
|
||||
int32 nbits = pvField->getNumberFields();
|
||||
if(nbits==1) return bitSet->get(offset);
|
||||
int32 nextSetBit = bitSet->nextSetBit(offset);
|
||||
if(nextSetBit>=(offset+nbits)) return false;
|
||||
if(bitSet->get(offset)) {
|
||||
if(nbits>1) {
|
||||
for(int32 i=offset+1; i<offset+nbits; i++) bitSet->clear(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
PVStructure *pvStructure = static_cast<PVStructure *>(pvField);
|
||||
while(offset<initialOffset + nbits) {
|
||||
PVField *pvSubField = pvStructure->getSubField(offset).get();
|
||||
int32 nbitsNow = pvSubField->getNumberFields();
|
||||
if(nbitsNow==1) {
|
||||
if(bitSet->get(offset)) {
|
||||
atLeastOneBitSet = true;
|
||||
} else {
|
||||
allBitsSet = false;
|
||||
}
|
||||
offset++;
|
||||
} else {
|
||||
offset++;
|
||||
PVStructure *pvSubStructure = static_cast<PVStructure*>(pvField);
|
||||
PVFieldPtrArray pvSubStructureFields =
|
||||
pvSubStructure->getPVFields();
|
||||
int num = pvSubStructure->getStructure()->getNumberFields();
|
||||
for(int32 i=0; i<num; i++) {
|
||||
PVField *pvSubSubField = pvSubStructureFields[i].get();
|
||||
bool result = checkBitSetPVField(pvSubSubField,bitSet,offset);
|
||||
if(result) {
|
||||
atLeastOneBitSet = true;
|
||||
if(!bitSet->get(offset)) {
|
||||
allBitsSet = false;
|
||||
}
|
||||
} else {
|
||||
allBitsSet = false;
|
||||
}
|
||||
offset += pvSubSubField->getNumberFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(allBitsSet) {
|
||||
if(nbits>1) {
|
||||
for(int32 i=initialOffset+1; i<initialOffset+nbits; i++){
|
||||
bitSet->clear(i);
|
||||
}
|
||||
}
|
||||
bitSet->set(initialOffset);
|
||||
}
|
||||
return atLeastOneBitSet;
|
||||
}
|
||||
|
||||
bool BitSetUtil::compress(BitSet *bitSet,PVStructure *pvStructure)
|
||||
{
|
||||
return checkBitSetPVField(pvStructure,bitSet,0);
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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(BitSet *bitSet,PVStructure *pvStructure);
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /*BITSETUTIL_H */
|
||||
36
src/Makefile
Normal file
36
src/Makefile
Normal file
@@ -0,0 +1,36 @@
|
||||
# Makefile for the pvData library
|
||||
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PVDATA_SRC = $(TOP)/src
|
||||
|
||||
include $(PVDATA_SRC)/misc/Makefile
|
||||
include $(PVDATA_SRC)/pv/Makefile
|
||||
include $(PVDATA_SRC)/factory/Makefile
|
||||
include $(PVDATA_SRC)/property/Makefile
|
||||
include $(PVDATA_SRC)/copy/Makefile
|
||||
include $(PVDATA_SRC)/pvMisc/Makefile
|
||||
include $(PVDATA_SRC)/json/Makefile
|
||||
|
||||
LIBRARY = pvData
|
||||
|
||||
pvData_LIBS += Com
|
||||
|
||||
EXPANDVARS += EPICS_PVD_MAJOR_VERSION
|
||||
EXPANDVARS += EPICS_PVD_MINOR_VERSION
|
||||
EXPANDVARS += EPICS_PVD_MAINTENANCE_VERSION
|
||||
EXPANDVARS += EPICS_PVD_DEVELOPMENT_FLAG
|
||||
|
||||
EXPANDFLAGS += $(foreach var,$(EXPANDVARS),-D$(var)="$(strip $($(var)))")
|
||||
|
||||
# shared library ABI version.
|
||||
SHRLIB_VERSION = $(EPICS_PVD_MAJOR_VERSION).$(EPICS_PVD_MINOR_VERSION).$(EPICS_PVD_MAINTENANCE_VERSION)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
# Can't use EXPAND as generated headers must appear
|
||||
# in O.Common, but EXPAND emits rules for O.$(T_A)
|
||||
../O.Common/pv/pvdVersionNum.h: ../pv/pvdVersionNum.h@
|
||||
$(MKDIR) $(COMMON_DIR)/pv
|
||||
$(EXPAND_TOOL) $(EXPANDFLAGS) $($@_EXPANDFLAGS) $< $@
|
||||
8
src/copy/Makefile
Normal file
8
src/copy/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVDATA_SRC)/copy
|
||||
|
||||
INC += pv/createRequest.h
|
||||
|
||||
LIBSRCS += createRequest.cpp
|
||||
LIBSRCS += requestmapper.cpp
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user