CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
Loading...
Searching...
No Matches
Subscriptions.h
Go to the documentation of this file.
1
20
21#if !defined(_SUBSCRIPTIONS_H_)
22#define _SUBSCRIPTIONS_H_
23
24#include "PsyTime.h"
25#include "Utils.h"
26#include "HTML.h"
27#include "ObjectIDs.h"
28#include "xml_parser.h"
29#include "DataMessage.h"
30
37#define COMP_WHITEBOARD 1
38#define COMP_CATALOG 2
39#define COMP_STREAM 3
40#define COMP_FEED 4
41#define COMP_SERVICE 5
42#define COMP_MODULE 6
43#define COMP_INTERNAL 6
44#define COMP_EXTERNAL 7
46
50#define COMP_MIGRATE_NO 0
51#define COMP_MIGRATE_ALLOW 1
53
54
55namespace cmlabs {
56
61#define TRIGGERFILTER_HASKEY 1
62#define TRIGGERFILTER_EQUALS 2
63#define TRIGGERFILTER_NOTEQUALS 3
64#define TRIGGERFILTER_EQUALSNUMERIC 4
65#define TRIGGERFILTER_NOTEQUALSNUMERIC 5
66#define TRIGGERFILTER_GREATERTHAN 6
67#define TRIGGERFILTER_LESSTHAN 7
68#define TRIGGERFILTER_MAXAGE 8
70
75#define INDEX_TIME 1
76#define INDEX_STRING 2
77#define INDEX_INTEGER 3
78#define INDEX_FLOAT 4
80
87struct FilterSpec {
88 uint8 filter;
89 uint64 time;
93 std::string toXML() {
94 return utils::StringFormat("\t<filter filter=\"%u\" time=\"%llu\" key=\"%s\" value=\"%s\" />\n",
95 filter, time, key, value);
96 }
97
98 bool fromXML(const char* xml) {
99 if (!xml) return false;
100 XMLResults xmlResults;
101 XMLNode node = XMLNode::parseString(xml, "filter", &xmlResults);
102 if (xmlResults.error != eXMLErrorNone)
103 return false;
104 if (node.isEmpty()) return false;
105 return fromXML(node);
106 }
107
108 bool fromXML(XMLNode &node) {
109 const char* str;
110 if (str = node.getAttribute("filter")) filter = (uint8)utils::Ascii2Uint32(str); else return false;
111 if (str = node.getAttribute("time")) time = utils::Ascii2Uint64(str); else return false;
112 if (str = node.getAttribute("key")) utils::strcpyavail(key, str, MAXKEYNAMELEN, true); else return false;
113 if (str = node.getAttribute("value")) utils::strcpyavail(value, str, MAXVALUENAMELEN, true); else return false;
114 return true;
115 }
116};
117
126struct QuerySpec {
127 uint32 source;
128 uint32 origin;
129 uint64 maxage;
130 uint32 maxcount;
132 bool binary;
133 uint32 ipHost;
134 uint16 ipPort;
145 std::string toXML() {
146 return utils::StringFormat("\t<query source=\"%u\" origin=\"%u\" maxage=\"%llu\" maxcount=\"%u\" binary=\"%s\" name=\"%s\" key=\"%s\" value=\"%s\" type=\"%s\" subdir=\"%s\" ext=\"%s\" operation=\"%s\" sourcename=\"%s\" hostname=\"%s\" iphost=\"%u\" port=\"%u\" />\n",
147 source, origin, maxage, maxcount, (binary ? "yes" : "no"), name, key, value, type, subdir, ext, operation,
149 }
150
151 bool fromXML(const char* xml) {
152 if (!xml) return false;
153 XMLResults xmlResults;
154 XMLNode node = XMLNode::parseString(xml, "query", &xmlResults);
155 if (xmlResults.error != eXMLErrorNone)
156 return false;
157 if (node.isEmpty()) return false;
158 return fromXML(node);
159 }
160
161 bool fromXML(XMLNode &node) {
162 const char* str;
163 if (str = node.getAttribute("source")) source = utils::Ascii2Uint32(str); else return false;
164 if (str = node.getAttribute("origin")) origin = utils::Ascii2Uint32(str); else return false;
165 if (str = node.getAttribute("maxage")) maxage = utils::Ascii2Uint64(str); else return false;
166 if (str = node.getAttribute("maxcount")) maxcount = utils::Ascii2Uint32(str); else return false;
167 if (str = node.getAttribute("context")) { if (!context.fromString(str)) return false; } else return false;
168 if (str = node.getAttribute("binary")) binary = (stricmp(str, "yes") == 0); else return false;
169 if (str = node.getAttribute("name")) utils::strcpyavail(name, str, MAXKEYNAMELEN, true); else return false;
170 if (str = node.getAttribute("key")) utils::strcpyavail(key, str, MAXKEYNAMELEN, true); else return false;
171 if (str = node.getAttribute("value")) utils::strcpyavail(value, str, MAXVALUENAMELEN, true); else return false;
172 if (str = node.getAttribute("type")) utils::strcpyavail(type, str, MAXKEYNAMELEN, true); else return false;
173 if (str = node.getAttribute("subdir")) utils::strcpyavail(subdir, str, MAXKEYNAMELEN, true); else return false;
174 if (str = node.getAttribute("ext")) utils::strcpyavail(ext, str, MAXKEYNAMELEN, true); else return false;
175 if (str = node.getAttribute("operation")) utils::strcpyavail(operation, str, MAXKEYNAMELEN, true); else return false;
176 if (str = node.getAttribute("sourcename")) utils::strcpyavail(sourceName, str, MAXKEYNAMELEN, true); else return false;
177 if (str = node.getAttribute("hostname")) utils::strcpyavail(hostName, str, MAXKEYNAMELEN, true); else return false;
178 if (str = node.getAttribute("iphost")) ipHost = utils::Ascii2Uint32(str); else return false;
179 if (str = node.getAttribute("ipport")) ipPort = utils::Ascii2Uint32(str); else return false;
180 return true;
181 }
182};
183
194 uint32 source;
195 uint32 origin;
196 uint64 maxage;
197 uint32 maxcount;
200 uint32 tag;
203 uint8 keytype;
204 uint32 from;
205 uint32 to;
206 uint64 startTime;
207 uint64 endTime;
208 int64 startInt;
209 int64 endInt;
210 float64 startFloat;
211 float64 endFloat;
215 std::string toXML() {
216 return utils::StringFormat("\t<retrieve source=\"%u\" origin=\"%u\" maxage=\"%llu\" maxcount=\"%u\" type=\"%s\" context=\"%s\" tag=\"%u\" name=\"%s\" key=\"%s\" keytype=\"%u\" from=\"%u\" to=\"%u\" starttime=\"%llu\" endtime=\"%llu\" startint=\"%lld\" endint=\"%lld\" startfloat=\"%f\" endfloat=\"%f\" startstring=\"%s\" endstring=\"%s\" />\n",
217 source, origin, maxage, maxcount, type.toString().c_str(), context.toString().c_str(),
218 tag, name, key, keytype, from, to,
220 }
221
222 bool fromXML(const char* xml) {
223 if (!xml) return false;
224 XMLResults xmlResults;
225 XMLNode node = XMLNode::parseString(xml, "retrieve", &xmlResults);
226 if (xmlResults.error != eXMLErrorNone)
227 return false;
228 if (node.isEmpty()) return false;
229 return fromXML(node);
230 }
231
232 bool fromXML(XMLNode &node) {
233 const char* str;
234 if (str = node.getAttribute("source")) source = utils::Ascii2Uint32(str); else return false;
235 if (str = node.getAttribute("origin")) origin = utils::Ascii2Uint32(str); else return false;
236 if (str = node.getAttribute("maxage")) maxage = utils::Ascii2Uint64(str); else return false;
237 if (str = node.getAttribute("maxcount")) maxcount = utils::Ascii2Uint32(str); else return false;
238 if (str = node.getAttribute("type")) { if (!type.fromString(str)) return false; } else return false;
239 if (str = node.getAttribute("context")) { if (!context.fromString(str)) return false; } else return false;
240 if (str = node.getAttribute("tag")) tag = utils::Ascii2Uint32(str); else return false;
241 if (str = node.getAttribute("name")) utils::strcpyavail(name, str, MAXKEYNAMELEN, true); else return false;
242 if (str = node.getAttribute("key")) utils::strcpyavail(key, str, MAXKEYNAMELEN, true); else return false;
243 if (str = node.getAttribute("keytype")) keytype = (uint8)utils::Ascii2Uint32(str); else return false;
244 if (str = node.getAttribute("from")) from = utils::Ascii2Uint32(str); else return false;
245 if (str = node.getAttribute("to")) to = utils::Ascii2Uint32(str); else return false;
246 if (str = node.getAttribute("starttime")) startTime = utils::Ascii2Uint64(str); else return false;
247 if (str = node.getAttribute("endtime")) endTime = utils::Ascii2Uint64(str); else return false;
248 if (str = node.getAttribute("startint")) startInt = utils::Ascii2Int64(str); else return false;
249 if (str = node.getAttribute("endint")) endInt = utils::Ascii2Int64(str); else return false;
250 if (str = node.getAttribute("startfloat")) startFloat = utils::Ascii2Float64(str); else return false;
251 if (str = node.getAttribute("endfloat")) endFloat = utils::Ascii2Float64(str); else return false;
252 if (str = node.getAttribute("startstring")) utils::strcpyavail(startString, str, MAXVALUENAMELEN, true); else return false;
253 if (str = node.getAttribute("endstring")) utils::strcpyavail(endString, str, MAXVALUENAMELEN, true); else return false;
254 return true;
255 }
256};
257
259#define MESSAGE_NON_GUARANTEED 1
260
270struct PostSpec {
271 uint32 to;
275 uint32 tag;
276 uint64 ttl;
277 uint8 policy;
280// char contentKey[MAXKEYNAMELEN + 1];
283 std::string toXML() {
284 if (contentCount) {
285 // ||S||key||val||I||key||val||S||key||val
286 const char* contentType, *key, *value;
287 std::string strContent;
288 std::vector<std::string> entries = utils::TextListSplit(content, "||", false, true);
289 uint32 slotCount = 3 * contentCount;
290 uint32 n = 0;
291 if (entries.size() == slotCount) {
292 while (n < slotCount) {
293 contentType = entries[n++].c_str();
294 key = entries[n++].c_str();
295 value = entries[n++].c_str();
296 if (strcmp(contentType, "S") == 0) {
297 strContent += utils::StringFormat("\t\t<content type=\"string\" key=\"%s\" value=\"%s\" />\n",
298 html::EncodeHTML(key).c_str(), html::EncodeHTML(value).c_str());
299 }
300 else if (strcmp(contentType, "I") == 0) {
301 strContent += utils::StringFormat("\t\t<content type=\"integer\" key=\"%s\" value=\"%s\" />\n",
302 html::EncodeHTML(key).c_str(), html::EncodeHTML(value).c_str());
303 }
304 else if (strcmp(contentType, "F") == 0) {
305 strContent += utils::StringFormat("\t\t<content type=\"float\" key=\"%s\" value=\"%s\" />\n",
306 html::EncodeHTML(key).c_str(), html::EncodeHTML(value).c_str());
307 }
308 }
309 }
310 return utils::StringFormat("\t<post to=\"%u\" type=\"%s\" context=\"%s\" contextchange=\"%s\" tag=\"%u\" ttl=\"%llu\" policy=\"%u\" name=\"%s\">\n%s</post>\n",
311 to, type.toString().c_str(), context.toString().c_str(), contextchange.toString().c_str(), tag, ttl, policy, name, strContent.c_str());
312 }
313 else {
314 return utils::StringFormat("\t<post to=\"%u\" type=\"%s\" context=\"%s\" contextchange=\"%s\" tag=\"%u\" ttl=\"%llu\" policy=\"%u\" name=\"%s\" />\n",
315 to, type.toString().c_str(), context.toString().c_str(), contextchange.toString().c_str(), tag, ttl, policy, name);
316 }
317 }
318
319 bool fromXML(const char* xml) {
320 if (!xml) return false;
321 XMLResults xmlResults;
322 XMLNode node = XMLNode::parseString(xml, "post", &xmlResults);
323 if (xmlResults.error != eXMLErrorNone)
324 return false;
325 if (node.isEmpty()) return false;
326 return fromXML(node);
327 }
328
329 bool fromXML(XMLNode &node) {
330 const char* str;
331 if (str = node.getAttribute("to")) to = utils::Ascii2Uint32(str); else return false;
332 if (str = node.getAttribute("type")) { if (!type.fromString(str)) return false; }
333 else return false;
334 if (str = node.getAttribute("context")) { if (!context.fromString(str)) return false; }
335 else return false;
336 if (str = node.getAttribute("contextchange")) { if (!contextchange.fromString(str)) return false; }
337 else return false;
338 if (str = node.getAttribute("tag")) tag = utils::Ascii2Uint32(str); else return false;
339 if (str = node.getAttribute("ttl")) ttl = utils::Ascii2Uint64(str); else return false;
340 if (str = node.getAttribute("policy")) policy = (uint8)utils::Ascii2Uint32(str); else return false;
341 if (str = node.getAttribute("name")) utils::strcpyavail(name, str, MAXKEYNAMELEN, true); else return false;
342 contentFromXML(node);
343 return true;
344 }
345
347 std::string strContent;
348 const char* str, *key, *value;
349 if ((key = node.getAttribute("contentkey")) && (value = node.getAttribute("content"))) {
350 strContent = utils::StringFormat("%s||S||%s||%s", content, html::DecodeHTML(key).c_str(), html::DecodeHTML(value).c_str());
351 utils::strcpyavail(content, strContent.c_str(), MAXCONTENTLEN, false);
352 contentCount++;
353 }
354
355 XMLNode subNode;
356 uint32 i, count = node.nChildNode("content");
357 for (i = 0; i < count; i++) {
358 if (!(subNode = node.getChildNode("content", i)).isEmpty()) {
359 if (!(key = subNode.getAttribute("key")) || !strlen(key))
360 continue;
361 if ( (!(value = subNode.getAttribute("content")) || !strlen(value)) &&
362 (!(value = subNode.getAttribute("value")) || !strlen(value)) )
363 continue;
364 str = subNode.getAttribute("type");
365 if (str && stricmp(str, "integer") == 0)
366 strContent = utils::StringFormat("%s||I||%s||%s", content, html::DecodeHTML(key).c_str(), html::DecodeHTML(value).c_str());
367 else if (str && ((stricmp(str, "double") == 0) || (stricmp(str, "float") == 0)))
368 strContent = utils::StringFormat("%s||F||%s||%s", content, html::DecodeHTML(key).c_str(), html::DecodeHTML(value).c_str());
369 else
370 strContent = utils::StringFormat("%s||S||%s||%s", content, html::DecodeHTML(key).c_str(), html::DecodeHTML(value).c_str());
371 utils::strcpyavail(content, strContent.c_str(), MAXCONTENTLEN, false);
372 contentCount++;
373 }
374 }
375 return true;
376 }
377
381 if (!contentCount)
382 return 0;
383 uint32 count = 0;
384 const char* contentType, *key, *value;
385 std::string strContent;
386 std::vector<std::string> entries = utils::TextListSplit(content, "||", false, true);
387 uint32 slotCount = 3 * contentCount, n = 0;
388 if (entries.size() == slotCount) {
389 while (n < slotCount) {
390 contentType = entries[n++].c_str();
391 key = entries[n++].c_str();
392 value = entries[n++].c_str();
393 if (strcmp(contentType, "S") == 0)
394 msg->setString(key, value);
395 else if (strcmp(contentType, "I") == 0)
396 msg->setInt(key, utils::Ascii2Int64(value));
397 else if (strcmp(contentType, "F") == 0)
398 msg->setFloat(key, utils::Ascii2Float64(value));
399 count++;
400 }
401 }
402 return count;
403 }
404};
405
413 std::string toXML() {
414 return utils::StringFormat("\t<signal type=\"%s\" name=\"%s\" />\n", type.toString().c_str(), name);
415 }
416
417 bool fromXML(const char* xml) {
418 if (!xml) return false;
419 XMLResults xmlResults;
420 XMLNode node = XMLNode::parseString(xml, "signal", &xmlResults);
421 if (xmlResults.error != eXMLErrorNone)
422 return false;
423 if (node.isEmpty()) return false;
424 return fromXML(node);
425 }
426 bool fromXML(XMLNode &node) {
427 const char* str;
428 if (str = node.getAttribute("type")) { if (!type.fromString(str)) return false; } else return false;
429 if (str = node.getAttribute("name")) utils::strcpyavail(name, str, MAXKEYNAMELEN, true); else return false;
430 return true;
431 }
432};
433
451 bool reset(uint32 s = 0) {
452 memset(this, 0, sizeof(TriggerSpec));
453 size = (s) ? s : sizeof(TriggerSpec);
455 return true;
456 }
457
459 if (n >= filterCount) return NULL;
460 return (FilterSpec*)
461 (((char*)this) + sizeof(TriggerSpec) + (n*sizeof(FilterSpec)));
462 }
463
465 if (n >= retrieveCount) return NULL;
466 return (RetrieveSpec*)
467 (((char*)this) + sizeof(TriggerSpec) + (filterCount*sizeof(FilterSpec)) + (n*sizeof(RetrieveSpec)));
468 }
469
470 RetrieveSpec* getRetrieveSpec(const char* name);
473 if (n >= queryCount) return NULL;
474 return (QuerySpec*)
475 (((char*)this) + sizeof(TriggerSpec) + (filterCount*sizeof(FilterSpec)) +
476 (retrieveCount*sizeof(RetrieveSpec)) + (n*sizeof(QuerySpec)));
477 }
478
479 QuerySpec* getQuerySpec(const char* name);
481 std::list<PostSpec*>* getPostSpecs(const char* name);
483 std::list<PostSpec*>* getPostSpecs(PsyType type);
485 PostSpec* getPostSpec(const char* name);
490 if (n >= postCount) return NULL;
491 return (PostSpec*)
492 (((char*)this) + sizeof(TriggerSpec) + (filterCount*sizeof(FilterSpec)) +
493 (retrieveCount*sizeof(RetrieveSpec)) + (queryCount*sizeof(QuerySpec)) +
494 (n * sizeof(PostSpec)));
495 }
496
497 SignalSpec* getSignalSpec(const char* name);
502 if (n >= signalCount) return NULL;
503 return (SignalSpec*)
504 (((char*)this) + sizeof(TriggerSpec) + (filterCount*sizeof(FilterSpec)) +
505 (retrieveCount*sizeof(RetrieveSpec)) + (queryCount*sizeof(QuerySpec)) +
506 (postCount*sizeof(PostSpec)) + (n * sizeof(SignalSpec)));
507 }
508
509 std::string toXML();
510
512 static bool UnitTest();
513
514 uint32 size;
515 uint32 cid;
516 uint32 id;
517 uint32 componentID;
518 uint32 interval;
519 uint32 from;
520 uint32 to;
521 uint32 tag;
522 uint32 delay;
524 uint32 groupparam;
525 uint16 crankID;
526 uint32 group;
531 uint16 filterCount;
533 uint16 queryCount;
534 uint16 postCount;
535 uint16 signalCount;
536 // Tail layout, in order:
537 // filterCount x FilterSpec
538 // retrieveCount x RetrieveSpec
539 // queryCount x QuerySpec
540 // postCount x PostSpec
541 // signalCount x SignalSpec
542};
543
544// T1.6: declarative join operator (<triggergroup>). See Docs/T1.6-triggergroup-plan.md.
545// A group joins several member triggers and activates the crank ONCE per completed set.
546// Packed, size-prefixed struct with a tail of GroupMemberSpec (same discipline as TriggerSpec):
547// member metadata is kept SEPARATE from TriggerSpec so the shared TriggerSpec binary
548// contract is untouched; members are matched back to their TriggerSpec by name.
549
554
559
564
569
574
581 uint32 maxage;
582 uint8 optional;
583 uint8 primary;
584 uint8 pad[2];
585};
586
596 bool reset(uint32 s = 0) {
597 memset(this, 0, sizeof(TriggerGroupSpec));
598 size = (s) ? s : sizeof(TriggerGroupSpec);
600 return true;
601 }
602
604 if (n >= memberCount) return NULL;
605 return (GroupMemberSpec*)(((char*)this) + sizeof(TriggerGroupSpec) + (n*sizeof(GroupMemberSpec)));
606 }
607
609 for (uint32 n = 0; n < memberCount; n++) {
611 if (m && stricmp(m->name, name) == 0) return m;
612 }
613 return NULL;
614 }
615
616 uint32 size;
617 uint32 cid;
618 uint32 id;
619 uint32 componentID;
620 uint16 crankID;
622
623 uint32 maxage;
624 uint32 count;
625 uint32 minCount;
626 uint32 within;
627 uint32 timeWindow;
628 uint32 debounce;
629 uint32 timeout;
631 uint8 mode;
632 uint8 slide;
633 uint8 dup;
634 uint8 order;
635 uint8 ontimeout;
636 uint16 memberCount;
637 // Tail layout: memberCount x GroupMemberSpec
638};
639
652 bool reset() {
653 memset(this, 0, sizeof(ComponentSetup));
654 size = sizeof(ComponentSetup);
656 return true;
657 }
658 uint32 size;
659 uint32 cid;
660 uint32 componentID;
661 uint16 spaceID;
662 uint32 tag;
663 uint8 type;
666 uint8 verbose;
667 uint8 debug;
668 uint8 migration;
669 uint8 priority;
672 bool rotate;
675
676 // Whiteboard, Stream, Catalog, Service, Feed
683 uint32 timeout;
684
685 // Recording & Playback
686 uint32 maxcount;
687 uint64 maxsize;
688 uint32 interval;
689
690 // Executable
692
693 // Setup
694 char setup[1024*1024];
695};
696
697// Local only, not transmitted
698
706
715public:
717 setup = new ComponentSetup;
718 setup->reset();
719 };
721 delete(setup);
722 setup = NULL;
723 while (triggers.size()) {
724 delete(triggers.front());
725 triggers.pop_front();
726 }
727 // T1.6: free triggergroup specs (malloc'd packed blocks).
728 while (triggerGroups.size()) {
729 free(triggerGroups.front());
730 triggerGroups.pop_front();
731 }
732 };
733
735 std::list<TriggerSpec*> triggers;
736 std::list<TriggerGroupSpec*> triggerGroups;
737 std::list<CustomView> customViews;
738};
739
740} // namespace cmlabs
741
742#endif //_SUBSCRIPTIONS_H_
743
The binary DataMessage container — the central data-exchange object of Psyclone/CMSDK.
HTML/URL helper utilities: entity encoding/decoding, MIME type lookup and URL component parsing.
Object type ids used to tag and verify every binary structure in CMSDK memory.
#define TRIGGERGROUPDATA
T1.6 <triggergroup> declarative join spec.
Definition ObjectIDs.h:76
#define TRIGGERDATA
Definition ObjectIDs.h:57
#define COMPONENTSETUPDATA
Definition ObjectIDs.h:60
CMSDK time: µs-resolution 64-bit timestamps and the Time Mapping Constant (TMC).
Cross-platform utility toolbox for CMSDK: threading, synchronization, shared memory,...
#define MAXKEYNAMELEN
Definition Utils.h:85
#define stricmp
Definition Utils.h:132
#define MAXCONTENTLEN
Definition Utils.h:87
#define MAXVALUENAMELEN
Definition Utils.h:86
std::list< TriggerGroupSpec * > triggerGroups
T1.6: <triggergroup> join specs; owned here (freed in destructor).
std::list< TriggerSpec * > triggers
The component's triggers; owned by this object (deleted in destructor).
std::list< CustomView > customViews
Custom UI views registered for the component.
ComponentSetup * setup
The component's setup block; owned by this object.
The central Psyclone data container: a self-contained binary message with typed, named user entries.
bool setFloat(const char *key, float64 value)
setFloat(const char* key, float64 value)
bool setString(const char *key, const char *value)
setString(const char* key, const char* value)
bool setInt(const char *key, int64 value)
setInt(const char* key, int64 value)
uint32 strcpyavail(char *dst, const char *src, uint32 maxlen, bool copyAvailable)
Bounded strcpy that always NUL-terminates.
Definition Utils.cpp:6463
std::string EncodeHTML(std::string str)
Encode a plain string for safe embedding in HTML (e.g.
Definition HTML.cpp:51
std::string DecodeHTML(std::string str)
Decode HTML entities in a string (e.g.
Definition HTML.cpp:12
uint32 Ascii2Uint32(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 32-bit decimal integer from a substring.
Definition Utils.cpp:7933
std::vector< std::string > TextListSplit(const char *text, const char *split, bool keepEmpty=true, bool autoTrim=false)
Split text on a separator.
Definition Utils.cpp:6918
std::string StringFormat(const char *format,...)
printf into a std::string.
Definition Utils.cpp:7033
uint64 Ascii2Uint64(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 64-bit decimal integer from a substring.
Definition Utils.cpp:7887
int64 Ascii2Int64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a signed 64-bit decimal integer from a substring.
Definition Utils.cpp:7869
float64 Ascii2Float64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a 64-bit float from a substring (decimal point, not locale dependent).
Definition Utils.cpp:7953
TriggerGroupOnTimeout
T1.6 action on window/maxage expiry with an incomplete set.
@ TRIGGERGROUP_ONTIMEOUT_DISCARD
drop the partial set silently-ish.
@ TRIGGERGROUP_ONTIMEOUT_FIRE
default: partial-fire + L1 warn.
TriggerGroupMode
T1.6 join mode.
@ TRIGGERGROUP_MODE_SNAPSHOT
fire on primary member; attach latest of others, no wait.
@ TRIGGERGROUP_MODE_NORMAL
default: accumulate + complete-check.
@ eXMLErrorNone
Definition xml_parser.h:131
TriggerGroupCount
T1.6 group completion policy: fire when ANY N members present (count), or all named.
@ TRIGGERGROUP_COUNT_ALL
0 = "all" (every named member required).
TriggerGroupOrder
T1.6 ordering constraint.
@ TRIGGERGROUP_ORDER_NONE
default: any arrival order.
@ TRIGGERGROUP_ORDER_STRICT
only fire if members arrived in declared order.
TriggerGroupDup
T1.6 duplicate-member handling before a set completes.
@ TRIGGERGROUP_DUP_KEEP
queue all duplicate member values.
@ TRIGGERGROUP_DUP_LATEST
default: latest member value wins.
Hierarchical execution-context identifier.
Definition Types.h:284
Hierarchical message type identifier — the key used for publish/subscribe matching in Psyclone.
Definition Types.h:123
Complete static setup for one component, as parsed from the system specification.
char setup[1024 *1024]
Raw component-specific setup XML, 1 MB max.
bool rotate
Rotate storage/playback when limits are reached.
char cmdline[MAXKEYNAMELEN+1]
Command line for external executable components.
char logfile[MAXKEYNAMELEN+1]
Log file name/path.
char operation[MAXKEYNAMELEN+1]
Default operation verb.
char base[MAXKEYNAMELEN+1]
Filename base for stored data.
char value[MAXVALUENAMELEN+1]
Default value parameter.
char subdir[MAXKEYNAMELEN+1]
Storage sub-directory.
uint16 spaceID
Id of the PsySpace the component runs in.
uint8 priority
Scheduling priority of the component.
char name[MAXKEYNAMELEN+1]
Component name.
uint32 timeout
Operation timeout in ms.
uint32 componentID
Unique component id.
uint8 migration
Migration policy, COMP_MIGRATE_NO or COMP_MIGRATE_ALLOW.
uint64 maxsize
Max total bytes to retain/record (0 = unlimited).
char root[MAXKEYNAMELEN+1]
Root dir or URL for the component's data.
uint32 size
Total struct size in bytes.
uint32 tag
Default tag for the component.
uint8 autoRestart
Restart the component automatically if it dies.
char extension[MAXKEYNAMELEN+1]
File extension / filetype for stored data.
uint8 type
Component kind, one of the COMP_... defines.
uint8 verbose
Verbosity level.
uint8 consoleOutput
Console output mode.
bool reset()
Zero the struct and stamp size/cid.
char function[MAXKEYNAMELEN+1]
Entry function name (for library-loaded modules).
char keys[MAXVALUENAMELEN+1]
Index key definitions (component-specific format).
uint32 interval
Playback interval in ms (0 = use recorded timing).
uint32 maxcount
Max number of messages to retain/record (0 = unlimited).
uint32 cid
Object id, COMPONENTSETUPDATA when valid.
uint8 debug
Debug level.
A custom UI view registered for a component (local configuration; never transmitted).
char templateURL[MAXKEYNAMELEN+1]
URL of the HTML template implementing the view.
uint32 compID
Component the view belongs to.
char name[MAXKEYNAMELEN+1]
Display name of the view.
One filter condition attached to a TriggerSpec: a test on a user entry of the candidate message.
char key[MAXKEYNAMELEN+1]
Name of the user entry to test.
char value[MAXVALUENAMELEN+1]
Comparison operand as text (parsed numerically for the numeric operations).
std::string toXML()
Serialise as a <filter .../> XML element.
bool fromXML(const char *xml)
Parse from an XML string containing a <filter .../> element.
uint8 filter
Filter operation, one of the TRIGGERFILTER_... codes.
uint64 time
Time operand in milliseconds (used by TRIGGERFILTER_MAXAGE).
bool fromXML(XMLNode &node)
Parse from an already-parsed <filter> XML node.
One member of a <triggergroup>, referencing a member trigger by name.
uint32 maxage
Per-member freshness bound in ms (0 = no per-member bound).
uint8 pad[2]
Explicit padding to keep the tail layout deterministic.
uint8 primary
1 = primary trigger for mode="snapshot" (defaults to first member).
char name[MAXKEYNAMELEN+1]
Member trigger name (matches a registered TriggerSpec name).
uint8 optional
1 = not required for completion; included if present.
Specification of a message to post when a trigger fires (or a crank completes).
uint8 policy
Delivery policy flags (e.g.
bool fromXML(const char *xml)
Parse from an XML string containing a <post .../> element.
PsyType type
Type of the posted message.
uint32 addContentToMsg(DataMessage *msg)
Unpack the inline content entries into msg as typed user entries.
char name[MAXKEYNAMELEN+1]
Name of this post spec.
uint32 contentCount
Number of inline content entries packed into content.
char content[MAXCONTENTLEN+1]
Packed content entries: "||T||key||value" repeated (T = S, I or F).
bool contentFromXML(XMLNode &node)
Collect inline <content> entries (and contentkey/content attributes) from the XML node into the packe...
uint32 to
Addressee component id (0 = publish to subscribers).
uint32 tag
Tag for the posted message.
uint64 ttl
Time-to-live of the posted message in microseconds.
std::string toXML()
Serialise as a <post ...>...</post> XML element including content children.
PsyContext context
Context the post applies in.
PsyContext contextchange
Context switch the posted message announces (NOCONTEXT if none).
bool fromXML(XMLNode &node)
Parse from an already-parsed <post> XML node, including its <content> children.
Specification of a query against a catalog/service/feed, attached to a TriggerSpec.
char type[MAXKEYNAMELEN+1]
Requested data/content type.
char hostName[MAXKEYNAMELEN+1]
External source: host name (alternative to ipHost).
uint32 ipHost
External source: IPv4 host (as uint32), 0 if not used.
char operation[MAXKEYNAMELEN+1]
Operation to perform (source-specific verb).
char key[MAXKEYNAMELEN+1]
Key to query on.
bool fromXML(const char *xml)
Parse from an XML string containing a <query .../> element.
PsyContext context
Restrict to data matching this context.
uint64 maxage
Maximum age of results in MICROSECONDS (XML gives ms; parser multiplies by 1000).
uint32 origin
Restrict to data originating from this component id (0 = any).
char value[MAXVALUENAMELEN+1]
Value to match.
char name[MAXKEYNAMELEN+1]
Name of this query, used to reference its results in the crank.
char subdir[MAXKEYNAMELEN+1]
Sub-directory/collection within the source.
bool fromXML(XMLNode &node)
Parse from an already-parsed <query> XML node.
char sourceName[MAXKEYNAMELEN+1]
Name of the source component (alternative to numeric id).
bool binary
Request results in binary form rather than text.
uint32 maxcount
Maximum number of results to return (0 = unlimited).
uint16 ipPort
External source: TCP/UDP port, 0 if not used.
char ext[MAXKEYNAMELEN+1]
File extension / data format selector.
std::string toXML()
Serialise as a <query .../> XML element.
uint32 source
Component id of the source to query.
Specification of a whiteboard retrieval attached to a TriggerSpec.
uint64 endTime
Range end when keytype == INDEX_TIME (microseconds).
char name[MAXKEYNAMELEN+1]
Name of this retrieve, used to reference its results in the crank.
char endString[MAXVALUENAMELEN+1]
Range end when keytype == INDEX_STRING.
bool fromXML(XMLNode &node)
Parse from an already-parsed <retrieve> XML node.
char startString[MAXVALUENAMELEN+1]
Range start when keytype == INDEX_STRING.
uint64 startTime
Range start when keytype == INDEX_TIME (microseconds).
uint32 origin
Restrict to messages originating from this component id (0 = any).
uint8 keytype
Interpretation of key: INDEX_TIME, INDEX_STRING, INDEX_INTEGER or INDEX_FLOAT.
int64 endInt
Range end when keytype == INDEX_INTEGER.
int64 startInt
Range start when keytype == INDEX_INTEGER.
PsyType type
Message type to match (wildcards allowed).
uint32 maxcount
Maximum number of messages to return (0 = unlimited).
uint32 source
Component id of the whiteboard to retrieve from.
uint32 from
Restrict to messages sent by this component id (0 = any).
float64 startFloat
Range start when keytype == INDEX_FLOAT.
PsyContext context
Context to match.
float64 endFloat
Range end when keytype == INDEX_FLOAT.
uint64 maxage
Maximum message age in MICROSECONDS (XML gives ms; parser multiplies by 1000).
char key[MAXKEYNAMELEN+1]
Indexed user entry to range-query on (empty = time/type retrieval only).
bool fromXML(const char *xml)
Parse from an XML string containing a <retrieve .../> element.
uint32 to
Restrict to messages addressed to this component id (0 = any).
uint32 tag
Tag to match (0 = any).
std::string toXML()
Serialise as a <retrieve .../> XML element.
Specification of a signal (a typed notification without payload) emitted when a trigger fires.
bool fromXML(XMLNode &node)
PsyType type
Type of the signal to emit.
bool fromXML(const char *xml)
Parse from an XML string containing a <signal .../> element.
std::string toXML()
Serialise as a <signal .../> XML element.
char name[MAXKEYNAMELEN+1]
Name of this signal spec.
Specification of a <triggergroup> declarative join (T1.6).
uint32 count
Completion count: 0 = all (TRIGGERGROUP_COUNT_ALL), else any-N.
uint8 dup
TriggerGroupDup (latest/keep).
uint8 order
TriggerGroupOrder (none/strict).
uint32 timeout
timeout= : incomplete-set expiry in ms (0 = unset, falls back to maxage).
uint32 debounce
debounce= : fire at most once per N ms with the latest set (0 = unset).
uint8 hasTimeWindow
1 = time= was specified (so timeWindow==0 means "identical content time").
uint32 size
Total block size in bytes including the member tail.
bool reset(uint32 s=0)
Zero the header and stamp size/cid.
uint8 ontimeout
TriggerGroupOnTimeout (fire/discard).
GroupMemberSpec * getMemberSpec(uint32 n)
uint8 mode
TriggerGroupMode (normal/snapshot).
char name[MAXKEYNAMELEN+1]
Group name (unique within the module).
uint16 memberCount
Number of GroupMemberSpecs in the tail.
uint32 id
Unique id of this group (also used as the group tag key).
GroupMemberSpec * getMemberSpec(const char *name)
uint16 crankID
Crank to run when the group fires.
uint32 minCount
min= : fire at N then re-fire as more of the tag-set arrive (0 = unset).
uint32 timeWindow
time= : max spread of member CONTENT times, ms (see hasTimeWindow).
uint8 slide
1 = sliding-window correlation: re-emit on each member update in-window.
uint32 cid
Object id, TRIGGERGROUPDATA when valid.
uint32 componentID
Id of the component owning the group.
uint32 within
within= : max spread of member POST times, ms (0 = unset).
A complete trigger definition: what fires a component's crank and what happens then.
uint32 size
Total block size in bytes including all tail specs.
uint16 signalCount
Number of SignalSpecs in the tail.
uint32 groupparam
Parameter for the group policy.
uint16 filterCount
Number of FilterSpecs in the tail.
uint32 id
Unique id of this trigger.
uint32 tag
Only messages with this tag fire the trigger (0 = any).
uint16 crankID
Id of the crank (processing function) to run when fired.
PsyContext context
Context in which the trigger is active.
RetrieveSpec * getRetrieveSpec(uint32 n)
PostSpec * getPostSpec(uint32 n)
FilterSpec * getFilterSpec(uint32 n)
uint8 grouppolicy
Policy for distributing triggers within a group of components.
uint32 from
Only messages sent by this component id fire the trigger (0 = any).
PostSpec * getPostSpec(const char *name)
uint32 interval
Periodic trigger interval in ms (0 = message-triggered only).
bool reset(uint32 s=0)
Zero the header and stamp size/cid.
uint32 delay
Delay in ms between trigger match and crank execution.
uint16 queryCount
Number of QuerySpecs in the tail.
std::list< PostSpec * > * getPostSpecs(const char *name)
PsyContext triggerContext
Context the triggering message must match.
char name[MAXKEYNAMELEN+1]
Trigger name.
SignalSpec * getSignalSpec(uint32 n)
QuerySpec * getQuerySpec(uint32 n)
PsyType type
Message type that fires the trigger (wildcards allowed).
uint32 group
Group id this trigger belongs to.
uint32 cid
Object id, TRIGGERDATA when valid.
std::string toXML()
Serialise the whole trigger (with all attached specs) as XML.
uint16 postCount
Number of PostSpecs in the tail.
uint16 retrieveCount
Number of RetrieveSpecs in the tail.
static bool UnitTest()
Run the built-in self test.
uint32 componentID
Id of the component owning the trigger.
uint32 to
Only messages addressed to this component id fire the trigger (0 = any).
SignalSpec * getSignalSpec(const char *name)
XMLAttribute getAttribute(int i=0) const
XMLNode getChildNode(int i=0) const
int nChildNode(XMLCSTR name) const
char isEmpty() const
enum XMLError error
Definition xml_parser.h:168
Small recursive XML DOM parser (XMLNode) used by CMSDK for all PsySpec XML parsing.