1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
17 // takes a pointer into a utf8 string and returns a unicode character for the
18 // first character at the pointer
19 unichar utf8_get_char (const char *p)
21 unichar result = static_cast<unsigned char>(*p);
23 // if its not a 7-bit ascii character
24 if((result & 0x80) != 0) {
25 // len is the number of bytes this character takes up in the string
26 unsigned char len = utf8_skip[result];
27 result &= 0x7F >> len;
31 result |= static_cast<unsigned char>(*++p) & 0x3F;
38 // takes a pointer into a string and finds its offset
39 static ustring::size_type utf8_ptr_to_offset(const char *str, const char *pos)
41 ustring::size_type offset = 0;
44 str += utf8_skip[*str];
51 // takes an offset into a string and returns a pointer to it
52 const char *utf8_offset_to_ptr(const char *str, ustring::size_type offset)
55 str += utf8_skip[*str];
59 // First overload: stop on '\0' character.
60 ustring::size_type utf8_byte_offset(const char* str, ustring::size_type offset)
62 if(offset == ustring::npos)
67 for(; offset != 0; --offset)
78 // Second overload: stop when reaching maxlen.
79 ustring::size_type utf8_byte_offset(const char* str, ustring::size_type offset,
80 ustring::size_type maxlen)
82 if(offset == ustring::npos)
85 const char *const pend = str + maxlen;
88 for(; offset != 0; --offset)
110 ustring::ustring(const ustring& other)
111 : _string(other._string), _utf8(other._utf8)
115 ustring& ustring::operator=(const ustring& other)
117 _string = other._string;
122 ustring::ustring(const std::string& src)
123 : _string(src), _utf8(true)
127 ustring::ustring(const char* src)
128 : _string(src), _utf8(true)
132 ustring& ustring::operator+=(const ustring& src)
134 assert(_utf8 == src._utf8);
135 _string += src._string;
139 ustring& ustring::operator+=(const char* src)
145 ustring& ustring::operator+=(char c)
151 ustring::size_type ustring::size() const
154 const char *const pdata = _string.data();
155 return utf8_ptr_to_offset(pdata, pdata + _string.size());
157 return _string.size();
160 ustring::size_type ustring::bytes() const
162 return _string.size();
165 ustring::size_type ustring::capacity() const
167 return _string.capacity();
170 ustring::size_type ustring::max_size() const
172 return _string.max_size();
175 bool ustring::empty() const
177 return _string.empty();
180 void ustring::clear()
185 ustring& ustring::erase(ustring::size_type i, ustring::size_type n)
188 // find a proper offset
189 size_type utf_i = utf8_byte_offset(_string.c_str(), i);
191 // if the offset is not npos, find a proper length for 'n'
192 size_type utf_n = utf8_byte_offset(_string.data() + utf_i, n,
193 _string.size() - utf_i);
194 _string.erase(utf_i, utf_n);
202 void ustring::resize(ustring::size_type n, char c)
205 const size_type size_now = size();
208 else if(n > size_now)
209 _string.append(n - size_now, c);
211 _string.resize(n, c);
214 ustring::value_type ustring::operator[](ustring::size_type i) const
216 return utf8_get_char(utf8_offset_to_ptr(_string.data(), i));
219 const char* ustring::data() const
221 return _string.data();
224 const char* ustring::c_str() const
226 return _string.c_str();
229 bool ustring::utf8() const
234 void ustring::setUtf8(bool utf8)