21#if !defined(_SUBSCRIPTIONS_H_)
22#define _SUBSCRIPTIONS_H_
37#define COMP_WHITEBOARD 1
43#define COMP_INTERNAL 6
44#define COMP_EXTERNAL 7
50#define COMP_MIGRATE_NO 0
51#define COMP_MIGRATE_ALLOW 1
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
77#define INDEX_INTEGER 3
94 return utils::StringFormat(
"\t<filter filter=\"%u\" time=\"%llu\" key=\"%s\" value=\"%s\" />\n",
99 if (!xml)
return false;
101 XMLNode node = XMLNode::parseString(xml,
"filter", &xmlResults);
104 if (node.
isEmpty())
return false;
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,
152 if (!xml)
return false;
154 XMLNode node = XMLNode::parseString(xml,
"query", &xmlResults);
157 if (node.
isEmpty())
return false;
167 if (str = node.
getAttribute(
"context")) {
if (!
context.fromString(str))
return false; }
else return false;
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",
223 if (!xml)
return false;
225 XMLNode node = XMLNode::parseString(xml,
"retrieve", &xmlResults);
228 if (node.
isEmpty())
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;
259#define MESSAGE_NON_GUARANTEED 1
286 const char* contentType, *key, *value;
287 std::string strContent;
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",
300 else if (strcmp(contentType,
"I") == 0) {
301 strContent +=
utils::StringFormat(
"\t\t<content type=\"integer\" key=\"%s\" value=\"%s\" />\n",
304 else if (strcmp(contentType,
"F") == 0) {
305 strContent +=
utils::StringFormat(
"\t\t<content type=\"float\" key=\"%s\" value=\"%s\" />\n",
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",
314 return utils::StringFormat(
"\t<post to=\"%u\" type=\"%s\" context=\"%s\" contextchange=\"%s\" tag=\"%u\" ttl=\"%llu\" policy=\"%u\" name=\"%s\" />\n",
320 if (!xml)
return false;
322 XMLNode node = XMLNode::parseString(xml,
"post", &xmlResults);
325 if (node.
isEmpty())
return false;
332 if (str = node.
getAttribute(
"type")) {
if (!
type.fromString(str))
return false; }
347 std::string strContent;
348 const char* str, *key, *value;
357 for (i = 0; i < count; i++) {
358 if (!(subNode = node.
getChildNode(
"content", i)).isEmpty()) {
359 if (!(key = subNode.
getAttribute(
"key")) || !strlen(key))
361 if ( (!(value = subNode.
getAttribute(
"content")) || !strlen(value)) &&
362 (!(value = subNode.
getAttribute(
"value")) || !strlen(value)) )
365 if (str &&
stricmp(str,
"integer") == 0)
367 else if (str && ((
stricmp(str,
"double") == 0) || (
stricmp(str,
"float") == 0)))
384 const char* contentType, *key, *value;
385 std::string strContent;
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)
395 else if (strcmp(contentType,
"I") == 0)
397 else if (strcmp(contentType,
"F") == 0)
418 if (!xml)
return false;
420 XMLNode node = XMLNode::parseString(xml,
"signal", &xmlResults);
423 if (node.
isEmpty())
return false;
428 if (str = node.
getAttribute(
"type")) {
if (!
type.fromString(str))
return false; }
else return false;
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.
#define COMPONENTSETUPDATA
CMSDK time: µs-resolution 64-bit timestamps and the Time Mapping Constant (TMC).
Cross-platform utility toolbox for CMSDK: threading, synchronization, shared memory,...
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.
std::string EncodeHTML(std::string str)
Encode a plain string for safe embedding in HTML (e.g.
std::string DecodeHTML(std::string str)
Decode HTML entities in a string (e.g.
uint32 Ascii2Uint32(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 32-bit decimal integer from a substring.
std::vector< std::string > TextListSplit(const char *text, const char *split, bool keepEmpty=true, bool autoTrim=false)
Split text on a separator.
std::string StringFormat(const char *format,...)
printf into a std::string.
uint64 Ascii2Uint64(const char *ascii, uint32 start=0, uint32 end=0)
Parse an unsigned 64-bit decimal integer from a substring.
int64 Ascii2Int64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a signed 64-bit decimal integer from a substring.
float64 Ascii2Float64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a 64-bit float from a substring (decimal point, not locale dependent).
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.
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.
Hierarchical message type identifier — the key used for publish/subscribe matching in Psyclone.
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.
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
Small recursive XML DOM parser (XMLNode) used by CMSDK for all PsySpec XML parsing.