diff options
author | phil <phil@FreeBSD.org> | 2016-03-17 00:46:36 +0000 |
---|---|---|
committer | phil <phil@FreeBSD.org> | 2016-03-17 00:46:36 +0000 |
commit | 0efb2620b96d9cbb76b33a390facfc24ff231ba3 (patch) | |
tree | afa76ef09b8528cae96477148b1c0437ceb1f2d4 /0.4.5/encoder | |
parent | 3ce11bd9fc4d042a890334b8e0c5adcb094b9d17 (diff) | |
download | FreeBSD-src-0efb2620b96d9cbb76b33a390facfc24ff231ba3.zip FreeBSD-src-0efb2620b96d9cbb76b33a390facfc24ff231ba3.tar.gz |
Tag libxo 0.4.5
Approved by: sjg
Diffstat (limited to '0.4.5/encoder')
-rw-r--r-- | 0.4.5/encoder/Makefile.am | 9 | ||||
-rw-r--r-- | 0.4.5/encoder/cbor/Makefile.am | 51 | ||||
-rw-r--r-- | 0.4.5/encoder/cbor/enc_cbor.c | 365 | ||||
-rw-r--r-- | 0.4.5/encoder/test/Makefile.am | 51 | ||||
-rw-r--r-- | 0.4.5/encoder/test/enc_test.c | 30 |
5 files changed, 506 insertions, 0 deletions
diff --git a/0.4.5/encoder/Makefile.am b/0.4.5/encoder/Makefile.am new file mode 100644 index 0000000..10d19de --- /dev/null +++ b/0.4.5/encoder/Makefile.am @@ -0,0 +1,9 @@ +# +# Copyright 2015, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +SUBDIRS = cbor test diff --git a/0.4.5/encoder/cbor/Makefile.am b/0.4.5/encoder/cbor/Makefile.am new file mode 100644 index 0000000..7ce44e0 --- /dev/null +++ b/0.4.5/encoder/cbor/Makefile.am @@ -0,0 +1,51 @@ +# +# $Id$ +# +# Copyright 2015, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +if LIBXO_WARNINGS_HIGH +LIBXO_WARNINGS = HIGH +endif +if HAVE_GCC +GCC_WARNINGS = yes +endif +include ${top_srcdir}/warnings.mk + +enc_cborincdir = ${includedir}/libxo + +AM_CFLAGS = \ + -I${top_srcdir}/libxo \ + -I${top_builddir}/libxo \ + ${WARNINGS} + +LIBNAME = libenc_cbor +pkglib_LTLIBRARIES = libenc_cbor.la +LIBS = \ + -L${top_builddir}/libxo -lxo + +LDADD = ${top_builddir}/libxo/libxo.la + +libenc_cbor_la_SOURCES = \ + enc_cbor.c + +pkglibdir = ${XO_ENCODERDIR} + +UGLY_NAME = cbor.enc + +install-exec-hook: + @DLNAME=`sh -c '. ./libenc_cbor.la ; echo $$dlname'` ; \ + if [ x"$$DLNAME" = x ]; \ + then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \ + if [ "$(build_os)" = "cygwin" ]; \ + then DLNAME="../bin/$$DLNAME"; fi ; \ + echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \ + mkdir -p ${DESTDIR}${XO_ENCODERDIR} ; \ + cd ${DESTDIR}${XO_ENCODERDIR} \ + && chmod +w . \ + && rm -f ${UGLY_NAME} \ + && ${LN_S} $$DLNAME ${UGLY_NAME} diff --git a/0.4.5/encoder/cbor/enc_cbor.c b/0.4.5/encoder/cbor/enc_cbor.c new file mode 100644 index 0000000..513063f --- /dev/null +++ b/0.4.5/encoder/cbor/enc_cbor.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +/* + * CBOR (RFC 7049) mades a suitable test case for libxo's external + * encoder API. It's simple, streaming, well documented, and an + * IETF standard. + * + * This encoder uses the "pretty" flag for diagnostics, which isn't + * really kosher, but it's example code. + */ + +#include <string.h> +#include <sys/types.h> +#include <unistd.h> +#include <stdint.h> +#include <ctype.h> +#include <stdlib.h> +#include <limits.h> + +#include "xo.h" +#include "xo_encoder.h" +#include "xo_buf.h" + +/* + * memdump(): dump memory contents in hex/ascii +0 1 2 3 4 5 6 7 +0123456789012345678901234567890123456789012345678901234567890123456789012345 +XX XX XX XX XX XX XX XX - XX XX XX XX XX XX XX XX abcdefghijklmnop + */ +static void +cbor_memdump (FILE *fp, const char *title, const char *data, + size_t len, const char *tag, int indent) +{ + enum { MAX_PER_LINE = 16 }; + char buf[ 80 ]; + char text[ 80 ]; + char *bp, *tp; + size_t i; +#if 0 + static const int ends[ MAX_PER_LINE ] = { 2, 5, 8, 11, 15, 18, 21, 24, + 29, 32, 35, 38, 42, 45, 48, 51 }; +#endif + + if (fp == NULL) + fp = stdout; + if (tag == NULL) + tag = ""; + + fprintf(fp, "%*s[%s] @ %p (%lx/%lu)\n", indent + 1, tag, + title, data, (unsigned long) len, (unsigned long) len); + + while (len > 0) { + bp = buf; + tp = text; + + for (i = 0; i < MAX_PER_LINE && i < len; i++) { + if (i && (i % 4) == 0) *bp++ = ' '; + if (i == 8) { + *bp++ = '-'; + *bp++ = ' '; + } + sprintf(bp, "%02x ", (unsigned char) *data); + bp += strlen(bp); + *tp++ = (isprint((int) *data) && *data >= ' ') ? *data : '.'; + data += 1; + } + + *tp = 0; + *bp = 0; + fprintf(fp, "%*s%-54s%s\n", indent + 1, tag, buf, text); + len -= i; + } +} + +/* + * CBOR breaks the first byte into two pieces, the major type in the + * top 3 bits and the minor value in the low 5 bits. The value can be + * a small value (0 .. 23), an 8-bit value (24), a 16-bit value (25), + * a 32-bit value (26), or a 64-bit value (27). A value of 31 + * represents an unknown length, which we'll use extensively for + * streaming our content. + */ +#define CBOR_MAJOR_MASK 0xE0 +#define CBOR_MINOR_MASK 0x1F +#define CBOR_MAJOR_SHIFT 5 + +#define CBOR_MAJOR(_x) ((_x) & CBOR_MAJOR_MASK) +#define CBOR_MAJOR_VAL(_x) ((_x) << CBOR_MAJOR_SHIFT) +#define CBOR_MINOR_VAL(_x) ((_x) & CBOR_MINOR_MASK) + +/* Major type codes */ +#define CBOR_UNSIGNED CBOR_MAJOR_VAL(0) /* 0x00 */ +#define CBOR_NEGATIVE CBOR_MAJOR_VAL(1) /* 0x20 */ +#define CBOR_BYTES CBOR_MAJOR_VAL(2) /* 0x40 */ +#define CBOR_STRING CBOR_MAJOR_VAL(3) /* 0x60 */ +#define CBOR_ARRAY CBOR_MAJOR_VAL(4) /* 0x80 */ +#define CBOR_MAP CBOR_MAJOR_VAL(5) /* 0xa0 */ +#define CBOR_SEMANTIC CBOR_MAJOR_VAL(6) /* 0xc0 */ +#define CBOR_SPECIAL CBOR_MAJOR_VAL(7) /* 0xe0 */ + +#define CBOR_ULIMIT 24 /* Largest unsigned value */ +#define CBOR_NLIMIT 23 /* Largest negative value */ + +#define CBOR_BREAK 0xFF +#define CBOR_INDEF 0x1F + +#define CBOR_FALSE 0xF4 +#define CBOR_TRUE 0xF5 +#define CBOR_NULL 0xF6 +#define CBOR_UNDEF 0xF7 + +#define CBOR_LEN8 0x18 /* 24 - 8-bit value */ +#define CBOR_LEN16 0x19 /* 25 - 16-bit value */ +#define CBOR_LEN32 0x1a /* 26 - 32-bit value */ +#define CBOR_LEN64 0x1b /* 27 - 64-bit value */ +#define CBOR_LEN128 0x1c /* 28 - 128-bit value */ + +typedef struct cbor_private_s { + xo_buffer_t c_data; /* Our data buffer */ + unsigned c_indent; /* Indent level */ + unsigned c_open_leaf_list; /* Open leaf list construct? */ +} cbor_private_t; + +static void +cbor_encode_uint (xo_buffer_t *xbp, uint64_t minor, unsigned limit) +{ + char *bp = xbp->xb_curp; + int i, m; + + if (minor > (1UL<<32)) { + *bp++ |= CBOR_LEN64; + m = 64; + + } else if (minor > (1<<16)) { + *bp++ |= CBOR_LEN32; + m = 32; + + } else if (minor > (1<<8)) { + *bp++ |= CBOR_LEN16; + m = 16; + + } else if (minor > limit) { + *bp++ |= CBOR_LEN8; + m = 8; + } else { + *bp++ |= minor & CBOR_MINOR_MASK; + m = 0; + } + + if (m) { + for (i = m - 8; i >= 0; i -= 8) + *bp++ = minor >> i; + } + + xbp->xb_curp = bp; +} + +static void +cbor_append (xo_handle_t *xop, cbor_private_t *cbor, xo_buffer_t *xbp, + unsigned major, unsigned minor, const char *data) +{ + if (!xo_buf_has_room(xbp, minor + 2)) + return; + + unsigned offset = xo_buf_offset(xbp); + + *xbp->xb_curp = major; + cbor_encode_uint(xbp, minor, CBOR_ULIMIT); + if (data) + xo_buf_append(xbp, data, minor); + + if (xo_get_flags(xop) & XOF_PRETTY) + cbor_memdump(stdout, "append", xo_buf_data(xbp, offset), + xbp->xb_curp - xbp->xb_bufp - offset, "", + cbor->c_indent * 2); +} + +static int +cbor_create (xo_handle_t *xop) +{ + cbor_private_t *cbor = xo_realloc(NULL, sizeof(*cbor)); + if (cbor == NULL) + return -1; + + bzero(cbor, sizeof(*cbor)); + xo_buf_init(&cbor->c_data); + + xo_set_private(xop, cbor); + + cbor_append(xop, cbor, &cbor->c_data, CBOR_MAP | CBOR_INDEF, 0, NULL); + + return 0; +} + +static int +cbor_content (xo_handle_t *xop, cbor_private_t *cbor, xo_buffer_t *xbp, + const char *value) +{ + int rc = 0; + + unsigned offset = xo_buf_offset(xbp); + + if (value == NULL || *value == '\0' || strcmp(value, "true") == 0) + cbor_append(xop, cbor, &cbor->c_data, CBOR_TRUE, 0, NULL); + else if (strcmp(value, "false") == 0) + cbor_append(xop, cbor, &cbor->c_data, CBOR_FALSE, 0, NULL); + else { + int negative = 0; + if (*value == '-') { + value += 1; + negative = 1; + } + + char *ep; + unsigned long long ival; + ival = strtoull(value, &ep, 0); + if (ival == ULLONG_MAX) /* Sometimes a string is just a string */ + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value); + else { + *xbp->xb_curp = negative ? CBOR_NEGATIVE : CBOR_UNSIGNED; + if (negative) + ival -= 1; /* Don't waste a negative zero */ + cbor_encode_uint(xbp, ival, negative ? CBOR_NLIMIT : CBOR_ULIMIT); + } + } + + if (xo_get_flags(xop) & XOF_PRETTY) + cbor_memdump(stdout, "content", xo_buf_data(xbp, offset), + xbp->xb_curp - xbp->xb_bufp - offset, "", + cbor->c_indent * 2); + + return rc; +} + +static int +cbor_handler (XO_ENCODER_HANDLER_ARGS) +{ + int rc = 0; + cbor_private_t *cbor = private; + xo_buffer_t *xbp = cbor ? &cbor->c_data : NULL; + + if (xo_get_flags(xop) & XOF_PRETTY) { + printf("%*sop %s: [%s] [%s]\n", cbor ? cbor->c_indent * 2 + 4 : 0, "", + xo_encoder_op_name(op), name ?: "", value ?: ""); + fflush(stdout); + } + + /* If we don't have private data, we're sunk */ + if (cbor == NULL && op != XO_OP_CREATE) + return -1; + + switch (op) { + case XO_OP_CREATE: /* Called when the handle is init'd */ + rc = cbor_create(xop); + break; + + case XO_OP_OPEN_CONTAINER: + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_MAP | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + break; + + case XO_OP_CLOSE_CONTAINER: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_OPEN_LIST: + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_ARRAY | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + break; + + case XO_OP_CLOSE_LIST: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_OPEN_LEAF_LIST: + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_ARRAY | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + cbor->c_open_leaf_list = 1; + break; + + case XO_OP_CLOSE_LEAF_LIST: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + cbor->c_open_leaf_list = 0; + break; + + case XO_OP_OPEN_INSTANCE: + cbor_append(xop, cbor, xbp, CBOR_MAP | CBOR_INDEF, 0, NULL); + cbor->c_indent += 1; + break; + + case XO_OP_CLOSE_INSTANCE: + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_STRING: /* Quoted UTF-8 string */ + if (!cbor->c_open_leaf_list) + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(value), value); + break; + + case XO_OP_CONTENT: /* Other content */ + if (!cbor->c_open_leaf_list) + cbor_append(xop, cbor, xbp, CBOR_STRING, strlen(name), name); + + /* + * It's content, not string, so we need to look at the + * string and build some content. Turns out we only + * care about true, false, null, and numbers. + */ + cbor_content(xop, cbor, xbp, value); + break; + + case XO_OP_FINISH: /* Clean up function */ + cbor_append(xop, cbor, xbp, CBOR_BREAK, 0, NULL); + cbor->c_indent -= 1; + break; + + case XO_OP_FLUSH: /* Clean up function */ + if (xo_get_flags(xop) & XOF_PRETTY) + cbor_memdump(stdout, "cbor", + xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp, + ">", 0); + else { + rc = write(1, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp); + if (rc > 0) + rc = 0; + } + break; + + case XO_OP_DESTROY: /* Clean up function */ + break; + + case XO_OP_ATTRIBUTE: /* Attribute name/value */ + break; + + case XO_OP_VERSION: /* Version string */ + break; + + } + + return rc; +} + +int +xo_encoder_library_init (XO_ENCODER_INIT_ARGS) +{ + arg->xei_handler = cbor_handler; + + return 0; +} diff --git a/0.4.5/encoder/test/Makefile.am b/0.4.5/encoder/test/Makefile.am new file mode 100644 index 0000000..1d8518e --- /dev/null +++ b/0.4.5/encoder/test/Makefile.am @@ -0,0 +1,51 @@ +# +# $Id$ +# +# Copyright 2015, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +if LIBXO_WARNINGS_HIGH +LIBXO_WARNINGS = HIGH +endif +if HAVE_GCC +GCC_WARNINGS = yes +endif +include ${top_srcdir}/warnings.mk + +enc_testincdir = ${includedir}/libxo + +AM_CFLAGS = \ + -I${top_srcdir}/libxo \ + -I${top_builddir}/libxo \ + ${WARNINGS} + +LIBNAME = libenc_test +pkglib_LTLIBRARIES = libenc_test.la +LIBS = \ + -L${top_builddir}/libxo -lxo + +LDADD = ${top_builddir}/libxo/libxo.la + +libenc_test_la_SOURCES = \ + enc_test.c + +pkglibdir = ${XO_ENCODERDIR} + +UGLY_NAME = test.enc + +install-exec-hook: + @DLNAME=`sh -c '. ./libenc_test.la ; echo $$dlname'` ; \ + if [ x"$$DLNAME" = x ]; \ + then DLNAME=${LIBNAME}.${XO_LIBEXT}; fi ; \ + if [ "$(build_os)" = "cygwin" ]; \ + then DLNAME="../bin/$$DLNAME"; fi ; \ + echo Install link $$DLNAME "->" ${UGLY_NAME} "..." ; \ + mkdir -p ${DESTDIR}${XO_ENCODERDIR} ; \ + cd ${DESTDIR}${XO_ENCODERDIR} \ + && chmod +w . \ + && rm -f ${UGLY_NAME} \ + && ${LN_S} $$DLNAME ${UGLY_NAME} diff --git a/0.4.5/encoder/test/enc_test.c b/0.4.5/encoder/test/enc_test.c new file mode 100644 index 0000000..ec49499 --- /dev/null +++ b/0.4.5/encoder/test/enc_test.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, Juniper Networks, Inc. + * All rights reserved. + * This SOFTWARE is licensed under the LICENSE provided in the + * ../Copyright file. By downloading, installing, copying, or otherwise + * using the SOFTWARE, you agree to be bound by the terms of that + * LICENSE. + * Phil Shafer, August 2015 + */ + +#include "xo.h" +#include "xo_encoder.h" + +static int +test_handler (XO_ENCODER_HANDLER_ARGS) +{ + printf("op %s: [%s] [%s]\n", xo_encoder_op_name(op), + name ?: "", value ?: ""); + + return 0; +} + +int +xo_encoder_library_init (XO_ENCODER_INIT_ARGS) +{ + arg->xei_version = XO_ENCODER_VERSION; + arg->xei_handler = test_handler; + + return 0; +} |