Skip site navigation (1)Skip section navigation (2)
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("&lt;", stdout);
+					break;
+
+				case '>':
+					fputs("&gt;", stdout);
+					break;
+
+				case '&':
+					fputs("&amp;", 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>