/* A C program against libwai, as a C developer writes one (wai/quickstart/test/c-library.sh): * * cc -std=c11 hello.c $(pkg-config --cflags --libs wai) -o hello && ./hello * * It packs an envelope, reads its version, unpacks it and compares the payload byte for byte, * has a buffer that is no envelope refused with a reason, and reads the native sink's interface * version. It prints one line and exits 0, or says what failed and exits 1. */ #include #include #include #include static int fail(const char *what) { const char *why = wai_last_error(); fprintf(stderr, "hello: %s: %s\n", what, why ? why : "(no reason)"); return 1; } int main(void) { static const char manifest[] = "{\"wai\":\"1.0\",\"media\":\"text\",\"intent\":\"replicate\"," "\"model_requirement\":{\"capability\":\"wai.text.zstd\"}," "\"conditioning\":{\"kind\":\"zstd\"},\"target\":null}"; static const uint8_t payload[] = "a payload carried byte for byte"; static const uint8_t junk[] = "these bytes are no envelope"; struct wai_buffer_t env = {0}, man = {0}, pay = {0}, man2 = {0}, pay2 = {0}; if (wai_envelope_pack(manifest, payload, sizeof payload, &env) != WAI_OK) return fail("pack"); if (wai_envelope_detect_version(env.data, env.len) != 1) return fail("the packed envelope's version"); if (wai_envelope_unpack(env.data, env.len, &man, &pay) != WAI_OK) return fail("unpack"); if (pay.len != sizeof payload || memcmp(pay.data, payload, sizeof payload) != 0) { fprintf(stderr, "hello: the unpacked payload is not the packed one\n"); return 1; } if (man.len == 0 || memchr(man.data, '{', man.len) == NULL) { fprintf(stderr, "hello: the unpacked manifest is not a JSON object\n"); return 1; } if (wai_envelope_unpack(junk, sizeof junk - 1, &man2, &pay2) == WAI_OK) { fprintf(stderr, "hello: bytes that are no envelope were unpacked\n"); return 1; } /* The reason is valid until the next call, so it is copied. */ const char *last = wai_last_error(); if (last == NULL || last[0] == '\0') { fprintf(stderr, "hello: a refusal with no reason\n"); return 1; } char why[256]; snprintf(why, sizeof why, "%s", last); uint32_t abi = wai_sink_abi_version(); if (abi != WAI_SINK_ABI_VERSION) { fprintf(stderr, "hello: the native sink's interface is version %u, the header's %u\n", (unsigned)abi, (unsigned)WAI_SINK_ABI_VERSION); return 1; } printf("libwai: an envelope of %zu bytes packed and unpacked, its payload byte for byte; " "bytes that are no envelope refused (%s); the native sink's interface version %u\n", (size_t)env.len, why, (unsigned)abi); wai_buffer_free(env); wai_buffer_free(man); wai_buffer_free(pay); wai_buffer_free(man2); wai_buffer_free(pay2); return 0; }