/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM is free software; you can redistribute it and/or modify it    
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; only version 2 of the License.      
 * 
 * NMM is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 
 * License for more details.  
 * 
 * You should have received a copy of the GNU General Public License 
 * along with NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */


/* This file (and the corresponding .cpp file) declare and define
 * several utility functions that might be useful in several
 * cases. The functions are usually described in the comment
 * blocks immidiately preceding them.
 */

#ifndef NMM_STRING_UTILS__HPP
#define NMM_STRING_UTILS__HPP NMM_STRING_UTILS__HPP

#include "nmm/nmm_prefix.hpp"

#include <string>
#include <sstream>

namespace NMM {

  /**
   * Concatenate a string with an integer. The integer is converted into a corresonding string and added behind the given string
   * 
   * @param str string 
   * @param i that should be added behind the string 
   */
  inline std::string operator+(const std::string str, const int& i) 
  {
    std::stringstream s;
    s<<str<<i;
    return s.str();
  }

  /**
   * Convert int to string
   * 
   * @param i integer that should be converted
   * @return string representation of the given interger i
   */
  inline std::string itoa(const int& i) 
  {
    std::stringstream s;
    s<<i;
    return s.str();
  }

  /**
   * Convert float to string
   * 
   * @param f float that should be converted
   * @return string representation of the given float f
   */
  inline std::string ftoa(const float& f) 
  {
    std::stringstream s;
    s<<f;
    return s.str();
  }

  /** Convert a string that is part of an URL to a common string (e.g by replacing %20 wtih whitespaces)
   *  
   * @param encoded string that should be converterd
   * @return string that can be used as part of an URL 
   */
  inline std::string urldecode(const std::string encoded) {
    const std::string hex_chars("0123456789abcdef");
    std::string retval = "";
    
    for (std::string::const_iterator i = encoded.begin(); i != encoded.end(); i++) {
      const char current = (*i);
      
      if ('%' != current) {
        retval += current;
      } else {
        int decimal = 0;
        for (int j = 0; j < 2; j++) {
          if (encoded.end() == ++i) {
            return "";
          }
          std::string::size_type hex_digit = hex_chars.find(tolower(*i));
          if (hex_chars.npos == hex_digit) {
            return "";
          }
          decimal = decimal*16 + static_cast<int>(hex_digit);
        }
        retval += (unsigned char) decimal; // must use unsigned to get high ascii chars like german umlauts
      }
    }
    
    return retval;
  }
    
  /** Convert a string so that it can be used as part of an URL  (e.g by replacing whitespaces with %20)
   *  
   * @param plain string that should be converterd
   * @return string that can be used as part of an URL 
   */
  inline std::string urlencode(const std::string plain) {
    const std::string hex_chars("0123456789ABCDEF");
    const std::string unsafe_chars("\"<>%\\^[]`+$,;/?:@=&#");
    std::string retval;
    
    for (std::string::const_iterator i = plain.begin(); i != plain.end(); i++) {
      const unsigned char current = (*i); // must use unsigned to get high ascii chars like german umlauts
      
      int decimal_code = (int) current;
      if ((unsafe_chars.npos == unsafe_chars.find(current)) && 
        (32 < decimal_code) && 
        (123 > decimal_code)) {
        retval += current;
      } else {
        if (0xFF < decimal_code) {
          return "";
        }
        retval += std::string("%") + hex_chars[decimal_code/16] + hex_chars[decimal_code%16];
      }
    }
    
    return retval;
  }

}

#include "nmm/nmm_suffix.hpp"

#endif //_NMM_UTILS_HPP_
