diff options
Diffstat (limited to 'Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c')
-rw-r--r-- | Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c b/Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c new file mode 100644 index 00000000000..577048a4293 --- /dev/null +++ b/Build/source/texk/web2c/mfluadir/otfcc/lib/bk/bkblock.c @@ -0,0 +1,132 @@ +#include "bkblock.h" + +static void bkblock_acells(bk_Block *b, uint32_t len) { + if (len <= b->length + b->free) { + // We have enough space + b->free -= len - b->length; + b->length = len; + } else { + // allocate space + b->length = len; + b->free = (len >> 1) & 0xFFFFFF; + RESIZE(b->cells, b->length + b->free); + } +} +bool bk_cellIsPointer(bk_Cell *cell) { + return cell->t >= p16; +} + +static bk_Cell *bkblock_grow(bk_Block *b, uint32_t len) { + uint32_t olen = b->length; + bkblock_acells(b, olen + len); + return &(b->cells[olen]); +} + +bk_Block *_bkblock_init() { + bk_Block *b; + NEW(b); + bkblock_acells(b, 0); + return b; +} + +static void bkblock_pushint(bk_Block *b, bk_CellType type, uint32_t x) { + bk_Cell *cell = bkblock_grow(b, 1); + cell->t = type; + cell->z = x; +} +static void bkblock_pushptr(bk_Block *b, bk_CellType type, bk_Block *p) { + bk_Cell *cell = bkblock_grow(b, 1); + cell->t = type; + cell->p = p; +} + +static void vbkpushitems(bk_Block *b, bk_CellType type0, va_list ap) { + bk_CellType curtype = type0; + while (curtype) { + if (curtype == bkcopy || curtype == bkembed) { + bk_Block *par = va_arg(ap, bk_Block *); + if (par && par->cells) { + for (uint32_t j = 0; j < par->length; j++) { + if (bk_cellIsPointer(par->cells + j)) { + bkblock_pushptr(b, par->cells[j].t, par->cells[j].p); + } else { + bkblock_pushint(b, par->cells[j].t, par->cells[j].z); + } + } + } + if (curtype == bkembed && par) { + FREE(par->cells); + FREE(par); + } + } else if (curtype < p16) { + uint32_t par = va_arg(ap, int); + bkblock_pushint(b, curtype, par); + } else { + bk_Block *par = va_arg(ap, bk_Block *); + bkblock_pushptr(b, curtype, par); + } + curtype = va_arg(ap, int); + } +} + +bk_Block *bk_new_Block(int type0, ...) { + va_list ap; + va_start(ap, type0); + bk_Block *b = _bkblock_init(); + vbkpushitems(b, type0, ap); + va_end(ap); + return b; +} + +bk_Block *bk_push(bk_Block *b, int type0, ...) { + va_list ap; + va_start(ap, type0); + vbkpushitems(b, type0, ap); + va_end(ap); + return b; +} + +bk_Block *bk_newBlockFromStringLen(size_t len, const char *str) { + if (!str) return NULL; + bk_Block *b = bk_new_Block(bkover); + for (size_t j = 0; j < len; j++) { + bkblock_pushint(b, b8, str[j]); + } + return b; +} + +bk_Block *bk_newBlockFromBuffer(MOVE caryll_Buffer *buf) { + if (!buf) return NULL; + bk_Block *b = bk_new_Block(bkover); + for (size_t j = 0; j < buf->size; j++) { + bkblock_pushint(b, b8, buf->data[j]); + } + buffree(buf); + return b; +} +bk_Block *bk_newBlockFromBufferCopy(OBSERVE caryll_Buffer *buf) { + if (!buf) return NULL; + bk_Block *b = bk_new_Block(bkover); + for (size_t j = 0; j < buf->size; j++) { + bkblock_pushint(b, b8, buf->data[j]); + } + return b; +} + +void bk_printBlock(bk_Block *b) { + fprintf(stderr, "Block size %08x\n", (uint32_t)b->length); + fprintf(stderr, "------------------\n"); + for (uint32_t j = 0; j < b->length; j++) { + if (bk_cellIsPointer(b->cells + j)) { + if (b->cells[j].p) { + fprintf(stderr, " %3d %p[%d]\n", b->cells[j].t, b->cells[j].p, + b->cells[j].p->_index); + } else { + fprintf(stderr, " %3d [NULL]\n", b->cells[j].t); + } + } else { + fprintf(stderr, " %3d %d\n", b->cells[j].t, b->cells[j].z); + } + } + fprintf(stderr, "------------------\n"); +} |