diff --git a/main/manager.c b/main/manager.c
index f0650457d9..332d2c591d 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -69,6 +69,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/threadstorage.h"
#include "asterisk/linkedlists.h"
#include "asterisk/term.h"
+#include "asterisk/astobj2.h"
/*!
* Linked list of events.
@@ -2935,6 +2936,47 @@ static void xml_copy_escape(struct ast_str **out, const char *src, int mode)
}
}
+struct variable_count {
+ char *varname;
+ int count;
+};
+
+static int compress_char(char c)
+{
+ c &= 0x7f;
+ if (c < 32)
+ return 0;
+ else if (c >= 'a' && c <= 'z')
+ return c - 64;
+ else if (c > 'z')
+ return '_';
+ else
+ return c - 32;
+}
+
+static int variable_count_hash_fn(const void *vvc, const int flags)
+{
+ const struct variable_count *vc = vvc;
+ int res = 0, i;
+ for (i = 0; i < 5; i++) {
+ if (vc->varname[i] == '\0')
+ break;
+ res += compress_char(vc->varname[i]) << (i * 6);
+ }
+ return res;
+}
+
+static int variable_count_cmp_fn(void *obj, void *vstr, int flags)
+{
+ /* Due to the simplicity of struct variable_count, it makes no difference
+ * if you pass in objects or strings, the same operation applies. This is
+ * due to the fact that the hash occurs on the first element, which means
+ * the address of both the struct and the string are exactly the same. */
+ struct variable_count *vc = obj;
+ char *str = vstr;
+ return !strcmp(vc->varname, str) ? CMP_MATCH : 0;
+}
+
/*! \brief Convert the input into XML or HTML.
* The input is supposed to be a sequence of lines of the form
* Name: value
@@ -2972,6 +3014,8 @@ static void xml_translate(struct ast_str **out, char *in, struct ast_variable *v
int in_data = 0; /* parsing data */
int inobj = 0;
int xml = (format == FORMAT_XML);
+ struct variable_count *vc = NULL;
+ struct ao2_container *vco = NULL;
for (v = vars; v; v = v->next) {
if (!dest && !strcasecmp(v->name, "ajaxdest"))
@@ -2983,36 +3027,14 @@ static void xml_translate(struct ast_str **out, char *in, struct ast_variable *v
dest = "unknown";
if (!objtype)
objtype = "generic";
-#if 0
- /* determine how large is the response.
- * This is a heuristic - counting colons (for headers),
- * newlines (for extra arguments), and escaped chars.
- * XXX needs to be checked carefully for overflows.
- * Even better, use some code that allows extensible strings.
- */
- for (x = 0; in[x]; x++) {
- if (in[x] == ':')
- colons++;
- else if (in[x] == '\n')
- breaks++;
- else if (strchr("&\"<>", in[x]))
- escaped++;
- }
- len = (size_t) (1 + strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "