Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

xml_token_string.h

Go to the documentation of this file.
00001 /*
00002 **  ClanLib SDK
00003 **  Copyright (c) 1997-2005 The ClanLib Team
00004 **
00005 **  This software is provided 'as-is', without any express or implied
00006 **  warranty.  In no event will the authors be held liable for any damages
00007 **  arising from the use of this software.
00008 **
00009 **  Permission is granted to anyone to use this software for any purpose,
00010 **  including commercial applications, and to alter it and redistribute it
00011 **  freely, subject to the following restrictions:
00012 **
00013 **  1. The origin of this software must not be misrepresented; you must not
00014 **     claim that you wrote the original software. If you use this software
00015 **     in a product, an acknowledgment in the product documentation would be
00016 **     appreciated but is not required.
00017 **  2. Altered source versions must be plainly marked as such, and must not be
00018 **     misrepresented as being the original software.
00019 **  3. This notice may not be removed or altered from any source distribution.
00020 **
00021 **  Note: Some of the libraries ClanLib link to may have additional
00022 **  requirements or restrictions.
00023 **
00024 **  File Author(s):
00025 **
00026 **    Magnus Norddahl
00027 */
00028 
00031 
00032 #ifndef header_xml_writer_generic
00033 #define header_xml_writer_generic
00034 
00035 #if _MSC_VER > 1000
00036 #pragma once
00037 #endif
00038 
00039 #include <string>
00040 #include <algorithm>
00041 #include <vector>
00042 
00043 //: String class for XML Tokens.
00044 //- !group=Core/XML!
00045 //- !header=core.h!
00046 class CL_XMLTokenString
00047 {
00048 public:
00049         CL_XMLTokenString();
00050 
00051         CL_XMLTokenString(char const * pointer, int len, bool is_need_escape);
00052 
00053         CL_XMLTokenString(char * pointer, int len, bool is_need_escape);
00054 
00055         CL_XMLTokenString(const CL_XMLTokenString & copy);
00056 
00057         CL_XMLTokenString & operator=(const CL_XMLTokenString & copy);
00058 
00059 public:
00060         char * ptr();
00061 
00062         char const * ptr() const;
00063 
00064         int length() const;
00065 
00066         char operator[](int i) const;
00067 
00068         char & operator[](int i);
00069 
00070         std::string to_string() const;
00071 
00072         bool empty() const;
00073 
00074         bool need_escape() const;
00075 
00076         char * begin();
00077 
00078         char * end();
00079 
00080         char * begin() const;
00081 
00082         char * end() const;
00083 
00084 private:
00085         char * pointer;
00086 
00087         int len;
00088 
00089         bool is_need_escape;
00090 };
00091 
00092 
00093 inline CL_XMLTokenString::CL_XMLTokenString()
00094         : pointer(0)
00095         , len(0)
00096         , is_need_escape(false)
00097 {
00098 }
00099 
00100 inline CL_XMLTokenString::CL_XMLTokenString(char * pointer, int len, bool is_need_escape)
00101         : pointer(pointer)
00102         , len(len)
00103         , is_need_escape(is_need_escape)
00104 {
00105 }
00106 
00107 // unsafe ctor
00108 inline CL_XMLTokenString::CL_XMLTokenString(char const * pointer, int len, bool is_need_escape)
00109         : pointer(const_cast<char*>(pointer))
00110         , len(len)
00111         , is_need_escape(is_need_escape)
00112 {
00113 }
00114 
00115 inline CL_XMLTokenString::CL_XMLTokenString(const CL_XMLTokenString & copy)
00116         : pointer(copy.pointer)
00117         , len(copy.len)
00118         , is_need_escape(copy.is_need_escape)
00119 {
00120 }
00121 
00122 inline CL_XMLTokenString & CL_XMLTokenString::operator=(const CL_XMLTokenString & copy)
00123 {
00124         if (this == &copy)
00125                 return *this;
00126 
00127         pointer = copy.pointer;
00128         len = copy.len;
00129         is_need_escape = copy.is_need_escape;
00130 
00131         return *this;
00132 }
00133 
00134 inline char * CL_XMLTokenString::ptr()
00135 {
00136         return pointer;
00137 }
00138 
00139 inline char const * CL_XMLTokenString::ptr() const
00140 {
00141         return pointer;
00142 }
00143    
00144 inline int CL_XMLTokenString::length() const
00145 {
00146         return len;
00147 }
00148 
00149 inline bool CL_XMLTokenString::empty() const
00150 {
00151         return len == 0;
00152 }
00153 
00154 inline char * CL_XMLTokenString::begin()
00155 {
00156         return pointer;
00157 }
00158 
00159 inline char * CL_XMLTokenString::end()
00160 {
00161         return pointer + len;
00162 }
00163 
00164 inline char * CL_XMLTokenString::begin() const
00165 {
00166         return pointer;
00167 }
00168 
00169 inline char * CL_XMLTokenString::end() const
00170 {
00171         return pointer + len;
00172 }
00173 
00174 inline bool CL_XMLTokenString::need_escape() const
00175 {
00176         return is_need_escape;
00177 }
00178 
00179 inline bool operator==(CL_XMLTokenString const & lhs, CL_XMLTokenString const & rhs)
00180 {
00181         return lhs.length() == rhs.length() && !memcmp(lhs.ptr(), rhs.ptr(), lhs.length());
00182 }
00183 
00184 inline char CL_XMLTokenString::operator[](int i) const
00185 {
00186         return pointer[i];
00187 }
00188 
00189 inline char & CL_XMLTokenString::operator[](int i)
00190 {
00191         return pointer[i];
00192 }
00193 
00194 template <typename Container, typename Iter>
00195 inline bool append_escape(Container & buff, size_t & buff_size, Iter & begin, Iter end, std::string const & escape, char escape_char)
00196 {
00197         if ((int)escape.size() <= (end - begin))
00198                 if (std::equal(escape.begin(), escape.end(), begin))
00199                 {
00200                         buff[buff_size] = escape_char;
00201                         buff_size += 1;
00202                         begin += escape.size();
00203                         return true;
00204                 }
00205         return false;
00206 }
00207 
00208 inline std::string replace_escapes_fast(CL_XMLTokenString const & token_string)
00209 {
00210         static std::string const amp("&amp;");
00211         static std::string const quot("&quot;");
00212         static std::string const apos("&apos;");
00213         static std::string const lt("&lt;");
00214         static std::string const gt("&gt;");
00215 
00216         char const * begin = token_string.begin();
00217         char const * end = token_string.end();
00218 
00219         std::string::size_type size = token_string.length();
00220 
00221         static std::vector<char> buff;
00222         if (buff.size() < size)
00223                 buff.resize(size);
00224 
00225         size_t buff_size = 0;
00226 
00227         while(begin != end)
00228         {
00229                 char const * pos = std::find(begin, end, '&');
00230                 std::copy(begin, pos, buff.begin() + buff_size);
00231                 buff_size += std::distance(begin, pos);
00232 
00233                 if (pos == end)
00234                         break;
00235 
00236                 begin = pos;
00237                 if (    append_escape(buff, buff_size, begin, end, amp, '&')
00238                         ||      append_escape(buff, buff_size, begin, end, quot, '\"')
00239                         ||      append_escape(buff, buff_size, begin, end, apos, '\'')
00240                         ||      append_escape(buff, buff_size, begin, end, gt, '>')
00241                         ||      append_escape(buff, buff_size, begin, end, lt, '<'))
00242                 {
00243                 }
00244                 else
00245                 {
00246                         buff[buff_size] = '&';
00247                         buff_size += 1;
00248                         ++begin;
00249                 }
00250         }
00251         return std::string(&buff[0], buff_size);
00252 }
00253 
00254 inline std::string CL_XMLTokenString::to_string() const
00255 {
00256         if (!is_need_escape)
00257                 return std::string(pointer, len);
00258 
00259         return replace_escapes_fast(*this);
00260 }
00261 
00262 inline CL_XMLTokenString trim_whitespace(CL_XMLTokenString const & str)
00263 {
00264         if (str.empty())
00265                 return str;
00266 
00267         char const * begin = str.begin();
00268         char const * end = str.end();
00269 
00270         while(begin != end)
00271         {
00272                 char ch = *begin;
00273                 if (    ch != ' '
00274                         &&      ch != '\t'
00275                         &&      ch != '\r'
00276                         &&      ch != '\n')
00277                 {
00278                         break;
00279                 }
00280                 ++begin;
00281         }
00282 
00283         while(end != begin)
00284         {
00285                 char const * old_end = end--;
00286                 
00287                 char ch = *end;
00288                 if (    ch != ' '
00289                         &&      ch != '\t'
00290                         &&      ch != '\r'
00291                         &&      ch != '\n')
00292                 {
00293                         end = old_end;
00294                         break;
00295                 }
00296                 --end;
00297         }
00298 
00299         return CL_XMLTokenString(begin, (int) std::distance(begin, end), str.need_escape());
00300 }
00301 
00302 #endif

Generated on Sat Feb 19 22:51:16 2005 for npcore by  doxygen 1.4.1