14e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
24e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#include "XmlRpcUtil.h"
34e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
44e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#ifndef MAKEDEPEND
54e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <ctype.h>
64e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <iostream>
74e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <stdarg.h>
84e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <stdio.h>
94e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <string.h>
104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif
114e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#include "XmlRpc.h"
134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piususing namespace XmlRpc;
154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius//#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output
184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#ifdef USE_WINDOWS_DEBUG
194e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#define WIN32_LEAN_AND_MEAN
204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#include <windows.h>
214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif
224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Version id
244e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusconst char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7";
254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Default log verbosity: 0 for no messages through 5 (writes everything)
274e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusint XmlRpcLogHandler::_verbosity = 0;
284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Default log handler
304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic class DefaultLogHandler : public XmlRpcLogHandler {
314e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piuspublic:
324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
334e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  void log(int level, const char* msg) {
344e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#ifdef USE_WINDOWS_DEBUG
354e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    if (level <= _verbosity) { OutputDebugString(msg); OutputDebugString("\n"); }
364e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else
374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    if (level <= _verbosity) std::cout << msg << std::endl;
384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif
394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  ~DefaultLogHandler() {}
424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} defaultLogHandler;
434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Message log singleton
454e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcLogHandler* XmlRpcLogHandler::_logHandler = &defaultLogHandler;
464e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
474e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
484e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Default error handler
494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic class DefaultErrorHandler : public XmlRpcErrorHandler {
504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piuspublic:
514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  void error(const char* msg) {
534e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#ifdef USE_WINDOWS_DEBUG
544e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    OutputDebugString(msg); OutputDebugString("\n");
554e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#else
564e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::cerr << msg << std::endl;
574e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif
584e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
594e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
604e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  ~DefaultErrorHandler() {}
614e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} defaultErrorHandler;
624e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
634e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
644e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Error handler singleton
654e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcErrorHandler* XmlRpcErrorHandler::_errorHandler = &defaultErrorHandler;
664e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
674e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
684e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Easy API for log verbosity
694e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusint XmlRpc::getVerbosity() { return XmlRpcLogHandler::getVerbosity(); }
704e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusvoid XmlRpc::setVerbosity(int level) { XmlRpcLogHandler::setVerbosity(level); }
714e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
724e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
734e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
744e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusvoid XmlRpcUtil::log(int level, const char* fmt, ...)
754e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
764e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (level <= XmlRpcLogHandler::getVerbosity())
774e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  {
784e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    va_list va;
794e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    char buf[1024];
804e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    va_start( va, fmt);
814e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    vsnprintf(buf,sizeof(buf)-1,fmt,va);
824e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    buf[sizeof(buf)-1] = 0;
834e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcLogHandler::getLogHandler()->log(level, buf);
844e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
854e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
864e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
874e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
884e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusvoid XmlRpcUtil::error(const char* fmt, ...)
894e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
904e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  va_list va;
914e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  va_start(va, fmt);
924e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  char buf[1024];
934e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  vsnprintf(buf,sizeof(buf)-1,fmt,va);
944e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  buf[sizeof(buf)-1] = 0;
954e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  XmlRpcErrorHandler::getErrorHandler()->error(buf);
964e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
974e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
984e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
994e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Returns contents between <tag> and </tag>, updates offset to char after </tag>
1004e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstd::string
1014e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcUtil::parseTag(const char* tag, std::string const& xml, int* offset)
1024e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
1034e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (*offset >= int(xml.length())) return std::string();
1044e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  size_t istart = xml.find(tag, *offset);
1054e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (istart == std::string::npos) return std::string();
1064e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  istart += strlen(tag);
1074e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string etag = "</";
1084e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  etag += tag + 1;
1094e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  size_t iend = xml.find(etag, istart);
1104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (iend == std::string::npos) return std::string();
1114e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  *offset = int(iend + etag.length());
1134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  return xml.substr(istart, iend-istart);
1144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
1154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Returns true if the tag is found and updates offset to the char after the tag
1184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool
1194e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcUtil::findTag(const char* tag, std::string const& xml, int* offset)
1204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
1214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (*offset >= int(xml.length())) return false;
1224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  size_t istart = xml.find(tag, *offset);
1234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (istart == std::string::npos)
1244e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    return false;
1254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  *offset = int(istart + strlen(tag));
1274e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  return true;
1284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
1294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1314e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Returns true if the tag is found at the specified offset (modulo any whitespace)
1324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// and updates offset to the char after the tag
1334e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusbool
1344e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcUtil::nextTagIs(const char* tag, std::string const& xml, int* offset)
1354e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
1364e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (*offset >= int(xml.length())) return false;
1374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  const char* cp = xml.c_str() + *offset;
1384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  int nc = 0;
1394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  while (*cp && isspace(*cp)) {
1404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    ++cp;
1414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    ++nc;
1424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
1434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  int len = int(strlen(tag));
1454e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if  (*cp && (strncmp(cp, tag, len) == 0)) {
1464e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    *offset += nc + len;
1474e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    return true;
1484e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
1494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  return false;
1504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
1514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Returns the next tag and updates offset to the char after the tag, or empty string
1534e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// if the next non-whitespace character is not '<'
1544e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstd::string
1554e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcUtil::getNextTag(std::string const& xml, int* offset)
1564e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
1574e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (*offset >= int(xml.length())) return std::string();
1584e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1594e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  size_t pos = *offset;
1604e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  const char* cp = xml.c_str() + pos;
1614e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  while (*cp && isspace(*cp)) {
1624e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    ++cp;
1634e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    ++pos;
1644e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
1654e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1664e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (*cp != '<') return std::string();
1674e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1684e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string s;
1694e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  do {
1704e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    s += *cp;
1714e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    ++pos;
1724e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  } while (*cp++ != '>' && *cp != 0);
1734e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1744e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  *offset = int(pos);
1754e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  return s;
1764e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
1774e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1784e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1794e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1804e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// xml encodings (xml-encoded entities are preceded with '&')
1814e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic const char  AMP = '&';
1824e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic const char  rawEntity[] = { '<',   '>',   '&',    '\'',    '\"',    0 };
1834e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic const char* xmlEntity[] = { "lt;", "gt;", "amp;", "apos;", "quot;", 0 };
1844e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstatic const int   xmlEntLen[] = { 3,     3,     4,      5,       5 };
1854e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1864e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1874e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Replace xml-encoded entities with the raw text equivalents.
1884e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1894e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstd::string
1904e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcUtil::xmlDecode(const std::string& encoded)
1914e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
1924e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string::size_type iAmp = encoded.find(AMP);
1934e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (iAmp == std::string::npos)
1944e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    return encoded;
1954e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1964e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string decoded(encoded, 0, iAmp);
1974e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string::size_type iSize = encoded.size();
1984e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  decoded.reserve(iSize);
1994e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2004e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  const char* ens = encoded.c_str();
2014e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  while (iAmp != iSize) {
2024e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    if (encoded[iAmp] == AMP && iAmp+1 < iSize) {
2034e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      int iEntity;
2044e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      for (iEntity=0; xmlEntity[iEntity] != 0; ++iEntity)
2054e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius	//if (encoded.compare(iAmp+1, xmlEntLen[iEntity], xmlEntity[iEntity]) == 0)
2064e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius	if (strncmp(ens+iAmp+1, xmlEntity[iEntity], xmlEntLen[iEntity]) == 0)
2074e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius        {
2084e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius          decoded += rawEntity[iEntity];
2094e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius          iAmp += xmlEntLen[iEntity]+1;
2104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius          break;
2114e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius        }
2124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      if (xmlEntity[iEntity] == 0)    // unrecognized sequence
2134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius        decoded += encoded[iAmp++];
2144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    } else {
2164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      decoded += encoded[iAmp++];
2174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    }
2184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
2194e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  return decoded;
2214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
2224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2244e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// Replace raw text with xml-encoded entities.
2254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstd::string
2274e2ea8184cc1f9609f1f1251394316629a108a78Roshan PiusXmlRpcUtil::xmlEncode(const std::string& raw)
2284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius{
2294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string::size_type iRep = raw.find_first_of(rawEntity);
2304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  if (iRep == std::string::npos)
2314e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    return raw;
2324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2334e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string encoded(raw, 0, iRep);
2344e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  std::string::size_type iSize = raw.size();
2354e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2364e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  while (iRep != iSize) {
2374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    int iEntity;
2384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    for (iEntity=0; rawEntity[iEntity] != 0; ++iEntity)
2394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      if (raw[iRep] == rawEntity[iEntity])
2404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      {
2414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius        encoded += AMP;
2424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius        encoded += xmlEntity[iEntity];
2434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius        break;
2444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      }
2454e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    if (rawEntity[iEntity] == 0)
2464e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      encoded += raw[iRep];
2474e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    ++iRep;
2484e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  }
2494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  return encoded;
2504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius}
2514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
2534e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
254