1 /* libobby - Network text editing library 2 * Copyright (C) 2005 0x539 dev group 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public 15 * License along with this program; if not, write to the Free 16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 #ifndef _OBBY_FORMATSTRING_HPP_ 20 #define _OBBY_FORMATSTRING_HPP_ 21 22 #include <cstdlib> 23 #include <string> 24 #include <vector> 25 #include <sstream> 26 #include <sigc++/signal.h> 27 28 namespace obby 29 { 30 31 /** Format string that may be used for type-safe printf-like formatting. 32 */ 33 34 template<typename string_type, typename stream_type> 35 class basic_format_string 36 { 37 public: basic_format_string(const string_type & format)38 basic_format_string(const string_type& format) 39 : m_content(format) { } basic_format_string(const basic_format_string & other)40 basic_format_string(const basic_format_string& other) 41 : m_content(other.m_content), m_arguments(other.m_arguments) { } ~basic_format_string()42 ~basic_format_string() { } 43 operator =(const string_type & format)44 basic_format_string& operator=(const string_type& format) { 45 m_content = format; 46 m_arguments.clear(); 47 return *this; 48 } operator =(const basic_format_string & other)49 basic_format_string& operator=(const basic_format_string& other) { 50 m_content = other.m_content; 51 m_arguments = other.m_arguments; 52 return *this; 53 } 54 str() const55 string_type str() const { 56 // Copy content 57 string_type content(m_content); 58 59 // Replace place holders 60 typename string_type::size_type pos = 0, end = 0; 61 while( (pos = content.find('%', pos)) != string_type::npos) 62 { 63 // Got first % char, look for second one. 64 end = content.find('%', pos + 1); 65 if(end == std::string::npos) 66 break; 67 68 // %% -> % in string 69 if(pos + 1 == end) 70 { 71 content.erase(++ pos, 1); 72 continue; 73 } 74 75 // Convert text in between to int 76 int argnum = strtol(content.c_str() + pos+1, NULL, 10); 77 const string_type& arg = m_arguments[argnum]; 78 content.replace(pos, end - pos + 1, arg); 79 pos += arg.length(); 80 } 81 82 // Return new string 83 return content; 84 } 85 86 template<class value_type> operator <<(const value_type & value)87 basic_format_string& operator<<(const value_type& value) { 88 stream_type value_stream; 89 value_stream << value; 90 m_arguments.push_back(value_stream.str() ); 91 return *this; 92 } 93 94 protected: 95 string_type m_content; 96 std::vector<string_type> m_arguments; 97 }; 98 99 typedef basic_format_string<std::string, std::stringstream> format_string; 100 101 } 102 103 #endif // _OBBY_FORMATSTRING_HPP_ 104