]> Dogcows Code - chaz/openbox/blob - otk/ustring.cc
8f3cdfc452fae6bfdc2c4af2f716da9c769ff9d0
[chaz/openbox] / otk / ustring.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef HAVE_CONFIG_H
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
6
7 #include "ustring.hh"
8
9 extern "C" {
10 #include <assert.h>
11 }
12
13 namespace otk {
14
15 // helper functions
16
17 static ustring::size_type utf8_find_offset(const char *str, const char *pos)
18 {
19 ustring::size_type offset = 0;
20
21 while (str < pos) {
22 str += g_utf8_skip[*str];
23 offset += g_utf8_skip[*str];
24 }
25
26 return offset;
27 }
28
29 // First overload: stop on '\0' character.
30 ustring::size_type utf8_byte_offset(const char* str, ustring::size_type offset)
31 {
32 if(offset == ustring::npos)
33 return ustring::npos;
34
35 const char* p = str;
36
37 for(; offset != 0; --offset)
38 {
39 if(*p == '\0')
40 return ustring::npos;
41
42 p += g_utf8_skip[*p];
43 }
44
45 return (p - str);
46 }
47
48 // Second overload: stop when reaching maxlen.
49 ustring::size_type utf8_byte_offset(const char* str, ustring::size_type offset,
50 ustring::size_type maxlen)
51 {
52 if(offset == ustring::npos)
53 return ustring::npos;
54
55 const char *const pend = str + maxlen;
56 const char* p = str;
57
58 for(; offset != 0; --offset)
59 {
60 if(p >= pend)
61 return ustring::npos;
62
63 p += g_utf8_skip[*p];
64 }
65
66 return (p - str);
67 }
68
69
70 // ustring methods
71
72 ustring::ustring()
73 {
74 }
75
76 ustring::~ustring()
77 {
78 }
79
80 ustring::ustring(const ustring& other)
81 : _string(other._string), _utf8(other._utf8)
82 {
83 }
84
85 ustring& ustring::operator=(const ustring& other)
86 {
87 _string = other._string;
88 _utf8 = other._utf8;
89 return *this;
90 }
91
92 ustring::ustring(const std::string& src)
93 : _string(src), _utf8(true)
94 {
95 }
96
97 ustring::ustring(const char* src)
98 : _string(src), _utf8(true)
99 {
100 }
101
102 ustring& ustring::operator+=(const ustring& src)
103 {
104 assert(_utf8 == src._utf8);
105 _string += src._string;
106 return *this;
107 }
108
109 ustring& ustring::operator+=(const char* src)
110 {
111 _string += src;
112 return *this;
113 }
114
115 ustring& ustring::operator+=(char c)
116 {
117 _string += c;
118 return *this;
119 }
120
121 ustring::size_type ustring::size() const
122 {
123 if (_utf8) {
124 const char *const pdata = _string.data();
125 return utf8_find_offset(pdata, pdata + _string.size());
126 } else
127 return _string.size();
128 }
129
130 ustring::size_type ustring::bytes() const
131 {
132 return _string.size();
133 }
134
135 ustring::size_type ustring::capacity() const
136 {
137 return _string.capacity();
138 }
139
140 ustring::size_type ustring::max_size() const
141 {
142 return _string.max_size();
143 }
144
145 void ustring::clear()
146 {
147 _string.erase();
148 }
149
150 ustring& ustring::erase(ustring::size_type i, ustring::size_type n)
151 {
152 if (_utf8) {
153 // find a proper offset
154 size_type utf_i = utf8_byte_offset(_string.c_str(), i);
155 if (utf_i != npos) {
156 // if the offset is not npos, find a proper length for 'n'
157 size_type utf_n = utf8_byte_offset(_string.data() + utf_i, n,
158 _string.size() - utf_i);
159 _string.erase(utf_i, utf_n);
160 }
161 } else
162 _string.erase(i, n);
163
164 return *this;
165 }
166
167 void ustring::resize(ustring::size_type n, char c)
168 {
169 if (_utf8) {
170 const size_type size_now = size();
171 if(n < size_now)
172 erase(n, npos);
173 else if(n > size_now)
174 _string.append(n - size_now, c);
175 } else
176 _string.resize(n, c);
177 }
178
179 const char* ustring::data() const
180 {
181 return _string.data();
182 }
183
184 const char* ustring::c_str() const
185 {
186 return _string.c_str();
187 }
188
189 bool ustring::utf8() const
190 {
191 return _utf8;
192 }
193
194 void ustring::setUtf8(bool utf8)
195 {
196 _utf8 = utf8;
197 }
198
199 }
This page took 0.04258 seconds and 4 git commands to generate.