--- /dev/null
+// Copyright 2005-6 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#include <cassert>
+#include <cstddef>
+
+#include "xml_utils.hpp"
+
+std::string xml_escape(const std::string & str)
+{
+ std::string result;
+ std::size_t begin = 0;
+
+ for (;;)
+ {
+ std::size_t end = str.find_first_of("\"&'<>", begin);
+ result.append(str, begin, end - begin);
+ if (end == std::string::npos)
+ return result;
+
+ const char * entity = NULL;
+ switch (str[end])
+ {
+ case '"': entity = """; break;
+ case '&': entity = "&"; break;
+ case '\'': entity = "'"; break;
+ case '<': entity = "<"; break;
+ case '>': entity = ">"; break;
+ }
+ assert(entity);
+ result.append(entity);
+
+ begin = end + 1;
+ }
+}