socsvn commit: r272199 - soc2014/zkorchev/freebsd_head/lib/libsol
zkorchev at FreeBSD.org
zkorchev at FreeBSD.org
Mon Aug 11 10:28:00 UTC 2014
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);
More information about the svn-soc-all
mailing list