fputs("TRUE\n", stdout);
break;
case YACItemUUID:
- UUIDPrint(item->atom.val.buf);
+ UUIDPrint(item->atom.v.uuid);
fputs("\n", stdout);
break;
- case YACItemUint:
- fprintf(stdout, "%zu\n", item->atom.val.uint);
+ case YACItemPint:
+ fprintf(stdout, "%zu\n", item->atom.v.pint);
break;
- case YACItemSint:
- fprintf(stdout, "%zd\n", item->atom.val.sint);
+ case YACItemNint:
+ fprintf(stdout, "%zd\n", item->atom.v.nint);
break;
case YACItemList: {
printf(
"[ %s%zd%s\n",
NoColour ? "" : ColourCyan,
- item->atom.len,
+ item->atom.v.list.len,
NoColour ? "" : ColourReset);
indent++;
- idx = item->atom.val.first;
+ idx = item->atom.v.list.head;
listIdx = 0;
while (idx != -1) {
err = printer(items, idx, indent, listIdx, NULL);
printf(
"{ %s%zd%s\n",
NoColour ? "" : ColourCyan,
- item->atom.len,
+ item->atom.v.list.len,
NoColour ? "" : ColourReset);
indent++;
- idx = item->atom.val.first;
+ idx = item->atom.v.list.head;
while (idx != -1) {
str = strndup(
- (const char *)(items->list[idx].atom.val.buf),
- items->list[idx].atom.len);
+ (const char *)(items->list[idx].atom.v.str.ptr),
+ items->list[idx].atom.v.str.len);
idx = items->list[idx].next;
err = printer(items, idx, indent, -1, str);
free(str);
printf(
"BLOB[ %s%zu l=%zu%s\n",
NoColour ? "" : ColourCyan,
- item->atom.len,
- item->atom.val.uint,
+ item->atom.v.blob.chunks,
+ item->atom.v.blob.chunkLen,
NoColour ? "" : ColourReset);
indent++;
idx++;
fputs("FLOAT: TODO\n", stdout);
break;
case YACItemTAI64: {
- if ((item->atom.len) == 16) {
- str = HexEnc(item->atom.val.buf, item->atom.len);
+ if ((item->atom.v.str.len) == 16) {
+ str = HexEnc(item->atom.v.str.ptr, item->atom.v.str.len);
fprintf(stdout, "TAI64NA(%s)\n", str);
free(str);
break;
}
- switch (item->atom.len) {
+ switch (item->atom.v.str.len) {
case 8:
fputs("TAI64(", stdout);
break;
break;
}
struct timeval tv;
- err = YACTAI64ToTimeval(&tv, item->atom.val.buf, item->atom.len);
+ err = YACTAI64ToTimeval(&tv, item->atom.v.str.ptr, item->atom.v.str.len);
if (err == YACErrTAI64BadNsec) {
- str = HexEnc(item->atom.val.buf, item->atom.len);
+ str = HexEnc(item->atom.v.str.ptr, item->atom.v.str.len);
fprintf(stdout, "unrepresentable: %s)\n", str);
free(str);
break;
time_t t = tv.tv_sec;
struct tm *tm = localtime(&t);
if (tm == NULL) {
- str = HexEnc(item->atom.val.buf, item->atom.len);
+ str = HexEnc(item->atom.v.str.ptr, item->atom.v.str.len);
fprintf(stdout, "unrepresentable: %s)\n", str);
free(str);
break;
char human[20] = {0};
strftime(human, sizeof human, "%Y-%m-%d %H:%M:%S", tm);
fputs(human, stdout);
- if ((item->atom.len) == 12) {
+ if ((item->atom.v.str.len) == 12) {
fprintf(stdout, ".%zu", tv.tv_usec);
}
fputs(")\n", stdout);
break;
}
case YACItemBin: {
- const size_t l = (item->atom.len > maxStrLen) ? maxStrLen : item->atom.len;
- str = HexEnc(item->atom.val.buf, l);
+ const size_t l =
+ (item->atom.v.str.len > maxStrLen) ? maxStrLen : item->atom.v.str.len;
+ str = HexEnc(item->atom.v.str.ptr, l);
fprintf(
stdout,
"%s%zu:%s%s%s\n",
NoColour ? "" : ColourMagenta,
- item->atom.len,
+ item->atom.v.str.len,
NoColour ? "" : ColourReset,
str,
- (item->atom.len > maxStrLen) ? "..." : "");
+ (item->atom.v.str.len > maxStrLen) ? "..." : "");
free(str);
break;
}
case YACItemStr: {
- const size_t l = (item->atom.len > maxStrLen) ? maxStrLen : item->atom.len;
- str = strndup((const char *)item->atom.val.buf, l);
- fprintf(stdout, "\"%s%s\"\n", str, (item->atom.len > maxStrLen) ? "..." : "");
+ 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);
+ fprintf(
+ stdout, "\"%s%s\"\n", str, (item->atom.v.str.len > maxStrLen) ? "..." : "");
free(str);
break;
}
case YACItemRaw:
- str = HexEnc(item->atom.val.buf, item->atom.len);
- fprintf(stdout, "(t=0x%X l=%zu v=%s)\n", item->atom.tag, item->atom.len, str);
+ 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:
fputs("TRUE\n", stdout);
break;
case YACItemUUID:
- UUIDPrint(atom->val.buf);
+ UUIDPrint(atom->v.uuid);
fputs("\n", stdout);
break;
- case YACItemUint:
- fprintf(stdout, "%zu\n", atom->val.uint);
+ case YACItemPint:
+ fprintf(stdout, "%zu\n", atom->v.pint);
break;
- case YACItemSint:
- fprintf(stdout, "%zd\n", atom->val.sint);
+ case YACItemNint:
+ fprintf(stdout, "%zd\n", atom->v.nint);
break;
case YACItemList:
fputs("[\n", stdout);
fputs("}\n", stdout);
break;
case YACItemBlob:
- printf("BLOB(l=%zu\n", atom->val.uint);
+ printf("BLOB(l=%zu\n", atom->v.blob.chunkLen);
state->indent++;
err = YACIterBlob(cbState, atom, off, buf, len, myCb);
if (err != YACErrNo) {
fputs("FLOAT: TODO\n", stdout);
break;
case YACItemTAI64:
- if ((atom->len) == 16) {
- hex = HexEnc(atom->val.buf, atom->len);
+ if ((atom->v.str.len) == 16) {
+ hex = HexEnc(atom->v.str.ptr, atom->v.str.len);
fprintf(stdout, "TAI64NA(%s)\n", hex);
free(hex);
break;
}
- switch (atom->len) {
+ switch (atom->v.str.len) {
case 8:
fputs("TAI64(", stdout);
break;
break;
}
struct timeval tv;
- err = YACTAI64ToTimeval(&tv, atom->val.buf, atom->len);
+ err = YACTAI64ToTimeval(&tv, atom->v.str.ptr, atom->v.str.len);
if (err == YACErrTAI64BadNsec) {
- hex = HexEnc(atom->val.buf, atom->len);
+ hex = HexEnc(atom->v.str.ptr, atom->v.str.len);
fprintf(stdout, "unrepresentable: %s)\n", hex);
free(hex);
break;
time_t t = tv.tv_sec;
struct tm *tm = localtime(&t);
if (tm == NULL) {
- hex = HexEnc(atom->val.buf, atom->len);
+ hex = HexEnc(atom->v.str.ptr, atom->v.str.len);
fprintf(stdout, "unrepresentable: %s)\n", hex);
free(hex);
break;
char human[20] = {0};
strftime(human, sizeof human, "%Y-%m-%d %H:%M:%S", tm);
fputs(human, stdout);
- if ((atom->len) == 12) {
+ if ((atom->v.str.len) == 12) {
fprintf(stdout, ".%zu", tv.tv_usec);
}
fputs(")\n", stdout);
break;
case YACItemBin: {
- const size_t l = (atom->len > maxStrLen) ? maxStrLen : atom->len;
- hex = HexEnc(atom->val.buf, l);
+ const size_t l = (atom->v.str.len > maxStrLen) ? maxStrLen : atom->v.str.len;
+ hex = HexEnc(atom->v.str.ptr, l);
fprintf(
- stdout, "%zu:%s%s\n", atom->len, hex, (atom->len > maxStrLen) ? "..." : "");
+ stdout,
+ "%zu:%s%s\n",
+ atom->v.str.len,
+ hex,
+ (atom->v.str.len > maxStrLen) ? "..." : "");
free(hex);
break;
}
case YACItemStr: {
- const size_t l = (atom->len > maxStrLen) ? maxStrLen : atom->len;
- hex = strndup((const char *)atom->val.buf, l);
- fprintf(stdout, "\"%s%s\"\n", hex, (atom->len > maxStrLen) ? "..." : "");
+ 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:
- hex = HexEnc(atom->val.buf, atom->len);
- fprintf(stdout, "(t=0x%X l=%zu v=%s)\n", atom->tag, atom->len, hex);
+ 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);
break;
default:
struct YACAtom atom;
memset(&atom, 0, sizeof(struct YACAtom));
ptrdiff_t off = 0;
- enum YACErr err = YACAtomDecode(&atom, buf, len);
- if (err != YACErrNo) {
- fprintf(stderr, "err: %s\n", YACErr2Str(err));
+ struct YACErrAndLen errLen = YACAtomDecode(&atom, buf, len);
+ if (errLen.err != YACErrNo) {
+ fprintf(stderr, "err: %s\n", YACErr2Str(errLen.err));
return EXIT_FAILURE;
}
- off += atom.off;
+ off += errLen.len;
struct CbState cbState = {.indent = 0};
- err = myCb(NULL, 0, -1, &cbState, &atom, &off, buf, len);
+ enum YACErr err = myCb(NULL, 0, -1, &cbState, &atom, &off, buf, len);
if (err != YACErrNo) {
fprintf(stderr, "err: %s\n", YACErr2Str(err));
return EXIT_FAILURE;
#include "frombe.h"
#include "utf8.h"
-enum YACErr
+struct YACErrAndLen
YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len)
{
- atom->len = 0;
- atom->tag = 0;
- atom->typ = 0;
- atom->off = 1;
+ atom->v.str.ptr = NULL;
+ atom->v.str.len = 0;
+ struct YACErrAndLen ret = {.err = YACErrInvalid, .len = 1};
if (len < 1) {
- return YACErrNotEnough;
+ ret.err = YACErrNotEnough;
+ return ret;
}
atom->tag = buf[0];
break;
}
if (ll != 0) {
- atom->off += ll;
- if ((ptrdiff_t)len < atom->off) {
- return YACErrNotEnough;
+ ret.len += ll;
+ if ((ptrdiff_t)len < ret.len) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
l = yacFromBE(buf + 1, ll);
if ((l < 61) || ((l < (1 << 8)) && (ll > 1)) ||
((l < (1 << 16)) && (ll > 2))) {
- return YACErrLenNonMinimal;
+ ret.err = YACErrLenNonMinimal;
+ return ret;
}
if (l > ((uint64_t)(1) << 60)) {
- return YACErrLenTooBig;
+ ret.err = YACErrLenTooBig;
+ return ret;
}
}
- atom->off += l;
- if ((ptrdiff_t)len < atom->off) {
- return YACErrNotEnough;
+ ret.len += l;
+ if ((ptrdiff_t)len < ret.len) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
- atom->len = l;
- atom->val.buf = buf + 1 + ll;
+ atom->v.str.len = l;
+ atom->v.str.ptr = buf + 1 + ll;
if (atom->typ == YACItemStr) {
size_t cpl = 0;
uint32_t cp = YACUTF8InvalidCp;
for (size_t n = 0; n < l;) {
- cpl = YACUTF8CpDecode(&cp, atom->val.buf + n, l - n);
+ cpl = YACUTF8CpDecode(&cp, atom->v.str.ptr + n, l - n);
if (cp == YACUTF8InvalidCp) {
- return YACErrBadUTF8;
+ ret.err = YACErrBadUTF8;
+ return ret;
}
n += cpl;
}
}
- return YACErrNo;
+ ret.err = YACErrNo;
+ return ret;
}
if ((atom->tag >= YACAtomInt0) && (atom->tag < YACAtomInt0 + 32)) {
- atom->val.uint = (uint64_t)(atom->tag - YACAtomInt0);
- atom->typ = YACItemUint;
- return YACErrNo;
+ atom->v.pint = (uint64_t)(atom->tag - YACAtomInt0);
+ atom->typ = YACItemPint;
+ ret.err = YACErrNo;
+ return ret;
}
if ((atom->tag >= YACAtomIntN1) && (atom->tag < YACAtomIntN1 + 32)) {
- atom->val.sint = -1 - (int64_t)(atom->tag - YACAtomIntN1);
- atom->typ = YACItemSint;
- return YACErrNo;
+ atom->v.nint = -1 - (int64_t)(atom->tag - YACAtomIntN1);
+ atom->typ = YACItemNint;
+ ret.err = YACErrNo;
+ return ret;
}
switch (atom->tag & 0xF0) {
case YACAtomIntPos1:
case YACAtomIntNeg1: {
- atom->typ = ((atom->tag & YACAtomIntNeg1) == YACAtomIntNeg1) ? YACItemSint :
- YACItemUint;
+ atom->typ = ((atom->tag & YACAtomIntNeg1) == YACAtomIntNeg1) ? YACItemNint :
+ YACItemPint;
const size_t l = (atom->tag & 0x0F) + 1;
- atom->off += l;
- if ((ptrdiff_t)len < atom->off) {
- return YACErrNotEnough;
+ ret.len += l;
+ if ((ptrdiff_t)len < ret.len) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
if (buf[1] == 0) {
- return YACErrIntNonMinimal;
+ ret.err = YACErrIntNonMinimal;
+ return ret;
}
if (l > 8) {
atom->typ = YACItemRaw;
- atom->len = l;
- atom->val.buf = buf + 1;
+ atom->v.str.len = l;
+ atom->v.str.ptr = buf + 1;
} else {
- atom->val.uint = yacFromBE(buf + 1, l);
- if ((atom->val.uint) < 32) {
- return YACErrIntNonMinimal;
+ atom->v.pint = yacFromBE(buf + 1, l);
+ if ((atom->v.pint) < 32) {
+ ret.err = YACErrIntNonMinimal;
+ return ret;
}
- if (atom->typ == YACItemSint) {
- atom->val.sint = -1 - (int64_t)(atom->val.uint);
+ if (atom->typ == YACItemNint) {
+ atom->v.nint = -1 - (int64_t)(atom->v.pint);
}
}
- return YACErrNo;
+ ret.err = YACErrNo;
+ return ret;
}
}
break;
case YACAtomUUID:
atom->typ = YACItemUUID;
- atom->off += 16;
- if ((ptrdiff_t)len < atom->off) {
- return YACErrNotEnough;
+ ret.len += 16;
+ if ((ptrdiff_t)len < ret.len) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
- atom->len = 16;
- atom->val.buf = buf + 1;
+ atom->v.uuid = buf + 1;
break;
case YACAtomList:
break;
case YACAtomBlob:
atom->typ = YACItemBlob;
- atom->off += 8;
- if ((ptrdiff_t)len < atom->off) {
- return YACErrNotEnough;
+ ret.len += 8;
+ if ((ptrdiff_t)len < ret.len) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
- atom->val.uint = yacFromBE(buf + 1, 8);
- if (atom->val.uint == 0) {
- return YACErrBlobBadLen;
+ atom->v.blob.chunkLen = yacFromBE(buf + 1, 8);
+ if (atom->v.blob.chunkLen == 0) {
+ ret.err = YACErrBlobBadLen;
+ return ret;
}
- if (atom->val.uint > ((uint64_t)(1) << 60)) {
- return YACErrLenTooBig;
+ if (atom->v.blob.chunkLen > ((uint64_t)(1) << 60)) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
break;
break;
}
atom->typ = YACItemFloat;
- atom->off += l;
- if ((ptrdiff_t)len < atom->off) {
- return YACErrNotEnough;
+ ret.len += l;
+ if ((ptrdiff_t)len < ret.len) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
atom->typ = YACItemRaw;
- atom->len = l;
- atom->val.buf = buf + 1;
+ atom->v.str.len = l;
+ atom->v.str.ptr = buf + 1;
break;
}
break;
}
atom->typ = YACItemTAI64;
- atom->off += l;
- if ((ptrdiff_t)len < atom->off) {
- return YACErrNotEnough;
+ ret.len += l;
+ if ((ptrdiff_t)len < ret.len) {
+ ret.err = YACErrNotEnough;
+ return ret;
}
- atom->len = l;
- atom->val.buf = buf + 1;
+ atom->v.str.len = l;
+ atom->v.str.ptr = buf + 1;
uint64_t v = yacFromBE(buf + 1, 8);
if (v > ((uint64_t)(1) << 63)) {
- return YACErrTAI64TooBig;
+ ret.err = YACErrTAI64TooBig;
+ return ret;
}
switch (l) {
case 12:
v = yacFromBE(buf + 1 + 8, 4);
if (v > 999999999) {
- return YACErrTAI64BadNsec;
+ ret.err = YACErrTAI64BadNsec;
+ return ret;
}
break;
case 16:
v = yacFromBE(buf + 1 + 8 + 4, 4);
if (v > 999999999) {
- return YACErrTAI64BadAsec;
+ ret.err = YACErrTAI64BadAsec;
+ return ret;
}
break;
}
break;
}
default:
- return YACErrUnknownType;
+ ret.err = YACErrUnknownType;
+ return ret;
}
- return YACErrNo;
+ ret.err = YACErrNo;
+ return ret;
}
YACItemFalse,
YACItemTrue,
YACItemUUID,
- YACItemUint,
- YACItemSint,
+ YACItemPint,
+ YACItemNint,
YACItemList,
YACItemMap,
YACItemBlob,
// @item YACItemTrue
// No additional fields are used.
// @item YACItemUUID
-// @code{.val.buf} contains the 16-byte UUID value.
-// @item YACItemUint
-// @code{.val.uint} contains positive integer's value.
-// @item YACItemSint
-// @code{.val.sint} contains negative integer's value.
+// @code{.v.uuid} contains the 16-byte UUID value.
+// @item YACItemPint
+// @code{.v.pint} contains positive integer's value.
+// @item YACItemNint
+// @code{.v.nint} contains negative integer's value.
// @item YACItemList
// No additional fields are used, if parsed through
// @code{YACAtomDecode()}.
// If parsed through the @code{YACItemsParse()}, then
-// @code{.len} contains the number of elements in a list,
-// @code{.val.first} is the items pool index of the first element.
-// It equals to -1, if list is empty.
+// @code{.v.list.len} contains the number of elements in a list.
+// @code{.v.list.head} is the items pool index of the first element.
+// @code{.v.list.head} equals to -1, if list is empty.
// @item YACItemMap
// No additional fields are used, if parsed through
// @code{YACAtomDecode()}.
// If parsed through the @code{YACItemsParse()}, then
-// @code{.len} contains the number of elements in a map,
-// @code{.val.first} is the items pool index of the first element's
+// @code{.v.list.len} contains the number of elements in a map,
+// @code{.v.list.head} is the items pool index of the first element's
// key. Key's item @code{.next} points to the value, that points to
// the next key, and so on.
-// @code{.val.first} equals to -1, if map is empty.
+// @code{.v.list.head} equals to -1, if map is empty.
// @item YACItemBlob
-// @code{.val.uint} contains the length of the chunk.
+// @code{.v.blob.chunkLen} contains the length of the chunk.
// If parsed through the @code{YACItemsParse()}, then
-// @code{.len} contains the number of chunks, including the
-// terminating binary string, that may be empty.
-// @code{.val.first} is the items pool index of the first chunk.
+// @code{.v.blob.chunks} contains the number of chunks, including
+// the terminating binary string, that may be empty.
// @item YACItemFloat
-// @code{.val.TODO} contains float's value.
+// @code{.v.TODO} contains float's value.
// @item YACItemTAI64
-// @code{.len} contains the length of the TAI64, that is either 8,
-// 12, or 16 bytes long. @code{.val.buf} points to the value itself.
+// @code{.v.str.len} contains the length of the TAI64, that is
+// either 8, 12, or 16 bytes long. @code{.v.str.ptr} points to the
+// value itself.
// @item YACItemBin
-// @code{.len} contains the length of the string.
-// @code{.val.buf} points to the value itself.
+// @code{.v.str.len} contains the length of the string.
+// @code{.v.str.ptr} points to the value itself.
// @item YACItemStr
-// @code{.len} contains the length of the string.
-// @code{.val.buf} points to the value itself.
+// @code{.v.str.len} contains the length of the string.
+// @code{.v.str.ptr} points to the value itself.
// @item YACItemRaw
// @code{.tag} is the raw value's tag, its first byte.
-// @code{.len} contains the length of its value.
-// @code{.val.buf} points to its value.
+// @code{.v.str.len} contains the length of its value.
+// @code{.v.str.ptr} points to its value.
// @end table
// @end deftypevar
struct YACAtom {
- ptrdiff_t off;
- size_t len;
union {
- uint64_t uint;
- int64_t sint;
- const unsigned char *buf;
- ptrdiff_t first;
- } val;
+ const unsigned char *uuid;
+ uint64_t pint;
+ int64_t nint;
+ struct {
+ ptrdiff_t head;
+ size_t len;
+ } list;
+ struct {
+ uint64_t chunkLen;
+ size_t chunks;
+ } blob;
+ struct {
+ const unsigned char *ptr;
+ size_t len;
+ } str;
+ } v;
enum YACItemType typ;
unsigned char tag;
char _pad[3];
};
-enum YACErr
+struct YACErrAndLen {
+ ptrdiff_t len;
+ enum YACErr err;
+ char _pad[4];
+};
+
+struct YACErrAndLen
YACAtomDecode(struct YACAtom *atom, const unsigned char *buf, const size_t len);
#endif // YAC_DEC_H
if (len > 12) {
return YACErrTAI64BadAsec;
}
- uint64_t v = yacFromBE(buf, 8);
+ int64_t v = (int64_t)yacFromBE(buf, 8);
v -= 0x4000000000000000;
{
- uint64_t diff = 0;
- for (size_t i = 0; i < sizeof YACLeapsecsN; i++) {
- if (v > (YACLeapsecs[i] + YACLeapsecsN - i)) {
- diff = YACLeapsecs1972 + YACLeapsecsN - i;
+ int64_t diff = 0;
+ for (size_t i = 0; i < YACLeapsecsN; i++) {
+ if (v > (YACLeapsecs[i] + (int64_t)YACLeapsecsN - (int64_t)i)) {
+ diff = YACLeapsecs1972 + (int64_t)YACLeapsecsN - (int64_t)i;
break;
}
}
}
tv->tv_sec = (time_t)v;
if (len > 8) {
- uint64_t n = (uint32_t)yacFromBE(buf + 8, 4);
+ uint32_t n = (uint32_t)yacFromBE(buf + 8, 4);
if ((n % 1000) != 0) {
return YACErrTAI64BadNsec;
}
void
YACTimevalToTAI64(unsigned char *buf, const struct timeval *tv)
{
- uint64_t v = (uint64_t)(tv->tv_sec);
- uint64_t diff = YACLeapsecs1972;
+ int64_t v = (int64_t)(tv->tv_sec);
+ int64_t diff = YACLeapsecs1972;
for (size_t i = 0; i < sizeof YACLeapsecsN; i++) {
if (v > YACLeapsecs[i]) {
diff += YACLeapsecsN - i;
}
}
v += 0x4000000000000000 + diff;
- yacToBE(buf, 8, v);
+ yacToBE(buf, 8, (uint64_t)v);
if (tv->tv_usec != 0) {
yacToBE(buf + 8, 4, (uint64_t)(tv->tv_usec) * 1000);
}
struct YACItem *item = &(items->list[items->len]);
item->next = -1;
item->off = *off;
- err = YACAtomDecode(&(item->atom), buf + *off, len - (size_t)(*off));
- if (err != YACErrNo) {
+ struct YACErrAndLen errLen =
+ YACAtomDecode(&(item->atom), buf + *off, len - (size_t)(*off));
+ if (errLen.err != YACErrNo) {
return err;
}
- (*off) += item->atom.off;
+ (*off) += errLen.len;
items->len++;
if (items->len <= 0) {
return YACErrNoMem;
}
switch (items->list[item].atom.typ) {
case YACItemList: {
- items->list[item].atom.val.first = item + 1;
- items->list[item].atom.len = 0;
+ items->list[item].atom.v.list.head = item + 1;
+ items->list[item].atom.v.list.len = 0;
ptrdiff_t prev = -1;
ptrdiff_t cur = -1;
ptrdiff_t idx = item;
}
cur = idx + 1;
if (items->list[cur].atom.typ == YACItemEOC) {
- if (items->list[item].atom.len == 0) {
- items->list[item].atom.val.first = -1;
+ if (items->list[item].atom.v.list.len == 0) {
+ items->list[item].atom.v.list.head = -1;
}
return YACErrNo;
}
}
prev = cur;
idx = (items->len) - 1;
- items->list[item].atom.len++;
+ items->list[item].atom.v.list.len++;
}
}
case YACItemMap: {
- items->list[item].atom.val.first = item + 1;
- items->list[item].atom.len = 0;
+ items->list[item].atom.v.list.head = item + 1;
+ items->list[item].atom.v.list.len = 0;
ptrdiff_t idx = item;
ptrdiff_t prev = -1;
ptrdiff_t cur = -1;
cur = idx + 1;
switch (items->list[cur].atom.typ) {
case YACItemEOC:
- if (items->list[item].atom.len == 0) {
- items->list[item].atom.val.first = -1;
+ if (items->list[item].atom.v.list.len == 0) {
+ items->list[item].atom.v.list.head = -1;
}
return YACErrNo;
case YACItemStr:
case YACItemFalse:
case YACItemTrue:
case YACItemUUID:
- case YACItemUint:
- case YACItemSint:
+ case YACItemPint:
+ case YACItemNint:
case YACItemList:
case YACItemMap:
case YACItemBlob:
default:
return YACErrMapBadKey;
}
- if (items->list[cur].atom.len == 0) {
+ if (items->list[cur].atom.v.str.len == 0) {
return YACErrMapBadKey;
}
- if (items->list[cur].atom.len < prevKeyLen) {
+ if (items->list[cur].atom.v.str.len < prevKeyLen) {
return YACErrMapUnordered;
}
- if ((items->list[cur].atom.len == prevKeyLen) &&
- (memcmp(prevKey, items->list[cur].atom.val.buf, prevKeyLen) >= 0)) {
+ if ((items->list[cur].atom.v.str.len == prevKeyLen) &&
+ (memcmp(prevKey, items->list[cur].atom.v.str.ptr, prevKeyLen) >= 0)) {
return YACErrMapUnordered;
}
- prevKeyLen = items->list[cur].atom.len;
- prevKey = items->list[cur].atom.val.buf;
+ prevKeyLen = items->list[cur].atom.v.str.len;
+ prevKey = items->list[cur].atom.v.str.ptr;
if (prev != -1) {
items->list[prev].next = cur;
}
items->list[prev].next = cur;
prev = cur;
idx = (items->len) - 1;
- items->list[item].atom.len++;
+ items->list[item].atom.v.list.len++;
}
}
case YACItemBlob: {
- items->list[item].atom.len = 0;
- const ptrdiff_t chunkLen = (ptrdiff_t)(items->list[item].atom.val.uint);
+ items->list[item].atom.v.blob.chunks = 0;
+ const ptrdiff_t chunkLen = (ptrdiff_t)(items->list[item].atom.v.blob.chunkLen);
ptrdiff_t idx = item;
ptrdiff_t prev = -1;
ptrdiff_t cur = -1;
switch (atom->typ) {
case YACItemNIL:
if (((ptrdiff_t)len - *off) <= chunkLen) {
- atom->off = chunkLen;
+ atom->v.str.len = (size_t)chunkLen;
return YACErrNotEnough;
}
atom->typ = YACItemBin;
- atom->val.buf = buf + *off;
- atom->len = (size_t)chunkLen;
+ atom->v.str.ptr = buf + *off;
+ atom->v.str.len = (size_t)chunkLen;
(*off) += chunkLen;
break;
case YACItemBin:
- if ((ptrdiff_t)(atom->len) >= chunkLen) {
+ if ((ptrdiff_t)(atom->v.str.len) >= chunkLen) {
return YACErrBlobBadTerm;
}
eoc = true;
case YACItemFalse:
case YACItemTrue:
case YACItemUUID:
- case YACItemUint:
- case YACItemSint:
+ case YACItemPint:
+ case YACItemNint:
case YACItemList:
case YACItemMap:
case YACItemBlob:
}
prev = cur;
idx = (items->len) - 1;
- items->list[item].atom.len++;
+ items->list[item].atom.v.blob.chunks++;
}
break;
}
case YACItemFalse:
case YACItemTrue:
case YACItemUUID:
- case YACItemUint:
- case YACItemSint:
+ case YACItemPint:
+ case YACItemNint:
case YACItemFloat:
case YACItemTAI64:
case YACItemBin:
diff = YACAtomBoolEncode(buf + *off, cap - (size_t)(*off), true);
break;
case YACItemUUID:
- diff = YACAtomUUIDEncode(buf + *off, cap - (size_t)(*off), item->atom.val.buf);
+ diff = YACAtomUUIDEncode(buf + *off, cap - (size_t)(*off), item->atom.v.uuid);
break;
- case YACItemUint:
- diff = YACAtomUintEncode(buf + *off, cap - (size_t)(*off), item->atom.val.uint);
+ case YACItemPint:
+ diff = YACAtomUintEncode(buf + *off, cap - (size_t)(*off), item->atom.v.pint);
break;
- case YACItemSint:
- diff = YACAtomSintEncode(buf + *off, cap - (size_t)(*off), item->atom.val.sint);
+ case YACItemNint:
+ diff = YACAtomSintEncode(buf + *off, cap - (size_t)(*off), item->atom.v.nint);
break;
case YACItemList:
diff = YACAtomListEncode(buf + *off, cap - (size_t)(*off));
return diff;
}
(*off) += diff;
- idx = item->atom.val.first;
+ idx = item->atom.v.list.head;
while (idx != -1) {
diff = YACItemsEncode(items, idx, off, buf, cap);
if (diff < 0) {
return diff;
}
(*off) += diff;
- idx = item->atom.val.first;
+ idx = item->atom.v.list.head;
while (idx != -1) {
diff = YACItemsEncode(items, idx, off, buf, cap);
if (diff < 0) {
diff = YACAtomEOCEncode(buf + *off, cap - (size_t)(*off));
break;
case YACItemBlob: {
- size_t chunkLen = item->atom.val.uint;
- diff = YACAtomBlobEncode(buf + *off, cap - (size_t)(*off), item->atom.val.uint);
+ size_t chunkLen = (size_t)(item->atom.v.blob.chunkLen);
+ diff = YACAtomBlobEncode(
+ buf + *off, cap - (size_t)(*off), item->atom.v.blob.chunkLen);
if (diff < 0) {
return diff;
}
for (;;) {
idx++;
item = &(items->list[idx]);
- if (item->atom.len != chunkLen) {
+ if (item->atom.v.str.len != chunkLen) {
break;
}
diff = YACAtomChunkEncode(
- buf + *off, cap - (size_t)(*off), item->atom.val.buf, item->atom.len);
+ buf + *off,
+ cap - (size_t)(*off),
+ item->atom.v.str.ptr,
+ item->atom.v.str.len);
if (diff < 0) {
return diff;
}
continue;
}
diff = YACAtomBinEncode(
- buf + *off, cap - (size_t)(*off), item->atom.val.buf, item->atom.len);
+ buf + *off,
+ cap - (size_t)(*off),
+ item->atom.v.str.ptr,
+ item->atom.v.str.len);
break;
}
case YACItemFloat:
return -1;
case YACItemTAI64:
diff = YACAtomTAI64Encode(
- buf + *off, cap - (size_t)(*off), item->atom.val.buf, item->atom.len);
+ buf + *off,
+ cap - (size_t)(*off),
+ item->atom.v.str.ptr,
+ item->atom.v.str.len);
break;
case YACItemBin:
diff = YACAtomBinEncode(
- buf + *off, cap - (size_t)(*off), item->atom.val.buf, item->atom.len);
+ buf + *off,
+ cap - (size_t)(*off),
+ item->atom.v.str.ptr,
+ item->atom.v.str.len);
break;
case YACItemStr:
diff = YACAtomStrEncode(
- buf + *off, cap - (size_t)(*off), item->atom.val.buf, item->atom.len);
+ buf + *off,
+ cap - (size_t)(*off),
+ item->atom.v.str.ptr,
+ item->atom.v.str.len);
break;
case YACItemRaw:
diff = YACAtomRawEncode(
buf + *off,
cap - (size_t)(*off),
item->atom.tag,
- item->atom.val.buf,
- item->atom.len);
+ item->atom.v.str.ptr,
+ item->atom.v.str.len);
break;
default:
return -1;
if (item->atom.typ != YACItemMap) {
return -1;
}
- ptrdiff_t idx = item->atom.val.first;
+ ptrdiff_t idx = item->atom.v.list.head;
while (idx != -1) {
- if ((items->list[idx].atom.len == keyLen) &&
- (memcmp(items->list[idx].atom.val.buf, key, keyLen) == 0)) {
+ if ((items->list[idx].atom.v.str.len == keyLen) &&
+ (memcmp(items->list[idx].atom.v.str.ptr, key, keyLen) == 0)) {
return idx + 1;
}
idx = items->list[idx].next;
const enum YACItemType typ)
{
ptrdiff_t idx = YACItemsGetByKey(items, itemIdx, key);
- if (idx == -1) {
- return -1;
- }
- if (items->list[idx].atom.typ != typ) {
+ if ((idx == -1) || (items->list[idx].atom.typ != typ)) {
return -1;
}
return idx;
bool
YACStrEqual(struct YACAtom *atom, const char *s)
{
- return (atom->len == strlen(s)) && (memcmp(atom->val.buf, s, atom->len) == 0);
+ return (atom->v.str.len == strlen(s)) &&
+ (memcmp(atom->v.str.ptr, s, atom->v.str.len) == 0);
}
bool
YACListHasOnlyType(struct YACItems *items, ptrdiff_t idx, const enum YACItemType typ)
{
- idx = items->list[idx].atom.val.first;
+ idx = items->list[idx].atom.v.list.head;
while (idx != -1) {
if (items->list[idx].atom.typ != typ) {
return false;
bool
YACMapHasOnlyType(struct YACItems *items, ptrdiff_t idx, const enum YACItemType typ)
{
- idx = items->list[idx].atom.val.first;
+ idx = items->list[idx].atom.v.list.head;
while (idx != -1) {
idx = items->list[idx].next;
if (items->list[idx].atom.typ != typ) {
// item, until its length is less than chunk len.
// @end deftypevar
struct YACItem {
- ptrdiff_t next;
ptrdiff_t off;
+ ptrdiff_t next;
struct YACAtom atom;
};
const size_t len,
YACIterCb cb)
{
+ struct YACErrAndLen errLen = {.err = YACErrInvalid, .len = 0};
enum YACErr err = YACErrInvalid;
bool eoc = false;
for (size_t n = 0;; n++) {
- err = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
- if (err != YACErrNo) {
- return err;
+ errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
+ if (errLen.err != YACErrNo) {
+ return errLen.err;
}
- (*off) += atom->off;
+ (*off) += errLen.len;
eoc = atom->typ == YACItemEOC;
err = cb(NULL, 0, eoc ? -1 : (ptrdiff_t)n, cbState, atom, off, buf, len);
if (err != YACErrNo) {
const size_t len,
YACIterCb cb)
{
+ struct YACErrAndLen errLen = {.err = YACErrInvalid, .len = 0};
+ enum YACErr err = YACErrInvalid;
const unsigned char *key = NULL;
size_t keyLen = 0;
- enum YACErr err = YACErrInvalid;
for (;;) {
- err = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
- if (err != YACErrNo) {
- return err;
+ errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
+ if (errLen.err != YACErrNo) {
+ return errLen.err;
}
- (*off) += atom->off;
+ (*off) += errLen.len;
if (atom->typ == YACItemEOC) {
err = cb(NULL, 0, -1, cbState, atom, off, buf, len);
if (err != YACErrNo) {
if (atom->typ != YACItemStr) {
return YACErrMapBadKey;
}
- if (atom->len == 0) {
+ if (atom->v.str.len == 0) {
return YACErrMapBadKey;
}
- if (atom->len < keyLen) {
+ if (atom->v.str.len < keyLen) {
return YACErrMapUnordered;
}
- if ((atom->len == keyLen) && (memcmp(key, atom->val.buf, keyLen) >= 0)) {
+ if ((atom->v.str.len == keyLen) &&
+ (memcmp(key, atom->v.str.ptr, keyLen) >= 0)) {
return YACErrMapUnordered;
}
- keyLen = atom->len;
- key = atom->val.buf;
- err = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
- if (err != YACErrNo) {
- return err;
+ keyLen = atom->v.str.len;
+ key = atom->v.str.ptr;
+ errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
+ if (errLen.err != YACErrNo) {
+ return errLen.err;
}
- (*off) += atom->off;
+ (*off) += errLen.len;
if (atom->typ == YACItemEOC) {
return YACErrMapNoVal;
}
const size_t len,
YACIterCb cb)
{
- const size_t chunkLen = atom->val.uint;
+ const size_t chunkLen = (size_t)(atom->v.blob.chunkLen);
+ struct YACErrAndLen errLen = {.err = YACErrInvalid, .len = 0};
enum YACErr err = YACErrInvalid;
bool eoc = false;
for (size_t n = 0; !eoc; n++) {
- err = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
- if (err != YACErrNo) {
- return err;
+ errLen = YACAtomDecode(atom, buf + *off, len - (size_t)(*off));
+ if (errLen.err != YACErrNo) {
+ return errLen.err;
}
- (*off) += atom->off;
+ (*off) += errLen.len;
switch (atom->typ) {
case YACItemNIL:
if (((ptrdiff_t)len - *off) <= (ptrdiff_t)chunkLen) {
- atom->off = (ptrdiff_t)chunkLen;
+ atom->v.str.len = chunkLen;
return YACErrNotEnough;
}
atom->typ = YACItemBin;
- atom->val.buf = buf + *off;
- atom->len = chunkLen;
+ atom->v.str.ptr = buf + *off;
+ atom->v.str.len = chunkLen;
(*off) += chunkLen;
break;
case YACItemBin:
- if ((atom->len) >= chunkLen) {
+ if ((atom->v.str.len) >= chunkLen) {
return YACErrBlobBadTerm;
}
eoc = true;
case YACItemFalse:
case YACItemTrue:
case YACItemUUID:
- case YACItemUint:
- case YACItemSint:
+ case YACItemPint:
+ case YACItemNint:
case YACItemList:
case YACItemMap:
case YACItemBlob:
}
atom->typ = YACItemEOC;
err = cb(NULL, 0, -1, cbState, atom, off, buf, len);
- if (err != YACErrNo) {
- return err;
- }
- return YACErrNo;
+ return err;
}
#include "leapsecs.h"
const size_t YACLeapsecsN = 27;
-const uint64_t YACLeapsecs1972 = 10;
-uint64_t YACLeapsecs[] = {
+const int64_t YACLeapsecs1972 = 10;
+int64_t YACLeapsecs[] = {
1483228800, // 2017-01
1435708800, // 2015-07
1341100800, // 2012-07
#include <stdint.h>
extern const size_t YACLeapsecsN;
-extern const uint64_t YACLeapsecs1972;
-extern uint64_t YACLeapsecs[];
+extern const int64_t YACLeapsecs1972;
+extern int64_t YACLeapsecs[];
#endif // YAC_LEAPSECS_H
idx = YACItemsGetByKey(items, cer->load, "ku");
if (idx != -1) {
item = &(items->list[idx]);
- if (item->atom.len == 0) {
+ if (item->atom.v.list.len == 0) {
(*failReason) = "empty /load/v/ku";
return YACErrUnsatisfiedSchema;
}
return YACErrUnsatisfiedSchema;
}
item = &(items->list[idx]);
- if (item->atom.len != 1) {
+ if (item->atom.v.list.len != 1) {
(*failReason) = "len(/load/v/pub) != 1";
return YACErrUnsatisfiedSchema;
}
- idx = items->list[idx].atom.val.first;
+ idx = items->list[idx].atom.v.list.head;
cer->pub = idx;
while (idx != -1) {
if (YACItemsGetByKeyAndType(items, idx, "a", YACItemStr) == -1) {
(*failReason) = "no /load/v/pub/id";
return YACErrUnsatisfiedSchema;
}
- cer->pkid = items->list[pkidIdx].atom.val.buf;
+ cer->pkid = items->list[pkidIdx].atom.v.uuid;
}
idx = items->list[idx].next;
}
return YACErrUnsatisfiedSchema;
}
item = &(items->list[cer->sub]);
- if (item->atom.len == 0) {
+ if (item->atom.v.list.len == 0) {
(*failReason) = "empty /load/v/sub";
return YACErrUnsatisfiedSchema;
}
return YACErrUnsatisfiedSchema;
}
item = &(items->list[sigsIdx]);
- if (item->atom.len != 1) {
+ if (item->atom.v.list.len != 1) {
(*failReason) = "len(/load/sigs) != 1";
return YACErrUnsatisfiedSchema;
}
- ptrdiff_t sigIdx = items->list[sigsIdx].atom.val.first;
+ ptrdiff_t sigIdx = items->list[sigsIdx].atom.v.list.head;
cer->sig = sigIdx;
while (sigIdx != -1) {
if (YACItemsGetByKey(items, sigIdx, "hash") != -1) {
(*failReason) = "no /sigs/./tbs/cid";
return YACErrUnsatisfiedSchema;
}
- cer->cid = items->list[cidIdx].atom.val.buf;
+ cer->cid = items->list[cidIdx].atom.v.uuid;
}
{
ptrdiff_t sidIdx =
(*failReason) = "no /sigs/./tbs/sid";
return YACErrUnsatisfiedSchema;
}
- cer->sid = items->list[sidIdx].atom.val.buf;
+ cer->sid = items->list[sidIdx].atom.v.uuid;
}
idx = YACItemsGetByKeyAndType(items, idx, "exp", YACItemList);
if (idx == -1) {
return YACErrUnsatisfiedSchema;
}
item = &(items->list[idx]);
- if (item->atom.len != 2) {
+ if (item->atom.v.list.len != 2) {
(*failReason) = "len(/sigs/./tbs/exp) != 2";
return YACErrUnsatisfiedSchema;
}
err = YACTAI64ToTimeval(
&(cer->since),
- items->list[idx + 1].atom.val.buf,
- items->list[idx + 1].atom.len);
+ items->list[idx + 1].atom.v.str.ptr,
+ items->list[idx + 1].atom.v.str.len);
if ((err != YACErrNo) || (cer->since.tv_usec != 0)) {
(*failReason) = "bad /sigs/./tbs/exp/since value";
return YACErrUnsatisfiedSchema;
}
err = YACTAI64ToTimeval(
&(cer->till),
- items->list[idx + 2].atom.val.buf,
- items->list[idx + 2].atom.len);
+ items->list[idx + 2].atom.v.str.ptr,
+ items->list[idx + 2].atom.v.str.len);
if ((err != YACErrNo) || (cer->till.tv_usec != 0)) {
(*failReason) = "bad /sigs/./tbs/exp/till value";
return YACErrUnsatisfiedSchema;
{
struct YACItem *sigA =
&(cer->items.list[YACItemsGetByKey(&(cer->items), signIdx, "a")]);
- if ((sigA->atom.len != pubA->atom.len) ||
- (memcmp(sigA->atom.val.buf, pubA->atom.val.buf, sigA->atom.len) != 0)) {
+ 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)) {
(*failReason) = "sign.a != pub.a";
return false;
}
memset(&tbsItems, 0, sizeof tbsItems);
struct YACItems tbs = {.list = tbsItems, items, items};
tbsItems[0].atom.typ = YACItemMap;
- tbsItems[0].atom.val.first = 1;
+ tbsItems[0].atom.v.list.head = 1;
tbsItems[1].atom.typ = YACItemStr;
- tbsItems[1].atom.len = 1;
- tbsItems[1].atom.val.buf = (const unsigned char *)"t";
+ 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.len = 3;
- tbsItems[2].atom.val.buf = (const unsigned char *)"cer";
+ 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.len = 1;
- tbsItems[3].atom.val.buf = (const unsigned char *)"v";
+ 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;
}
return opts.sigVerifiers[i].func(
failReason,
- pubA->atom.val.buf,
- pubA->atom.len,
- sigV->atom.val.buf,
- sigV->atom.len,
- pubV->atom.val.buf,
- pubV->atom.len,
+ pubA->atom.v.str.ptr,
+ pubA->atom.v.str.len,
+ sigV->atom.v.str.ptr,
+ sigV->atom.v.str.len,
+ pubV->atom.v.str.ptr,
+ pubV->atom.v.str.len,
buf,
(size_t)off);
}