#include <assert.h>
#include <errno.h>
#include <fcntl.h>
+#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <yac/dec.h>
#include <yac/dectai.h>
#include <yac/err.h>
-#include <yac/pool.h>
+#include <yac/items.h>
#include "hex.c.in"
}
}
+static int OffDigits = 0;
+static char OffFmt[10] = {0};
+
static enum YACErr
printer(
- const struct YACItemPool *pool,
+ const struct YACItems *items,
ptrdiff_t idx,
ptrdiff_t indent,
ptrdiff_t listIdx,
const char *mapKey)
{
- struct YACItem *item = &(pool->list[idx]);
- printf("%04zd ", item->off);
+ struct YACItem *item = &(items->list[idx]);
+ printf(OffFmt, item->off);
if (item->atom.typ == YACItemEOC) {
indent--;
assert(indent >= 0);
idx = item->atom.val.first;
listIdx = 0;
while (idx != -1) {
- err = printer(pool, idx, indent, listIdx, NULL);
+ err = printer(items, idx, indent, listIdx, NULL);
if (err != YACErrNo) {
return err;
}
- idx = pool->list[idx].next;
+ idx = items->list[idx].next;
listIdx++;
}
- fputs(" ", stdout);
+ for (int i = 0; i < OffDigits + 1; i++) {
+ fputs(" ", stdout);
+ }
indent--;
printIndent(indent);
fputs("]\n", stdout);
idx = item->atom.val.first;
while (idx != -1) {
str = strndup(
- (const char *)(pool->list[idx].atom.val.buf), pool->list[idx].atom.len);
- idx = pool->list[idx].next;
- err = printer(pool, idx, indent, -1, str);
+ (const char *)(items->list[idx].atom.val.buf),
+ items->list[idx].atom.len);
+ idx = items->list[idx].next;
+ err = printer(items, idx, indent, -1, str);
free(str);
if (err != YACErrNo) {
return err;
}
- idx = pool->list[idx].next;
+ idx = items->list[idx].next;
+ }
+ for (int i = 0; i < OffDigits + 1; i++) {
+ fputs(" ", stdout);
}
- fputs(" ", stdout);
indent--;
printIndent(indent);
fputs("}\n", stdout);
idx++;
listIdx = 0;
while (idx != -1) {
- err = printer(pool, idx, indent, listIdx, NULL);
+ err = printer(items, idx, indent, listIdx, NULL);
if (err != YACErrNo) {
return err;
}
- idx = pool->list[idx].next;
+ idx = items->list[idx].next;
listIdx++;
}
- fputs(" ", stdout);
+ for (int i = 0; i < OffDigits + 1; i++) {
+ fputs(" ", stdout);
+ }
indent--;
printIndent(indent);
fputs("]\n", stdout);
buf = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
}
- struct YACItemPool pool;
- YACItemPoolInit(&pool);
+ OffDigits = (int)(1 + floor(log10((double)len)));
+ snprintf(OffFmt, sizeof OffFmt, "%%0%dzd ", OffDigits);
+
+ struct YACItems items;
+ YACItemsInit(&items);
ptrdiff_t off = 0;
- enum YACErr err = YACItemPoolParse(&pool, &off, buf, len);
+ enum YACErr err = YACItemsParse(&items, &off, buf, len);
if (err != YACErrNo) {
fprintf(stderr, "err: %d\n", err);
return EXIT_FAILURE;
}
- err = printer(&pool, 0, 0, -1, NULL);
+ err = printer(&items, 0, 0, -1, NULL);
if (err != YACErrNo) {
fprintf(stderr, "err: %d\n", err);
return EXIT_FAILURE;
// @item YACItemList
// No additional fields are used, if parsed through
// @code{YACAtomDecode()}.
-// If parsed through the @code{YACItemPoolParse()}, then
+// If parsed through the @code{YACItemsParse()}, then
// @code{.len} contains the number of elements in a list,
-// @code{.val.first} is the pool index of the first element.
+// @code{.val.first} is the items pool index of the first element.
// It equals to -1, if list is empty.
// @item YACItemMap
// No additional fields are used, if parsed through
// @code{YACAtomDecode()}.
-// If parsed through the @code{YACItemPoolParse()}, then
+// If parsed through the @code{YACItemsParse()}, then
// @code{.len} contains the number of elements in a map,
-// @code{.val.first} is the 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} 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.
// @item YACItemBlob
// @code{.val.uint} contains the length of the chunk.
-// If parsed through the @code{YACItemPoolParse()}, then
+// 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 pool index of the first chunk.
+// @code{.val.first} is the items pool index of the first chunk.
// @item YACItemFloat
// @code{.val.TODO} contains float's value.
// @item YACItemTAI64
#include "dec.h"
#include "err.h"
-#include "pool.h"
+#include "items.h"
-static const ptrdiff_t yacPoolChunkLen = 32;
+static const ptrdiff_t yacItemsPoolGrowLen = 32;
enum YACErr
-YACItemPoolInit(struct YACItemPool *pool)
+YACItemsInit(struct YACItems *items)
{
- pool->len = 0;
- pool->cap = yacPoolChunkLen;
- pool->list = calloc((size_t)(pool->cap), sizeof(struct YACItem));
- if (pool->list == NULL) {
+ items->len = 0;
+ items->cap = yacItemsPoolGrowLen;
+ items->list = calloc((size_t)(items->cap), sizeof(struct YACItem));
+ if (items->list == NULL) {
return YACErrNoMem;
}
return YACErrNo;
}
enum YACErr
-YACItemPoolGrow(struct YACItemPool *pool)
+yacItemsGrow(struct YACItems *items)
{
- pool->cap += yacPoolChunkLen;
- if (pool->cap <= 0) {
+ items->cap += yacItemsPoolGrowLen;
+ if (items->cap <= 0) {
return YACErrNoMem;
}
- const size_t size = (size_t)(pool->cap) * sizeof(struct YACItem);
- pool->list = realloc(pool->list, size);
- if (pool->list == NULL) {
+ const size_t size = (size_t)(items->cap) * sizeof(struct YACItem);
+ items->list = realloc(items->list, size);
+ if (items->list == NULL) {
return YACErrNoMem;
}
- const size_t begin = (size_t)(pool->len) * sizeof(struct YACItem);
- memset((unsigned char *)(pool->list) + begin, 0, size - begin);
+ const size_t begin = (size_t)(items->len) * sizeof(struct YACItem);
+ memset((unsigned char *)(items->list) + begin, 0, size - begin);
return YACErrNo;
}
static enum YACErr
-yacItemPoolAdd(
- struct YACItemPool *pool,
+yacItemsAdd(
+ struct YACItems *items,
ptrdiff_t *off,
const unsigned char *buf,
const size_t len)
{
enum YACErr err = YACErrInvalid;
- if (pool->len == pool->cap) {
- err = YACItemPoolGrow(pool);
+ if (items->len == items->cap) {
+ err = yacItemsGrow(items);
if (err != YACErrNo) {
return err;
}
}
- struct YACItem *item = &(pool->list[pool->len]);
+ struct YACItem *item = &(items->list[items->len]);
item->next = -1;
item->off = *off;
err = YACAtomDecode(&(item->atom), buf + *off, len - (size_t)(*off));
return err;
}
(*off) += item->atom.off;
- pool->len++;
- if (pool->len <= 0) {
+ items->len++;
+ if (items->len <= 0) {
return YACErrNoMem;
}
return YACErrNo;
}
enum YACErr
-YACItemPoolParse(
- struct YACItemPool *pool,
+YACItemsParse(
+ struct YACItems *items,
ptrdiff_t *off,
const unsigned char *buf,
const size_t len)
{
- ptrdiff_t item = pool->len;
- enum YACErr err = yacItemPoolAdd(pool, off, buf, len);
+ ptrdiff_t item = items->len;
+ enum YACErr err = yacItemsAdd(items, off, buf, len);
if (err != YACErrNo) {
return err;
}
- switch (pool->list[item].atom.typ) {
+ switch (items->list[item].atom.typ) {
case YACItemList: {
- pool->list[item].atom.val.first = item + 1;
- pool->list[item].atom.len = 0;
+ items->list[item].atom.val.first = item + 1;
+ items->list[item].atom.len = 0;
ptrdiff_t prev = -1;
ptrdiff_t cur = -1;
ptrdiff_t idx = item;
for (;;) {
- err = YACItemPoolParse(pool, off, buf, len);
+ err = YACItemsParse(items, off, buf, len);
if (err != YACErrNo) {
return err;
}
cur = idx + 1;
- if (pool->list[cur].atom.typ == YACItemEOC) {
- if (pool->list[item].atom.len == 0) {
- pool->list[item].atom.val.first = -1;
+ if (items->list[cur].atom.typ == YACItemEOC) {
+ if (items->list[item].atom.len == 0) {
+ items->list[item].atom.val.first = -1;
}
return YACErrNo;
}
if (prev != -1) {
- pool->list[prev].next = cur;
+ items->list[prev].next = cur;
}
prev = cur;
- idx = (pool->len) - 1;
- pool->list[item].atom.len++;
+ idx = (items->len) - 1;
+ items->list[item].atom.len++;
}
}
case YACItemMap: {
- pool->list[item].atom.val.first = item + 1;
- pool->list[item].atom.len = 0;
+ items->list[item].atom.val.first = item + 1;
+ items->list[item].atom.len = 0;
ptrdiff_t idx = item;
ptrdiff_t prev = -1;
ptrdiff_t cur = -1;
size_t prevKeyLen = 0;
const unsigned char *prevKey = NULL;
for (;;) {
- err = YACItemPoolParse(pool, off, buf, len);
+ err = YACItemsParse(items, off, buf, len);
if (err != YACErrNo) {
return err;
}
cur = idx + 1;
- switch (pool->list[cur].atom.typ) {
+ switch (items->list[cur].atom.typ) {
case YACItemEOC:
- if (pool->list[item].atom.len == 0) {
- pool->list[item].atom.val.first = -1;
+ if (items->list[item].atom.len == 0) {
+ items->list[item].atom.val.first = -1;
}
return YACErrNo;
case YACItemStr:
default:
return YACErrMapBadKey;
}
- if (pool->list[cur].atom.len == 0) {
+ if (items->list[cur].atom.len == 0) {
return YACErrMapBadKey;
}
- if (pool->list[cur].atom.len < prevKeyLen) {
+ if (items->list[cur].atom.len < prevKeyLen) {
return YACErrMapUnordered;
}
- if ((pool->list[cur].atom.len == prevKeyLen) &&
- (memcmp(prevKey, pool->list[cur].atom.val.buf, prevKeyLen) >= 0)) {
+ if ((items->list[cur].atom.len == prevKeyLen) &&
+ (memcmp(prevKey, items->list[cur].atom.val.buf, prevKeyLen) >= 0)) {
return YACErrMapUnordered;
}
- prevKeyLen = pool->list[cur].atom.len;
- prevKey = pool->list[cur].atom.val.buf;
+ prevKeyLen = items->list[cur].atom.len;
+ prevKey = items->list[cur].atom.val.buf;
if (prev != -1) {
- pool->list[prev].next = cur;
+ items->list[prev].next = cur;
}
prev = cur;
- idx = (pool->len) - 1;
- err = YACItemPoolParse(pool, off, buf, len);
+ idx = (items->len) - 1;
+ err = YACItemsParse(items, off, buf, len);
if (err != YACErrNo) {
return err;
}
cur = idx + 1;
- if (pool->list[cur].atom.typ == YACItemEOC) {
+ if (items->list[cur].atom.typ == YACItemEOC) {
return YACErrMapNoVal;
}
- pool->list[prev].next = cur;
+ items->list[prev].next = cur;
prev = cur;
- idx = (pool->len) - 1;
- pool->list[item].atom.len++;
+ idx = (items->len) - 1;
+ items->list[item].atom.len++;
}
}
case YACItemBlob: {
- pool->list[item].atom.len = 0;
- const ptrdiff_t chunkLen = (ptrdiff_t)(pool->list[item].atom.val.uint);
+ items->list[item].atom.len = 0;
+ const ptrdiff_t chunkLen = (ptrdiff_t)(items->list[item].atom.val.uint);
ptrdiff_t idx = item;
ptrdiff_t prev = -1;
ptrdiff_t cur = -1;
bool eoc = false;
while (!eoc) {
- err = YACItemPoolParse(pool, off, buf, len);
+ err = YACItemsParse(items, off, buf, len);
if (err != YACErrNo) {
return err;
}
cur = idx + 1;
- struct YACAtom *atom = &(pool->list[cur].atom);
+ struct YACAtom *atom = &(items->list[cur].atom);
switch (atom->typ) {
case YACItemNIL:
if (((ptrdiff_t)len - *off) <= chunkLen) {
return YACErrBlobBadAtom;
}
if (prev != -1) {
- pool->list[prev].next = cur;
+ items->list[prev].next = cur;
}
prev = cur;
- idx = (pool->len) - 1;
- pool->list[item].atom.len++;
+ idx = (items->len) - 1;
+ items->list[item].atom.len++;
}
break;
}