// Generated by nim-ffi C codegen. Do not edit by hand. // // CBOR ABI (`_cbor`). Use this for callers that cross a process or machine // boundary (the request has to be serialized anyway) or any generic / cross- // language caller. Build the request with the FfiCbor helpers below — a CBOR map // whose keys are the Nim parameter names (listed per proc) — call the matching // `_cbor`, and decode the RET_OK response (a CBOR-encoded value; for // string-returning procs a CBOR text string) with ffi_decode_text. RET_ERR // delivers raw error text. For same-process callers, prefer the native `` // ABI in the companion .h header. #ifndef NIM_FFI_GEN_MY_TIMER_CBOR_H #define NIM_FFI_GEN_MY_TIMER_CBOR_H #include #include #include #include #ifdef __cplusplus extern "C" { #endif #ifndef NIM_FFI_RET_CODES #define NIM_FFI_RET_CODES #define RET_OK 0 #define RET_ERR 1 #define RET_MISSING_CALLBACK 2 #endif #ifndef NIM_FFI_CALLBACK_T #define NIM_FFI_CALLBACK_T typedef void (*FFICallBack)(int callerRet, const char *msg, size_t len, void *userData); #endif #ifndef NIM_FFI_CBOR_HELPERS #define NIM_FFI_CBOR_HELPERS // --- minimal growable CBOR request encoder -------------------------------- typedef struct { uint8_t *buf; size_t cap; size_t len; } FfiCbor; static inline FfiCbor ffi_cbor_new(void) { FfiCbor c; c.cap = 256; c.len = 0; c.buf = (uint8_t *)malloc(c.cap); return c; } static inline void ffi_cbor_free(FfiCbor *c) { free(c->buf); c->buf = NULL; } static inline void ffi_cbor_put(FfiCbor *c, uint8_t b) { if (c->len >= c->cap) { c->cap *= 2; c->buf = (uint8_t *)realloc(c->buf, c->cap); } c->buf[c->len++] = b; } static inline void ffi_cbor_head(FfiCbor *c, uint8_t major, uint64_t arg) { uint8_t mt = (uint8_t)(major << 5); if (arg < 24) { ffi_cbor_put(c, mt | (uint8_t)arg); } else if (arg <= 0xff) { ffi_cbor_put(c, mt | 24); ffi_cbor_put(c, (uint8_t)arg); } else if (arg <= 0xffff) { ffi_cbor_put(c, mt | 25); ffi_cbor_put(c, (uint8_t)(arg >> 8)); ffi_cbor_put(c, (uint8_t)arg); } else if (arg <= 0xffffffffULL) { ffi_cbor_put(c, mt | 26); ffi_cbor_put(c, (uint8_t)(arg >> 24)); ffi_cbor_put(c, (uint8_t)(arg >> 16)); ffi_cbor_put(c, (uint8_t)(arg >> 8)); ffi_cbor_put(c, (uint8_t)arg); } else { ffi_cbor_put(c, mt | 27); for (int s = 56; s >= 0; s -= 8) ffi_cbor_put(c, (uint8_t)(arg >> s)); } } static inline void ffi_cbor_map(FfiCbor *c, size_t n) { ffi_cbor_head(c, 5, n); } static inline void ffi_cbor_text(FfiCbor *c, const char *s) { size_t n = s ? strlen(s) : 0; ffi_cbor_head(c, 3, n); for (size_t i = 0; i < n; i++) ffi_cbor_put(c, (uint8_t)s[i]); } static inline void ffi_cbor_kv_text(FfiCbor *c, const char *k, const char *v) { ffi_cbor_text(c, k); ffi_cbor_text(c, v); } static inline void ffi_cbor_kv_uint(FfiCbor *c, const char *k, uint64_t v) { ffi_cbor_text(c, k); ffi_cbor_head(c, 0, v); } static inline void ffi_cbor_kv_int(FfiCbor *c, const char *k, int64_t v) { ffi_cbor_text(c, k); if (v >= 0) ffi_cbor_head(c, 0, (uint64_t)v); else ffi_cbor_head(c, 1, (uint64_t)(-(v + 1))); } // --- response decoding ----------------------------------------------------- // Zero-copy view of a top-level CBOR text string (the RET_OK payload). Sets // *out/*outLen to point INTO `data` (no allocation; valid only while `data` is) // and returns 1; returns 0 for a non-text-string payload. static inline int ffi_text_view(const uint8_t *data, size_t len, const uint8_t **out, size_t *outLen) { if (len < 1 || (data[0] >> 5) != 3) return 0; uint8_t info = data[0] & 0x1f; size_t p = 1; uint64_t slen = 0; if (info < 24) { slen = info; } else if (info == 24) { if (len < p + 1) return 0; slen = data[p++]; } else if (info == 25) { if (len < p + 2) return 0; slen = ((uint64_t)data[p] << 8) | data[p + 1]; p += 2; } else if (info == 26) { if (len < p + 4) return 0; slen = ((uint64_t)data[p] << 24) | ((uint64_t)data[p + 1] << 16) | ((uint64_t)data[p + 2] << 8) | data[p + 3]; p += 4; } else { return 0; } if (len < p + slen) return 0; *out = data + p; *outLen = (size_t)slen; return 1; } // Owning variant: malloc a NUL-terminated copy. NULL for a non-text payload. // Caller frees. static inline char *ffi_decode_text(const uint8_t *data, size_t len) { const uint8_t *view; size_t slen; if (!ffi_text_view(data, len, &view, &slen)) return NULL; char *out = (char *)malloc(slen + 1); if (!out) return NULL; memcpy(out, view, slen); out[slen] = '\0'; return out; } #endif // NIM_FFI_CBOR_HELPERS // request map keys: {"config": TimerConfig} void *my_timer_create_cbor(const uint8_t *reqCbor, size_t reqCborLen, FFICallBack callback, void *userData); // request map keys: {"req": EchoRequest} int my_timer_echo_cbor(void *ctx, FFICallBack callback, void *userData, const uint8_t *reqCbor, size_t reqCborLen); // request: empty CBOR map (0xA0) int my_timer_version_cbor(void *ctx, FFICallBack callback, void *userData, const uint8_t *reqCbor, size_t reqCborLen); // request map keys: {"req": ComplexRequest} int my_timer_complex_cbor(void *ctx, FFICallBack callback, void *userData, const uint8_t *reqCbor, size_t reqCborLen); // request map keys: {"job": JobSpec, "retry": RetryPolicy, "schedule": ScheduleConfig} int my_timer_schedule_cbor(void *ctx, FFICallBack callback, void *userData, const uint8_t *reqCbor, size_t reqCborLen); int my_timer_destroy(void *ctx); uint64_t my_timer_add_event_listener_cbor(void *ctx, const char *eventName, FFICallBack callback, void *userData); int my_timer_remove_event_listener(void *ctx, uint64_t listenerId); #ifdef __cplusplus } // extern "C" #endif #endif /* NIM_FFI_GEN_MY_TIMER_CBOR_H */