#include "stdafx.h"
#include "StringUtil.h"

using namespace std;

//---------------------------------------------------------------------------------------------------------------------
// Trim from start
//---------------------------------------------------------------------------------------------------------------------
string& LeftTrim(string& s)
{
  s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace))));
  return s;
}

//---------------------------------------------------------------------------------------------------------------------
// Trim from end
//---------------------------------------------------------------------------------------------------------------------
string& RightTrim(string& s)
{
  s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(), s.end());
  return s;
}

//---------------------------------------------------------------------------------------------------------------------
// Trim from both ends
//---------------------------------------------------------------------------------------------------------------------
string& Trim(string& s)
{
  return LeftTrim(RightTrim(s));
}

//---------------------------------------------------------------------------------------------------------------------
// Adapted from http://www.digitalpeer.com/blog/simple
//---------------------------------------------------------------------------------------------------------------------
vector<string> Tokenize(const string& str, const string& delimiters)
{
  vector<string> tokens;
  string::size_type delimPos = 0, tokenPos = 0, pos = 0;

  if (str.length() < 1)  return tokens;
  while (1)
  {
    delimPos = str.find_first_of(delimiters, pos);
    tokenPos = str.find_first_not_of(delimiters, pos);

    if (string::npos != delimPos)
    {
      if (string::npos != tokenPos)
      {
        if (tokenPos < delimPos)
        {
          tokens.push_back(str.substr(pos, delimPos - pos));
        }
        else
        {
          tokens.push_back("");
        }
      }
      else
      {
        tokens.push_back("");
      }
      pos = delimPos + 1;
    }
    else
    {
      if (string::npos != tokenPos)
      {
        tokens.push_back(str.substr(pos));
      }
      else
      {
        tokens.push_back("");
      }
      break;
    }
  }
  return tokens;
}

//---------------------------------------------------------------------------------------------------------------------
// Adapted from http://mdawson.net/misc/xmlescape.php
//---------------------------------------------------------------------------------------------------------------------
/**
* Escape characters that will interfere with xml.
*
* @param sSrc The source string to escape.
* @return sSrc encoded for insertion into xml.
*/
string EncodeForXml(const string& sSrc)
{
  ostringstream sRet;

  for (string::const_iterator iter = sSrc.begin(); iter != sSrc.end(); iter++)
  {
    unsigned char c = (unsigned char)*iter;

    switch (c)
    {
    case '&': sRet << "&amp;"; break;
    case '<': sRet << "&lt;"; break;
    case '>': sRet << "&gt;"; break;
    case '"': sRet << "&quot;"; break;
    case '\'': sRet << "&apos;"; break;

    default:
      if (c<32 || c>127)
      {
        sRet << "&#" << (unsigned int)c << ";";
      }
      else
      {
        sRet << c;
      }
    }
  }

  return sRet.str();
}
