Date: Mon, 11 Aug 2014 10:28:00 GMT From: zkorchev@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272199 - soc2014/zkorchev/freebsd_head/lib/libsol Message-ID: <201408111028.s7BAS0qD048631@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: zkorchev Date: Mon Aug 11 10:27:59 2014 New Revision: 272199 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272199 Log: libsol basic xml support Modified: soc2014/zkorchev/freebsd_head/lib/libsol/sol.c soc2014/zkorchev/freebsd_head/lib/libsol/sol.h Modified: soc2014/zkorchev/freebsd_head/lib/libsol/sol.c ============================================================================== --- soc2014/zkorchev/freebsd_head/lib/libsol/sol.c Mon Aug 11 08:58:35 2014 (r272198) +++ soc2014/zkorchev/freebsd_head/lib/libsol/sol.c Mon Aug 11 10:27:59 2014 (r272199) @@ -40,7 +40,8 @@ yajl_gen g; struct { - unsigned char stack[SOL_DEPTH_MAX]; + char *stack[SOL_DEPTH_MAX]; + //unsigned char stack[SOL_DEPTH_MAX]; unsigned depth; int first; } c; @@ -51,11 +52,52 @@ // TODO track whether a key or a value is expected and generate error when appropriate? +static void xml_open(struct sol_stream *restrict stream) +{ + const char *tag; + + if (stream->ctx.c.depth == 0) return; + + tag = stream->ctx.c.stack[stream->ctx.c.depth - 1]; + if (!tag && (stream->ctx.c.depth > 1)) + tag = stream->ctx.c.stack[stream->ctx.c.depth - 2]; + + if (tag) + printf("<%s>", tag); + else + printf("<item>"); +} + +static void xml_close(struct sol_stream *restrict stream) +{ + char *tag; + int clean = 0; + + if (stream->ctx.c.depth == 0) return; + + tag = stream->ctx.c.stack[stream->ctx.c.depth - 1]; + if (tag) + { + clean = 1; + stream->ctx.c.depth -= 1; + } + else if (stream->ctx.c.depth > 1) + tag = stream->ctx.c.stack[stream->ctx.c.depth - 2]; + + if (tag) + { + printf("</%s>", tag); + if (clean) free(tag); + } + else + printf("</item>"); +} + static void padding(const struct sol_stream *restrict stream) { #define T4 "\t\t\t\t" static const char buf[] = "\n" T4 T4 T4 T4 T4 T4 T4 T4; - printf("%.*s", 1 + stream->ctx.c.depth - stream->ctx.c.stack[0], buf); + printf("%.*s", 1 + stream->ctx.c.depth - (stream->ctx.c.stack[0] != 0), buf); #undef T4 } @@ -89,6 +131,8 @@ else if (!strcmp(format, "xml")) { stream->f = SOL_XML; + stream->ctx.c.depth = 0; + printf("<?xml version=\"1.1\" encoding=\"UTF-8\" ?>\n"); } else return 0; @@ -149,6 +193,9 @@ break; case SOL_XML: + if (stream->ctx.c.depth == SOL_DEPTH_MAX) + return 1; + stream->ctx.c.stack[stream->ctx.c.depth++] = 0; break; } @@ -158,6 +205,7 @@ int sol_array_end(struct sol_stream *restrict stream) { flush(stream); + switch (stream->f) { case SOL_JSON: @@ -170,6 +218,12 @@ padding(stream); printf("]"); break; + + case SOL_XML: + stream->ctx.c.depth -= 1; + if (stream->ctx.c.stack[stream->ctx.c.depth - 1]) + stream->ctx.c.depth -= 1; + break; } return 0; @@ -190,7 +244,11 @@ padding(stream); printf("{"); } - stream->ctx.c.stack[stream->ctx.c.depth++] = 1; + stream->ctx.c.stack[stream->ctx.c.depth++] = (void *)1; // TODO fix this + break; + + case SOL_XML: + xml_open(stream); break; } @@ -200,6 +258,7 @@ int sol_map_end(struct sol_stream *restrict stream) { flush(stream); + switch (stream->f) { case SOL_JSON: @@ -215,12 +274,16 @@ } stream->ctx.c.first = 0; break; + + case SOL_XML: + xml_close(stream); + break; } return 0; } -int sol_map_key(struct sol_stream *restrict stream, const char *key, size_t length) +int sol_map_key(struct sol_stream *restrict stream, const char *restrict key, size_t length) { switch (stream->f) { @@ -232,6 +295,26 @@ padding(stream); printf("%s", key); // TODO escape special chars break; + + case SOL_XML: + { + char *copy; + + if (stream->ctx.c.depth == SOL_DEPTH_MAX) + return 1; + + copy = malloc(length + 1); + if (!copy) return 1; + memcpy(copy, key, length); + copy[length] = 0; + + stream->ctx.c.stack[stream->ctx.c.depth] = copy; + if (stream->ctx.c.stack[stream->ctx.c.depth]) + stream->ctx.c.depth += 1; + else + return 1; + } + break; } return 0; @@ -264,6 +347,34 @@ printf("\"%s\"", data); } break; + + case SOL_XML: + { + size_t i; + + xml_open(stream); + for(i = 0; i < length; ++i) + switch (data[i]) + { + case '<': + fputs("<", stdout); + break; + + case '>': + fputs(">", stdout); + break; + + case '&': + fputs("&", stdout); + break; + + default: + putchar(data[i]); + break; + } + xml_close(stream); + } + break; } return 0; @@ -287,6 +398,12 @@ printf("%s", (value ? "true" : "false")); } break; + + case SOL_XML: + xml_open(stream); + printf(value ? "true" : "false"); + xml_close(stream); + break; } return 0; @@ -310,6 +427,12 @@ printf("%" PRId64, value); } break; + + case SOL_XML: + xml_open(stream); + printf("%" PRId64, value); + xml_close(stream); + break; } return 0; @@ -337,6 +460,12 @@ printf("%" PRIx64, value); } break; + + case SOL_XML: + xml_open(stream); + printf("%" PRIx64, value); + xml_close(stream); + break; } return 0; @@ -361,6 +490,12 @@ printf("%f", value); } break; + + case SOL_XML: + xml_open(stream); + printf("%f", value); + xml_close(stream); + break; } return 0; Modified: soc2014/zkorchev/freebsd_head/lib/libsol/sol.h ============================================================================== --- soc2014/zkorchev/freebsd_head/lib/libsol/sol.h Mon Aug 11 08:58:35 2014 (r272198) +++ soc2014/zkorchev/freebsd_head/lib/libsol/sol.h Mon Aug 11 10:27:59 2014 (r272199) @@ -35,7 +35,8 @@ enum sol_format f; struct { - unsigned char stack[SOL_DEPTH_MAX]; + char *stack[SOL_DEPTH_MAX]; + //unsigned char stack[SOL_DEPTH_MAX]; unsigned depth; int first; } c; @@ -51,7 +52,7 @@ int sol_map_start(struct sol_stream *restrict stream); int sol_map_end(struct sol_stream *restrict stream); -int sol_map_key(struct sol_stream *restrict stream, const char *key, size_t length); +int sol_map_key(struct sol_stream *restrict stream, const char *restrict key, size_t length); int sol_map_keyi(struct sol_stream *restrict stream, intmax_t number); int sol_boolean(struct sol_stream *restrict stream, unsigned char value);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408111028.s7BAS0qD048631>