[svn-commits] rizzo: trunk r45334 - /trunk/main/manager.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Oct 17 10:51:35 MST 2006


Author: rizzo
Date: Tue Oct 17 12:51:34 2006
New Revision: 45334

URL: http://svn.digium.com/view/asterisk?rev=45334&view=rev
Log:
Improve the XML formatting of responses coming from web interface.
Normal responses are sequences of lines of the form "Name: value",
with \r\n as line terminators and an empty line as a response
terminator.

Generi CLI commands, however, do not have such a clean formatting,
and the existing code failed to generate valid XML for them.
Obviously we can only use heuristics here, and we do the following:
- accept either \r or \n as a line terminator, trimming trailing whitespace;
- if a line does not have a ":" in it, assume that from this point on
  we have unformatted data, and use "Opaque-data:" as a name;
- if a line does have a ":" in it, the Name field is not always
  a legal identifier, so replace non-alphanum characters with underscores;

All the above is to be refined as we improve the formatting of
responses from the CLI.

And, all the above ought to go as a comment in the code rather than
just in a commit message...
  

Modified:
    trunk/main/manager.c

Modified: trunk/main/manager.c
URL: http://svn.digium.com/view/asterisk/trunk/main/manager.c?rev=45334&r1=45333&r2=45334&view=diff
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Tue Oct 17 12:51:34 2006
@@ -296,7 +296,7 @@
 	int colons = 0;
 	int breaks = 0;
 	size_t len;
-	int count = 1;
+	int in_data = 0;	/* parsing data */
 	int escaped = 0;
 	int inobj = 0;
 	int x;
@@ -311,6 +311,11 @@
 		dest = "unknown";
 	if (!objtype)
 		objtype = "generic";
+
+	/* determine how large is the response.
+	 * This is a heuristic - counting colons (for headers),
+	 * newlines (for extra arguments), and escaped chars.
+	 */
 	for (x = 0; in[x]; x++) {
 		if (in[x] == ':')
 			colons++;
@@ -322,39 +327,52 @@
 	len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&amp;" */
 	out = ast_malloc(len);
 	if (!out)
-		return 0;
+		return NULL;
 	tmp = out;
-	while (*in) {
-		var = in;
-		while (*in && (*in >= 32))
-			in++;
-		if (*in) {
-			if ((count > 3) && inobj) {
-				ast_build_string(&tmp, &len, " /></response>\n");
-				inobj = 0;
+	/* we want to stop when we find an empty line */
+	while (in && *in) {
+		in = ast_skip_blanks(in);	/* trailing \n from before */
+		val = strsep(&in, "\r\n");	/* mark start and end of line */
+		ast_trim_blanks(val);
+		ast_verbose("inobj %d in_data %d line <%s>\n", inobj, in_data, val);
+		if (ast_strlen_zero(val)) {
+			if (in_data) { /* close data */
+				ast_build_string(&tmp, &len, "'");
+				in_data = 0;
 			}
-			count = 0;
-			while (*in && (*in < 32)) {
-				*in = '\0';
-				in++;
-				count++;
+			ast_build_string(&tmp, &len, " /></response>\n");
+			inobj = 0;
+			continue;
+		}
+		/* we expect Name: value lines */
+		if (in_data) {
+			var = NULL;
+		} else {
+			var = strsep(&val, ":");
+			if (val) {	/* found the field name */
+				val = ast_skip_blanks(val);
+				ast_trim_blanks(var);
+			} else {		/* field name not found, move to opaque mode */
+				val = var;
+				var = "Opaque-data";
 			}
-			val = strchr(var, ':');
-			if (val) {
-				*val = '\0';
-				val++;
-				if (*val == ' ')
-					val++;
-				if (!inobj) {
-					ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype);
-					inobj = 1;
-				}
-				ast_build_string(&tmp, &len, " ");				
-				xml_copy_escape(&tmp, &len, var, 1);
-				ast_build_string(&tmp, &len, "='");
-				xml_copy_escape(&tmp, &len, val, 0);
+		}
+		if (!inobj) {
+			ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype);
+			inobj = 1;
+		}
+		if (!in_data) {
+			ast_build_string(&tmp, &len, " ");				
+			xml_copy_escape(&tmp, &len, var, 1 | 2);
+			ast_build_string(&tmp, &len, "='");
+			xml_copy_escape(&tmp, &len, val, 0);
+			if (!strcmp(var, "Opaque-data")) {
+				in_data = 1;
+			} else {
 				ast_build_string(&tmp, &len, "'");
 			}
+		} else {
+			xml_copy_escape(&tmp, &len, val, 0);
 		}
 	}
 	if (inobj)



More information about the svn-commits mailing list