19static const uint64
T0 = 63960700000000000ULL;
24static std::string
Esc(
const std::string& s) {
26 for (
unsigned char c : s) {
27 if (c ==
'"' || c ==
'\\') { o +=
'\\'; o += (char)c; }
28 else if (c < 0x20) {
char b[8]; snprintf(b,
sizeof(b),
"\\u%04x", c); o += b; }
33static std::string
Hex(
const char* d, uint32 n) {
34 static const char* h =
"0123456789abcdef";
36 for (uint32 i = 0; i < n; i++) { o += h[((uint8)d[i]) >> 4]; o += h[((uint8)d[i]) & 15]; }
46static Entry S(
const char* k,
const char* v) {
return Entry{ k,
"string",
"\"" +
Esc(v) +
"\"" }; }
47static Entry I(
const char* k, int64 v) {
return Entry{ k,
"int", std::to_string((
long long)v) }; }
49int main(
int argc,
char** argv) {
50 std::string out = argc > 1 ? argv[1] :
"kotlin/fixtures";
51 std::vector<Fixture> fx;
53 fx.push_back({
"empty",
Base(),
true, {} });
61 fx.push_back({
"scalars", m,
true, {
S(
"Text",
"hello"),
I(
"Serial", 4242),
I(
"Negative", -7),
62 Entry{
"Gain",
"double",
"0.75" },
Entry{
"TCap",
"time", std::to_string((
unsigned long long)(
T0 + 123456)) } } });
66 for (
int i = 0; i < 320; i++) pcm[i] = (
char)(i < 256 ? i : 0);
70 m->
setString(
"Unicode",
"M\xC3\xADmir \xE2\x80\x93 \xC3\xA6\xC3\xB8\xC3\xA5 \xE2\x9C\x93");
71 fx.push_back({
"audio_frame", m,
true, {
S(
"PsyPost",
"AudioFrame"),
S(
"PsyDevice",
"phone-s25"),
72 Entry{
"pcm",
"data",
"\"" +
Hex(pcm, 320) +
"\"" },
73 S(
"Unicode",
"M\xC3\xADmir \xE2\x80\x93 \xC3\xA6\xC3\xB8\xC3\xA5 \xE2\x9C\x93") } });
102 fx.push_back({
"header_fields", m,
true, {
S(
"k",
"v") } });
110 fx.push_back({
"attached", m,
true, {
Entry{
"Attached",
"message",
"{\"Inner\":\"yes\",\"N\":3}" },
S(
"After",
"tail") } });
116 m->
setString(
"Long",
"a fairly long original value");
121 fx.push_back({
"overwrite_delete", m,
false, {
S(
"Long",
"short"),
I(
"Kept", 1) } });
123 std::string js =
"{\n \"generator\": \"kotlin/tools/gen_fixtures.cpp (C++ CMSDK)\",\n \"fixtures\": [\n";
124 for (
size_t i = 0; i < fx.size(); i++) {
126 std::string path = out +
"/" + fx[i].name +
".bin";
127 FILE* f = fopen(path.c_str(),
"wb");
128 if (!f) { fprintf(stderr,
"cannot write %s\n", path.c_str());
return 1; }
133 snprintf(hdr,
sizeof(hdr),
134 "\"header\": {\"size\":%u,\"time\":%llu,\"sendtime\":%llu,\"recvtime\":%llu,\"ttl\":%llu,"
135 "\"priority\":%u,\"policy\":%u,\"from\":%u,\"to\":%u,\"tag\":%u,\"status\":%u,\"reference\":%llu,"
136 "\"serial\":%llu,\"type\":\"%s\",\"contextchange\":\"%s\",\"userCount\":%u,\"userSize\":%u,"
137 "\"cenc\":%u,\"memid\":%llu,\"origin\":%u,\"destination\":%u,\"cyclecputime\":%u,\"cyclewalltime\":%u,"
138 "\"chaincputime\":%u,\"chainwalltime\":%u,\"chaincount\":%u,\"systemid\":%u}",
145 js +=
" {\"name\":\"" + fx[i].name +
"\",\"compact\":" + (fx[i].compact ?
"true" :
"false") +
",\n " + hdr +
",\n \"entries\": [";
146 for (
size_t e = 0; e < fx[i].entries.size(); e++)
147 js += (e ?
"," :
"") + std::string(
"\n {\"key\":\"") + fx[i].entries[e].key +
"\",\"kind\":\"" +
148 fx[i].entries[e].kind +
"\",\"value\":" + fx[i].entries[e].json +
"}";
149 js +=
"]}" + std::string(i + 1 < fx.size() ?
",\n" :
"\n");
150 printf(
"%-18s %5u bytes compact=%s\n", fx[i].name.c_str(), h->
size, fx[i].compact ?
"yes" :
"no");
154 FILE* f = fopen((out +
"/expected.json").c_str(),
"wb");
156 fwrite(js.data(), 1, js.size(), f);
The binary DataMessage container — the central data-exchange object of Psyclone/CMSDK.
Object type ids used to tag and verify every binary structure in CMSDK memory.
CMSDK time: µs-resolution 64-bit timestamps and the Time Mapping Constant (TMC).
The central Psyclone data container: a self-contained binary message with typed, named user entries.
bool setTime(const char *key, uint64 value)
setTime(const char* key, uint64 value)
bool setTTL(uint64 ttl)
setTTL(uint64 ttl)
bool deleteEntry(const char *key)
deleteEntry(const char* key)
bool setPriority(uint16 priority)
setPriority(uint16 priority)
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)
bool setTag(uint32 tag)
setTag(uint32 tag)
DataMessageHeader * data
Pointer to the message's flat memory block (header + user entries).
bool setStatus(uint16 status)
setStatus(uint16 status)
bool setAttachedMessage(const char *key, DataMessage *msg)
setAttachedMessage(const char* key, DataMessage* msg)
bool setRecvTime(uint64 time)
setRecvTime(uint64 time)
bool setFrom(uint32 from)
setFrom(uint32 from)
bool setTo(uint32 to)
setTo(uint32 to)
bool setCreatedTime(uint64 t)
setCreatedTime(uint64 t)
bool setReference(uint64 ref)
setReference(uint64 ref) Set message reference
bool setType(PsyType &type)
setType(PsyType &type)
bool setDouble(const char *key, double value)
setDouble(const char* key, double value)
bool setPolicy(uint8 policy)
setPolicy(uint8 policy)
bool setData(const char *key, const char *value, uint32 size)
setData(const char* key, const char* value, uint32 size)
bool setSerial(uint64 serial)
setSerial(uint64 serial)
bool setContextChange(PsyContext &context)
setContextChange(PsyContext& context)
bool setSendTime(uint64 time)
setSendTime(uint64 time)
static Entry S(const char *k, const char *v)
static Entry I(const char *k, int64 v)
static DataMessage * Base()
static std::string Esc(const std::string &s)
static std::string Hex(const char *d, uint32 n)
std::vector< Entry > entries
Hierarchical execution-context identifier.
bool fromString(const char *text)
Hierarchical message type identifier — the key used for publish/subscribe matching in Psyclone.
bool fromString(const char *text)
Parse dotted decimal notation (e.g.
std::string toString()
Render as dotted decimal notation, e.g. "2.201.3"; empty string if invalid.