-Yet Another Codec.
-Yet another format for binary reprensentation of structured data.
-Its implementations are not heavily tested, project was just created.
+KEKS is compact, deterministic, concise and streaming binary
+serialisation format. It is aimed to be lightweight in terms of CPU,
+memory, storage and codec implementation size usage. It supports wide
+range of data types, making it able to transparently replace JSON.
--- /dev/null
+ckeks is C99 implementation of the KEKS codec.
+Look at doc/ for more information.
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include <string.h>
#include <time.h>
-#include <yac/err.h>
-#include <yac/items.h>
-#include <yac/pki/cer.h>
+#include <keks/err.h>
+#include <keks/items.h>
+#include <keks/pki/cer.h>
#include "../lib/mmap.h"
#include "../lib/uuid.h"
return EXIT_FAILURE;
}
const size_t cersLen = (size_t)argc - 1;
- struct YACCer *cers = calloc(cersLen, sizeof(struct YACCer));
+ struct KEKSCer *cers = calloc(cersLen, sizeof(struct KEKSCer));
assert(cers != NULL);
char *failReason = NULL;
for (int i = 1; i < argc; i++) {
fputs(argv[i], stdout);
fputs(":\t", stdout);
size_t off = 0;
- enum YACErr err = YACCerParse(&(cers[i - 1]), &off, &failReason, buf, len);
- if (err != YACErrNo) {
+ enum KEKSErr err = KEKSCerParse(&(cers[i - 1]), &off, &failReason, buf, len);
+ if (err != KEKSErrNo) {
fprintf(stderr, "%s: %s\n", argv[i], failReason);
return EXIT_FAILURE;
}
return EXIT_FAILURE;
}
- struct YACCerSigVerifier sigVerifiers[] = {
+ struct KEKSCerSigVerifier sigVerifiers[] = {
{.algo = "ed25519-blake2b", .func = ed25519blake2bSignatureVerifier},
{.algo = "gost3410-256A", .func = gost3410SignatureVerifier},
{.algo = "gost3410-512C", .func = gost3410SignatureVerifier},
{.algo = NULL},
};
- struct YACCerVerifyOpts opts = {.t = now, .sigVerifiers = sigVerifiers};
+ struct KEKSCerVerifyOpts opts = {.t = now, .sigVerifiers = sigVerifiers};
- struct YACCer *toVerify = &(cers[0]);
- struct YACCer *verifier = NULL;
+ struct KEKSCer *toVerify = &(cers[0]);
+ struct KEKSCer *verifier = NULL;
for (;;) {
fputs("verifying ", stdout);
UUIDPrint(toVerify->cid);
fputs(": ", stdout);
- if (!YACCerVerify(&failReason, &verifier, toVerify, cers, cersLen, opts)) {
+ if (!KEKSCerVerify(&failReason, &verifier, toVerify, cers, cersLen, opts)) {
fputs(failReason, stdout);
fputs("\n", stdout);
return EXIT_FAILURE;
break;
}
{
- size_t ku = YACItemsGetByKey(&(verifier->items), verifier->load, "ku");
- if ((ku == 0) || YACItemsGetByKey(&(verifier->items), ku, "ca") == 0) {
+ size_t ku = KEKSItemsGetByKey(&(verifier->items), verifier->load, "ku");
+ if ((ku == 0) || KEKSItemsGetByKey(&(verifier->items), ku, "ca") == 0) {
fputs("no ca ku\n", stdout);
return EXIT_FAILURE;
}
$CFLAGS -I$PREFIX/include \
-o $3 $2.c $deps \
$LDFLAGS $GCL3_LDFLAGS $MONOCYPHER_LDFLAGS -L$PREFIX/lib \
- -lyac -lyacpki $GCL3_LDLIBS $MONOCYPHER_LDLIBS -static
+ -lkeks -lkekspki $GCL3_LDLIBS $MONOCYPHER_LDLIBS -static
-#ifndef YAC_VERIFIER_ED25519_BLAKE2B_H
-#define YAC_VERIFIER_ED25519_BLAKE2B_H
+#ifndef KEKS_VERIFIER_ED25519_BLAKE2B_H
+#define KEKS_VERIFIER_ED25519_BLAKE2B_H
#include <stdbool.h>
#include <stdlib.h>
const unsigned char *data,
const size_t dataLen);
-#endif // YAC_VERIFIER_ED25519_BLAKE2B_H
+#endif // KEKS_VERIFIER_ED25519_BLAKE2B_H
-#ifndef YAC_VERIFIER_GOST3410_H
-#define YAC_VERIFIER_GOST3410_H
+#ifndef KEKS_VERIFIER_GOST3410_H
+#define KEKS_VERIFIER_GOST3410_H
#include <stdbool.h>
#include <stdlib.h>
const unsigned char *data,
const size_t dataLen);
-#endif // YAC_VERIFIER_GOST3410_H
+#endif // KEKS_VERIFIER_GOST3410_H
#include <stdlib.h>
#include <string.h>
-#include <yac/err.h>
-#include <yac/items.h>
+#include <keks/err.h>
+#include <keks/items.h>
#include "../lib/mmap.h"
if (!Mmap(&buf, &len, argv[1])) {
exit(EXIT_FAILURE);
}
- struct YACItems items;
- enum YACErr err = YACItemsInit(&items);
- if (err != YACErrNo) {
+ struct KEKSItems items;
+ enum KEKSErr err = KEKSItemsInit(&items);
+ if (err != KEKSErrNo) {
return EXIT_FAILURE;
}
size_t off = 0;
- err = YACItemsParse(&items, &off, buf, len);
- if (err != YACErrNo) {
+ err = KEKSItemsParse(&items, &off, buf, len);
+ if (err != KEKSErrNo) {
return EXIT_SUCCESS;
}
{
unsigned char *dst = malloc(len);
assert(dst != NULL);
off = 0;
- assert(YACItemsEncode(&items, 0, &off, dst, len));
+ assert(KEKSItemsEncode(&items, 0, &off, dst, len));
assert(off == len - tailLen);
assert(memcmp(dst, buf, len - tailLen) == 0);
}
CFLAGS=$(cat ../../conf/cflags)
LDFLAGS=$(cat ../../conf/ldflags)
read PREFIX <../../conf/prefix
-$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $deps $LDFLAGS -L$PREFIX/lib -lyac -lm -static
+$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $deps $LDFLAGS -L$PREFIX/lib -lkeks -lm -static
-#ifndef YAC_HEX_H
-#define YAC_HEX_H
+#ifndef KEKS_HEX_H
+#define KEKS_HEX_H
#include <stdlib.h>
char *
HexEnc(const unsigned char *src, const size_t srcLen);
-#endif // YAC_HEX_H
+#endif // KEKS_HEX_H
-#ifndef YAC_MMAP_H
-#define YAC_MMAP_H
+#ifndef KEKS_MMAP_H
+#define KEKS_MMAP_H
#include <stdbool.h>
#include <stdlib.h>
bool
Mmap(unsigned char **buf, size_t *len, const char *path);
-#endif // YAC_MMAP_H
+#endif // KEKS_MMAP_H
#include <stdlib.h>
#include <time.h>
-#include <yac/dectai.h>
-#include <yac/err.h>
+#include <keks/dectai.h>
+#include <keks/err.h>
#include "hex.h"
#include "printai.h"
-enum YACErr
+enum KEKSErr
PrintTAI64(const unsigned char *buf, const size_t len)
{
char *hex = NULL;
hex = HexEnc(buf, len);
fprintf(stdout, "TAI64NA(%s)\n", hex);
free(hex);
- return YACErrNo;
+ return KEKSErrNo;
}
switch (len) {
case 8:
break;
}
struct timespec tv;
- enum YACErr err = YACTAI64ToTimespec(&tv, buf, len);
+ enum KEKSErr err = KEKSTAI64ToTimespec(&tv, buf, len);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
switch (err) {
#pragma clang diagnostic pop
- case YACErrNo:
+ case KEKSErrNo:
break;
- case YACErrTAI64InPast:
+ case KEKSErrTAI64InPast:
hex = HexEnc(buf, len);
fprintf(stdout, "in past: %s)\n", hex);
free(hex);
- return YACErrNo;
+ return KEKSErrNo;
default:
return err;
}
- err = YACTimespecToUTC(&tv);
+ err = KEKSTimespecToUTC(&tv);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
switch (err) {
#pragma clang diagnostic pop
- case YACErrNo:
+ case KEKSErrNo:
break;
- case YACErrTAI64InPast:
+ case KEKSErrTAI64InPast:
hex = HexEnc(buf, len);
fprintf(stdout, "in past: %s)\n", hex);
free(hex);
- return YACErrNo;
+ return KEKSErrNo;
default:
return err;
}
hex = HexEnc(buf, len);
fprintf(stdout, "unrepresentable: %s)\n", hex);
free(hex);
- return YACErrNo;
+ return KEKSErrNo;
}
{
char human[20] = {0};
fprintf(stdout, ".%09zu", tv.tv_nsec);
}
fputs(")\n", stdout);
- return YACErrNo;
+ return KEKSErrNo;
}
--- /dev/null
+#ifndef KEKS_PRINTAI_H
+#define KEKS_PRINTAI_H
+
+#include <stddef.h>
+
+#include <keks/err.h>
+
+enum KEKSErr
+PrintTAI64(const unsigned char *buf, const size_t len);
+
+#endif // KEKS_PRINTAI_H
--- /dev/null
+#ifndef KEKS_UUID_H
+#define KEKS_UUID_H
+
+void
+UUIDPrint(const unsigned char *buf);
+
+#endif // KEKS_UUID_H
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include <string.h>
#include <unistd.h>
-#include <yac/dec.h>
-#include <yac/err.h>
-#include <yac/items.h>
+#include <keks/dec.h>
+#include <keks/err.h>
+#include <keks/items.h>
#include "../lib/hex.h"
#include "../lib/mmap.h"
exit(EXIT_FAILURE);
}
-static enum YACErr
+static enum KEKSErr
printer( // NOLINT(misc-no-recursion)
- const struct YACItems *items,
+ const struct KEKSItems *items,
size_t idx,
size_t indent,
const bool inList,
items->offsets[idx],
NoColour ? "" : ColourReset);
}
- struct YACItem *item = &(items->list[idx]);
+ struct KEKSItem *item = &(items->list[idx]);
printIndent(indent);
if (inList) {
fprintf(
NoColour ? "" : ColourReset);
}
char *str = NULL;
- enum YACErr err = YACErrInvalid;
+ enum KEKSErr err = KEKSErrInvalid;
switch (item->atom.typ) {
- case YACItemInvalid:
+ case KEKSItemInvalid:
fputs("INVALID\n", stdout);
break;
- case YACItemNIL:
+ case KEKSItemNIL:
fputs("NIL\n", stdout);
break;
- case YACItemFalse:
+ case KEKSItemFalse:
fputs("FALSE\n", stdout);
break;
- case YACItemTrue:
+ case KEKSItemTrue:
fputs("TRUE\n", stdout);
break;
- case YACItemUUID:
+ case KEKSItemUUID:
UUIDPrint(item->atom.v.uuid);
fputs("\n", stdout);
break;
- case YACItemPint:
+ case KEKSItemPint:
fprintf(stdout, "%zu\n", item->atom.v.pint);
break;
- case YACItemNint:
+ case KEKSItemNint:
fprintf(stdout, "%zd\n", item->atom.v.nint);
break;
- case YACItemList: {
+ case KEKSItemList: {
fprintf(
stdout,
"[ %s%zd%s\n",
listIdx = 0;
while (idx != 0) {
err = printer(items, idx, indent, true, listIdx, NULL);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
idx = items->list[idx].next;
fputs("]\n", stdout);
break;
}
- case YACItemMap: {
+ case KEKSItemMap: {
fprintf(
stdout,
"{ %s%zd%s\n",
idx = items->list[idx].next;
err = printer(items, idx, indent, false, 0, str);
free(str);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
idx = items->list[idx].next;
fputs("}\n", stdout);
break;
}
- case YACItemBlob:
+ case KEKSItemBlob:
fprintf(
stdout,
"BLOB[ %s%zu l=%zu%s\n",
listIdx = 0;
while (idx != 0) {
err = printer(items, idx, indent, true, listIdx, NULL);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
idx = items->list[idx].next;
printIndent(indent);
fputs("]\n", stdout);
break;
- case YACItemFloat:
+ case KEKSItemFloat:
fputs("FLOAT: TODO\n", stdout);
break;
- case YACItemTAI64: {
+ case KEKSItemTAI64: {
err = PrintTAI64(item->atom.v.str.ptr, item->atom.v.str.len);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
break;
}
- case YACItemBin: {
+ case KEKSItemBin: {
const size_t l =
(item->atom.v.str.len > MaxStrLen) ? MaxStrLen : item->atom.v.str.len;
str = HexEnc(item->atom.v.str.ptr, l);
free(str);
break;
}
- case YACItemStr: {
+ case KEKSItemStr: {
const size_t l =
(item->atom.v.str.len > MaxStrLen) ? MaxStrLen : item->atom.v.str.len;
str = strndup((const char *)item->atom.v.str.ptr, l);
free(str);
break;
}
- case YACItemRaw:
+ case KEKSItemRaw:
str = HexEnc(item->atom.v.str.ptr, item->atom.v.str.len);
fprintf(
stdout, "(t=0x%X l=%zu v=%s)\n", item->atom.tag, item->atom.v.str.len, str);
free(str);
break;
- case YACItemEOC:
+ case KEKSItemEOC:
default:
fprintf(stderr, "unknown atom\n");
return EXIT_FAILURE;
}
- return YACErrNo;
+ return KEKSErrNo;
}
int
OffDigits = NoOffsets ? -1 : (int)(1 + floor(log10((double)len)));
snprintf(OffFmt, sizeof OffFmt, "%%s%%0%dzd%%s ", OffDigits);
- struct YACItems items;
- enum YACErr err = YACItemsInit(&items);
- if (err != YACErrNo) {
- fprintf(stderr, "err: %s\n", YACErr2Str(err));
+ struct KEKSItems items;
+ enum KEKSErr err = KEKSItemsInit(&items);
+ if (err != KEKSErrNo) {
+ fprintf(stderr, "err: %s\n", KEKSErr2Str(err));
return EXIT_FAILURE;
}
if (NoOffsets) {
items.offsets = NULL;
}
size_t off = 0;
- err = YACItemsParse(&items, &off, buf, len);
- if (err != YACErrNo) {
- fprintf(stderr, "err: %s\n", YACErr2Str(err));
+ err = KEKSItemsParse(&items, &off, buf, len);
+ if (err != KEKSErrNo) {
+ fprintf(stderr, "err: %s\n", KEKSErr2Str(err));
return EXIT_FAILURE;
}
err = printer(&items, 0, 0, false, 0, NULL);
- if (err != YACErrNo) {
- fprintf(stderr, "err: %s\n", YACErr2Str(err));
+ if (err != KEKSErrNo) {
+ fprintf(stderr, "err: %s\n", KEKSErr2Str(err));
return EXIT_FAILURE;
}
if (!noTotals) {
printf(
"items: %zu size: %zu\n",
items.len,
- items.len * (sizeof(struct YACItem) + (NoOffsets ? 0 : sizeof(size_t))));
+ items.len * (sizeof(struct KEKSItem) + (NoOffsets ? 0 : sizeof(size_t))));
}
if (off < len) {
char *hex = HexEnc(buf + off, len - off);
assert(dst != NULL);
size_t lenExpected = off;
off = 0;
- assert(YACItemsEncode(&items, 0, &off, dst, len));
+ assert(KEKSItemsEncode(&items, 0, &off, dst, len));
assert(off == lenExpected);
assert(memcmp(dst, buf, lenExpected) == 0);
}
CFLAGS=$(cat ../../conf/cflags)
LDFLAGS=$(cat ../../conf/ldflags)
read PREFIX <../../conf/prefix
-$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $deps $LDFLAGS -L$PREFIX/lib -lyac -lm
+$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $deps $LDFLAGS -L$PREFIX/lib -lkeks -lm
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include <stdlib.h>
#include <string.h>
-#include <yac/dec.h>
-#include <yac/err.h>
-#include <yac/iter.h>
+#include <keks/dec.h>
+#include <keks/err.h>
+#include <keks/iter.h>
#include "../lib/hex.h"
#include "../lib/mmap.h"
int indent;
};
-static enum YACErr
+static enum KEKSErr
myCb(
const unsigned char *key,
const size_t keyLen,
const bool inList,
const size_t idx,
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len)
{
struct CbState *state = (struct CbState *)(cbState);
- if ((atom->typ) == YACItemEOC) {
+ if ((atom->typ) == KEKSItemEOC) {
state->indent--;
assert(state->indent >= 0);
}
}
char *hex = NULL;
- enum YACErr err = YACErrInvalid;
+ enum KEKSErr err = KEKSErrInvalid;
switch (atom->typ) {
- case YACItemInvalid:
+ case KEKSItemInvalid:
fputs("INVALID\n", stdout);
break;
- case YACItemEOC:
+ case KEKSItemEOC:
break;
- case YACItemNIL:
+ case KEKSItemNIL:
fputs("NIL\n", stdout);
break;
- case YACItemFalse:
+ case KEKSItemFalse:
fputs("FALSE\n", stdout);
break;
- case YACItemTrue:
+ case KEKSItemTrue:
fputs("TRUE\n", stdout);
break;
- case YACItemUUID:
+ case KEKSItemUUID:
UUIDPrint(atom->v.uuid);
fputs("\n", stdout);
break;
- case YACItemPint:
+ case KEKSItemPint:
fprintf(stdout, "%zu\n", atom->v.pint);
break;
- case YACItemNint:
+ case KEKSItemNint:
fprintf(stdout, "%zd\n", atom->v.nint);
break;
- case YACItemList:
+ case KEKSItemList:
fputs("[\n", stdout);
state->indent++;
- err = YACIterList(cbState, atom, off, buf, len, myCb);
- if (err != YACErrNo) {
+ err = KEKSIterList(cbState, atom, off, buf, len, myCb);
+ if (err != KEKSErrNo) {
return err;
}
fputs("]\n", stdout);
break;
- case YACItemMap:
+ case KEKSItemMap:
fputs("{\n", stdout);
state->indent++;
- err = YACIterMap(cbState, atom, off, buf, len, myCb);
- if (err != YACErrNo) {
+ err = KEKSIterMap(cbState, atom, off, buf, len, myCb);
+ if (err != KEKSErrNo) {
return err;
}
fputs("}\n", stdout);
break;
- case YACItemBlob:
+ case KEKSItemBlob:
printf("BLOB(l=%zu\n", atom->v.blob.chunkLen);
state->indent++;
- err = YACIterBlob(cbState, atom, off, buf, len, myCb);
- if (err != YACErrNo) {
+ err = KEKSIterBlob(cbState, atom, off, buf, len, myCb);
+ if (err != KEKSErrNo) {
return err;
}
fputs(")\n", stdout);
break;
- case YACItemFloat:
+ case KEKSItemFloat:
fputs("FLOAT: TODO\n", stdout);
break;
- case YACItemTAI64:
+ case KEKSItemTAI64:
err = PrintTAI64(atom->v.str.ptr, atom->v.str.len);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
break;
- case YACItemBin: {
+ case KEKSItemBin: {
const size_t l = (atom->v.str.len > maxStrLen) ? maxStrLen : atom->v.str.len;
hex = HexEnc(atom->v.str.ptr, l);
fprintf(
free(hex);
break;
}
- case YACItemStr: {
+ case KEKSItemStr: {
const size_t l = (atom->v.str.len > maxStrLen) ? maxStrLen : atom->v.str.len;
hex = strndup((const char *)(atom->v.str.ptr), l);
fprintf(stdout, "\"%s%s\"\n", hex, (atom->v.str.len > maxStrLen) ? "..." : "");
free(hex);
break;
}
- case YACItemRaw:
+ case KEKSItemRaw:
hex = HexEnc(atom->v.str.ptr, atom->v.str.len);
fprintf(stdout, "(t=0x%X l=%zu v=%s)\n", atom->tag, atom->v.str.len, hex);
free(hex);
fprintf(stderr, "unknown atom\n");
return EXIT_FAILURE;
}
- return YACErrNo;
+ return KEKSErrNo;
}
int
if (!Mmap(&buf, &len, argv[1])) {
exit(EXIT_FAILURE);
}
- struct YACAtom atom;
- memset(&atom, 0, sizeof(struct YACAtom));
+ struct KEKSAtom atom;
+ memset(&atom, 0, sizeof(struct KEKSAtom));
size_t off = 0;
size_t got = 0;
- enum YACErr err = YACAtomDecode(&got, &atom, buf, len);
- if (err != YACErrNo) {
- fprintf(stderr, "err: %s\n", YACErr2Str(err));
+ enum KEKSErr err = KEKSAtomDecode(&got, &atom, buf, len);
+ if (err != KEKSErrNo) {
+ fprintf(stderr, "err: %s\n", KEKSErr2Str(err));
return EXIT_FAILURE;
}
off += got;
struct CbState cbState = {.indent = 0};
err = myCb(NULL, 0, false, 0, &cbState, &atom, &off, buf, len);
- if (err != YACErrNo) {
- fprintf(stderr, "err: %s\n", YACErr2Str(err));
+ if (err != KEKSErrNo) {
+ fprintf(stderr, "err: %s\n", KEKSErr2Str(err));
return EXIT_FAILURE;
}
assert(cbState.indent == 0);
CFLAGS=$(cat ../../conf/cflags)
LDFLAGS=$(cat ../../conf/ldflags)
read PREFIX <../../conf/prefix
-$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $deps $LDFLAGS -L$PREFIX/lib -lyac
+$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $deps $LDFLAGS -L$PREFIX/lib -lkeks
--- /dev/null
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <keks/atoms.h>
+#include <keks/enc.h>
+#include <keks/enctai.h>
+
+static size_t Off = 0;
+static size_t Got = 0;
+
+static void
+adder(const bool ok)
+{
+ assert(ok);
+ Off += Got;
+}
+
+int
+main(void)
+{
+ const size_t len = (size_t)68 * (uint16_t)1024;
+ unsigned char *buf = malloc(len);
+ assert(buf != NULL);
+ unsigned char *bin = malloc((uint32_t)1 << (uint8_t)17);
+ assert(bin != NULL);
+
+ adder(KEKSAtomMapEncode(&Got, buf + Off, len - Off)); // .
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"nil", 3));
+ adder(KEKSAtomNILEncode(&Got, buf + Off, len - Off));
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"str", 3));
+ adder(KEKSAtomMapEncode(&Got, buf + Off, len - Off)); // .str
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"bin", 3));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .str.bin
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, (const unsigned char *)"", 0));
+ memset(bin, '0', 60);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 60));
+ memset(bin, '1', 61);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 61));
+ memset(bin, '2', 255);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 255));
+ memset(bin, 'A', 61 + 255);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 61 + 255));
+ memset(bin, 'B', 62 + 255);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 62 + 255));
+ memset(bin, '3', 1024);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 1024));
+ memset(bin, '4', 63 + 255 + 65535 + 1);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 63 + 255 + 65535 + 1));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .str.bin
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"utf8", 4));
+ adder(KEKSAtomStrEncode(
+ &Got, buf + Off, len - Off, (const unsigned char *)"Đ¿Ñ€Đ¸Đ²ĐµÑ‚ Đ¼Đ¸Ñ€", 19));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .str
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"blob", 4));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .blob
+
+ adder(KEKSAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.0
+ memset(bin, '5', 1);
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 1));
+
+ adder(KEKSAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.1
+ memset(bin, '6', 12);
+ adder(KEKSAtomChunkEncode(&Got, buf + Off, len - Off, bin, 12));
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, NULL, 0));
+
+ adder(KEKSAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.2
+ memset(bin, '7', 12);
+ adder(KEKSAtomChunkEncode(&Got, buf + Off, len - Off, bin, 12));
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, bin, 1));
+
+ adder(KEKSAtomBlobEncode(&Got, buf + Off, len - Off, 5)); // .blob.3
+ adder(KEKSAtomChunkEncode(
+ &Got, buf + Off, len - Off, (const unsigned char *)"12345", 5));
+ adder(KEKSAtomChunkEncode(
+ &Got, buf + Off, len - Off, (const unsigned char *)"67890", 5));
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, (const unsigned char *)"-", 1));
+
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .blob
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"bool", 4));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .bool
+ adder(KEKSAtomBoolEncode(&Got, buf + Off, len - Off, true));
+ adder(KEKSAtomBoolEncode(&Got, buf + Off, len - Off, false));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .bool
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"ints", 4));
+ adder(KEKSAtomMapEncode(&Got, buf + Off, len - Off)); // .ints
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"neg", 3));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .ints.neg
+ adder(KEKSAtomSintEncode(&Got, buf + Off, len - Off, -1));
+ adder(KEKSAtomSintEncode(&Got, buf + Off, len - Off, -2));
+ adder(KEKSAtomSintEncode(&Got, buf + Off, len - Off, -32));
+ adder(KEKSAtomSintEncode(&Got, buf + Off, len - Off, -33));
+ adder(KEKSAtomSintEncode(&Got, buf + Off, len - Off, -123));
+ adder(KEKSAtomSintEncode(&Got, buf + Off, len - Off, -1234));
+ adder(KEKSAtomSintEncode(&Got, buf + Off, len - Off, -12345678));
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomNint,
+ (const unsigned char *)"\x8A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ 11));
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomNint,
+ (const unsigned char
+ *)"\x91\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 18));
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomNint,
+ (const unsigned char
+ *)"\xBE\x00\xA1\xE5\xA4\x61\x28\x03\x41\x85\x6D\x4A\xD9\x08\xA6\x9E\xA5\xF3\xCC\xC1\x0C\x78\x82\x14\x2B\xB7\xD8\x01\xCC\x38\x0F\x26\xB6\xB4\xD6\x96\x32\x02\x4E\xE5\x21\xF8\xCF\xAF\xB4\x43\xD4\x9A\x2A\x3D\x0C\xC7\x3B\xB4\x75\x7E\x88\x2F\x53\x96\xED\x30\x2B\x41\x82\x10\xD0\xD4\x9D\x71\xBE\x86\xCA\x69\x9C\xF5\xEE\x3B\xD6\xD5\x7E\xD6\x58\xE6\x93\x16\x22\x96\x44\xBA\x65\x0C\x92\xD7\xF0\xD4\xDB\x29\xC3\xAD\x1D\xFA\x99\x79\x16\x6F\x4C\x6E\x79\x56\x1A\x58\xF8\xE2\xC6\x3D\x08\xDF\x4E\x22\x46\xED\x1F\x64\xD2\xD6\x13\xA1\x9D\x8C\x9A\x68\x70\xE6\x18\x8E\x2F\x3A\xD4\x0C\x03\x8F\xDA\x30\x45\x2F\x8D\xDF\xCD\x21\x2A\x6A\x97\x4B\xC2\x5E\xC6\xA0\x56\x4C\x66\xA7\xD2\x87\x50\xFF\x9D\xB4\x58\xB7\x44\x41\xE4\x9E\xE5\xE8\x2D\xBF\x49\x74\xD6\x45\x67\x8E\x0A\xD0\x31\xF9\x7A\xAB\xA8\x55\x45\x1E\xEF\x17\xA8\x9B\x42\x82\x1E\x53\x08\x16\xDD\x57\x93\xA8\x3B\x7A\x82\xE8\xED\xE8\x1E\x7F\x33\x95\x69\x1F\x76\x17\x84\xF8\xBC\x62\x79\x61\xCD\x40\x84\x5E\xE9\x08\xA4\x0B\x9D\x1F\x01\x92\x7B\x38\xEB\x1A\x7D\x4E\xFD\x60\xDB\x09\x44\xF7\xEC\x1B\x83\x2B\x7E\x6E\xB1\x83\x3F\x9A\x35\x15\x76\xAD\x5D\xE5\x71\xFA\xE8\x86\x5D\xA7\x51\x4F\x06\xB0\xFB\xF3\x8C\x1F\x2A\x85\x38\xF5\xD3\x8B\x4E\x18\x00\x1C\xCB\xB9\xDD\xCB\x48\x85\x30\xF6\x08\x6D\x14\x74\x4D\x8B\x56\x72\x16\x6E\x48\xE9\xEF\x93\x77\x25\x75\xDB\x66\xB6\xF2\x57\xC6\xFF\xAD\x6E\x2C\x29\x15\x10\xC5\xED\x02\xE1\xA8\xB2\x4B\x44\xEC\x1E\x2A\x91\x68\x62\x38\xE8\xDE\xFD\x18\xC0\x19\x98\x63\x4A\x50\x76\xA6\xB7\xF8\x5F\xC8\x1A\x1D\x61\xA1\x5B\x2C\x52\x8D\xFA\x08\x2C\xE3\xE3\xE2\xCA\x64\x9A\xC0\x48\x17\xEC\x5C\x12\x3E\x0B\x76\x1A\xB1\x03\xF7\x80\xC0\x14\xF0\x21\xBB\xEB\x7E\xA3\xB8\x6E\x0C\xA1\xC8\x33\xE3\x8E\xF5\xC8\x97\xA6\xD7\xE1\xF4\xA2\x39\x8C\x49\x0B\x3D\x65\xE2\xF4\x5C\x7F\xAE\x40\x2D\x1D\xF1\x69\x8B\x6F\xDD\xB1\x85\x48\x16\x64\x87\x1C\x26\x64\xBF\xD1\x68\x6B\x2B\x33\x72\x78\x3F\x18\x56\xF6\x24\x7A\x3F\x84\x37\xA2\x81\x8F\x68\xB7\xC4\xEA\x13\xA5\xF5\x7B\x73\xC7\x28\x70\xB6\x84\x04\x5F\x14",
+ 481));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.neg
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"pos", 3));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .ints.pos
+ adder(KEKSAtomUintEncode(&Got, buf + Off, len - Off, 0));
+ adder(KEKSAtomUintEncode(&Got, buf + Off, len - Off, 1));
+ adder(KEKSAtomUintEncode(&Got, buf + Off, len - Off, 31));
+ adder(KEKSAtomUintEncode(&Got, buf + Off, len - Off, 32));
+ adder(KEKSAtomUintEncode(&Got, buf + Off, len - Off, 123));
+ adder(KEKSAtomUintEncode(&Got, buf + Off, len - Off, 1234));
+ adder(KEKSAtomUintEncode(&Got, buf + Off, len - Off, 12345678));
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomPint,
+ (const unsigned char *)"\x8B\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 12));
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomPint,
+ (const unsigned char
+ *)"\x91\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 18));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.pos
+
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints
+
+ adder(
+ KEKSAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"uuid", 4));
+ adder(KEKSAtomUUIDEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ (const unsigned char
+ *)"\x0e\x87\x5e\x3f\xd3\x85\x49\xeb\x87\xb4\xbe\x42\xd6\x41\xc3\x67"));
+
+ adder(KEKSAtomStrEncode(
+ &Got, buf + Off, len - Off, (const unsigned char *)"dates", 5));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .dates
+ {
+ struct timespec ts;
+ ts.tv_sec = 1234567890;
+ assert(KEKSTimespecToTAI(&ts));
+ unsigned char tai[12] = {0};
+ assert(KEKSTimespecToTAI64(tai, &ts));
+ adder(KEKSAtomTAI64Encode(&Got, buf + Off, len - Off, tai, 8));
+
+ ts.tv_nsec = 456000;
+ assert(KEKSTimespecToTAI64(tai, &ts));
+ adder(KEKSAtomTAI64Encode(&Got, buf + Off, len - Off, tai, 12));
+
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomTAI64N,
+ (const unsigned char *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55",
+ 12));
+
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomTAI64NA,
+ (const unsigned char
+ *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55\x07\x5B\xCD\x15",
+ 16));
+ }
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .dates
+
+ adder(KEKSAtomStrEncode(
+ &Got, buf + Off, len - Off, (const unsigned char *)"floats", 6));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .floats
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomFloat32,
+ (const unsigned char *)"\x01\x02\x03\x04",
+ 4));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .floats
+
+ adder(KEKSAtomStrEncode(
+ &Got, buf + Off, len - Off, (const unsigned char *)"empties", 7));
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off)); // .empties
+ adder(KEKSAtomListEncode(&Got, buf + Off, len - Off));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off));
+ adder(KEKSAtomMapEncode(&Got, buf + Off, len - Off));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off));
+ adder(KEKSAtomBlobEncode(&Got, buf + Off, len - Off, 123));
+ adder(KEKSAtomBinEncode(&Got, buf + Off, len - Off, NULL, 0));
+ memset(bin, '\x00', 16);
+ adder(KEKSAtomUUIDEncode(&Got, buf + Off, len - Off, bin));
+ adder(KEKSAtomRawEncode(
+ &Got,
+ buf + Off,
+ len - Off,
+ KEKSAtomTAI64,
+ (const unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00",
+ 8));
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .empties
+
+ adder(KEKSAtomEOCEncode(&Got, buf + Off, len - Off)); // .
+
+ free(bin);
+ assert(write(STDOUT_FILENO, buf, Off) == (ssize_t)Off);
+ free(buf);
+
+ return EXIT_SUCCESS;
+}
CFLAGS=$(cat ../../conf/cflags)
LDFLAGS=$(cat ../../conf/ldflags)
read PREFIX <../../conf/prefix
-$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $LDFLAGS -L$PREFIX/lib -lyac
+$CC $CFLAGS -I$PREFIX/include -o $3 $2.c $LDFLAGS -L$PREFIX/lib -lkeks
/build/
-/cyac.info
+/ckeks.info
/docstringer.log
--- /dev/null
+@node Atom
+@cindex atom
+@unnumbered Atom
+
+@anchor{KEKSAtom}
+@DOCSTRING KEKSAtom@
+
+@anchor{KEKSItemType}
+@DOCSTRING KEKSItemType@
+
+@DOCSTRING KEKSAtomDecode@
+
+@DOCSTRING KEKSAtomEOCEncode@
+@anchor{KEKSAtomNILEncode}
+@DOCSTRING KEKSAtomNILEncode@
+@DOCSTRING KEKSAtomBoolEncode@
+@DOCSTRING KEKSAtomUUIDEncode@
+@DOCSTRING KEKSAtomUintEncode@
+@DOCSTRING KEKSAtomSintEncode@
+@DOCSTRING KEKSAtomListEncode@
+@DOCSTRING KEKSAtomMapEncode@
+@DOCSTRING KEKSAtomBlobEncode@
+@DOCSTRING KEKSAtomStrEncode@
+@anchor{KEKSAtomBinEncode}
+@DOCSTRING KEKSAtomBinEncode@
+@anchor{KEKSAtomChunkEncode}
+@DOCSTRING KEKSAtomChunkEncode@
+@DOCSTRING KEKSAtomTAI64Encode@
+@DOCSTRING KEKSAtomRawEncode@
#!/bin/sh -e
cd "$(dirname "$(realpath -- "$0")")"
-rm -fr build cyac.info docstringer.log
+rm -fr build ckeks.info docstringer.log
@pindex cmd/test-vector
@item cmd/test-vector
Example program that forms the same test vector as
-@file{tyac/test-vector.tcl} in a streaming way.
+@file{tkeks/test-vector.tcl} in a streaming way.
@pindex cmd/print-itered
@item cmd/test-itered
@cindex errors
@unnumbered Errors
-@DOCSTRING YACErr@
+@DOCSTRING KEKSErr@
-@DOCSTRING YACErr2Str@
+@DOCSTRING KEKSErr2Str@
\input texinfo
-@settitle cyac
+@settitle ckeks
@copying
Copyright @copyright{} 2024-2025 @email{stargrave@@stargrave.org, Sergey Matveev}
@end copying
@node Top
-@top cyac
+@top ckeks
-C99 implementation of the @url{http://www.yac.cypherpunks.su, YAC}
+C99 implementation of the @url{http://www.keks.cypherpunks.su, KEKS}
codec.
@itemize
@item No TAI64NA support.
@end itemize
-cyac is
+ckeks is
@url{https://www.gnu.org/philosophy/pragmatic.html, copylefted}
@url{https://www.gnu.org/philosophy/free-sw.html, free software}
licenced under @url{https://www.gnu.org/licenses/lgpl-3.0.html, GNU LGPLv3}.
--- /dev/null
+@node Items
+@cindex items
+@unnumbered Items
+
+Streamable decoding by one atom is not very convenient in many cases.
+There is ability to recursively decode the whole structures.
+
+@anchor{KEKSItems}
+@DOCSTRING KEKSItems@
+@anchor{KEKSItem}
+@DOCSTRING KEKSItem@
+@DOCSTRING KEKSItemsInit@
+@anchor{KEKSItemsGrow}
+@DOCSTRING KEKSItemsGrow@
+@anchor{KEKSItemsParse}
+@DOCSTRING KEKSItemsParse@
+@DOCSTRING KEKSItemsEncode@
+@DOCSTRING KEKSItemsGetByKeyLen@
+@anchor{KEKSItemsGetByKey}
+@DOCSTRING KEKSItemsGetByKey@
+@DOCSTRING KEKSItemsGetByKeyAndType@
+@DOCSTRING KEKSStrEqual@
+@DOCSTRING KEKSListHasOnlyType@
+@DOCSTRING KEKSMapHasOnlyType@
--- /dev/null
+@node PKI
+@cindex PKI
+@unnumbered PKI
+
+@file{lib/pki} contains PKI-related code. It is not directly related to
+the KEKS codec, so it is placed isolated nearby. Currently there are
+functions to deal with certificate verification:
+
+@anchor{KEKSCer}
+@DOCSTRING KEKSCer@
+
+@DOCSTRING KEKSCerParse@
+
+@DOCSTRING KEKSCerVerify@
+
+@DOCSTRING KEKSCerVerifyOpts@
+
+@anchor{KEKSCerSigVerifier}
+@DOCSTRING KEKSCerSigVerifier@
--- /dev/null
+@node Datetime
+@cindex TAI64
+@cindex datetime
+@unnumbered Datetime
+
+KEKS uses @url{http://cr.yp.to/libtai/tai64.html, TAI64} for datetime
+objects. There are helpers to convert it to UTC and vice versa.
+
+@DOCSTRING KEKSTAI64ToTimespec@
+@DOCSTRING KEKSTimespecToUTC@
+@DOCSTRING KEKSTimespecToTAI64@
+@DOCSTRING KEKSTimespecToTAI@
+@DOCSTRING KEKSLeapsecs@
/*.o
/compile_flags.txt
-/libyac.a
+/libkeks.a
--- /dev/null
+#ifndef KEKS_ATOMS_H
+#define KEKS_ATOMS_H
+
+enum KEKSAtomType {
+ KEKSAtomEOC = 0x00,
+ KEKSAtomNIL = 0x01,
+ KEKSAtomFalse = 0x02,
+ KEKSAtomTrue = 0x03,
+ KEKSAtomUUID = 0x04,
+ KEKSAtomList = 0x08,
+ KEKSAtomMap = 0x09,
+ KEKSAtomBlob = 0x0B,
+ KEKSAtomPint = 0x0C,
+ KEKSAtomNint = 0x0D,
+ KEKSAtomFloat16 = 0x10,
+ KEKSAtomFloat32 = 0x11,
+ KEKSAtomFloat64 = 0x12,
+ KEKSAtomFloat128 = 0x13,
+ KEKSAtomFloat256 = 0x14,
+ KEKSAtomTAI64 = 0x18,
+ KEKSAtomTAI64N = 0x19,
+ KEKSAtomTAI64NA = 0x1A,
+
+ KEKSAtomStrings = 0x80,
+ KEKSAtomIsUTF8 = 0x40,
+};
+
+#endif // KEKS_ATOMS_H
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include "frombe.h"
#include "utf8.h"
-enum YACErr
-YACAtomDecode( // NOLINT(misc-no-recursion)
+enum KEKSErr
+KEKSAtomDecode( // NOLINT(misc-no-recursion)
size_t *got,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
const unsigned char *buf,
const size_t len)
{
atom->v.str.len = 0;
(*got) = 1;
if (len < 1) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
atom->tag = buf[0];
- if ((atom->tag & (uint8_t)YACAtomStrings) > 0) {
+ if ((atom->tag & (uint8_t)KEKSAtomStrings) > 0) {
atom->typ =
- ((atom->tag & (uint8_t)YACAtomIsUTF8) == 0) ? YACItemBin : YACItemStr;
+ ((atom->tag & (uint8_t)KEKSAtomIsUTF8) == 0) ? KEKSItemBin : KEKSItemStr;
uint64_t l = atom->tag & (uint8_t)63;
size_t ll = 0;
switch (l) {
if (ll != 0) {
(*got) += ll;
if (len < (*got)) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
- uint64_t ul = yacFromBE(buf + 1, ll);
+ uint64_t ul = keksFromBE(buf + 1, ll);
if (ul > (SIZE_MAX - (63 + 255 + 65535))) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
l += ul;
}
const size_t ls = (size_t)l;
(*got) += ls;
if ((*got) <= ls) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
if (len < (*got)) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
atom->v.str.len = ls;
atom->v.str.ptr = buf + 1 + ll;
- if (atom->typ == YACItemStr) {
+ if (atom->typ == KEKSItemStr) {
if (l > PTRDIFF_MAX) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
size_t cpl = 0;
- uint32_t cp = YACUTF8InvalidCp;
+ uint32_t cp = KEKSUTF8InvalidCp;
for (size_t n = 0; n < l; n += cpl) {
- cpl = YACUTF8CpDecode(&cp, atom->v.str.ptr + (ptrdiff_t)n, l - n);
- if (cp == YACUTF8InvalidCp) {
- return YACErrBadUTF8;
+ cpl = KEKSUTF8CpDecode(&cp, atom->v.str.ptr + (ptrdiff_t)n, l - n);
+ if (cp == KEKSUTF8InvalidCp) {
+ return KEKSErrBadUTF8;
}
}
}
- return YACErrNo;
+ return KEKSErrNo;
}
switch (atom->tag) {
- case YACAtomEOC:
- atom->typ = YACItemEOC;
+ case KEKSAtomEOC:
+ atom->typ = KEKSItemEOC;
break;
- case YACAtomNIL:
- atom->typ = YACItemNIL;
+ case KEKSAtomNIL:
+ atom->typ = KEKSItemNIL;
break;
- case YACAtomFalse:
- atom->typ = YACItemFalse;
+ case KEKSAtomFalse:
+ atom->typ = KEKSItemFalse;
break;
- case YACAtomTrue:
- atom->typ = YACItemTrue;
+ case KEKSAtomTrue:
+ atom->typ = KEKSItemTrue;
break;
- case YACAtomUUID:
- atom->typ = YACItemUUID;
+ case KEKSAtomUUID:
+ atom->typ = KEKSItemUUID;
(*got) += 16;
if (len < (*got)) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
atom->v.uuid = buf + 1;
break;
- case YACAtomList:
- atom->typ = YACItemList;
+ case KEKSAtomList:
+ atom->typ = KEKSItemList;
break;
- case YACAtomMap:
- atom->typ = YACItemMap;
+ case KEKSAtomMap:
+ atom->typ = KEKSItemMap;
break;
- case YACAtomBlob: {
- atom->typ = YACItemBlob;
+ case KEKSAtomBlob: {
+ atom->typ = KEKSItemBlob;
(*got) += 8;
if (len < (*got)) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
- const uint64_t chunkLen = yacFromBE(buf + 1, 8);
+ const uint64_t chunkLen = keksFromBE(buf + 1, 8);
if (chunkLen > (SIZE_MAX - 1)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
atom->v.blob.chunkLen = (size_t)chunkLen + 1;
break;
}
- case YACAtomPint:
- case YACAtomNint: {
- atom->typ = (atom->tag == YACAtomPint) ? YACItemPint : YACItemNint;
+ case KEKSAtomPint:
+ case KEKSAtomNint: {
+ atom->typ = (atom->tag == KEKSAtomPint) ? KEKSItemPint : KEKSItemNint;
size_t binGot = 0;
- struct YACAtom bin;
- memset(&bin, 0, sizeof(struct YACAtom));
- if ((buf[1] & (unsigned char)YACAtomStrings) == 0) {
- return YACErrIntNonBin;
+ struct KEKSAtom bin;
+ memset(&bin, 0, sizeof(struct KEKSAtom));
+ if ((buf[1] & (unsigned char)KEKSAtomStrings) == 0) {
+ return KEKSErrIntNonBin;
}
- enum YACErr err = YACAtomDecode(&binGot, &bin, buf + 1, len - 1);
- if (err != YACErrNo) {
+ enum KEKSErr err = KEKSAtomDecode(&binGot, &bin, buf + 1, len - 1);
+ if (err != KEKSErrNo) {
return err;
}
(*got) += binGot;
- if (bin.typ != YACItemBin) {
- return YACErrIntNonBin;
+ if (bin.typ != KEKSItemBin) {
+ return KEKSErrIntNonBin;
}
if (bin.v.str.len == 0) {
- if (atom->typ == YACItemPint) {
+ if (atom->typ == KEKSItemPint) {
atom->v.pint = 0;
} else {
atom->v.nint = -1;
}
- return YACErrNo;
+ return KEKSErrNo;
}
if (bin.v.str.ptr[0] == 0) {
- return YACErrIntNonMinimal;
+ return KEKSErrIntNonMinimal;
}
if (bin.v.str.len > 8) {
- atom->typ = YACItemRaw;
+ atom->typ = KEKSItemRaw;
atom->v.str.len = binGot;
atom->v.str.ptr = buf + 1;
- return YACErrNo;
+ return KEKSErrNo;
}
- atom->v.pint = yacFromBE(bin.v.str.ptr, bin.v.str.len);
- if (atom->typ == YACItemNint) {
+ atom->v.pint = keksFromBE(bin.v.str.ptr, bin.v.str.len);
+ if (atom->typ == KEKSItemNint) {
if (atom->v.pint >= ((uint64_t)1 << (uint8_t)63)) {
- atom->typ = YACItemRaw;
+ atom->typ = KEKSItemRaw;
atom->v.str.len = binGot;
atom->v.str.ptr = buf + 1;
} else {
atom->v.nint = -1 - (int64_t)(atom->v.pint);
}
}
- return YACErrNo;
+ return KEKSErrNo;
}
- case YACAtomFloat16:
- case YACAtomFloat32:
- case YACAtomFloat64:
- case YACAtomFloat128:
- case YACAtomFloat256: {
+ case KEKSAtomFloat16:
+ case KEKSAtomFloat32:
+ case KEKSAtomFloat64:
+ case KEKSAtomFloat128:
+ case KEKSAtomFloat256: {
size_t l = 0;
switch (atom->tag) {
- case YACAtomFloat16:
+ case KEKSAtomFloat16:
l = 2;
break;
- case YACAtomFloat32:
+ case KEKSAtomFloat32:
l = 4;
break;
- case YACAtomFloat64:
+ case KEKSAtomFloat64:
l = 8;
break;
- case YACAtomFloat128:
+ case KEKSAtomFloat128:
l = 16;
break;
- case YACAtomFloat256:
+ case KEKSAtomFloat256:
l = 32;
break;
}
- atom->typ = YACItemFloat;
+ atom->typ = KEKSItemFloat;
(*got) += l;
if (len < (*got)) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
- atom->typ = YACItemRaw;
+ atom->typ = KEKSItemRaw;
atom->v.str.len = l;
atom->v.str.ptr = buf + 1;
break;
}
- case YACAtomTAI64:
- case YACAtomTAI64N:
- case YACAtomTAI64NA: {
+ case KEKSAtomTAI64:
+ case KEKSAtomTAI64N:
+ case KEKSAtomTAI64NA: {
size_t l = 0;
switch (atom->tag) {
- case YACAtomTAI64:
+ case KEKSAtomTAI64:
l = 8;
break;
- case YACAtomTAI64N:
+ case KEKSAtomTAI64N:
l = 12;
break;
- case YACAtomTAI64NA:
+ case KEKSAtomTAI64NA:
l = 16;
break;
}
- atom->typ = YACItemTAI64;
+ atom->typ = KEKSItemTAI64;
(*got) += l;
if (len < (*got)) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
atom->v.str.len = l;
atom->v.str.ptr = buf + 1;
- uint64_t v = yacFromBE(buf + 1, 8);
+ uint64_t v = keksFromBE(buf + 1, 8);
if (v > ((uint64_t)1 << (uint8_t)63)) {
- return YACErrTAI64TooBig;
+ return KEKSErrTAI64TooBig;
}
if (l > 8) {
- v = yacFromBE(buf + 1 + 8, 4);
+ v = keksFromBE(buf + 1 + 8, 4);
if ((l == 12) && (v == 0)) {
- return YACErrTAI64NonMinimal;
+ return KEKSErrTAI64NonMinimal;
}
if (v > 999999999) {
- return YACErrTAI64BadNsec;
+ return KEKSErrTAI64BadNsec;
}
}
if (l > 12) {
- v = yacFromBE(buf + 1 + 8 + 4, 4);
+ v = keksFromBE(buf + 1 + 8 + 4, 4);
if (v == 0) {
- return YACErrTAI64NonMinimal;
+ return KEKSErrTAI64NonMinimal;
}
if (v > 999999999) {
- return YACErrTAI64BadAsec;
+ return KEKSErrTAI64BadAsec;
}
}
break;
}
default:
- return YACErrUnknownType;
+ return KEKSErrUnknownType;
}
- return YACErrNo;
+ return KEKSErrNo;
}
-#ifndef YAC_DEC_H
-#define YAC_DEC_H
+#ifndef KEKS_DEC_H
+#define KEKS_DEC_H
#include <stddef.h>
#include <stdint.h>
#include "err.h"
-// TEXINFO: YACItemType
-// @deftp {Data type} {enum YACItemType}
+// TEXINFO: KEKSItemType
+// @deftp {Data type} {enum KEKSItemType}
// High-level type of the atom.
// @itemize
-// @item YACItemInvalid -- invalid item value, uninitialised
-// @item YACItemEOC
-// @item YACItemNIL
-// @item YACItemFalse
-// @item YACItemTrue
-// @item YACItemUUID
-// @item YACItemPint -- positive integer
-// @item YACItemNint -- negative integer
-// @item YACItemList
-// @item YACItemMap
-// @item YACItemBlob
-// @item YACItemFloat
-// @item YACItemTAI64
-// @item YACItemBin
-// @item YACItemStr
-// @item YACItemRaw -- raw value, non-decodable by the library
+// @item KEKSItemInvalid -- invalid item value, uninitialised
+// @item KEKSItemEOC
+// @item KEKSItemNIL
+// @item KEKSItemFalse
+// @item KEKSItemTrue
+// @item KEKSItemUUID
+// @item KEKSItemPint -- positive integer
+// @item KEKSItemNint -- negative integer
+// @item KEKSItemList
+// @item KEKSItemMap
+// @item KEKSItemBlob
+// @item KEKSItemFloat
+// @item KEKSItemTAI64
+// @item KEKSItemBin
+// @item KEKSItemStr
+// @item KEKSItemRaw -- raw value, non-decodable by the library
// @end itemize
// @end deftp
-enum YACItemType {
- YACItemInvalid = 0,
- YACItemEOC = 1,
- YACItemNIL,
- YACItemFalse,
- YACItemTrue,
- YACItemUUID,
- YACItemPint,
- YACItemNint,
- YACItemList,
- YACItemMap,
- YACItemBlob,
- YACItemFloat,
- YACItemTAI64,
- YACItemBin,
- YACItemStr,
- YACItemRaw,
+enum KEKSItemType {
+ KEKSItemInvalid = 0,
+ KEKSItemEOC = 1,
+ KEKSItemNIL,
+ KEKSItemFalse,
+ KEKSItemTrue,
+ KEKSItemUUID,
+ KEKSItemPint,
+ KEKSItemNint,
+ KEKSItemList,
+ KEKSItemMap,
+ KEKSItemBlob,
+ KEKSItemFloat,
+ KEKSItemTAI64,
+ KEKSItemBin,
+ KEKSItemStr,
+ KEKSItemRaw,
};
-// TEXINFO: YACAtom
-// @deftp {Data type} {struct YACAtom}
+// TEXINFO: KEKSAtom
+// @deftp {Data type} {struct KEKSAtom}
// Basic unit of the library, describing single TLV-like value.
// @table @code
// @item .tag
// Real value of the atom's tag. May be used during debugging or
// when constructing raw value.
// @item .typ
-// High level @ref{YACItemType, type} of the atom's value. As a rule
+// High level @ref{KEKSItemType, type} of the atom's value. As a rule
// you should look solely on it.
// @item .v.uuid
// Pointer to 16-byte UUID value.
// Raw values use it as a payload.
// @end table
// @end deftp
-struct YACAtom {
+struct KEKSAtom {
union {
const unsigned char *uuid;
uint64_t pint;
size_t len;
} str;
} v;
- enum YACItemType typ;
+ enum KEKSItemType typ;
unsigned char tag;
char _pad[3];
};
-// TEXINFO: YACAtomDecode
-// @deftypefun {enum YACErr} YACAtomDecode ( @
+// TEXINFO: KEKSAtomDecode
+// @deftypefun {enum KEKSErr} KEKSAtomDecode ( @
// size_t *got, @
-// struct YACAtom *atom, @
+// struct KEKSAtom *atom, @
// const unsigned char *buf, @
// const size_t len)
-// Decode the @ref{YACAtom, @var{atom}} from provided @var{buf} of
-// length @var{len}. If error is @code{YACErrNotEnough}, then @var{got}
+// Decode the @ref{KEKSAtom, @var{atom}} from provided @var{buf} of
+// length @var{len}. If error is @code{KEKSErrNotEnough}, then @var{got}
// will contain how many bytes is missing in the buffer for full atom
// decoding. Otherwise it will contain the full atom's size.
// @end deftypefun
-enum YACErr
-YACAtomDecode(
+enum KEKSErr
+KEKSAtomDecode(
size_t *got,
- struct YACAtom *,
+ struct KEKSAtom *,
const unsigned char *buf,
const size_t len);
-#endif // YAC_DEC_H
+#endif // KEKS_DEC_H
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include "frombe.h"
#include "leapsecs.h"
-enum YACErr
-YACTAI64ToTimespec(struct timespec *ts, const unsigned char *buf, const size_t len)
+enum KEKSErr
+KEKSTAI64ToTimespec(struct timespec *ts, const unsigned char *buf, const size_t len)
{
if (len > 12) {
- return YACErrTAI64BadAsec;
+ return KEKSErrTAI64BadAsec;
}
- int64_t v = (int64_t)yacFromBE(buf, 8);
+ int64_t v = (int64_t)keksFromBE(buf, 8);
v -= 0x4000000000000000;
if (v <= 0) {
- return YACErrTAI64InPast;
+ return KEKSErrTAI64InPast;
}
if (((uint64_t)1 << ((sizeof(time_t) * 8) - 1)) < (uint64_t)v) {
- return YACErrTAI64TooBig;
+ return KEKSErrTAI64TooBig;
}
ts->tv_sec = (time_t)v;
if (len > 8) {
- uint32_t n = (uint32_t)yacFromBE(buf + 8, 4);
+ uint32_t n = (uint32_t)keksFromBE(buf + 8, 4);
ts->tv_nsec = n;
}
- return YACErrNo;
+ return KEKSErrNo;
}
-enum YACErr
-YACTimespecToUTC(struct timespec *ts)
+enum KEKSErr
+KEKSTimespecToUTC(struct timespec *ts)
{
int64_t v = (int64_t)(ts->tv_sec);
- enum YACErr err = YACErrNo;
+ enum KEKSErr err = KEKSErrNo;
{
int64_t diff = 10;
- for (int64_t i = 0; i < YACLeapsecsN; i++) {
- if (v < YACLeapsecs[i]) {
+ for (int64_t i = 0; i < KEKSLeapsecsN; i++) {
+ if (v < KEKSLeapsecs[i]) {
break;
}
diff++;
- if (v == YACLeapsecs[i]) {
- err = YACErrTAI64IsLeap;
+ if (v == KEKSLeapsecs[i]) {
+ err = KEKSErrTAI64IsLeap;
break;
}
}
v -= diff;
}
if (v <= 0) {
- return YACErrTAI64InPast;
+ return KEKSErrTAI64InPast;
}
ts->tv_sec = (time_t)v;
return err;
--- /dev/null
+#ifndef KEKS_DECTAI_H
+#define KEKS_DECTAI_H
+
+#include <stddef.h>
+#include <time.h>
+
+#include "err.h"
+
+// TEXINFO: KEKSTAI64ToTimespec
+// @deftypefun {enum KEKSErr} KEKSTAI64ToTimespec @
+// (struct timespec *tv, const unsigned char *buf, const size_t len)
+// Convert TAI64* value from @var{buf} to @var{ts} structure.
+// @code{KEKSErrTAI64InPast} error is returned if value represents time
+// before 1970. Some systems support those dates, but not guaranteed to.
+// @code{KEKSErrTAI64TooBig} error is returned when time is out of bounds
+// of @code{time_t} representation. @code{KEKSErrTAI64BadAsec} is
+// returned if TAI64NA is provided, because currently no systems support
+// attoseconds.
+// @end deftypefun
+enum KEKSErr
+KEKSTAI64ToTimespec(struct timespec *ts, const unsigned char *buf, const size_t len);
+
+// TEXINFO: KEKSTimespecToUTC
+// @deftypefun {enum KEKSErr} KEKSTimespecToUTC (struct timespec *ts)
+// Convert TAI stored in @var{ts} structure to UTC. @code{KEKSErrTAI64InPast}
+// error is returned if value represents time before 1970.
+// @end deftypefun
+enum KEKSErr
+KEKSTimespecToUTC(struct timespec *ts);
+
+#endif // KEKS_DECTAI_H
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include "tobe.h"
bool
-YACAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap)
+KEKSAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap)
{
(*len) = 1;
if (cap < 1) {
return false;
}
- buf[0] = YACAtomEOC;
+ buf[0] = KEKSAtomEOC;
return true;
}
bool
-YACAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap)
+KEKSAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap)
{
(*len) = 1;
if (cap < 1) {
return false;
}
- buf[0] = YACAtomNIL;
+ buf[0] = KEKSAtomNIL;
return true;
}
bool
-YACAtomBoolEncode(size_t *len, unsigned char *buf, const size_t cap, const bool v)
+KEKSAtomBoolEncode(size_t *len, unsigned char *buf, const size_t cap, const bool v)
{
(*len) = 1;
if (cap < 1) {
return false;
}
- buf[0] = v ? YACAtomTrue : YACAtomFalse;
+ buf[0] = v ? KEKSAtomTrue : KEKSAtomFalse;
return true;
}
bool
-YACAtomUUIDEncode(
+KEKSAtomUUIDEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
if (cap < (1 + 16)) {
return false;
}
- buf[0] = YACAtomUUID;
+ buf[0] = KEKSAtomUUID;
memcpy(buf + 1, v, 16);
return true;
}
static bool
-yacAtomIntEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v)
+keksAtomIntEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v)
{
if (cap < 1) {
return false;
}
if (v == 0) {
const bool ok =
- YACAtomBinEncode(len, buf + 1, cap - 1, (const unsigned char *)"", 0);
+ KEKSAtomBinEncode(len, buf + 1, cap - 1, (const unsigned char *)"", 0);
(*len)++;
return ok;
}
}
l++;
unsigned char be[8] = {0};
- yacToBE(be, l, v);
- const bool ok = YACAtomBinEncode(len, buf + 1, cap - 1, be, l);
+ keksToBE(be, l, v);
+ const bool ok = KEKSAtomBinEncode(len, buf + 1, cap - 1, be, l);
(*len)++;
return ok;
}
bool
-YACAtomUintEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v)
+KEKSAtomUintEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v)
{
- bool ok = yacAtomIntEncode(len, buf, cap, v);
+ bool ok = keksAtomIntEncode(len, buf, cap, v);
if (ok) {
- buf[0] = YACAtomPint;
+ buf[0] = KEKSAtomPint;
}
return ok;
}
bool
-YACAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, const int64_t v)
+KEKSAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, const int64_t v)
{
if (v >= 0) {
- return YACAtomUintEncode(len, buf, cap, (uint64_t)v);
+ return KEKSAtomUintEncode(len, buf, cap, (uint64_t)v);
}
const uint64_t vp = (uint64_t)(-(v + 1));
- bool ok = yacAtomIntEncode(len, buf, cap, vp);
+ bool ok = keksAtomIntEncode(len, buf, cap, vp);
if (ok) {
- buf[0] = YACAtomNint;
+ buf[0] = KEKSAtomNint;
}
return ok;
}
bool
-YACAtomListEncode(size_t *len, unsigned char *buf, const size_t cap)
+KEKSAtomListEncode(size_t *len, unsigned char *buf, const size_t cap)
{
(*len) = 1;
if (cap < 1) {
return false;
}
- buf[0] = YACAtomList;
+ buf[0] = KEKSAtomList;
return true;
}
bool
-YACAtomMapEncode(size_t *len, unsigned char *buf, const size_t cap)
+KEKSAtomMapEncode(size_t *len, unsigned char *buf, const size_t cap)
{
(*len) = 1;
if (cap < 1) {
return false;
}
- buf[0] = YACAtomMap;
+ buf[0] = KEKSAtomMap;
return true;
}
bool
-YACAtomBlobEncode(
+KEKSAtomBlobEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
if (cap < 1 + 8) {
return false;
}
- buf[0] = YACAtomBlob;
- yacToBE(buf + 1, 8, (uint64_t)chunkLen - 1);
+ buf[0] = KEKSAtomBlob;
+ keksToBE(buf + 1, 8, (uint64_t)chunkLen - 1);
return true;
}
static bool
-yacAtomStrEncode(
+keksAtomStrEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
if (srcLen >= (63 + 255 + 65535)) {
lVal = 63;
lLen = 8;
- yacToBE(lBuf, 8, (uint64_t)srcLen - (63 + 255 + 65535));
+ keksToBE(lBuf, 8, (uint64_t)srcLen - (63 + 255 + 65535));
} else if (srcLen >= (62 + 255)) {
lVal = 62;
lLen = 2;
- yacToBE(lBuf, 2, (uint64_t)srcLen - (62 + 255));
+ keksToBE(lBuf, 2, (uint64_t)srcLen - (62 + 255));
} else if (srcLen >= 61) {
lVal = 61;
lLen = 1;
if (cap < (*len)) {
return false;
}
- buf[0] = (uint8_t)YACAtomStrings | lVal;
+ buf[0] = (uint8_t)KEKSAtomStrings | lVal;
if (utf8) {
- buf[0] |= (unsigned char)YACAtomIsUTF8;
+ buf[0] |= (unsigned char)KEKSAtomIsUTF8;
}
memcpy(buf + 1, lBuf, lLen);
memcpy(buf + 1 + lLen, src, srcLen);
}
bool
-YACAtomStrEncode(
+KEKSAtomStrEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char *src,
const size_t srcLen)
{
- return yacAtomStrEncode(len, buf, cap, src, srcLen, true);
+ return keksAtomStrEncode(len, buf, cap, src, srcLen, true);
}
bool
-YACAtomBinEncode(
+KEKSAtomBinEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char *src,
const size_t srcLen)
{
- return yacAtomStrEncode(len, buf, cap, src, srcLen, false);
+ return keksAtomStrEncode(len, buf, cap, src, srcLen, false);
}
bool
-YACAtomChunkEncode(
+KEKSAtomChunkEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
if (cap < (*len)) {
return false;
}
- buf[0] = YACAtomNIL;
+ buf[0] = KEKSAtomNIL;
memcpy(buf + 1, src, srcLen);
return true;
}
bool
-YACAtomTAI64Encode(
+KEKSAtomTAI64Encode(
size_t *len,
unsigned char *buf,
const size_t cap,
}
switch (srcLen) {
case 8:
- buf[0] = YACAtomTAI64;
+ buf[0] = KEKSAtomTAI64;
break;
case 12:
- buf[0] = YACAtomTAI64N;
+ buf[0] = KEKSAtomTAI64N;
break;
case 16:
- buf[0] = YACAtomTAI64NA;
+ buf[0] = KEKSAtomTAI64NA;
break;
default:
return 0;
}
bool
-YACAtomRawEncode(
+KEKSAtomRawEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
-#ifndef YAC_ENC_H
-#define YAC_ENC_H
+#ifndef KEKS_ENC_H
+#define KEKS_ENC_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-// TEXINFO: YACAtomEOCEncode
-// @deftypefun bool YACAtomEOCEncode @
+// TEXINFO: KEKSAtomEOCEncode
+// @deftypefun bool KEKSAtomEOCEncode @
// (size_t *len, unsigned char *buf, const size_t cap)
// Encode EOC atom in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap);
+KEKSAtomEOCEncode(size_t *len, unsigned char *buf, const size_t cap);
-// TEXINFO: YACAtomNILEncode
-// @deftypefun bool YACAtomNILEncode @
+// TEXINFO: KEKSAtomNILEncode
+// @deftypefun bool KEKSAtomNILEncode @
// (size_t *len, unsigned char *buf, const size_t cap)
// Encode NUL atom in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap);
+KEKSAtomNILEncode(size_t *len, unsigned char *buf, const size_t cap);
-// TEXINFO: YACAtomBoolEncode
-// @deftypefun bool YACAtomBoolEncode @
+// TEXINFO: KEKSAtomBoolEncode
+// @deftypefun bool KEKSAtomBoolEncode @
// (size_t *len, unsigned char *buf, const size_t cap, const bool v)
// Encode boolean atom in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomBoolEncode(size_t *len, unsigned char *buf, const size_t cap, const bool v);
+KEKSAtomBoolEncode(size_t *len, unsigned char *buf, const size_t cap, const bool v);
-// TEXINFO: YACAtomUUIDEncode
-// @deftypefun bool YACAtomUUIDEncode @
+// TEXINFO: KEKSAtomUUIDEncode
+// @deftypefun bool KEKSAtomUUIDEncode @
// (size_t *len, unsigned char *buf, const size_t cap, const unsigned char v[16])
// Encode UUID atom in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomUUIDEncode(
+KEKSAtomUUIDEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char v[16]);
-// TEXINFO: YACAtomUintEncode
-// @deftypefun bool YACAtomUintEncode @
+// TEXINFO: KEKSAtomUintEncode
+// @deftypefun bool KEKSAtomUintEncode @
// (size_t *len, unsigned char *buf, const size_t cap, const uint64_t v)
// Encode positive integer atom in provided @var{buf} with capacity of
// @var{cap}.
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomUintEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v);
+KEKSAtomUintEncode(size_t *len, unsigned char *buf, const size_t cap, const uint64_t v);
-// TEXINFO: YACAtomSintEncode
-// @deftypefun bool YACAtomSintEncode @
+// TEXINFO: KEKSAtomSintEncode
+// @deftypefun bool KEKSAtomSintEncode @
// (size_t *len, unsigned char *buf, const size_t cap, const int64_t v)
// Encode signed integer atom in provided @var{buf} with capacity of
// @var{cap}. If it is zero or positive, then it encodes unsigned one.
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, const int64_t v);
+KEKSAtomSintEncode(size_t *len, unsigned char *buf, const size_t cap, const int64_t v);
-// TEXINFO: YACAtomListEncode
-// @deftypefun bool YACAtomListEncode @
+// TEXINFO: KEKSAtomListEncode
+// @deftypefun bool KEKSAtomListEncode @
// (size_t *len, unsigned char *buf, const size_t cap)
// Encode LIST atom in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
// bytes were written to buffer. Do not forget to add EOC atom at the end.
// @end deftypefun
bool
-YACAtomListEncode(size_t *len, unsigned char *buf, const size_t cap);
+KEKSAtomListEncode(size_t *len, unsigned char *buf, const size_t cap);
-// TEXINFO: YACAtomMapEncode
-// @deftypefun bool YACAtomMapEncode @
+// TEXINFO: KEKSAtomMapEncode
+// @deftypefun bool KEKSAtomMapEncode @
// (size_t *len, unsigned char *buf, const size_t cap)
// Encode MAP atom in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
// bytes were written to buffer. Do not forget to add EOC atom at the end.
// @end deftypefun
bool
-YACAtomMapEncode(size_t *len, unsigned char *buf, const size_t cap);
+KEKSAtomMapEncode(size_t *len, unsigned char *buf, const size_t cap);
-// TEXINFO: YACAtomBlobEncode
-// @deftypefun bool YACAtomBlobEncode @
+// TEXINFO: KEKSAtomBlobEncode
+// @deftypefun bool KEKSAtomBlobEncode @
// (size_t *len, unsigned char *buf, const size_t cap, const size_t chunkLen)
// Encode BLOB atom in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
-// bytes were written to buffer. You must call @ref{YACAtomChunkEncode}
+// bytes were written to buffer. You must call @ref{KEKSAtomChunkEncode}
// functions for subsequent chunks, and terminate the blob with
-// @ref{YACAtomBinEncode}.
+// @ref{KEKSAtomBinEncode}.
// @end deftypefun
bool
-YACAtomBlobEncode(
+KEKSAtomBlobEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const size_t chunkLen);
-// TEXINFO: YACAtomStrEncode
-// @deftypefun bool YACAtomStrEncode @
+// TEXINFO: KEKSAtomStrEncode
+// @deftypefun bool KEKSAtomStrEncode @
// (size_t *len, unsigned char *buf, const size_t cap, @
// const unsigned char *src, const size_t srcLen)
// Encode STR atom in provided @var{buf} with capacity of @var{cap}.
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomStrEncode(
+KEKSAtomStrEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char *src,
const size_t srcLen);
-// TEXINFO: YACAtomBinEncode
-// @deftypefun bool YACAtomBinEncode @
+// TEXINFO: KEKSAtomBinEncode
+// @deftypefun bool KEKSAtomBinEncode @
// (size_t *len, unsigned char *buf, const size_t cap, @
// const unsigned char *src, const size_t srcLen)
// Encode BIN atom in provided @var{buf} with capacity of @var{cap}.
// bytes were written to buffer.
// @end deftypefun
bool
-YACAtomBinEncode(
+KEKSAtomBinEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char *src,
const size_t srcLen);
-// TEXINFO: YACAtomChunkEncode
-// @deftypefun bool YACAtomChunkEncode @
+// TEXINFO: KEKSAtomChunkEncode
+// @deftypefun bool KEKSAtomChunkEncode @
// (size_t *len, unsigned char *buf, const size_t cap, @
// const unsigned char *src, const size_t srcLen)
// Encode the chunk in provided @var{buf} with capacity of @var{cap}.
// In case of success, true is returned and @var{len} will hold how many
// bytes were written to buffer. It is just a convenient wrapper instead
-// of using @ref{YACAtomNILEncode} followed by @var{srcLen} bytes.
+// of using @ref{KEKSAtomNILEncode} followed by @var{srcLen} bytes.
// @end deftypefun
bool
-YACAtomChunkEncode(
+KEKSAtomChunkEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char *src,
const size_t srcLen);
-// TEXINFO: YACAtomTAI64Encode
-// @deftypefun bool YACAtomTAI64Encode @
+// TEXINFO: KEKSAtomTAI64Encode
+// @deftypefun bool KEKSAtomTAI64Encode @
// (size_t *len, unsigned char *buf, const size_t cap, @
// const unsigned char *src, const size_t srcLen)
// Encode the TAI64* atom in provided @var{buf} with capacity of @var{cap}.
// 16 byte string.
// @end deftypefun
bool
-YACAtomTAI64Encode(
+KEKSAtomTAI64Encode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char *src,
const size_t srcLen);
-// TEXINFO: YACAtomRawEncode
-// @deftypefun bool YACAtomRawEncode @
+// TEXINFO: KEKSAtomRawEncode
+// @deftypefun bool KEKSAtomRawEncode @
// (size_t *len, unsigned char *buf, const size_t cap, @
// const unsigned char typ, const unsigned char *src, const size_t srcLen)
// Encode raw atom in provided @var{buf} with capacity of @var{cap}.
// of manual writing of the @code{typ} byte followed by @var{srcLen} bytes.
// @end deftypefun
bool
-YACAtomRawEncode(
+KEKSAtomRawEncode(
size_t *len,
unsigned char *buf,
const size_t cap,
const unsigned char *src,
const size_t srcLen);
-#endif // YAC_ENC_H
+#endif // KEKS_ENC_H
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include "tobe.h"
bool
-YACTimespecToTAI64(unsigned char *buf, const struct timespec *ts)
+KEKSTimespecToTAI64(unsigned char *buf, const struct timespec *ts)
{
int64_t v = (int64_t)(ts->tv_sec);
uint64_t val = (uint64_t)v + 0x4000000000000000;
if (val <= (uint64_t)v) {
return false;
}
- yacToBE(buf, 8, val);
+ keksToBE(buf, 8, val);
if (ts->tv_nsec != 0) {
- yacToBE(buf + 8, 4, (uint64_t)(ts->tv_nsec));
+ keksToBE(buf + 8, 4, (uint64_t)(ts->tv_nsec));
}
return true;
}
bool
-YACTimespecToTAI(struct timespec *ts)
+KEKSTimespecToTAI(struct timespec *ts)
{
int64_t v = 10 + (int64_t)(ts->tv_sec);
- for (int64_t i = 0; i < YACLeapsecsN; i++) {
- if (v >= YACLeapsecs[i]) {
+ for (int64_t i = 0; i < KEKSLeapsecsN; i++) {
+ if (v >= KEKSLeapsecs[i]) {
v++;
}
}
-#ifndef YAC_ENCTAI_H
-#define YAC_ENCTAI_H
+#ifndef KEKS_ENCTAI_H
+#define KEKS_ENCTAI_H
#include <stdbool.h>
#include <time.h>
-// TEXINFO: YACTimespecToTAI64
-// @deftypefun bool YACTimespecToTAI64 @
+// TEXINFO: KEKSTimespecToTAI64
+// @deftypefun bool KEKSTimespecToTAI64 @
// (unsigned char *buf, const struct timespec *ts)
// Convert @var{ts} structure to TAI64/TAI64N in the @var{buf}.
// If @var{ts} contains non zero nanoseconds count, then be sure that
// False is returned if represented time is out of allowable bounds.
// @end deftypefun
bool
-YACTimespecToTAI64(unsigned char *buf, const struct timespec *ts);
+KEKSTimespecToTAI64(unsigned char *buf, const struct timespec *ts);
-// TEXINFO: YACTimespecToTAI
-// @deftypefun bool YACTimespecToTAI (struct timespec *ts)
+// TEXINFO: KEKSTimespecToTAI
+// @deftypefun bool KEKSTimespecToTAI (struct timespec *ts)
// Convert UTC stored in @var{ts} structure to TAI.
// False is returned if represented time is out of allowable bounds.
// @end deftypefun
bool
-YACTimespecToTAI(struct timespec *ts);
+KEKSTimespecToTAI(struct timespec *ts);
-#endif // YAC_ENCTAI_H
+#endif // KEKS_ENCTAI_H
#include "err.h"
const char *
-YACErr2Str(const enum YACErr err)
+KEKSErr2Str(const enum KEKSErr err)
{
switch (err) {
- case YACErrInvalid:
+ case KEKSErrInvalid:
return "Invalid";
- case YACErrNo:
+ case KEKSErrNo:
return "No";
- case YACErrNotEnough:
+ case KEKSErrNotEnough:
return "NotEnough";
- case YACErrUnknownType:
+ case KEKSErrUnknownType:
return "UnknownType";
- case YACErrLenTooBig:
+ case KEKSErrLenTooBig:
return "LenTooBig";
- case YACErrBadUTF8:
+ case KEKSErrBadUTF8:
return "BadUTF8";
- case YACErrIntNonBin:
+ case KEKSErrIntNonBin:
return "IntNonBin";
- case YACErrIntNonMinimal:
+ case KEKSErrIntNonMinimal:
return "IntNonMinimal";
- case YACErrBlobBadAtom:
+ case KEKSErrBlobBadAtom:
return "BlobBadAtom";
- case YACErrBlobBadTerm:
+ case KEKSErrBlobBadTerm:
return "BlobBadTerm";
- case YACErrTAI64TooBig:
+ case KEKSErrTAI64TooBig:
return "TAI64TooBig";
- case YACErrTAI64BadNsec:
+ case KEKSErrTAI64BadNsec:
return "TAI64BadNsec";
- case YACErrTAI64BadAsec:
+ case KEKSErrTAI64BadAsec:
return "TAI64BadAsec";
- case YACErrTAI64InPast:
+ case KEKSErrTAI64InPast:
return "TAI64InPast";
- case YACErrTAI64IsLeap:
+ case KEKSErrTAI64IsLeap:
return "TAI64IsLeap";
- case YACErrTAI64NonMinimal:
+ case KEKSErrTAI64NonMinimal:
return "TAI64NonMinimal";
- case YACErrMapBadKey:
+ case KEKSErrMapBadKey:
return "MapBadKey";
- case YACErrMapUnordered:
+ case KEKSErrMapUnordered:
return "MapUnordered";
- case YACErrNoMem:
+ case KEKSErrNoMem:
return "NoMem";
- case YACErrUnsatisfiedSchema:
+ case KEKSErrUnsatisfiedSchema:
return "UnsatisfiedSchema";
- case YACErrDeepRecursion:
+ case KEKSErrDeepRecursion:
return "DeepRecursion";
- case YACErrUnexpectedEOC:
+ case KEKSErrUnexpectedEOC:
return "UnexpectedEOC";
default:
return "unknown";
--- /dev/null
+#ifndef KEKS_ERR_H
+#define KEKS_ERR_H
+
+// TEXINFO: KEKSErr
+// @deftp {Data type} {enum KEKSErr}
+// Errors are just a predefined enumeration value.
+// @table @code
+// @item KEKSErrInvalid
+// Unset error, must be never met.
+// @item KEKSErrNo
+// No error, everything is good.
+// @item KEKSErrNotEnough
+// Not enough data. Atom's @code{.off} must contain how much.
+// @item KEKSErrUnknownType, // unknown atom's type
+// Unknown atom's type.
+// @item KEKSErrLenTooBig,
+// Too long string (>1<<60), can not be decoded.
+// @item KEKSErrBadUTF8
+// Invalid UTF-8 codepoint or zero byte met.
+// @item KEKSErrIntNonMinimal
+// Non minimal integer encoding.
+// @item KEKSErrBlobBadAtom
+// Blob contains unexpected atom.
+// @item KEKSErrBlobBadTerm
+// Blob contains invalid terminator.
+// @item KEKSErrTAI64TooBig
+// Too large TAI64 value, out-of-bounds.
+// @item KEKSErrTAI64BadNsec
+// Invalid TAI64 nanoseconds value.
+// @item KEKSErrTAI64BadAsec
+// Invalid TAI64 attoseconds value.
+// @item KEKSErrMapBadKey
+// Either bad type of map's key, or it is empty.
+// @item KEKSErrMapUnordered
+// Unordered map keys.
+// @item KEKSErrNoMem
+// Not enough memory for allocation.
+// @item KEKSErrUnsatisfiedSchema
+// Unsatisfied structure's schema.
+// @item KEKSErrDeepRecursion
+// Too deep recursion involved during parsing.
+// @item KEKSErrUnexpectedEOC
+// Unexpected EOC met.
+// @end table
+// @end deftp
+enum KEKSErr {
+ KEKSErrInvalid = 0,
+ KEKSErrNo = 1,
+ KEKSErrNotEnough,
+ KEKSErrUnknownType,
+ KEKSErrLenTooBig,
+ KEKSErrBadUTF8,
+ KEKSErrIntNonBin,
+ KEKSErrIntNonMinimal,
+ KEKSErrBlobBadAtom,
+ KEKSErrBlobBadTerm,
+ KEKSErrTAI64TooBig,
+ KEKSErrTAI64BadNsec,
+ KEKSErrTAI64BadAsec,
+ KEKSErrTAI64InPast,
+ KEKSErrTAI64IsLeap,
+ KEKSErrTAI64NonMinimal,
+ KEKSErrMapBadKey,
+ KEKSErrMapUnordered,
+ KEKSErrNoMem,
+ KEKSErrUnsatisfiedSchema,
+ KEKSErrDeepRecursion,
+ KEKSErrUnexpectedEOC,
+};
+
+// TEXINFO: KEKSErr2Str
+// @deftypefun {const char *} KEKSErr2Str (const enum KEKSErr)
+// Get human-readable string of the error.
+// @end deftypefun
+const char *
+KEKSErr2Str(const enum KEKSErr);
+
+#endif // KEKS_ERR_H
#include "frombe.h"
uint64_t
-yacFromBE(const unsigned char *buf, const size_t len)
+keksFromBE(const unsigned char *buf, const size_t len)
{
uint64_t v = 0;
switch (len) {
--- /dev/null
+#ifndef KEKS_FROMBE_H
+#define KEKS_FROMBE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+// Decode big-endian integer of the length @var{len}.
+uint64_t
+keksFromBE(const unsigned char *buf, const size_t len);
+
+#endif // KEKS_FROMBE_H
--- /dev/null
+redo-ifchange *.h libkeks.a ../conf/prefix
+read PREFIX <../conf/prefix
+mkdir -p $PREFIX/include/keks $PREFIX/lib
+cp -f *.h $PREFIX/include/keks
+cp -f libkeks.a $PREFIX/lib
+chmod 644 $PREFIX/include/keks/*.h $PREFIX/lib/libkeks.a
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include "err.h"
#include "items.h"
-static const ptrdiff_t yacItemsPoolGrowLen = 64;
+static const ptrdiff_t keksItemsPoolGrowLen = 64;
static const size_t parseMaxRecursionDepth = 1024;
-enum YACErr
-YACItemsInit(struct YACItems *items)
+enum KEKSErr
+KEKSItemsInit(struct KEKSItems *items)
{
items->len = 0;
- items->cap = yacItemsPoolGrowLen;
- items->list = calloc((size_t)(items->cap), sizeof(struct YACItem));
+ items->cap = keksItemsPoolGrowLen;
+ items->list = calloc((size_t)(items->cap), sizeof(struct KEKSItem));
if (items->list == NULL) {
- return YACErrNoMem;
+ return KEKSErrNoMem;
}
items->offsets = calloc((size_t)(items->cap), sizeof(size_t));
if (items->offsets == NULL) {
- return YACErrNoMem;
+ return KEKSErrNoMem;
}
- return YACErrNo;
+ return KEKSErrNo;
}
-enum YACErr
-YACItemsGrow(struct YACItems *items)
+enum KEKSErr
+KEKSItemsGrow(struct KEKSItems *items)
{
if (items->cap == -1) {
- return YACErrNoMem;
+ return KEKSErrNoMem;
}
- if ((SIZE_MAX - yacItemsPoolGrowLen) < (size_t)(items->cap)) {
- return YACErrNoMem;
+ if ((SIZE_MAX - keksItemsPoolGrowLen) < (size_t)(items->cap)) {
+ return KEKSErrNoMem;
}
- items->cap += yacItemsPoolGrowLen;
+ items->cap += keksItemsPoolGrowLen;
{
- const ptrdiff_t possibleN = SIZE_MAX / sizeof(struct YACItem);
+ const ptrdiff_t possibleN = SIZE_MAX / sizeof(struct KEKSItem);
if (items->cap > possibleN) {
- return YACErrNoMem;
+ return KEKSErrNoMem;
}
}
- size_t size = (size_t)(items->cap) * sizeof(struct YACItem);
+ size_t size = (size_t)(items->cap) * sizeof(struct KEKSItem);
items->list = realloc(items->list, size);
if (items->list == NULL) {
- return YACErrNoMem;
+ return KEKSErrNoMem;
}
- size_t begin = items->len * sizeof(struct YACItem);
+ size_t begin = items->len * sizeof(struct KEKSItem);
memset((unsigned char *)(items->list) + begin, 0, size - begin);
if (items->offsets != NULL) {
size = (size_t)(items->cap) * sizeof(size_t);
items->offsets = realloc(items->offsets, size);
if (items->offsets == NULL) {
- return YACErrNoMem;
+ return KEKSErrNoMem;
}
begin = items->len * sizeof(size_t);
memset((unsigned char *)(items->offsets) + begin, 0, size - begin);
}
- return YACErrNo;
+ return KEKSErrNo;
}
-static enum YACErr
-yacItemsAdd(
- struct YACItems *items,
+static enum KEKSErr
+keksItemsAdd(
+ struct KEKSItems *items,
size_t *off,
const unsigned char *buf,
const size_t len)
{
- enum YACErr err = YACErrInvalid;
+ enum KEKSErr err = KEKSErrInvalid;
if (items->len == (size_t)(items->cap)) {
- err = YACItemsGrow(items);
- if (err != YACErrNo) {
+ err = KEKSItemsGrow(items);
+ if (err != KEKSErrNo) {
return err;
}
}
- struct YACItem *item = &(items->list[items->len]);
+ struct KEKSItem *item = &(items->list[items->len]);
item->next = 0;
if (items->offsets != NULL) {
items->offsets[items->len] = *off;
}
size_t got = 0;
assert(len >= (*off));
- err = YACAtomDecode(&got, &(item->atom), buf + *off, len - (*off));
- if (err != YACErrNo) {
+ err = KEKSAtomDecode(&got, &(item->atom), buf + *off, len - (*off));
+ if (err != KEKSErrNo) {
return err;
}
if ((SIZE_MAX - got) < (*off)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
(*off) += got;
items->len++;
- return YACErrNo;
+ return KEKSErrNo;
}
-static enum YACErr
-yacItemsParse( // NOLINT(misc-no-recursion)
- struct YACItems *items,
+static enum KEKSErr
+keksItemsParse( // NOLINT(misc-no-recursion)
+ struct KEKSItems *items,
size_t *off,
const unsigned char *buf,
const size_t len,
const size_t recursionDepth)
{
if (recursionDepth >= parseMaxRecursionDepth) {
- return YACErrDeepRecursion;
+ return KEKSErrDeepRecursion;
}
size_t item = items->len;
- enum YACErr err = yacItemsAdd(items, off, buf, len);
- if (err != YACErrNo) {
+ enum KEKSErr err = keksItemsAdd(items, off, buf, len);
+ if (err != KEKSErrNo) {
return err;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
switch (items->list[item].atom.typ) {
#pragma clang diagnostic pop
- case YACItemList: {
+ case KEKSItemList: {
if (!allowContainers) {
- return YACErrUnknownType;
+ return KEKSErrUnknownType;
}
items->list[item].atom.v.list.head = item + 1;
items->list[item].atom.v.list.len = 0;
size_t cur = 0;
size_t idx = item;
for (;;) {
- err = yacItemsParse(items, off, buf, len, true, recursionDepth + 1);
- if (err != YACErrNo) {
+ err = keksItemsParse(items, off, buf, len, true, recursionDepth + 1);
+ if (err != KEKSErrNo) {
return err;
}
cur = idx + 1;
- if (items->list[cur].atom.typ == YACItemEOC) {
+ if (items->list[cur].atom.typ == KEKSItemEOC) {
if (items->list[item].atom.v.list.len == 0) {
items->list[item].atom.v.list.head = 0;
}
- return YACErrNo;
+ return KEKSErrNo;
}
if (prev != 0) {
items->list[prev].next = cur;
items->list[item].atom.v.list.len++;
}
}
- case YACItemMap: {
+ case KEKSItemMap: {
if (!allowContainers) {
- return YACErrUnknownType;
+ return KEKSErrUnknownType;
}
items->list[item].atom.v.list.head = item + 1;
items->list[item].atom.v.list.len = 0;
size_t prevKeyLen = 0;
const unsigned char *prevKey = NULL;
for (;;) {
- err = yacItemsParse(items, off, buf, len, false, recursionDepth + 1);
- if (err != YACErrNo) {
+ err = keksItemsParse(items, off, buf, len, false, recursionDepth + 1);
+ if (err != KEKSErrNo) {
return err;
}
cur = idx + 1;
#pragma clang diagnostic ignored "-Wswitch-enum"
switch (items->list[cur].atom.typ) {
#pragma clang diagnostic pop
- case YACItemEOC:
+ case KEKSItemEOC:
if (items->list[item].atom.v.list.len == 0) {
items->list[item].atom.v.list.head = 0;
}
- return YACErrNo;
- case YACItemStr:
+ return KEKSErrNo;
+ case KEKSItemStr:
break;
default:
- return YACErrMapBadKey;
+ return KEKSErrMapBadKey;
}
if (items->list[cur].atom.v.str.len == 0) {
- return YACErrMapBadKey;
+ return KEKSErrMapBadKey;
}
if (items->list[cur].atom.v.str.len < prevKeyLen) {
- return YACErrMapUnordered;
+ return KEKSErrMapUnordered;
}
if ((items->list[cur].atom.v.str.len == prevKeyLen) &&
(memcmp(prevKey, items->list[cur].atom.v.str.ptr, prevKeyLen) >= 0)) {
- return YACErrMapUnordered;
+ return KEKSErrMapUnordered;
}
prevKeyLen = items->list[cur].atom.v.str.len;
prevKey = items->list[cur].atom.v.str.ptr;
}
prev = cur;
idx = (items->len) - 1;
- err = yacItemsParse(items, off, buf, len, true, recursionDepth + 1);
- if (err != YACErrNo) {
+ err = keksItemsParse(items, off, buf, len, true, recursionDepth + 1);
+ if (err != KEKSErrNo) {
return err;
}
cur = idx + 1;
- if (items->list[cur].atom.typ == YACItemEOC) {
- return YACErrUnexpectedEOC;
+ if (items->list[cur].atom.typ == KEKSItemEOC) {
+ return KEKSErrUnexpectedEOC;
}
items->list[prev].next = cur;
prev = cur;
items->list[item].atom.v.list.len++;
}
}
- case YACItemBlob: {
+ case KEKSItemBlob: {
if (!allowContainers) {
- return YACErrUnknownType;
+ return KEKSErrUnknownType;
}
items->list[item].atom.v.blob.chunks = 0;
const size_t chunkLen = items->list[item].atom.v.blob.chunkLen;
size_t cur = 0;
bool eoc = false;
while (!eoc) {
- err = yacItemsParse(items, off, buf, len, false, recursionDepth + 1);
- if (err != YACErrNo) {
+ err = keksItemsParse(items, off, buf, len, false, recursionDepth + 1);
+ if (err != KEKSErrNo) {
return err;
}
cur = idx + 1;
- struct YACAtom *atom = &(items->list[cur].atom);
+ struct KEKSAtom *atom = &(items->list[cur].atom);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
switch (atom->typ) {
#pragma clang diagnostic pop
- case YACItemNIL:
+ case KEKSItemNIL:
atom->v.str.len = chunkLen;
assert(len >= (*off));
if ((len - (*off)) <= chunkLen) {
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
- atom->typ = YACItemBin;
+ atom->typ = KEKSItemBin;
atom->v.str.ptr = buf + *off;
if ((SIZE_MAX - chunkLen) < (*off)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
(*off) += chunkLen;
break;
- case YACItemBin:
+ case KEKSItemBin:
if (atom->v.str.len >= chunkLen) {
- return YACErrBlobBadTerm;
+ return KEKSErrBlobBadTerm;
}
eoc = true;
break;
default:
- return YACErrBlobBadAtom;
+ return KEKSErrBlobBadAtom;
}
if (prev != 0) {
items->list[prev].next = cur;
default:
break;
}
- return YACErrNo;
+ return KEKSErrNo;
}
-enum YACErr
-YACItemsParse( // NOLINT(misc-no-recursion)
- struct YACItems *items,
+enum KEKSErr
+KEKSItemsParse( // NOLINT(misc-no-recursion)
+ struct KEKSItems *items,
size_t *off,
const unsigned char *buf,
const size_t len)
{
- enum YACErr err = yacItemsParse(items, off, buf, len, true, 0);
- if (items->list[0].atom.typ == YACItemEOC) {
- err = YACErrUnexpectedEOC;
+ enum KEKSErr err = keksItemsParse(items, off, buf, len, true, 0);
+ if (items->list[0].atom.typ == KEKSItemEOC) {
+ err = KEKSErrUnexpectedEOC;
}
return err;
}
bool
-YACItemsEncode( // NOLINT(misc-no-recursion)
- const struct YACItems *items,
+KEKSItemsEncode( // NOLINT(misc-no-recursion)
+ const struct KEKSItems *items,
size_t idx,
size_t *off,
unsigned char *buf,
const size_t cap)
{
- const struct YACItem *item = &(items->list[idx]);
+ const struct KEKSItem *item = &(items->list[idx]);
size_t got = 0;
bool ok = false;
assert(cap >= (*off));
switch (item->atom.typ) {
- case YACItemInvalid:
- case YACItemEOC:
+ case KEKSItemInvalid:
+ case KEKSItemEOC:
return false;
- case YACItemNIL:
- ok = YACAtomNILEncode(&got, buf + *off, cap - (*off));
+ case KEKSItemNIL:
+ ok = KEKSAtomNILEncode(&got, buf + *off, cap - (*off));
break;
- case YACItemFalse:
- ok = YACAtomBoolEncode(&got, buf + *off, cap - (*off), false);
+ case KEKSItemFalse:
+ ok = KEKSAtomBoolEncode(&got, buf + *off, cap - (*off), false);
break;
- case YACItemTrue:
- ok = YACAtomBoolEncode(&got, buf + *off, cap - (*off), true);
+ case KEKSItemTrue:
+ ok = KEKSAtomBoolEncode(&got, buf + *off, cap - (*off), true);
break;
- case YACItemUUID:
- ok = YACAtomUUIDEncode(&got, buf + *off, cap - (*off), item->atom.v.uuid);
+ case KEKSItemUUID:
+ ok = KEKSAtomUUIDEncode(&got, buf + *off, cap - (*off), item->atom.v.uuid);
break;
- case YACItemPint:
- ok = YACAtomUintEncode(&got, buf + *off, cap - (*off), item->atom.v.pint);
+ case KEKSItemPint:
+ ok = KEKSAtomUintEncode(&got, buf + *off, cap - (*off), item->atom.v.pint);
break;
- case YACItemNint:
- ok = YACAtomSintEncode(&got, buf + *off, cap - (*off), item->atom.v.nint);
+ case KEKSItemNint:
+ ok = KEKSAtomSintEncode(&got, buf + *off, cap - (*off), item->atom.v.nint);
break;
- case YACItemList:
- ok = YACAtomListEncode(&got, buf + *off, cap - (*off));
+ case KEKSItemList:
+ ok = KEKSAtomListEncode(&got, buf + *off, cap - (*off));
if (!ok) {
return false;
}
(*off) += got;
idx = item->atom.v.list.head;
while (idx != 0) {
- ok = YACItemsEncode(items, idx, off, buf, cap);
+ ok = KEKSItemsEncode(items, idx, off, buf, cap);
if (!ok) {
return false;
}
idx = items->list[idx].next;
}
assert(cap >= (*off));
- ok = YACAtomEOCEncode(&got, buf + *off, cap - (*off));
+ ok = KEKSAtomEOCEncode(&got, buf + *off, cap - (*off));
break;
- case YACItemMap:
- ok = YACAtomMapEncode(&got, buf + *off, cap - (*off));
+ case KEKSItemMap:
+ ok = KEKSAtomMapEncode(&got, buf + *off, cap - (*off));
if (!ok) {
return false;
}
(*off) += got;
idx = item->atom.v.list.head;
while (idx != 0) {
- ok = YACItemsEncode(items, idx, off, buf, cap);
+ ok = KEKSItemsEncode(items, idx, off, buf, cap);
if (!ok) {
return false;
}
idx = items->list[idx].next;
}
- ok = YACAtomEOCEncode(&got, buf + *off, cap - (*off));
+ ok = KEKSAtomEOCEncode(&got, buf + *off, cap - (*off));
break;
- case YACItemBlob: {
+ case KEKSItemBlob: {
const size_t chunkLen = (item->atom.v.blob.chunkLen);
- ok = YACAtomBlobEncode(&got, buf + *off, cap - (*off), chunkLen);
+ ok = KEKSAtomBlobEncode(&got, buf + *off, cap - (*off), chunkLen);
if (!ok) {
return 0;
}
break;
}
assert(cap >= (*off));
- ok = YACAtomChunkEncode(
+ ok = KEKSAtomChunkEncode(
&got,
buf + *off,
cap - (*off),
continue;
}
assert(cap >= (*off));
- ok = YACAtomBinEncode(
+ ok = KEKSAtomBinEncode(
&got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len);
break;
}
- case YACItemFloat:
+ case KEKSItemFloat:
return false;
- case YACItemTAI64:
- ok = YACAtomTAI64Encode(
+ case KEKSItemTAI64:
+ ok = KEKSAtomTAI64Encode(
&got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len);
break;
- case YACItemBin:
- ok = YACAtomBinEncode(
+ case KEKSItemBin:
+ ok = KEKSAtomBinEncode(
&got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len);
break;
- case YACItemStr:
- ok = YACAtomStrEncode(
+ case KEKSItemStr:
+ ok = KEKSAtomStrEncode(
&got, buf + *off, cap - (*off), item->atom.v.str.ptr, item->atom.v.str.len);
break;
- case YACItemRaw:
- ok = YACAtomRawEncode(
+ case KEKSItemRaw:
+ ok = KEKSAtomRawEncode(
&got,
buf + *off,
cap - (*off),
}
size_t
-YACItemsGetByKeyLen(
- const struct YACItems *items,
+KEKSItemsGetByKeyLen(
+ const struct KEKSItems *items,
const size_t itemIdx,
const char *key,
const size_t keyLen)
{
- const struct YACItem *item = &(items->list[itemIdx]);
- if (item->atom.typ != YACItemMap) {
+ const struct KEKSItem *item = &(items->list[itemIdx]);
+ if (item->atom.typ != KEKSItemMap) {
return 0;
}
size_t idx = item->atom.v.list.head;
}
size_t
-YACItemsGetByKey(const struct YACItems *items, const size_t itemIdx, const char *key)
+KEKSItemsGetByKey(const struct KEKSItems *items, const size_t itemIdx, const char *key)
{
- return YACItemsGetByKeyLen(items, itemIdx, key, strlen(key));
+ return KEKSItemsGetByKeyLen(items, itemIdx, key, strlen(key));
}
size_t
-YACItemsGetByKeyAndType(
- const struct YACItems *items,
+KEKSItemsGetByKeyAndType(
+ const struct KEKSItems *items,
const size_t itemIdx,
const char *key,
- const enum YACItemType typ)
+ const enum KEKSItemType typ)
{
- const size_t idx = YACItemsGetByKey(items, itemIdx, key);
+ const size_t idx = KEKSItemsGetByKey(items, itemIdx, key);
if ((idx == 0) || (items->list[idx].atom.typ != typ)) {
return 0;
}
}
bool
-YACStrEqual(const struct YACAtom *atom, const char *s)
+KEKSStrEqual(const struct KEKSAtom *atom, const char *s)
{
return (atom->v.str.len == strlen(s)) &&
(memcmp(atom->v.str.ptr, s, atom->v.str.len) == 0);
}
bool
-YACListHasOnlyType(const struct YACItems *items, size_t idx, const enum YACItemType typ)
+KEKSListHasOnlyType(
+ const struct KEKSItems *items,
+ size_t idx,
+ const enum KEKSItemType typ)
{
idx = items->list[idx].atom.v.list.head;
while (idx != 0) {
}
bool
-YACMapHasOnlyType(const struct YACItems *items, size_t idx, const enum YACItemType typ)
+KEKSMapHasOnlyType(
+ const struct KEKSItems *items,
+ size_t idx,
+ const enum KEKSItemType typ)
{
idx = items->list[idx].atom.v.list.head;
while (idx != 0) {
-#ifndef YAC_POOL_H
-#define YAC_POOL_H
+#ifndef KEKS_POOL_H
+#define KEKS_POOL_H
#include <stdbool.h>
#include <stddef.h>
#include "dec.h"
#include "err.h"
-// TEXINFO: YACItem
-// @deftp {Data type} {struct YACItem}
+// TEXINFO: KEKSItem
+// @deftp {Data type} {struct KEKSItem}
// Each item contain the @code{.atom} structure. But item can be a part
// of the list or map, so @code{.next} contains the pool index value to
// the next element of the list or map. It equals to 0, if it is the
// Blob's first element always exists and it is the next binary string
// item, until its length is less than chunk length.
// @end deftp
-struct YACItem {
+struct KEKSItem {
size_t next;
- struct YACAtom atom;
+ struct KEKSAtom atom;
};
-// TEXINFO: YACItems
-// @deftp {Data type} {struct YACItems}
-// Items pool @code{.list} contains concatenated @code{YACItem}s. Item's
+// TEXINFO: KEKSItems
+// @deftp {Data type} {struct KEKSItems}
+// Items pool @code{.list} contains concatenated @code{KEKSItem}s. Item's
// @code{.next} can be used as an index in that pool:
// @code{items->list[item.next]}.
//
// element.
//
// @code{.cap} and @code{.len} are capacity and length of the
-// @code{.list}. If you use @ref{YACItemsParse}, then it parses the
+// @code{.list}. If you use @ref{KEKSItemsParse}, then it parses the
// buffer and continuously appends new items to that list. If its length
-// matches with the capacity, then @ref{YACItemsGrow} is called to
+// matches with the capacity, then @ref{KEKSItemsGrow} is called to
// enlarge the underlying buffer, possibly reallocating the whole of it.
// So be careful with the pointers to the list's items, because they
// could be invalidated after the growth. Using their indices instead
// Corresponding @code{.offsets} store the offset of the decoded item
// relative to the previously provided buffer.
// @end deftp
-struct YACItems {
- struct YACItem *list;
+struct KEKSItems {
+ struct KEKSItem *list;
size_t *offsets;
size_t len;
ptrdiff_t cap;
};
-// TEXINFO: YACItemsInit
-// @deftypefun {enum YACErr} YACItemsInit (struct YACItems *items)
-// Initialise the @ref{YACItems} structure by allocating an initial
+// TEXINFO: KEKSItemsInit
+// @deftypefun {enum KEKSErr} KEKSItemsInit (struct KEKSItems *items)
+// Initialise the @ref{KEKSItems} structure by allocating an initial
// capacity for the underlying storage.
//
// If you do not want to use heap allocation and want to use
// the proper @code{.cap}acity.
//
// If you do not want to store items offsets during decoding, or you use
-// @ref{YACItems} only for encoding purposes, then set @code{.offsets}
+// @ref{KEKSItems} only for encoding purposes, then set @code{.offsets}
// to NULL (do not forget to free it, if it was initialised before).
// @end deftypefun
-enum YACErr
-YACItemsInit(struct YACItems *);
+enum KEKSErr
+KEKSItemsInit(struct KEKSItems *);
-// TEXINFO: YACItemsGrow
-// @deftypefun {enum YACErr} YACItemsGrow (struct YACItems *items)
+// TEXINFO: KEKSItemsGrow
+// @deftypefun {enum KEKSErr} KEKSItemsGrow (struct KEKSItems *items)
// Enlarge underlying storage of items, increasing its capacity. If
// @code{.cap} equals to -1, then nothing will happen and
-// @code{YACErrNoMem} error will be returned. You can use that -1 value
+// @code{KEKSErrNoMem} error will be returned. You can use that -1 value
// to omit attempts to call heap allocation functions.
// @end deftypefun
-enum YACErr
-YACItemsGrow(struct YACItems *);
+enum KEKSErr
+KEKSItemsGrow(struct KEKSItems *);
-// TEXINFO: YACItemsParse
-// @deftypefun {enum YACErr} YACItemsParse ( @
-// struct YACItems *items, @
+// TEXINFO: KEKSItemsParse
+// @deftypefun {enum KEKSErr} KEKSItemsParse ( @
+// struct KEKSItems *items, @
// size_t *off, @
// const unsigned char *buf, @
// const size_t len)
// Parse the provided @var{buf} appending newly created linked
-// @ref{YACItem}s in @var{items}. If there is not enough capacity
-// available, then @ref{YACItemsGrow} is automatically called. If
+// @ref{KEKSItem}s in @var{items}. If there is not enough capacity
+// available, then @ref{KEKSItemsGrow} is automatically called. If
// @code{.offsets} equal to NULL, then no offsets will be stored.
//
// @code{off}set is a position in @var{buf} from which the parsing will
// be done. Its final value is the position when we stopped.
// @end deftypefun
-enum YACErr
-YACItemsParse(
- struct YACItems *,
+enum KEKSErr
+KEKSItemsParse(
+ struct KEKSItems *,
size_t *off,
const unsigned char *buf,
const size_t len);
-// TEXINFO: YACItemsEncode
-// @deftypefun bool YACItemsEncode ( @
-// const struct YACItems *items, @
+// TEXINFO: KEKSItemsEncode
+// @deftypefun bool KEKSItemsEncode ( @
+// const struct KEKSItems *items, @
// size_t idx, @
// size_t *off, @
// unsigned char *buf, @
// length of the encoded data.
// @end deftypefun
bool
-YACItemsEncode(
- const struct YACItems *,
+KEKSItemsEncode(
+ const struct KEKSItems *,
size_t idx,
size_t *off,
unsigned char *buf,
const size_t cap);
-// TEXINFO: YACItemsGetByKeyLen
-// @deftypefun size_t YACItemsGetByKeyLen ( @
-// const struct YACItems *items, @
+// TEXINFO: KEKSItemsGetByKeyLen
+// @deftypefun size_t KEKSItemsGetByKeyLen ( @
+// const struct KEKSItems *items, @
// const size_t itemIdx, @
// const char *key, @
// const size_t keyLen)
// in @var{items}'es element @var{itemIdx}. Returns zero if none found.
// @end deftypefun
size_t
-YACItemsGetByKeyLen(
- const struct YACItems *,
+KEKSItemsGetByKeyLen(
+ const struct KEKSItems *,
const size_t itemIdx,
const char *key,
const size_t keyLen);
-// TEXINFO: YACItemsGetByKey
-// @deftypefun size_t YACItemsGetByKey ( @
-// const struct YACItems *items, @
+// TEXINFO: KEKSItemsGetByKey
+// @deftypefun size_t KEKSItemsGetByKey ( @
+// const struct KEKSItems *items, @
// const size_t itemIdx, @
// const char *key)
// Get the index of the null-terminated key with @var{key} name in
// @var{items}'es element @var{itemIdx}. Returns zero if none found.
// @end deftypefun
size_t
-YACItemsGetByKey(const struct YACItems *, const size_t itemIdx, const char *key);
+KEKSItemsGetByKey(const struct KEKSItems *, const size_t itemIdx, const char *key);
-// TEXINFO: YACItemsGetByKeyAndType
-// @deftypefun size_t YACItemsGetByKeyAndType ( @
-// const struct YACItems *items, @
+// TEXINFO: KEKSItemsGetByKeyAndType
+// @deftypefun size_t KEKSItemsGetByKeyAndType ( @
+// const struct KEKSItems *items, @
// const size_t itemIdx, @
// const char *key, @
-// const enum YACItemType typ)
-// Same as @ref{YACItemsGetByKey}, but also check that value's type is @var{typ}.
+// const enum KEKSItemType typ)
+// Same as @ref{KEKSItemsGetByKey}, but also check that value's type is @var{typ}.
// @end deftypefun
size_t
-YACItemsGetByKeyAndType(
- const struct YACItems *,
+KEKSItemsGetByKeyAndType(
+ const struct KEKSItems *,
const size_t itemIdx,
const char *key,
- const enum YACItemType typ);
+ const enum KEKSItemType typ);
-// TEXINFO: YACStrEqual
-// @deftypefun bool YACStrEqual (const struct YACAtom *atom, const char *s)
+// TEXINFO: KEKSStrEqual
+// @deftypefun bool KEKSStrEqual (const struct KEKSAtom *atom, const char *s)
// Returns true if string atom's value equal to null-terminated @var{s}.
// @end deftypefun
bool
-YACStrEqual(const struct YACAtom *, const char *s);
+KEKSStrEqual(const struct KEKSAtom *, const char *s);
-// TEXINFO: YACListHasOnlyType
-// @deftypefun bool YACListHasOnlyType ( @
-// const struct YACItems *items, @
+// TEXINFO: KEKSListHasOnlyType
+// @deftypefun bool KEKSListHasOnlyType ( @
+// const struct KEKSItems *items, @
// const size_t idx, @
-// const enum YACItemType typ)
+// const enum KEKSItemType typ)
// Returns true if @var{idx} list in @var{items} contains only values
// with the @var{typ} type.
// @end deftypefun
bool
-YACListHasOnlyType(const struct YACItems *, size_t idx, const enum YACItemType typ);
+KEKSListHasOnlyType(const struct KEKSItems *, size_t idx, const enum KEKSItemType typ);
-// TEXINFO: YACMapHasOnlyType
-// @deftypefun bool YACMapHasOnlyType ( @
-// const struct YACItems *items, @
+// TEXINFO: KEKSMapHasOnlyType
+// @deftypefun bool KEKSMapHasOnlyType ( @
+// const struct KEKSItems *items, @
// const size_t idx, @
-// const enum YACItemType typ)
+// const enum KEKSItemType typ)
// Returns true if @var{idx} map in @var{items} contains only values
// with the @var{typ} type.
// @end deftypefun
bool
-YACMapHasOnlyType(const struct YACItems *, size_t idx, const enum YACItemType typ);
+KEKSMapHasOnlyType(const struct KEKSItems *, size_t idx, const enum KEKSItemType typ);
-#endif // YAC_POOL_H
+#endif // KEKS_POOL_H
-// cyac -- C YAC encoder implementation
+// ckeks -- C KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
#include "err.h"
#include "iter.h"
-enum YACErr
-YACIterList(
+enum KEKSErr
+KEKSIterList(
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len,
- YACIterCb cb)
+ KEKSIterCb cb)
{
size_t got = 0;
- enum YACErr err = YACErrInvalid;
+ enum KEKSErr err = KEKSErrInvalid;
bool eoc = false;
for (size_t n = 0;; n++) {
assert(len >= (*off));
- err = YACAtomDecode(&got, atom, buf + *off, len - (*off));
- if (err != YACErrNo) {
+ err = KEKSAtomDecode(&got, atom, buf + *off, len - (*off));
+ if (err != KEKSErrNo) {
return err;
}
if ((SIZE_MAX - got) < (*off)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
(*off) += got;
- eoc = atom->typ == YACItemEOC;
+ eoc = atom->typ == KEKSItemEOC;
err = cb(NULL, 0, !eoc, n, cbState, atom, off, buf, len);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
if (eoc) {
break;
}
}
- return YACErrNo;
+ return KEKSErrNo;
}
-enum YACErr
-YACIterMap(
+enum KEKSErr
+KEKSIterMap(
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len,
- YACIterCb cb)
+ KEKSIterCb cb)
{
- enum YACErr err = YACErrInvalid;
+ enum KEKSErr err = KEKSErrInvalid;
size_t got = 0;
const unsigned char *key = NULL;
size_t keyLen = 0;
for (;;) {
assert(len >= (*off));
- err = YACAtomDecode(&got, atom, buf + *off, len - (*off));
- if (err != YACErrNo) {
+ err = KEKSAtomDecode(&got, atom, buf + *off, len - (*off));
+ if (err != KEKSErrNo) {
return err;
}
if ((SIZE_MAX - got) < (*off)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
(*off) += got;
- if (atom->typ == YACItemEOC) {
+ if (atom->typ == KEKSItemEOC) {
err = cb(NULL, 0, false, 0, cbState, atom, off, buf, len);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
break;
}
- if (atom->typ != YACItemStr) {
- return YACErrMapBadKey;
+ if (atom->typ != KEKSItemStr) {
+ return KEKSErrMapBadKey;
}
if (atom->v.str.len == 0) {
- return YACErrMapBadKey;
+ return KEKSErrMapBadKey;
}
if (atom->v.str.len < keyLen) {
- return YACErrMapUnordered;
+ return KEKSErrMapUnordered;
}
if ((atom->v.str.len == keyLen) &&
(memcmp(key, atom->v.str.ptr, keyLen) >= 0)) {
- return YACErrMapUnordered;
+ return KEKSErrMapUnordered;
}
keyLen = atom->v.str.len;
key = atom->v.str.ptr;
assert(len >= (*off));
- err = YACAtomDecode(&got, atom, buf + *off, len - (*off));
- if (err != YACErrNo) {
+ err = KEKSAtomDecode(&got, atom, buf + *off, len - (*off));
+ if (err != KEKSErrNo) {
return err;
}
if ((SIZE_MAX - got) < (*off)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
(*off) += got;
- if (atom->typ == YACItemEOC) {
- return YACErrUnexpectedEOC;
+ if (atom->typ == KEKSItemEOC) {
+ return KEKSErrUnexpectedEOC;
}
err = cb(key, keyLen, false, 0, cbState, atom, off, buf, len);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
}
- return YACErrNo;
+ return KEKSErrNo;
}
-enum YACErr
-YACIterBlob(
+enum KEKSErr
+KEKSIterBlob(
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len,
- YACIterCb cb)
+ KEKSIterCb cb)
{
const size_t chunkLen = atom->v.blob.chunkLen;
- enum YACErr err = YACErrInvalid;
+ enum KEKSErr err = KEKSErrInvalid;
size_t got = 0;
bool eoc = false;
for (size_t n = 0; !eoc; n++) {
assert(len >= (*off));
- err = YACAtomDecode(&got, atom, buf + *off, len - (*off));
- if (err != YACErrNo) {
+ err = KEKSAtomDecode(&got, atom, buf + *off, len - (*off));
+ if (err != KEKSErrNo) {
return err;
}
if ((SIZE_MAX - got) < (*off)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
(*off) += got;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
switch (atom->typ) {
#pragma clang diagnostic pop
- case YACItemNIL:
+ case KEKSItemNIL:
assert(len >= (*off));
if ((len - *off) <= chunkLen) {
atom->v.str.len = chunkLen;
- return YACErrNotEnough;
+ return KEKSErrNotEnough;
}
- atom->typ = YACItemBin;
+ atom->typ = KEKSItemBin;
atom->v.str.ptr = buf + *off;
atom->v.str.len = chunkLen;
if ((SIZE_MAX - chunkLen) < (*off)) {
- return YACErrLenTooBig;
+ return KEKSErrLenTooBig;
}
(*off) += chunkLen;
break;
- case YACItemBin:
+ case KEKSItemBin:
if ((atom->v.str.len) >= chunkLen) {
- return YACErrBlobBadTerm;
+ return KEKSErrBlobBadTerm;
}
eoc = true;
break;
default:
- return YACErrBlobBadAtom;
+ return KEKSErrBlobBadAtom;
}
err = cb(NULL, 0, true, n, cbState, atom, off, buf, len);
- if (err != YACErrNo) {
+ if (err != KEKSErrNo) {
return err;
}
}
- atom->typ = YACItemEOC;
+ atom->typ = KEKSItemEOC;
err = cb(NULL, 0, false, 0, cbState, atom, off, buf, len);
return err;
}
-#ifndef YAC_ITER_H
-#define YAC_ITER_H
+#ifndef KEKS_ITER_H
+#define KEKS_ITER_H
#include <stdbool.h>
#include <stddef.h>
#include "dec.h"
#include "err.h"
-typedef enum YACErr (*YACIterCb)(
+typedef enum KEKSErr (*KEKSIterCb)(
const unsigned char *key,
const size_t keyLen,
const bool inList,
const size_t idx,
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len);
-enum YACErr
-YACIterList(
+enum KEKSErr
+KEKSIterList(
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len,
- YACIterCb cb);
+ KEKSIterCb cb);
-enum YACErr
-YACIterMap(
+enum KEKSErr
+KEKSIterMap(
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len,
- YACIterCb cb);
+ KEKSIterCb cb);
-enum YACErr
-YACIterBlob(
+enum KEKSErr
+KEKSIterBlob(
void *cbState,
- struct YACAtom *atom,
+ struct KEKSAtom *atom,
size_t *off,
const unsigned char *buf,
const size_t len,
- YACIterCb cb);
+ KEKSIterCb cb);
-#endif // YAC_ITER_H
+#endif // KEKS_ITER_H
#include "leapsecs.h"
-const int64_t YACLeapsecsN = 27;
-const int64_t YACLeapsecs[] = {
+const int64_t KEKSLeapsecsN = 27;
+const int64_t KEKSLeapsecs[] = {
78796810, // 1972-07
94694411, // 1973-01
126230412, // 1974-01
--- /dev/null
+#ifndef KEKS_LEAPSECS_H
+#define KEKS_LEAPSECS_H
+
+#include <stdint.h>
+
+// TEXINFO: KEKSLeapsecs
+// @deftypevar {const int64_t *} KEKSLeapsecs
+// Leap seconds database. It contains TAI seconds when an additional
+// second was added. @var{KEKSLeapsecsN} variable holds the length of
+// that list.
+// @end deftypevar
+extern const int64_t KEKSLeapsecsN;
+extern const int64_t KEKSLeapsecs[];
+
+#endif // KEKS_LEAPSECS_H
--- /dev/null
+/libkekspki.a
#include "../items.h"
#include "cer.h"
-enum YACErr
-YACCerParse(
- struct YACCer *cer,
+enum KEKSErr
+KEKSCerParse(
+ struct KEKSCer *cer,
size_t *off,
char **failReason,
const unsigned char *buf,
const size_t len)
{
- struct YACItems *items = &(cer->items);
- YACItemsInit(items);
- enum YACErr err = YACItemsParse(items, off, buf, len);
- if (err != YACErrNo) {
+ struct KEKSItems *items = &(cer->items);
+ KEKSItemsInit(items);
+ enum KEKSErr err = KEKSItemsParse(items, off, buf, len);
+ if (err != KEKSErrNo) {
return err;
}
size_t idx = 0;
- struct YACItem *item = NULL;
- if (YACItemsGetByKey(items, 0, "hash") != 0) {
+ struct KEKSItem *item = NULL;
+ if (KEKSItemsGetByKey(items, 0, "hash") != 0) {
(*failReason) = "unexpected /hash";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- size_t loadIdx = YACItemsGetByKey(items, 0, "load");
+ size_t loadIdx = KEKSItemsGetByKey(items, 0, "load");
{
if (loadIdx == 0) {
(*failReason) = "no /load";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- idx = YACItemsGetByKeyAndType(items, loadIdx, "t", YACItemStr);
+ idx = KEKSItemsGetByKeyAndType(items, loadIdx, "t", KEKSItemStr);
if (loadIdx == 0) {
(*failReason) = "no /load/t";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- if (!YACStrEqual(&(items->list[idx].atom), "cer")) {
+ if (!KEKSStrEqual(&(items->list[idx].atom), "cer")) {
(*failReason) = "/load/t != cer";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
}
- cer->load = YACItemsGetByKey(items, loadIdx, "v");
+ cer->load = KEKSItemsGetByKey(items, loadIdx, "v");
{
if (cer->load == 0) {
(*failReason) = "no /load/v";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- idx = YACItemsGetByKey(items, cer->load, "ku");
+ idx = KEKSItemsGetByKey(items, cer->load, "ku");
if (idx != 0) {
item = &(items->list[idx]);
if (item->atom.v.list.len == 0) {
(*failReason) = "empty /load/v/ku";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- if (!YACMapHasOnlyType(items, idx, YACItemNIL)) {
+ if (!KEKSMapHasOnlyType(items, idx, KEKSItemNIL)) {
(*failReason) = "bad /load/v/ku value";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
}
}
- idx = YACItemsGetByKey(items, cer->load, "pub");
+ idx = KEKSItemsGetByKey(items, cer->load, "pub");
{
if (idx == 0) {
(*failReason) = "no /load/v/pub";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
item = &(items->list[idx]);
if (item->atom.v.list.len != 1) {
(*failReason) = "len(/load/v/pub) != 1";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
idx = items->list[idx].atom.v.list.head;
cer->pub = idx;
while (idx != 0) {
- if (YACItemsGetByKeyAndType(items, idx, "a", YACItemStr) == 0) {
+ if (KEKSItemsGetByKeyAndType(items, idx, "a", KEKSItemStr) == 0) {
(*failReason) = "no /load/v/pub/a";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- if (YACItemsGetByKeyAndType(items, idx, "v", YACItemBin) == 0) {
+ if (KEKSItemsGetByKeyAndType(items, idx, "v", KEKSItemBin) == 0) {
(*failReason) = "no /load/v/pub/v";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
{
- size_t pkidIdx = YACItemsGetByKeyAndType(items, idx, "id", YACItemUUID);
+ size_t pkidIdx = KEKSItemsGetByKeyAndType(items, idx, "id", KEKSItemUUID);
if (pkidIdx == 0) {
(*failReason) = "no /load/v/pub/id";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
cer->pkid = items->list[pkidIdx].atom.v.uuid;
}
idx = items->list[idx].next;
}
}
- cer->sub = YACItemsGetByKey(items, cer->load, "sub");
+ cer->sub = KEKSItemsGetByKey(items, cer->load, "sub");
{
if (cer->sub == 0) {
(*failReason) = "no /load/v/sub";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
item = &(items->list[cer->sub]);
if (item->atom.v.list.len == 0) {
(*failReason) = "empty /load/v/sub";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- if (!YACMapHasOnlyType(items, cer->sub, YACItemStr)) {
+ if (!KEKSMapHasOnlyType(items, cer->sub, KEKSItemStr)) {
(*failReason) = "bad /load/v/sub value";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
}
- if (YACItemsGetByKey(items, cer->load, "crit") != 0) {
+ if (KEKSItemsGetByKey(items, cer->load, "crit") != 0) {
(*failReason) = "/load/v/crit is unsupported";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- size_t sigsIdx = YACItemsGetByKey(items, 0, "sigs");
+ size_t sigsIdx = KEKSItemsGetByKey(items, 0, "sigs");
{
if (sigsIdx == 0) {
(*failReason) = "no /sigs";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
item = &(items->list[sigsIdx]);
if (item->atom.v.list.len != 1) {
(*failReason) = "len(/load/sigs) != 1";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
size_t sigIdx = items->list[sigsIdx].atom.v.list.head;
cer->sig = sigIdx;
while (sigIdx != 0) {
- if (YACItemsGetByKey(items, sigIdx, "hash") != 0) {
+ if (KEKSItemsGetByKey(items, sigIdx, "hash") != 0) {
(*failReason) = "unexpected /sigs/./hash met";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
{
- idx = YACItemsGetByKey(items, sigIdx, "sign");
+ idx = KEKSItemsGetByKey(items, sigIdx, "sign");
if (idx == 0) {
(*failReason) = "no /sigs/./sign";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- if (YACItemsGetByKeyAndType(items, idx, "a", YACItemStr) == 0) {
+ if (KEKSItemsGetByKeyAndType(items, idx, "a", KEKSItemStr) == 0) {
(*failReason) = "no /sigs/./sign/a";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- if (YACItemsGetByKeyAndType(items, idx, "v", YACItemBin) == 0) {
+ if (KEKSItemsGetByKeyAndType(items, idx, "v", KEKSItemBin) == 0) {
(*failReason) = "no /sigs/./sign/v";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
}
{
- idx = YACItemsGetByKey(items, sigIdx, "tbs");
+ idx = KEKSItemsGetByKey(items, sigIdx, "tbs");
if (idx == 0) {
(*failReason) = "no /sigs/./tbs";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
{
size_t cidIdx =
- YACItemsGetByKeyAndType(items, idx, "cid", YACItemUUID);
+ KEKSItemsGetByKeyAndType(items, idx, "cid", KEKSItemUUID);
if (cidIdx == 0) {
(*failReason) = "no /sigs/./tbs/cid";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
cer->cid = items->list[cidIdx].atom.v.uuid;
}
{
size_t sidIdx =
- YACItemsGetByKeyAndType(items, idx, "sid", YACItemUUID);
+ KEKSItemsGetByKeyAndType(items, idx, "sid", KEKSItemUUID);
if (sidIdx == 0) {
(*failReason) = "no /sigs/./tbs/sid";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
cer->sid = items->list[sidIdx].atom.v.uuid;
}
- idx = YACItemsGetByKeyAndType(items, idx, "exp", YACItemList);
+ idx = KEKSItemsGetByKeyAndType(items, idx, "exp", KEKSItemList);
if (idx == 0) {
(*failReason) = "no /sigs/./tbs/exp";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- if (!YACListHasOnlyType(items, idx, YACItemTAI64)) {
+ if (!KEKSListHasOnlyType(items, idx, KEKSItemTAI64)) {
(*failReason) = "bad /sigs/./tbs/exp value";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
item = &(items->list[idx]);
if (item->atom.v.list.len != 2) {
(*failReason) = "len(/sigs/./tbs/exp) != 2";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- err = YACTAI64ToTimespec(
+ err = KEKSTAI64ToTimespec(
&(cer->since),
items->list[idx + 1].atom.v.str.ptr,
items->list[idx + 1].atom.v.str.len);
- if ((err != YACErrNo) || (cer->since.tv_nsec != 0)) {
+ if ((err != KEKSErrNo) || (cer->since.tv_nsec != 0)) {
(*failReason) = "bad /sigs/./tbs/exp/since value";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- err = YACTimespecToUTC(&(cer->since));
- if (err != YACErrNo) {
+ err = KEKSTimespecToUTC(&(cer->since));
+ if (err != KEKSErrNo) {
(*failReason) = "bad /sigs/./tbs/exp/since UTC value";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- err = YACTAI64ToTimespec(
+ err = KEKSTAI64ToTimespec(
&(cer->till),
items->list[idx + 2].atom.v.str.ptr,
items->list[idx + 2].atom.v.str.len);
- if ((err != YACErrNo) || (cer->till.tv_nsec != 0)) {
+ if ((err != KEKSErrNo) || (cer->till.tv_nsec != 0)) {
(*failReason) = "bad /sigs/./tbs/exp/till value";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
- err = YACTimespecToUTC(&(cer->till));
- if (err != YACErrNo) {
+ err = KEKSTimespecToUTC(&(cer->till));
+ if (err != KEKSErrNo) {
(*failReason) = "bad /sigs/./tbs/exp/till UTC value";
- return YACErrUnsatisfiedSchema;
+ return KEKSErrUnsatisfiedSchema;
}
}
sigIdx = items->list[sigIdx].next;
}
}
- return YACErrNo;
+ return KEKSErrNo;
}
bool
-YACCerVerify(
+KEKSCerVerify(
char **failReason,
- struct YACCer **verifier,
- struct YACCer *cer,
- struct YACCer *pool,
+ struct KEKSCer **verifier,
+ struct KEKSCer *cer,
+ struct KEKSCer *pool,
const size_t poolLen,
- const struct YACCerVerifyOpts opts)
+ const struct KEKSCerVerifyOpts opts)
{
if (opts.t.tv_sec <= cer->since.tv_sec) {
(*failReason) = "unsatisfied since";
(*failReason) = "no verifier found";
return false;
}
- struct YACItem *pubA = &((*verifier)->items.list[YACItemsGetByKey(
+ struct KEKSItem *pubA = &((*verifier)->items.list[KEKSItemsGetByKey(
&((*verifier)->items), (*verifier)->pub, "a")]);
- struct YACItem *pubV = &((*verifier)->items.list[YACItemsGetByKey(
+ struct KEKSItem *pubV = &((*verifier)->items.list[KEKSItemsGetByKey(
&((*verifier)->items), (*verifier)->pub, "v")]);
- size_t signIdx = YACItemsGetByKey(&(cer->items), cer->sig, "sign");
- struct YACItem *sigV =
- &(cer->items.list[YACItemsGetByKey(&(cer->items), signIdx, "v")]);
+ size_t signIdx = KEKSItemsGetByKey(&(cer->items), cer->sig, "sign");
+ struct KEKSItem *sigV =
+ &(cer->items.list[KEKSItemsGetByKey(&(cer->items), signIdx, "v")]);
{
- struct YACItem *sigA =
- &(cer->items.list[YACItemsGetByKey(&(cer->items), signIdx, "a")]);
+ struct KEKSItem *sigA =
+ &(cer->items.list[KEKSItemsGetByKey(&(cer->items), signIdx, "a")]);
if ((sigA->atom.v.str.len != pubA->atom.v.str.len) ||
(memcmp(sigA->atom.v.str.ptr, pubA->atom.v.str.ptr, sigA->atom.v.str.len) !=
0)) {
size_t off = 0;
{
const size_t items = 5;
- struct YACItem tbsItems[5];
+ struct KEKSItem tbsItems[5];
memset(&tbsItems, 0, sizeof tbsItems);
- struct YACItems tbs = {
+ struct KEKSItems tbs = {
.list = tbsItems, .offsets = NULL, .len = items, .cap = -1};
- tbsItems[0].atom.typ = YACItemMap;
+ tbsItems[0].atom.typ = KEKSItemMap;
tbsItems[0].atom.v.list.head = 1;
- tbsItems[1].atom.typ = YACItemStr;
+ tbsItems[1].atom.typ = KEKSItemStr;
tbsItems[1].atom.v.str.len = 1;
tbsItems[1].atom.v.str.ptr = (const unsigned char *)"t";
tbsItems[1].next = 2;
- tbsItems[2].atom.typ = YACItemStr;
+ tbsItems[2].atom.typ = KEKSItemStr;
tbsItems[2].atom.v.str.len = 3;
tbsItems[2].atom.v.str.ptr = (const unsigned char *)"cer";
tbsItems[2].next = 3;
- tbsItems[3].atom.typ = YACItemStr;
+ tbsItems[3].atom.typ = KEKSItemStr;
tbsItems[3].atom.v.str.len = 1;
tbsItems[3].atom.v.str.ptr = (const unsigned char *)"v";
tbsItems[3].next = 4;
- tbsItems[4].atom.typ = YACItemNIL;
+ tbsItems[4].atom.typ = KEKSItemNIL;
tbsItems[4].next = 0;
- if (!YACItemsEncode(&tbs, 0, &off, buf, cap)) {
+ if (!KEKSItemsEncode(&tbs, 0, &off, buf, cap)) {
(*failReason) = "can not prepare tbs: start";
return false;
}
}
off -= 2; // strip off NIL and EOC, continue map generation
- if (!YACItemsEncode(&(cer->items), cer->load, &off, buf, cap)) {
+ if (!KEKSItemsEncode(&(cer->items), cer->load, &off, buf, cap)) {
(*failReason) = "can not prepare tbs: load";
return false;
}
{
size_t got = 0;
- if (!YACAtomStrEncode(
+ if (!KEKSAtomStrEncode(
&got, buf + off, cap - off, (const unsigned char *)"tbs", 3)) {
(*failReason) = "can not prepare tbs: tbs key";
return false;
}
off += got;
}
- if (!YACItemsEncode(
+ if (!KEKSItemsEncode(
&(cer->items),
- YACItemsGetByKey(&(cer->items), cer->sig, "tbs"),
+ KEKSItemsGetByKey(&(cer->items), cer->sig, "tbs"),
&off,
buf,
cap)) {
}
{
size_t got = 0;
- if (!YACAtomEOCEncode(&got, buf + off, cap - off)) {
+ if (!KEKSAtomEOCEncode(&got, buf + off, cap - off)) {
(*failReason) = "can not prepare tbs: eoc";
return false;
}
off += got;
}
for (size_t i = 0; opts.sigVerifiers[i].algo != NULL; i++) {
- if (!YACStrEqual(&(pubA->atom), opts.sigVerifiers[i].algo)) {
+ if (!KEKSStrEqual(&(pubA->atom), opts.sigVerifiers[i].algo)) {
continue;
}
return opts.sigVerifiers[i].func(
-#ifndef YAC_CER_H
-#define YAC_CER_H
+#ifndef KEKS_CER_H
+#define KEKS_CER_H
#include <stdbool.h>
#include <stddef.h>
#include "../err.h"
#include "../items.h"
-// TEXINFO: YACCer
-// @deftp {Data type} {struct YACCer}
+// TEXINFO: KEKSCer
+// @deftp {Data type} {struct KEKSCer}
// Parsed certificate structure.
// @table @code
// @item .items
-// Holds parsed @ref{YACItems} items.
+// Holds parsed @ref{KEKSItems} items.
// @item .load
// Items index of the @code{/load/v}, certificate body.
// @item .pub
// Parsed un"till" datetime.
// @end table
// @end deftp
-struct YACCer {
- struct YACItems items;
+struct KEKSCer {
+ struct KEKSItems items;
size_t load;
size_t pub;
size_t sub;
struct timespec till;
};
-// TEXINFO: YACCerParse
-// @deftypefun {enum YACErr} YACCerParse ( @
-// struct YACCer *cer, @
+// TEXINFO: KEKSCerParse
+// @deftypefun {enum KEKSErr} KEKSCerParse ( @
+// struct KEKSCer *cer, @
// size_t *off, @
// char **failReason, @
// const unsigned char *buf, @
// const size_t len)
-// Parse represented YAC certificate from @var{buf} of @var{len} length,
+// Parse represented KEKS certificate from @var{buf} of @var{len} length,
// to the @var{cer}, starting with @var{off} offset in the buffer.
// Offset will be updated to show where parsing stopped. If parsing,
-// made by @ref{YACItemsParse}, finished successfully, then
-// @code{YACErrUnsatisfiedSchema} may be returned after that, setting
+// made by @ref{KEKSItemsParse}, finished successfully, then
+// @code{KEKSErrUnsatisfiedSchema} may be returned after that, setting
// the @var{failReason} to the string describing the error.
// @end deftypefun
-enum YACErr
-YACCerParse(
- struct YACCer *,
+enum KEKSErr
+KEKSCerParse(
+ struct KEKSCer *,
size_t *off,
char **failReason,
const unsigned char *buf,
const size_t len);
-typedef bool (*yacSigVerifier)(
+typedef bool (*keksSigVerifier)(
char **failReason,
const unsigned char *ai,
const size_t aiLen,
const unsigned char *data,
const size_t dataLen);
-// TEXINFO: YACCerSigVerifier
-// @deftp {Data type} {struct YACCerSigVerifier}
+// TEXINFO: KEKSCerSigVerifier
+// @deftp {Data type} {struct KEKSCerSigVerifier}
// Cryptographic signature verifier. That structure's @code{.algo} holds
-// the string identifier of the algorithm met in the YAC structures.
+// the string identifier of the algorithm met in the KEKS structures.
// @code{.func} holds the pointer to the verifier function itself, that
// accepts the algorithm identifier, signature, raw public key, the data
// to be verified.
// @end deftp
-struct YACCerSigVerifier {
+struct KEKSCerSigVerifier {
char *algo;
- yacSigVerifier func;
+ keksSigVerifier func;
};
-// TEXINFO: YACCerVerifyOpts
-// @deftp {Data type} {struct YACCerVerifyOpts}
+// TEXINFO: KEKSCerVerifyOpts
+// @deftp {Data type} {struct KEKSCerVerifyOpts}
// Certificate verification options:
// @table @code
// @item .t
// Validity time to check against.
// @item .sigVerifiers
-// List of @ref{YACCerSigVerifier}.
+// List of @ref{KEKSCerSigVerifier}.
// Its last dummy element must have NULL @code{.algo}.
// @end table
// @end deftp
-struct YACCerVerifyOpts {
+struct KEKSCerVerifyOpts {
struct timespec t;
- struct YACCerSigVerifier *sigVerifiers;
+ struct KEKSCerSigVerifier *sigVerifiers;
};
-// TEXINFO: YACCerVerify
-// @deftypefun bool YACCerVerify ( @
+// TEXINFO: KEKSCerVerify
+// @deftypefun bool KEKSCerVerify ( @
// char **failReason, @
-// struct YACCer **verifier, @
-// struct YACCer *cer, @
-// struct YACCer *pool, @
+// struct KEKSCer **verifier, @
+// struct KEKSCer *cer, @
+// struct KEKSCer *pool, @
// const size_t poolLen, @
-// const struct YACCerVerifyOpts opts)
+// const struct KEKSCerVerifyOpts opts)
// Verify @var{cer} certificate. @var{pool} is a list of certificates of
// @var{poolLen} length, which is searched for verifier certificates. If
// verifier is found (certificate with @code{pkid} equals to @code{sid}),
// verification process.
// @end deftypefun
bool
-YACCerVerify(
+KEKSCerVerify(
char **failReason,
- struct YACCer **verifier,
- struct YACCer *cer,
- struct YACCer *pool,
+ struct KEKSCer **verifier,
+ struct KEKSCer *cer,
+ struct KEKSCer *pool,
const size_t poolLen,
- const struct YACCerVerifyOpts opts);
+ const struct KEKSCerVerifyOpts opts);
-#endif // YAC_CER_H
+#endif // KEKS_CER_H
--- /dev/null
+redo-ifchange *.h libkekspki.a ../../conf/prefix
+read PREFIX <../../conf/prefix
+mkdir -p $PREFIX/include/keks/pki $PREFIX/lib
+cp -f *.h $PREFIX/include/keks/pki
+cp -f libkekspki.a $PREFIX/lib
+chmod 644 $PREFIX/include/keks/pki/*.h $PREFIX/lib/libkekspki.a
#include "tobe.h"
void
-yacToBE(unsigned char *buf, const size_t len, const uint64_t v)
+keksToBE(unsigned char *buf, const size_t len, const uint64_t v)
{
switch (len) {
case 1:
--- /dev/null
+#ifndef KEKS_TOBE_H
+#define KEKS_TOBE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+// Store big-endian integer of the length @var{len}.
+void
+keksToBE(unsigned char *buf, const size_t len, const uint64_t v);
+
+#endif // KEKS_TOBE_H
#define BETWEEN(c, l, u) (((c) >= (l)) && ((c) <= (u)))
-const uint32_t YACUTF8InvalidCp = 0xFFFD;
+const uint32_t KEKSUTF8InvalidCp = 0xFFFD;
static const struct {
uint32_t mincp;
};
size_t
-YACUTF8CpDecode(uint32_t *cp, const unsigned char *str, const size_t len)
+KEKSUTF8CpDecode(uint32_t *cp, const unsigned char *str, const size_t len)
{
assert(cp != NULL);
if (str == NULL || len == 0) {
- (*cp) = YACUTF8InvalidCp;
+ (*cp) = KEKSUTF8InvalidCp;
return 0;
}
if (str[0] == 0) {
- (*cp) = YACUTF8InvalidCp;
+ (*cp) = KEKSUTF8InvalidCp;
return 1;
}
size_t off = 0;
}
}
if (off == 4) {
- (*cp) = YACUTF8InvalidCp;
+ (*cp) = KEKSUTF8InvalidCp;
return 1;
}
size_t i = 0;
if ((1 + off) > len) {
- (*cp) = YACUTF8InvalidCp;
+ (*cp) = KEKSUTF8InvalidCp;
for (i = 0; 1 + i < len; i++) {
if (!BETWEEN(str[1 + i], 0x80, 0xBF)) {
break;
}
for (i = 1; i <= off; i++) {
if (!BETWEEN(str[i], 0x80, 0xBF)) {
- (*cp) = YACUTF8InvalidCp;
+ (*cp) = KEKSUTF8InvalidCp;
return 1 + (i - 1);
}
(*cp) = (*cp << (uint8_t)6) | // NOLINT(hicpp-signed-bitwise)
(str[i] & (uint8_t)0x3F);
}
if ((*cp < lut[off].mincp) || BETWEEN(*cp, 0xD800, 0xDFFF) || (*cp > 0x10FFFF)) {
- (*cp) = YACUTF8InvalidCp;
+ (*cp) = KEKSUTF8InvalidCp;
}
return 1 + off;
}
--- /dev/null
+#ifndef KEKS_UTF8_H
+#define KEKS_UTF8_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+extern const uint32_t KEKSUTF8InvalidCp;
+
+size_t
+KEKSUTF8CpDecode(uint32_t *cp, const unsigned char *str, const size_t len);
+
+#endif // KEKS_UTF8_H
+++ /dev/null
-C99 implementation of the YAC codec.
-Look at doc/ for more information.
+++ /dev/null
-#ifndef YAC_PRINTAI_H
-#define YAC_PRINTAI_H
-
-#include <stddef.h>
-
-#include <yac/err.h>
-
-enum YACErr
-PrintTAI64(const unsigned char *buf, const size_t len);
-
-#endif // YAC_PRINTAI_H
+++ /dev/null
-#ifndef YAC_UUID_H
-#define YAC_UUID_H
-
-void
-UUIDPrint(const unsigned char *buf);
-
-#endif // YAC_UUID_H
+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <yac/atoms.h>
-#include <yac/enc.h>
-#include <yac/enctai.h>
-
-static size_t Off = 0;
-static size_t Got = 0;
-
-static void
-adder(const bool ok)
-{
- assert(ok);
- Off += Got;
-}
-
-int
-main(void)
-{
- const size_t len = (size_t)68 * (uint16_t)1024;
- unsigned char *buf = malloc(len);
- assert(buf != NULL);
- unsigned char *bin = malloc((uint32_t)1 << (uint8_t)17);
- assert(bin != NULL);
-
- adder(YACAtomMapEncode(&Got, buf + Off, len - Off)); // .
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"nil", 3));
- adder(YACAtomNILEncode(&Got, buf + Off, len - Off));
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"str", 3));
- adder(YACAtomMapEncode(&Got, buf + Off, len - Off)); // .str
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"bin", 3));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .str.bin
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, (const unsigned char *)"", 0));
- memset(bin, '0', 60);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 60));
- memset(bin, '1', 61);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 61));
- memset(bin, '2', 255);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 255));
- memset(bin, 'A', 61 + 255);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 61 + 255));
- memset(bin, 'B', 62 + 255);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 62 + 255));
- memset(bin, '3', 1024);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 1024));
- memset(bin, '4', 63 + 255 + 65535 + 1);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 63 + 255 + 65535 + 1));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .str.bin
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"utf8", 4));
- adder(YACAtomStrEncode(
- &Got, buf + Off, len - Off, (const unsigned char *)"Đ¿Ñ€Đ¸Đ²ĐµÑ‚ Đ¼Đ¸Ñ€", 19));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .str
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"blob", 4));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .blob
-
- adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.0
- memset(bin, '5', 1);
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 1));
-
- adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.1
- memset(bin, '6', 12);
- adder(YACAtomChunkEncode(&Got, buf + Off, len - Off, bin, 12));
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, NULL, 0));
-
- adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 12)); // .blob.2
- memset(bin, '7', 12);
- adder(YACAtomChunkEncode(&Got, buf + Off, len - Off, bin, 12));
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, bin, 1));
-
- adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 5)); // .blob.3
- adder(YACAtomChunkEncode(
- &Got, buf + Off, len - Off, (const unsigned char *)"12345", 5));
- adder(YACAtomChunkEncode(
- &Got, buf + Off, len - Off, (const unsigned char *)"67890", 5));
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, (const unsigned char *)"-", 1));
-
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .blob
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"bool", 4));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .bool
- adder(YACAtomBoolEncode(&Got, buf + Off, len - Off, true));
- adder(YACAtomBoolEncode(&Got, buf + Off, len - Off, false));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .bool
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"ints", 4));
- adder(YACAtomMapEncode(&Got, buf + Off, len - Off)); // .ints
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"neg", 3));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .ints.neg
- adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -1));
- adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -2));
- adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -32));
- adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -33));
- adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -123));
- adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -1234));
- adder(YACAtomSintEncode(&Got, buf + Off, len - Off, -12345678));
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomNint,
- (const unsigned char *)"\x8A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
- 11));
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomNint,
- (const unsigned char
- *)"\x91\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- 18));
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomNint,
- (const unsigned char
- *)"\xBE\x00\xA1\xE5\xA4\x61\x28\x03\x41\x85\x6D\x4A\xD9\x08\xA6\x9E\xA5\xF3\xCC\xC1\x0C\x78\x82\x14\x2B\xB7\xD8\x01\xCC\x38\x0F\x26\xB6\xB4\xD6\x96\x32\x02\x4E\xE5\x21\xF8\xCF\xAF\xB4\x43\xD4\x9A\x2A\x3D\x0C\xC7\x3B\xB4\x75\x7E\x88\x2F\x53\x96\xED\x30\x2B\x41\x82\x10\xD0\xD4\x9D\x71\xBE\x86\xCA\x69\x9C\xF5\xEE\x3B\xD6\xD5\x7E\xD6\x58\xE6\x93\x16\x22\x96\x44\xBA\x65\x0C\x92\xD7\xF0\xD4\xDB\x29\xC3\xAD\x1D\xFA\x99\x79\x16\x6F\x4C\x6E\x79\x56\x1A\x58\xF8\xE2\xC6\x3D\x08\xDF\x4E\x22\x46\xED\x1F\x64\xD2\xD6\x13\xA1\x9D\x8C\x9A\x68\x70\xE6\x18\x8E\x2F\x3A\xD4\x0C\x03\x8F\xDA\x30\x45\x2F\x8D\xDF\xCD\x21\x2A\x6A\x97\x4B\xC2\x5E\xC6\xA0\x56\x4C\x66\xA7\xD2\x87\x50\xFF\x9D\xB4\x58\xB7\x44\x41\xE4\x9E\xE5\xE8\x2D\xBF\x49\x74\xD6\x45\x67\x8E\x0A\xD0\x31\xF9\x7A\xAB\xA8\x55\x45\x1E\xEF\x17\xA8\x9B\x42\x82\x1E\x53\x08\x16\xDD\x57\x93\xA8\x3B\x7A\x82\xE8\xED\xE8\x1E\x7F\x33\x95\x69\x1F\x76\x17\x84\xF8\xBC\x62\x79\x61\xCD\x40\x84\x5E\xE9\x08\xA4\x0B\x9D\x1F\x01\x92\x7B\x38\xEB\x1A\x7D\x4E\xFD\x60\xDB\x09\x44\xF7\xEC\x1B\x83\x2B\x7E\x6E\xB1\x83\x3F\x9A\x35\x15\x76\xAD\x5D\xE5\x71\xFA\xE8\x86\x5D\xA7\x51\x4F\x06\xB0\xFB\xF3\x8C\x1F\x2A\x85\x38\xF5\xD3\x8B\x4E\x18\x00\x1C\xCB\xB9\xDD\xCB\x48\x85\x30\xF6\x08\x6D\x14\x74\x4D\x8B\x56\x72\x16\x6E\x48\xE9\xEF\x93\x77\x25\x75\xDB\x66\xB6\xF2\x57\xC6\xFF\xAD\x6E\x2C\x29\x15\x10\xC5\xED\x02\xE1\xA8\xB2\x4B\x44\xEC\x1E\x2A\x91\x68\x62\x38\xE8\xDE\xFD\x18\xC0\x19\x98\x63\x4A\x50\x76\xA6\xB7\xF8\x5F\xC8\x1A\x1D\x61\xA1\x5B\x2C\x52\x8D\xFA\x08\x2C\xE3\xE3\xE2\xCA\x64\x9A\xC0\x48\x17\xEC\x5C\x12\x3E\x0B\x76\x1A\xB1\x03\xF7\x80\xC0\x14\xF0\x21\xBB\xEB\x7E\xA3\xB8\x6E\x0C\xA1\xC8\x33\xE3\x8E\xF5\xC8\x97\xA6\xD7\xE1\xF4\xA2\x39\x8C\x49\x0B\x3D\x65\xE2\xF4\x5C\x7F\xAE\x40\x2D\x1D\xF1\x69\x8B\x6F\xDD\xB1\x85\x48\x16\x64\x87\x1C\x26\x64\xBF\xD1\x68\x6B\x2B\x33\x72\x78\x3F\x18\x56\xF6\x24\x7A\x3F\x84\x37\xA2\x81\x8F\x68\xB7\xC4\xEA\x13\xA5\xF5\x7B\x73\xC7\x28\x70\xB6\x84\x04\x5F\x14",
- 481));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.neg
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"pos", 3));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .ints.pos
- adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 0));
- adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 1));
- adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 31));
- adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 32));
- adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 123));
- adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 1234));
- adder(YACAtomUintEncode(&Got, buf + Off, len - Off, 12345678));
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomPint,
- (const unsigned char *)"\x8B\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- 12));
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomPint,
- (const unsigned char
- *)"\x91\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
- 18));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints.pos
-
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .ints
-
- adder(
- YACAtomStrEncode(&Got, buf + Off, len - Off, (const unsigned char *)"uuid", 4));
- adder(YACAtomUUIDEncode(
- &Got,
- buf + Off,
- len - Off,
- (const unsigned char
- *)"\x0e\x87\x5e\x3f\xd3\x85\x49\xeb\x87\xb4\xbe\x42\xd6\x41\xc3\x67"));
-
- adder(YACAtomStrEncode(
- &Got, buf + Off, len - Off, (const unsigned char *)"dates", 5));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .dates
- {
- struct timespec ts;
- ts.tv_sec = 1234567890;
- assert(YACTimespecToTAI(&ts));
- unsigned char tai[12] = {0};
- assert(YACTimespecToTAI64(tai, &ts));
- adder(YACAtomTAI64Encode(&Got, buf + Off, len - Off, tai, 8));
-
- ts.tv_nsec = 456000;
- assert(YACTimespecToTAI64(tai, &ts));
- adder(YACAtomTAI64Encode(&Got, buf + Off, len - Off, tai, 12));
-
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomTAI64N,
- (const unsigned char *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55",
- 12));
-
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomTAI64NA,
- (const unsigned char
- *)"\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55\x07\x5B\xCD\x15",
- 16));
- }
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .dates
-
- adder(YACAtomStrEncode(
- &Got, buf + Off, len - Off, (const unsigned char *)"floats", 6));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .floats
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomFloat32,
- (const unsigned char *)"\x01\x02\x03\x04",
- 4));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .floats
-
- adder(YACAtomStrEncode(
- &Got, buf + Off, len - Off, (const unsigned char *)"empties", 7));
- adder(YACAtomListEncode(&Got, buf + Off, len - Off)); // .empties
- adder(YACAtomListEncode(&Got, buf + Off, len - Off));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off));
- adder(YACAtomMapEncode(&Got, buf + Off, len - Off));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off));
- adder(YACAtomBlobEncode(&Got, buf + Off, len - Off, 123));
- adder(YACAtomBinEncode(&Got, buf + Off, len - Off, NULL, 0));
- memset(bin, '\x00', 16);
- adder(YACAtomUUIDEncode(&Got, buf + Off, len - Off, bin));
- adder(YACAtomRawEncode(
- &Got,
- buf + Off,
- len - Off,
- YACAtomTAI64,
- (const unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00",
- 8));
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .empties
-
- adder(YACAtomEOCEncode(&Got, buf + Off, len - Off)); // .
-
- free(bin);
- assert(write(STDOUT_FILENO, buf, Off) == (ssize_t)Off);
- free(buf);
-
- return EXIT_SUCCESS;
-}
+++ /dev/null
-@node Atom
-@cindex atom
-@unnumbered Atom
-
-@anchor{YACAtom}
-@DOCSTRING YACAtom@
-
-@anchor{YACItemType}
-@DOCSTRING YACItemType@
-
-@DOCSTRING YACAtomDecode@
-
-@DOCSTRING YACAtomEOCEncode@
-@anchor{YACAtomNILEncode}
-@DOCSTRING YACAtomNILEncode@
-@DOCSTRING YACAtomBoolEncode@
-@DOCSTRING YACAtomUUIDEncode@
-@DOCSTRING YACAtomUintEncode@
-@DOCSTRING YACAtomSintEncode@
-@DOCSTRING YACAtomListEncode@
-@DOCSTRING YACAtomMapEncode@
-@DOCSTRING YACAtomBlobEncode@
-@DOCSTRING YACAtomStrEncode@
-@anchor{YACAtomBinEncode}
-@DOCSTRING YACAtomBinEncode@
-@anchor{YACAtomChunkEncode}
-@DOCSTRING YACAtomChunkEncode@
-@DOCSTRING YACAtomTAI64Encode@
-@DOCSTRING YACAtomRawEncode@
+++ /dev/null
-@node Items
-@cindex items
-@unnumbered Items
-
-Streamable decoding by one atom is not very convenient in many cases.
-There is ability to recursively decode the whole structures.
-
-@anchor{YACItems}
-@DOCSTRING YACItems@
-@anchor{YACItem}
-@DOCSTRING YACItem@
-@DOCSTRING YACItemsInit@
-@anchor{YACItemsGrow}
-@DOCSTRING YACItemsGrow@
-@anchor{YACItemsParse}
-@DOCSTRING YACItemsParse@
-@DOCSTRING YACItemsEncode@
-@DOCSTRING YACItemsGetByKeyLen@
-@anchor{YACItemsGetByKey}
-@DOCSTRING YACItemsGetByKey@
-@DOCSTRING YACItemsGetByKeyAndType@
-@DOCSTRING YACStrEqual@
-@DOCSTRING YACListHasOnlyType@
-@DOCSTRING YACMapHasOnlyType@
+++ /dev/null
-@node PKI
-@cindex PKI
-@unnumbered PKI
-
-@file{lib/pki} contains PKI-related code. It is not directly related to
-the YAC codec, so it is placed isolated nearby. Currently there are
-functions to deal with certificate verification:
-
-@anchor{YACCer}
-@DOCSTRING YACCer@
-
-@DOCSTRING YACCerParse@
-
-@DOCSTRING YACCerVerify@
-
-@DOCSTRING YACCerVerifyOpts@
-
-@anchor{YACCerSigVerifier}
-@DOCSTRING YACCerSigVerifier@
+++ /dev/null
-@node Datetime
-@cindex TAI64
-@cindex datetime
-@unnumbered Datetime
-
-YAC uses @url{http://cr.yp.to/libtai/tai64.html, TAI64} for datetime
-objects. There are helpers to convert it to UTC and vice versa.
-
-@DOCSTRING YACTAI64ToTimespec@
-@DOCSTRING YACTimespecToUTC@
-@DOCSTRING YACTimespecToTAI64@
-@DOCSTRING YACTimespecToTAI@
-@DOCSTRING YACLeapsecs@
+++ /dev/null
-#ifndef YAC_ATOMS_H
-#define YAC_ATOMS_H
-
-enum YACAtomType {
- YACAtomEOC = 0x00,
- YACAtomNIL = 0x01,
- YACAtomFalse = 0x02,
- YACAtomTrue = 0x03,
- YACAtomUUID = 0x04,
- YACAtomList = 0x08,
- YACAtomMap = 0x09,
- YACAtomBlob = 0x0B,
- YACAtomPint = 0x0C,
- YACAtomNint = 0x0D,
- YACAtomFloat16 = 0x10,
- YACAtomFloat32 = 0x11,
- YACAtomFloat64 = 0x12,
- YACAtomFloat128 = 0x13,
- YACAtomFloat256 = 0x14,
- YACAtomTAI64 = 0x18,
- YACAtomTAI64N = 0x19,
- YACAtomTAI64NA = 0x1A,
-
- YACAtomStrings = 0x80,
- YACAtomIsUTF8 = 0x40,
-};
-
-#endif // YAC_ATOMS_H
+++ /dev/null
-#ifndef YAC_DECTAI_H
-#define YAC_DECTAI_H
-
-#include <stddef.h>
-#include <time.h>
-
-#include "err.h"
-
-// TEXINFO: YACTAI64ToTimespec
-// @deftypefun {enum YACErr} YACTAI64ToTimespec @
-// (struct timespec *tv, const unsigned char *buf, const size_t len)
-// Convert TAI64* value from @var{buf} to @var{ts} structure.
-// @code{YACErrTAI64InPast} error is returned if value represents time
-// before 1970. Some systems support those dates, but not guaranteed to.
-// @code{YACErrTAI64TooBig} error is returned when time is out of bounds
-// of @code{time_t} representation. @code{YACErrTAI64BadAsec} is
-// returned if TAI64NA is provided, because currently no systems support
-// attoseconds.
-// @end deftypefun
-enum YACErr
-YACTAI64ToTimespec(struct timespec *ts, const unsigned char *buf, const size_t len);
-
-// TEXINFO: YACTimespecToUTC
-// @deftypefun {enum YACErr} YACTimespecToUTC (struct timespec *ts)
-// Convert TAI stored in @var{ts} structure to UTC. @code{YACErrTAI64InPast}
-// error is returned if value represents time before 1970.
-// @end deftypefun
-enum YACErr
-YACTimespecToUTC(struct timespec *ts);
-
-#endif // YAC_DECTAI_H
+++ /dev/null
-#ifndef YAC_ERR_H
-#define YAC_ERR_H
-
-// TEXINFO: YACErr
-// @deftp {Data type} {enum YACErr}
-// Errors are just a predefined enumeration value.
-// @table @code
-// @item YACErrInvalid
-// Unset error, must be never met.
-// @item YACErrNo
-// No error, everything is good.
-// @item YACErrNotEnough
-// Not enough data. Atom's @code{.off} must contain how much.
-// @item YACErrUnknownType, // unknown atom's type
-// Unknown atom's type.
-// @item YACErrLenTooBig,
-// Too long string (>1<<60), can not be decoded.
-// @item YACErrBadUTF8
-// Invalid UTF-8 codepoint or zero byte met.
-// @item YACErrIntNonMinimal
-// Non minimal integer encoding.
-// @item YACErrBlobBadAtom
-// Blob contains unexpected atom.
-// @item YACErrBlobBadTerm
-// Blob contains invalid terminator.
-// @item YACErrTAI64TooBig
-// Too large TAI64 value, out-of-bounds.
-// @item YACErrTAI64BadNsec
-// Invalid TAI64 nanoseconds value.
-// @item YACErrTAI64BadAsec
-// Invalid TAI64 attoseconds value.
-// @item YACErrMapBadKey
-// Either bad type of map's key, or it is empty.
-// @item YACErrMapUnordered
-// Unordered map keys.
-// @item YACErrNoMem
-// Not enough memory for allocation.
-// @item YACErrUnsatisfiedSchema
-// Unsatisfied structure's schema.
-// @item YACErrDeepRecursion
-// Too deep recursion involved during parsing.
-// @item YACErrUnexpectedEOC
-// Unexpected EOC met.
-// @end table
-// @end deftp
-enum YACErr {
- YACErrInvalid = 0,
- YACErrNo = 1,
- YACErrNotEnough,
- YACErrUnknownType,
- YACErrLenTooBig,
- YACErrBadUTF8,
- YACErrIntNonBin,
- YACErrIntNonMinimal,
- YACErrBlobBadAtom,
- YACErrBlobBadTerm,
- YACErrTAI64TooBig,
- YACErrTAI64BadNsec,
- YACErrTAI64BadAsec,
- YACErrTAI64InPast,
- YACErrTAI64IsLeap,
- YACErrTAI64NonMinimal,
- YACErrMapBadKey,
- YACErrMapUnordered,
- YACErrNoMem,
- YACErrUnsatisfiedSchema,
- YACErrDeepRecursion,
- YACErrUnexpectedEOC,
-};
-
-// TEXINFO: YACErr2Str
-// @deftypefun {const char *} YACErr2Str (const enum YACErr)
-// Get human-readable string of the error.
-// @end deftypefun
-const char *
-YACErr2Str(const enum YACErr);
-
-#endif // YAC_ERR_H
+++ /dev/null
-#ifndef YAC_FROMBE_H
-#define YAC_FROMBE_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-// Decode big-endian integer of the length @var{len}.
-uint64_t
-yacFromBE(const unsigned char *buf, const size_t len);
-
-#endif // YAC_FROMBE_H
+++ /dev/null
-redo-ifchange *.h libyac.a ../conf/prefix
-read PREFIX <../conf/prefix
-mkdir -p $PREFIX/include/yac $PREFIX/lib
-cp -f *.h $PREFIX/include/yac
-cp -f libyac.a $PREFIX/lib
-chmod 644 $PREFIX/include/yac/*.h $PREFIX/lib/libyac.a
+++ /dev/null
-#ifndef YAC_LEAPSECS_H
-#define YAC_LEAPSECS_H
-
-#include <stdint.h>
-
-// TEXINFO: YACLeapsecs
-// @deftypevar {const int64_t *} YACLeapsecs
-// Leap seconds database. It contains TAI seconds when an additional
-// second was added. @var{YACLeapsecsN} variable holds the length of
-// that list.
-// @end deftypevar
-extern const int64_t YACLeapsecsN;
-extern const int64_t YACLeapsecs[];
-
-#endif // YAC_LEAPSECS_H
+++ /dev/null
-/libyacpki.a
+++ /dev/null
-redo-ifchange *.h libyacpki.a ../../conf/prefix
-read PREFIX <../../conf/prefix
-mkdir -p $PREFIX/include/yac/pki $PREFIX/lib
-cp -f *.h $PREFIX/include/yac/pki
-cp -f libyacpki.a $PREFIX/lib
-chmod 644 $PREFIX/include/yac/pki/*.h $PREFIX/lib/libyacpki.a
+++ /dev/null
-#ifndef YAC_TOBE_H
-#define YAC_TOBE_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-// Store big-endian integer of the length @var{len}.
-void
-yacToBE(unsigned char *buf, const size_t len, const uint64_t v);
-
-#endif // YAC_TOBE_H
+++ /dev/null
-#ifndef YAC_UTF8_H
-#define YAC_UTF8_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-extern const uint32_t YACUTF8InvalidCp;
-
-size_t
-YACUTF8CpDecode(uint32_t *cp, const unsigned char *str, const size_t len);
-
-#endif // YAC_UTF8_H
-Go implementation of the YAC codec.
+GoKEKS is Go implementation of the KEKS codec.
* No FLOAT*, INTs greater than 64-bit, TAI64NA.
They are stored/decoded just as a raw value
* Actual negative integer maximal size is -2^63-1
-gyac is free software: see the file COPYING.LESSER for copying conditions.
+GoKEKS is free software: see the file COPYING.LESSER for copying conditions.
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
"github.com/google/uuid"
- "go.cypherpunks.su/yac/gyac/atom/be"
- "go.cypherpunks.su/yac/gyac/types"
+ "go.cypherpunks.su/keks/atom/be"
+ "go.cypherpunks.su/keks/types"
)
var (
return
}
-// Decode a single YAC-encoded atom. Atom means that it does not decode
+// Decode a single KEKS-encoded atom. Atom means that it does not decode
// full lists, maps, blobs and may return types.EOC.
func Decode(r io.Reader) (t types.Type, v any, read int64, err error) {
buf := make([]byte, 1)
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
"github.com/google/uuid"
- "go.cypherpunks.su/yac/gyac/atom/be"
+ "go.cypherpunks.su/keks/atom/be"
)
var bigIntZero = big.NewInt(0)
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
-package gyac
+package keks
import (
"fmt"
"log"
"os"
- "go.cypherpunks.su/yac/gyac"
+ "go.cypherpunks.su/keks"
)
func main() {
- item, read, err := gyac.Decode(bufio.NewReader(os.Stdin))
+ item, read, err := keks.Decode(bufio.NewReader(os.Stdin))
if err != nil {
log.Fatal(err)
}
"github.com/google/uuid"
- "go.cypherpunks.su/yac/gyac"
- "go.cypherpunks.su/yac/gyac/atom"
+ "go.cypherpunks.su/keks"
+ "go.cypherpunks.su/keks/atom"
)
func mustHexDec(s string) []byte {
"utf8": "Đ¿Ñ€Đ¸Đ²ĐµÑ‚ Đ¼Đ¸Ñ€",
},
"blob": []any{
- gyac.Blob{ChunkLen: 12, R: strings.NewReader("5")},
- gyac.Blob{ChunkLen: 12, R: strings.NewReader(strings.Repeat("6", 12))},
- gyac.Blob{ChunkLen: 12, R: strings.NewReader(strings.Repeat("7", 13))},
- gyac.Blob{ChunkLen: 5, R: strings.NewReader("1234567890-")},
+ keks.Blob{ChunkLen: 12, R: strings.NewReader("5")},
+ keks.Blob{ChunkLen: 12, R: strings.NewReader(strings.Repeat("6", 12))},
+ keks.Blob{ChunkLen: 12, R: strings.NewReader(strings.Repeat("7", 13))},
+ keks.Blob{ChunkLen: 5, R: strings.NewReader("1234567890-")},
},
"empties": []any{
[]any{},
map[string]any{},
- gyac.Blob{ChunkLen: 123, R: bytes.NewReader(nil)},
+ keks.Blob{ChunkLen: 123, R: bytes.NewReader(nil)},
uuid.Nil,
atom.Raw{T: atom.TAI64, V: mustHexDec("0000000000000000")},
},
},
"uuid": uuid.MustParse("0e875e3f-d385-49eb-87b4-be42d641c367"),
}
- item, err := gyac.FromGo(data)
+ item, err := keks.FromGo(data)
if err != nil {
log.Fatal(err)
}
"github.com/google/uuid"
"go.cypherpunks.su/tai64n/v4"
- "go.cypherpunks.su/yac/gyac/atom"
+ "go.cypherpunks.su/keks/atom"
)
func mustHexDec(s string) []byte {
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
-package gyac
+package keks
import (
"bytes"
"errors"
"io"
- "go.cypherpunks.su/yac/gyac/atom"
- "go.cypherpunks.su/yac/gyac/types"
+ "go.cypherpunks.su/keks/atom"
+ "go.cypherpunks.su/keks/types"
)
const parseMaxRecursionDepth = 1 << 10
return
}
-// Decode single YAC-encoded data item.
+// Decode single KEKS-encoded data item.
func Decode(r io.Reader) (item Item, read int64, err error) {
item, read, err = decode(r, true, 0)
if item.T == types.EOC {
--- /dev/null
+// KEKS (http://www.keks.cypherpunks.su) is compact, deterministic,
+// concise and streaming binary serialisation format. It is aimed to be
+// lightweight in terms of CPU, memory, storage and codec implementation
+// size usage. It supports wide range of data types, making it able to
+// transparently replace JSON.
+package keks
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
-package gyac
+package keks
import (
"bytes"
"github.com/google/uuid"
- "go.cypherpunks.su/yac/gyac/atom"
- "go.cypherpunks.su/yac/gyac/types"
+ "go.cypherpunks.su/keks/atom"
+ "go.cypherpunks.su/keks/types"
)
// Encode an item.
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
-package gyac
+package keks
import (
"fmt"
"github.com/google/uuid"
"go.cypherpunks.su/tai64n/v4"
- "go.cypherpunks.su/yac/gyac/atom"
- "go.cypherpunks.su/yac/gyac/types"
+ "go.cypherpunks.su/keks/atom"
+ "go.cypherpunks.su/keks/types"
)
func structTagRead(f reflect.StructField) (name string, omit bool) {
name = f.Name
- v, ok := f.Tag.Lookup("yac")
+ v, ok := f.Tag.Lookup("keks")
if !ok {
return
}
-package gyac
+package keks
import (
"bytes"
-module go.cypherpunks.su/yac/gyac
+module go.cypherpunks.su/keks
go 1.22
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
"errors"
"io"
- "go.cypherpunks.su/yac/gyac"
- "go.cypherpunks.su/yac/gyac/types"
+ "go.cypherpunks.su/keks"
+ "go.cypherpunks.su/keks/types"
)
-// Decode YAC-encoded data to the dst structure.
+// Decode KEKS-encoded data to the dst structure.
// It will return an error if decoded data is not map.
func Decode(dst any, src io.Reader) (err error) {
- var item gyac.Item
- item, _, err = gyac.Decode(src)
+ var item keks.Item
+ item, _, err = keks.Decode(src)
if err != nil {
return
}
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// Fill up dst structure with the contents taken from the src map.
func FromMap(dst any, src map[string]any) error {
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
- Result: dst, TagName: "yac",
+ Result: dst, TagName: "keks",
})
if err != nil {
return err
tmp=$(mktemp -d)
trap "rm -fr $tmp" HUP PIPE INT QUIT TERM EXIT
cd $tmp
-PATH="$root/../tyac:$PATH"
+PATH="$root/../tcl:$PATH"
mk-fuzz-inputs
cd "$root"
dst=testdata/fuzz/FuzzItemDecode
package pki
import (
- "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b"
- "go.cypherpunks.su/yac/gyac/pki/gost"
+ "go.cypherpunks.su/keks/pki/ed25519-blake2b"
+ "go.cypherpunks.su/keks/pki/gost"
)
const (
"github.com/google/uuid"
- "go.cypherpunks.su/yac/gyac"
- pkihash "go.cypherpunks.su/yac/gyac/pki/hash"
+ "go.cypherpunks.su/keks"
+ pkihash "go.cypherpunks.su/keks/pki/hash"
)
// Algorithm-value often used structure.
type AV struct {
- A string `yac:"a"`
- V []byte `yac:"v"`
+ A string `keks:"a"`
+ V []byte `keks:"v"`
}
// Calculate UUID of the AV. UUIDv4 is generated from the hash output of
id = uuid.Nil
return
}
- item, err := gyac.FromGo(av)
+ item, err := keks.FromGo(av)
if err != nil {
panic(err)
}
"github.com/google/uuid"
- "go.cypherpunks.su/yac/gyac"
- "go.cypherpunks.su/yac/gyac/mapstruct"
- ed25519blake2b "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b"
- "go.cypherpunks.su/yac/gyac/pki/gost"
+ "go.cypherpunks.su/keks"
+ "go.cypherpunks.su/keks/mapstruct"
+ ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b"
+ "go.cypherpunks.su/keks/pki/gost"
)
const (
// Public key.
type Pub struct {
- A string `yac:"a"`
- V []byte `yac:"v"`
- Id uuid.UUID `yac:"id"`
+ A string `keks:"a"`
+ V []byte `keks:"v"`
+ Id uuid.UUID `keks:"id"`
}
// Certificate load (contents).
type CerLoad struct {
- KU *map[string]*struct{} `yac:"ku,omitempty"`
- Subj map[string]string `yac:"sub"`
- Crit *[]map[string]any `yac:"crit,omitempty"`
- Pub []Pub `yac:"pub"`
+ KU *map[string]*struct{} `keks:"ku,omitempty"`
+ Subj map[string]string `keks:"sub"`
+ Crit *[]map[string]any `keks:"crit,omitempty"`
+ Pub []Pub `keks:"pub"`
}
// Parse SignedData contents as CerLoad (certificate) and check its
return nil
}
-// Parse YAC-encoded data as SignedData with the CerLoad (certificate) contents.
+// Parse KEKS-encoded data as SignedData with the CerLoad (certificate) contents.
func CerParse(data []byte) (sd *SignedData, err error) {
sd, err = SignedDataParse(data)
if err != nil {
return
}
tbs := SignedDataTBS{T: sd.Load.T, V: sd.Load.V, TBS: sig.TBS}
- var item gyac.Item
- item, err = gyac.FromGo(tbs)
+ var item keks.Item
+ item, err = keks.FromGo(tbs)
if err != nil {
return
}
ed25519-blake2b ed25519-blake2b" | while read caAlgo eeAlgo ; do
subj="-subj CN=CA -subj C=RU"
-test_expect_success "$caAlgo: CA generation" "yacertool \
+test_expect_success "$caAlgo: CA generation" "kekscertool \
-algo $caAlgo \
-ku ca -ku sig $subj \
-prv $TMPDIR/ca.prv -cer $TMPDIR/ca.cer"
-test_expect_success "$caAlgo: CA regeneration" "yacertool \
+test_expect_success "$caAlgo: CA regeneration" "kekscertool \
-algo $caAlgo \
-ku ca -ku sig $subj \
-prv $TMPDIR/ca.prv -cer $TMPDIR/ca.cer \
-reuse-key"
-test_expect_success "$caAlgo: CA self-signature" "yacertool \
+test_expect_success "$caAlgo: CA self-signature" "kekscertool \
-ca-cer $TMPDIR/ca.cer \
-cer $TMPDIR/ca.cer \
-verify"
subj="-subj CN=SubCA -subj C=RU"
-test_expect_success "$eeAlgo: SubCA generation" "yacertool \
+test_expect_success "$eeAlgo: SubCA generation" "kekscertool \
-algo $eeAlgo \
-ku ca -ku sig $subj \
-prv $TMPDIR/subca.prv -cer $TMPDIR/subca.cer \
-ca-cer $TMPDIR/ca.cer -ca-prv $TMPDIR/ca.prv"
-test_expect_success "$eeAlgo: SubCA signature" "yacertool \
+test_expect_success "$eeAlgo: SubCA signature" "kekscertool \
-ca-cer $TMPDIR/ca.cer \
-cer $TMPDIR/subca.cer \
-verify"
subj="-subj CN=EE -subj C=RU"
-test_expect_success "$eeAlgo: EE generation" "yacertool \
+test_expect_success "$eeAlgo: EE generation" "kekscertool \
-algo $eeAlgo $subj \
-ca-prv $TMPDIR/subca.prv -ca-cer $TMPDIR/subca.cer \
-prv $TMPDIR/ee.prv -cer $TMPDIR/ee.cer"
-test_expect_success "$eeAlgo: EE chain" "yacertool \
+test_expect_success "$eeAlgo: EE chain" "kekscertool \
-ca-cer $TMPDIR/ca.cer \
-ca-cer $TMPDIR/subca.cer \
-cer $TMPDIR/ee.cer \
"strings"
"time"
- "go.cypherpunks.su/yac/gyac"
- "go.cypherpunks.su/yac/gyac/pki"
- ed25519blake2b "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b"
- "go.cypherpunks.su/yac/gyac/pki/gost"
- "go.cypherpunks.su/yac/gyac/pki/utils"
+ "go.cypherpunks.su/keks"
+ "go.cypherpunks.su/keks/pki"
+ ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b"
+ "go.cypherpunks.su/keks/pki/gost"
+ "go.cypherpunks.su/keks/pki/utils"
)
func main() {
log.Fatal("no -prv is set")
}
- var item gyac.Item
+ var item keks.Item
var prv crypto.Signer
var prvRaw []byte
var pub []byte
if err != nil {
log.Fatal(err)
}
- item, err = gyac.FromGo(pki.AV{A: *algo, V: prvRaw})
+ item, err = keks.FromGo(pki.AV{A: *algo, V: prvRaw})
if err != nil {
log.Fatal(err)
}
log.Fatal(err)
}
- item, err = gyac.FromGo(sd)
+ item, err = keks.FromGo(sd)
if err != nil {
log.Fatal(err)
}
"os"
"time"
- "go.cypherpunks.su/yac/gyac"
- "go.cypherpunks.su/yac/gyac/pki"
- pkihash "go.cypherpunks.su/yac/gyac/pki/hash"
- "go.cypherpunks.su/yac/gyac/pki/utils"
+ "go.cypherpunks.su/keks"
+ "go.cypherpunks.su/keks/pki"
+ pkihash "go.cypherpunks.su/keks/pki/hash"
+ "go.cypherpunks.su/keks/pki/utils"
)
func main() {
if err != nil {
log.Fatal(err)
}
- var item gyac.Item
- item, err = gyac.FromGo(sd)
+ var item keks.Item
+ item, err = keks.FromGo(sd)
if err != nil {
log.Fatal(err)
}
--- /dev/null
+// keks/pki provides PKI-related capabilities based on KEKS encoded formats.
+package pki
+++ ed25519/ed25519.go 2024-12-03 11:07:51.892841000 +0300
@@ -20,11 +20,12 @@
"crypto"
- "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b/edwards25519"
+ "go.cypherpunks.su/gokeks/pki/ed25519-blake2b/edwards25519"
cryptorand "crypto/rand"
- "crypto/sha512"
"crypto/subtle"
"crypto"
"crypto/rand"
- "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b/ed25519"
+ "go.cypherpunks.su/keks/pki/ed25519-blake2b/ed25519"
)
func NewKeypair() (signer crypto.Signer, prv, pub []byte, err error) {
# That script copies the library (tested on 1.23.3) and patches it to
# use BLAKE2b hash.
-modname=go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b
+modname=go.cypherpunks.su/gokeks/pki/ed25519-blake2b
go mod init $modname
dst=$PWD
cd $(go env GOROOT)/src
"crypto"
"errors"
- "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b/ed25519"
+ "go.cypherpunks.su/keks/pki/ed25519-blake2b/ed25519"
)
func NewSigner(v []byte) (prv crypto.Signer, pub []byte, err error) {
import (
"errors"
- "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b/ed25519"
+ "go.cypherpunks.su/keks/pki/ed25519-blake2b/ed25519"
)
func Verify(pub, signed, signature []byte) (valid bool, err error) {
-module go.cypherpunks.su/yac/gyac/pki
+module go.cypherpunks.su/keks/pki
go 1.22
"go.cypherpunks.su/gogost/v6/gost3410"
"go.cypherpunks.su/gogost/v6/gost34112012256"
"go.cypherpunks.su/gogost/v6/gost34112012512"
- "go.cypherpunks.su/yac/gyac/pki/utils"
+ "go.cypherpunks.su/keks/pki/utils"
)
func Verify(algo string, pub, signed, signature []byte) (valid bool, err error) {
"errors"
"fmt"
- "go.cypherpunks.su/yac/gyac/mapstruct"
- ed25519blake2b "go.cypherpunks.su/yac/gyac/pki/ed25519-blake2b"
- "go.cypherpunks.su/yac/gyac/pki/gost"
+ "go.cypherpunks.su/keks/mapstruct"
+ ed25519blake2b "go.cypherpunks.su/keks/pki/ed25519-blake2b"
+ "go.cypherpunks.su/keks/pki/gost"
)
-// Parse private key contained in AV YAC-encoded structure.
+// Parse private key contained in AV KEKS-encoded structure.
func PrvParse(data []byte) (prv crypto.Signer, pub []byte, err error) {
var av AV
var tail []byte
"github.com/google/uuid"
- "go.cypherpunks.su/yac/gyac"
- "go.cypherpunks.su/yac/gyac/mapstruct"
- "go.cypherpunks.su/yac/gyac/types"
+ "go.cypherpunks.su/keks"
+ "go.cypherpunks.su/keks/mapstruct"
+ "go.cypherpunks.su/keks/types"
)
type SignedDataLoad struct {
- V any `yac:"v,omitempty"`
- T string `yac:"t"`
+ V any `keks:"v,omitempty"`
+ T string `keks:"t"`
}
type SigTBS struct {
- Hashes *map[string][]byte `yac:"hash,omitempty"`
- CID *uuid.UUID `yac:"cid,omitempty"`
- Exp *[]time.Time `yac:"exp,omitempty"`
- When *time.Time `yac:"when,omitempty"`
- SID uuid.UUID `yac:"sid"`
+ Hashes *map[string][]byte `keks:"hash,omitempty"`
+ CID *uuid.UUID `keks:"cid,omitempty"`
+ Exp *[]time.Time `keks:"exp,omitempty"`
+ When *time.Time `keks:"when,omitempty"`
+ SID uuid.UUID `keks:"sid"`
}
type Sig struct {
- TBS SigTBS `yac:"tbs,omitempty"`
- CerLoc *[]string `yac:"cer-loc,omitempty"`
- Sign AV `yac:"sign"`
+ TBS SigTBS `keks:"tbs,omitempty"`
+ CerLoc *[]string `keks:"cer-loc,omitempty"`
+ Sign AV `keks:"sign"`
}
type SignedDataTBS struct {
- V any `yac:"v"`
- T string `yac:"t"`
- TBS SigTBS `yac:"tbs"`
+ V any `keks:"v"`
+ T string `keks:"t"`
+ TBS SigTBS `keks:"tbs"`
}
type SignedData struct {
- Hashes *map[string]*struct{} `yac:"hash,omitempty"`
- Cers *[]*SignedData `yac:"certs,omitempty"`
- Load SignedDataLoad `yac:"load"`
- Sigs []*Sig `yac:"sigs"`
+ Hashes *map[string]*struct{} `keks:"hash,omitempty"`
+ Cers *[]*SignedData `keks:"certs,omitempty"`
+ Load SignedDataLoad `keks:"load"`
+ Sigs []*Sig `keks:"sigs"`
}
// Parse signed-data from decoded item.
-func SignedDataParseItem(item gyac.Item) (sd *SignedData, err error) {
+func SignedDataParseItem(item keks.Item) (sd *SignedData, err error) {
if item.T != types.Map {
err = errors.New("SignedDataParse: non-map")
return
return
}
-// Parse signed-data from YAC-encoded data. This is just a wrapper over
+// Parse signed-data from KEKS-encoded data. This is just a wrapper over
// SignedDataParseItem.
func SignedDataParse(data []byte) (sd *SignedData, err error) {
- var item gyac.Item
- item, _, err = gyac.Decode(bytes.NewReader(data))
+ var item keks.Item
+ item, _, err = keks.Decode(bytes.NewReader(data))
if err != nil {
return
}
sdTBS := SignedDataTBS{T: sd.Load.T, V: sd.Load.V, TBS: sigTBS}
sig := Sig{TBS: sigTBS}
sig.Sign.A = parent.Pub[0].A
- var item gyac.Item
- item, err = gyac.FromGo(sdTBS)
+ var item keks.Item
+ item, err = keks.FromGo(sdTBS)
if err != nil {
return
}
-package gyac
+package keks
// Bitewise sorting by length first.
type ByLenFirst []string
-// gyac -- Go YAC encoder implementation
+// keks -- Go KEKS encoder implementation
// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.
-package gyac
+package keks
import (
"fmt"
"github.com/google/uuid"
"go.cypherpunks.su/tai64n/v4"
- "go.cypherpunks.su/yac/gyac/atom"
- "go.cypherpunks.su/yac/gyac/types"
+ "go.cypherpunks.su/keks/atom"
+ "go.cypherpunks.su/keks/types"
)
// Convert an item to various native Go types, atom.Raw, Blob, uuid.UUID.
+++ /dev/null
-// YAC (http://www.yac.cypherpunks.su) is yet another binary
-// serialisation encoding format. It is aimed to be lightweight in terms
-// of CPU, memory, storage and codec implementation size usage. YAC is
-// deterministic and streamable. It supports wide range of data types,
-// making it able to transparently replace JSON.
-package gyac
+++ /dev/null
-// gyac/pki provides PKI-related capabilities based on YAC encoded formats.
-package pki
--- /dev/null
+PyKEKS Python3 implementation of KEKS codec.
+
+* No FLOAT*, TAI64NA, or nanoseconds support.
+ They are stored/decoded just as a raw value
+
+PyKEKS is free software: see the file COPYING.LESSER for copying conditions.
#!/usr/bin/env python3
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
# This program is free software: you can redistribute it and/or modify
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""Python YAC encoder/decoder implementation
+"""Python KEKS encoder/decoder implementation
-`YAC <http://www.yac.cypherpunks.su>`__ is yet another binary
-serialisation encoding format. It is aimed to be lightweight in
-terms of CPU, memory, storage and codec implementation size usage.
-YAC is deterministic and streamable. It supports wide range of data
-types, making it able to transparently replace JSON.
+`KEKS <http://www.keks.cypherpunks.su>`__ is compact, deterministic,
+concise and streaming binary serialisation format. It is aimed to be
+lightweight in terms of CPU, memory, storage and codec implementation
+size usage. It supports wide range of data types, making it able to
+transparently replace JSON.
It has :py:func:`loads` and :py:func:`dumps` functions, similar to
-native :py:module:`json` library's. YAC supports dictionaries, lists,
+native :py:module:`json` library's. KEKS supports dictionaries, lists,
None, booleans, UUID, floats (currently not implemented!), integers
(including big ones), datetime, Unicode and binary strings.
-There is special :py:func:`pyac.Raw` namedtuple, that holds arbitrary
-YAC encoded data, that can not be represented in native Python types.
-Also there is :py:func:`pyac.Blob` namedtuple, that holds the data, that
+There is special :py:func:`keks.Raw` namedtuple, that holds arbitrary
+KEKS encoded data, that can not be represented in native Python types.
+Also there is :py:func:`keks.Blob` namedtuple, that holds the data, that
is encoded streamingly in chunks.
"""
def loads(v, **kwargs):
- """Decode YAC-encoded data.
+ """Decode KEKS-encoded data.
:param bool sets: transform maps with NIL-only values to set()s
:param bool leapsecUTCAllow: allow TAI64 values equal to leap seconds,
if __name__ == "__main__":
from argparse import ArgumentParser
from argparse import FileType
- parser = ArgumentParser(description="Decode YAC file")
+ parser = ArgumentParser(description="Decode KEKS file")
parser.add_argument(
"--nosets", action="store_true",
help="Do not fold NIL-valued maps to sets")
from datetime import datetime
from datetime import timedelta
from uuid import UUID
-import pyac
+import keks
data = {
-123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789,
],
},
- "floats": [pyac.Raw(pyac.TagFloat32, bytes.fromhex("01020304"))],
+ "floats": [keks.Raw(keks.TagFloat32, bytes.fromhex("01020304"))],
"nil": None,
"bool": [True, False],
"str": {
"utf8": "Đ¿Ñ€Đ¸Đ²ĐµÑ‚ Đ¼Đ¸Ñ€",
},
"blob": [
- pyac.Blob(12, 1 * b"5"),
- pyac.Blob(12, 12 * b"6"),
- pyac.Blob(12, 13 * b"7"),
- pyac.Blob(5, b"1234567890-"),
+ keks.Blob(12, 1 * b"5"),
+ keks.Blob(12, 12 * b"6"),
+ keks.Blob(12, 13 * b"7"),
+ keks.Blob(5, b"1234567890-"),
],
"empties": [
[],
{},
- pyac.Blob(123, b""),
+ keks.Blob(123, b""),
UUID("00000000-0000-0000-0000-000000000000"),
- pyac.Raw(pyac.TagTAI64, bytes.fromhex("0000000000000000")),
+ keks.Raw(keks.TagTAI64, bytes.fromhex("0000000000000000")),
],
"uuid": UUID("0e875e3f-d385-49eb-87b4-be42d641c367"),
}
data["dates"] = [
(datetime(1970, 1, 1) + timedelta(seconds=1234567890)),
(datetime(1970, 1, 1) + timedelta(seconds=1234567890)).replace(microsecond=456),
- pyac.Raw(pyac.TagTAI64N, bytes.fromhex("40000000499602F40006F855")),
- pyac.Raw(pyac.TagTAI64NA, bytes.fromhex("40000000499602F40006F855075BCD15")),
+ keks.Raw(keks.TagTAI64N, bytes.fromhex("40000000499602F40006F855")),
+ keks.Raw(keks.TagTAI64NA, bytes.fromhex("40000000499602F40006F855075BCD15")),
]
-raw = pyac.dumps(data)
-dec, tail = pyac.loads(raw)
+raw = keks.dumps(data)
+dec, tail = keks.loads(raw)
assert tail == b""
-assert pyac.dumps(dec) == raw
+assert keks.dumps(dec) == raw
assert dec == data
print(raw.hex())
import afl
-from pyac import loads
-from pyac import DecodeError
+from keks import loads
+from keks import DecodeError
afl.init()
data = stdin.buffer.read()
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis.strategies import tuples
from hypothesis.strategies import uuids
-from pyac import Blob
+from keks import Blob
junk_st = binary(max_size=8)
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
from hypothesis.strategies import integers
-from pyac import Blob
-from pyac import DecodeError
-from pyac import dumps
-from pyac import loads
-from pyac import NotEnoughData
+from keks import Blob
+from keks import DecodeError
+from keks import dumps
+from keks import loads
+from keks import NotEnoughData
from tests.strategies import junk_st
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
-from pyac import dumps
-from pyac import loads
+from keks import dumps
+from keks import loads
from tests.strategies import junk_st
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
-from pyac import dumps
-from pyac import loads
+from keks import dumps
+from keks import loads
from tests.strategies import junk_st
from tests.strategies import everything_st
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
-from pyac import dumps
-from pyac import loads
-from pyac import NotEnoughData
-from pyac import Raw
+from keks import dumps
+from keks import loads
+from keks import NotEnoughData
+from keks import Raw
from tests.strategies import junk_st
from unittest import skipIf
from unittest import TestCase
-from pyac import Blob
-from pyac import Leapsecs1972
-from pyac import loads
-from pyac import Raw
-from pyac import TagTAI64
-from pyac import TagTAI64N
-from pyac import TagTAI64NA
-from pyac import TAI64Base
+from keks import Blob
+from keks import Leapsecs1972
+from keks import loads
+from keks import Raw
+from keks import TagTAI64
+from keks import TagTAI64N
+from keks import TagTAI64NA
+from keks import TAI64Base
testsDir = dirname(abspath(__file__))
class TestFuzzInputs(TestCase):
- """Check tyac/mk-fuzz-inputs output
+ """Check tcl/mk-fuzz-inputs output
You have to create fuzz-inputs directory in tests and fill it up
with mk-fuzz-inputs.
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
from hypothesis.strategies import binary
-from pyac import DecodeError
-from pyac import dumps
-from pyac import loads
-from pyac import NotEnoughData
-from pyac import Raw
+from keks import DecodeError
+from keks import dumps
+from keks import loads
+from keks import NotEnoughData
+from keks import Raw
class TestUnknownType(TestCase):
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
from hypothesis.strategies import integers
-from pyac import DecodeError
-from pyac import dumps
-from pyac import loads
-from pyac import NotEnoughData
+from keks import DecodeError
+from keks import dumps
+from keks import loads
+from keks import NotEnoughData
from tests.strategies import junk_st
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
from hypothesis.strategies import lists
-from pyac import dumps
-from pyac import loads
-from pyac import NotEnoughData
+from keks import dumps
+from keks import loads
+from keks import NotEnoughData
from tests.strategies import any_st
from tests.strategies import everything_st
from tests.strategies import junk_st
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis.strategies import dictionaries
from hypothesis.strategies import sets
-from pyac import DecodeError
-from pyac import dumps
-from pyac import loads
+from keks import DecodeError
+from keks import dumps
+from keks import loads
from tests.strategies import any_st
from tests.strategies import junk_st
from tests.strategies import mapkey_st
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
from hypothesis.strategies import integers
-from pyac import NotEnoughData
+from keks import NotEnoughData
class TestNotEnoughData(TestCase):
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from unittest import TestCase
-from pyac import _byte
-from pyac import DecodeError
-from pyac import loads
-from pyac import TagBlob
-from pyac import TagList
-from pyac import TagPInt
+from keks import _byte
+from keks import DecodeError
+from keks import loads
+from keks import TagBlob
+from keks import TagList
+from keks import TagPInt
class TestTooDeepInt(TestCase):
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis.strategies import binary
from hypothesis.strategies import integers
-from pyac import DecodeError
-from pyac import dumps
-from pyac import loads
-from pyac import NotEnoughData
+from keks import DecodeError
+from keks import dumps
+from keks import loads
+from keks import NotEnoughData
from tests.strategies import junk_st
from tests.strategies import unicode_allowed
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
from hypothesis.strategies import datetimes
-from pyac import _byte
-from pyac import DecodeError
-from pyac import dumps
-from pyac import Leapsecs
-from pyac import loads
-from pyac import NotEnoughData
-from pyac import Raw
-from pyac import TAI64Base
+from keks import _byte
+from keks import DecodeError
+from keks import dumps
+from keks import Leapsecs
+from keks import loads
+from keks import NotEnoughData
+from keks import Raw
+from keks import TAI64Base
from tests.strategies import junk_st
class TestLeapsecs(TestCase):
def test_match_DJB(self) -> None:
- """Check that our pyac.Leapsecs is equally calculated to DJB's one
+ """Check that our keks.Leapsecs is equally calculated to DJB's one
"""
for our, their in zip(Leapsecs, DJB_Leapsecs):
self.assertEqual(
-# pyac -- Python YAC implementation
+# PyKEKS -- Python KEKS implementation
# Copyright (C) 2024-2025 Antont Rudenko <rudenko.ad@phystech.edu>
# 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
from hypothesis import given
from hypothesis.strategies import uuids
-from pyac import dumps
-from pyac import loads
-from pyac import NotEnoughData
+from keks import dumps
+from keks import loads
+from keks import NotEnoughData
from tests.strategies import junk_st
+++ /dev/null
-Python implementation of YAC codec.
-
-* No FLOAT*, TAI64NA, or nanoseconds support.
- They are stored/decoded just as a raw value
-
-pyac is free software: see the file COPYING.LESSER for copying conditions.
chunked format.
@item
-Is not embedded strings length, like in YAC and CBOR, is a more
+Is not embedded strings length, like in KEKS and CBOR, is a more
complicated code? Definitely. But there are so many short strings in a
schemaless format for specifying map/structure keys. So many algorithm
identifiers, that are also relatively short human-readable strings. So
@cindex encoding
@unnumbered Encoding
-YAC can store various primitive scalar types (strings, integers, ...)
+KEKS can store various primitive scalar types (strings, integers, ...)
and container types (lists, maps, ...). Serialisation process is just
emitting the TLV-like encoding for each item recursively.
\input texinfo
-@settitle YAC
+@settitle KEKS
@copying
Copyright @copyright{} 2024-2025 @email{stargrave@@stargrave.org, Sergey Matveev}
@firstparagraphindent insert
@node Top
-@top YAC
+@top KEKS
-YAC (Yet Another Codec) -- yet another format for binary reprensentation
-of structured data. But why!? Because there is no satisfiable codec for
-all set of requirements below.
+KEKS is compact, deterministic, concise and streaming binary
+serialisation format. It is aimed to be lightweight in terms of CPU,
+memory, storage and codec implementation size usage. It supports wide
+range of data types, making it able to transparently replace JSON.
+
+KEKS means: kompakt, entschlossen, knapp, strömend.
+
+But why!? Because there is no satisfiable codec for all set of
+requirements below.
@itemize
@item
Y @tab Y @tab Y @tab Y @tab ~
@item @url{https://en.wikipedia.org/wiki/Canonical_S-expressions, Canonical S-expression} @tab
Y @tab Y @tab Y @tab Y @tab ~
-@item YAC @tab
+@item KEKS @tab
Y @tab Y @tab Y @tab Y @tab Y
@end multitable
Y @tab Y @tab N @tab Y @tab Y @tab Y @tab Y @tab N
@item CSExp @tab
Y @tab Y @tab N @tab N @tab N @tab Y @tab N @tab N
-@item YAC @tab
+@item KEKS @tab
Y @tab Y @tab Y @tab Y @tab Y @tab Y @tab Y @tab Y
@end multitable
@node Install
@unnumbered Install
-Currently there are draft versions of the codec written on C, Go, Python
-and Tcl. But all of them are currently badly covered with tests.
+Currently there are draft versions of the codec written on C, Go,
+Python and Tcl.
@cindex git
You can obtain development source code with
-@command{git clone git://git.cypherpunks.su/yac.git}
-(also you can use @url{http://git.cypherpunks.su/yac.git},
-@url{https://git.cypherpunks.su/yac.git}).
+@command{git clone git://git.cypherpunks.su/keks.git}
+(also you can use @url{http://git.cypherpunks.su/keks.git},
+@url{https://git.cypherpunks.su/keks.git}).
Also there is @url{https://yggdrasil-network.github.io/, Yggdrasil}
-accessible address: @url{http://y.www.yac.cypherpunks.su/}.
+accessible address: @url{http://y.www.keks.cypherpunks.su/}.
@node Schema
@unnumbered Schema
-YAC can be decoded without any schema definition. But semantic meaning
+KEKS can be decoded without any schema definition. But semantic meaning
and constraints of various fields are expected to be written in a human
readable language somewhere nearby.
--- /dev/null
+TclKEKS implementation of the KEK encoder.
+
+* No FLOAT* support. They can be stored just as a raw value.
+
+TclKEKS is free software: see the file COPYING.LESSER for copying conditions.
--- /dev/null
+#!/usr/bin/env tclsh8.6
+
+source [file join [file dirname $::argv0] keks.tcl]
+namespace import KEKS::*
+eval [lindex $::argv 0]
+puts [binary encode hex $::KEKS::buf]
-# tyac -- Tcl YAC encoder implementation
+# TclKEKS -- Tcl KEKS encoder implementation
# Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
# This program is free software: you can redistribute it and/or modify
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see <http://www.gnu.org/licenses/>.
-namespace eval YAC {
+namespace eval KEKS {
variable buf {}
-source tyac.tcl
-namespace import YAC::*
+source keks.tcl
+namespace import KEKS::*
MAP {
ints {MAP {
uuid {UUID 0e875e3f-d385-49eb-87b4-be42d641c367}
}
-puts [binary encode hex $::YAC::buf]
+puts [binary encode hex $::KEKS::buf]
+++ /dev/null
-Tcl implementation of the YAC encoder.
-
-* No FLOAT* support. They can be stored just as a raw value.
-
-tyac is free software: see the file COPYING.LESSER for copying conditions.
+++ /dev/null
-#!/usr/bin/env tclsh8.6
-
-source [file join [file dirname $::argv0] tyac.tcl]
-namespace import YAC::*
-eval [lindex $::argv 0]
-puts [binary encode hex $::YAC::buf]