1 | #ifndef __rf_word_ih__ |
---|
2 | #define __rf_word_ih__ |
---|
3 | |
---|
4 | #include "rf_word.hh" |
---|
5 | #include "rf_common.ih" |
---|
6 | |
---|
7 | #include <wctype.h> |
---|
8 | #include <wchar.h> |
---|
9 | #include <locale.h> |
---|
10 | |
---|
11 | namespace rftype |
---|
12 | { |
---|
13 | |
---|
14 | using namespace rfrt ; |
---|
15 | |
---|
16 | inline Word::Word (wchar_t const* _wstr) : |
---|
17 | Term (term_sym, type_word) |
---|
18 | { |
---|
19 | size_t len = wcslen(_wstr); |
---|
20 | Header* h = static_cast<Header*>( |
---|
21 | allocator.allocate(sizeof(Header) + len * sizeof(wchar_t))); |
---|
22 | h->ref_count = 1; |
---|
23 | h->length = len; |
---|
24 | uint32_t hash = 0; |
---|
25 | for (size_t i = 0; i < len; i++) { |
---|
26 | h->content[i] = _wstr[i]; |
---|
27 | hash = update_hash(hash, h->content + i, sizeof(wchar_t)); |
---|
28 | } |
---|
29 | h->hash = finish_hash(hash); |
---|
30 | ptr_data2 = h; |
---|
31 | } |
---|
32 | |
---|
33 | inline Word::Word (char const* _str, char const* _locale /* = null */) : |
---|
34 | Term (term_sym, type_word) |
---|
35 | { |
---|
36 | char const* saved_locale = null; |
---|
37 | if (_locale != null) { |
---|
38 | saved_locale = setlocale(LC_CTYPE, null); |
---|
39 | setlocale(LC_CTYPE, _locale); |
---|
40 | } |
---|
41 | char const* s = _str; |
---|
42 | mbstate_t ps; |
---|
43 | size_t len = mbsrtowcs(null, &s, 0, &ps); |
---|
44 | // if (len == (size_t)(-1)) throw_sys_error(errno); |
---|
45 | Header* h = static_cast<Header*>( |
---|
46 | allocator.allocate(sizeof(Header) + len * sizeof(wchar_t))); |
---|
47 | h->ref_count = 1; |
---|
48 | h->length = len; |
---|
49 | s = _str; |
---|
50 | uint32_t hash = 0; |
---|
51 | for (size_t i = 0; i < len; i++) { |
---|
52 | size_t l = mbrtowc(h->content + i, s, MB_CUR_MAX, &ps); |
---|
53 | s += l; |
---|
54 | hash = update_hash(hash, h->content + i, sizeof(wchar_t)); |
---|
55 | } |
---|
56 | h->hash = finish_hash(hash); |
---|
57 | ptr_data2 = h; |
---|
58 | if (_locale != null) setlocale(LC_CTYPE, saved_locale); |
---|
59 | } |
---|
60 | |
---|
61 | inline Word::Word (Word const& _word) : |
---|
62 | Term (term_sym, type_word) |
---|
63 | { |
---|
64 | ptr_data2 = _word.ptr_data2; |
---|
65 | Header* h = static_cast<Header*>(ptr_data2); |
---|
66 | h->ref_count++; |
---|
67 | } |
---|
68 | |
---|
69 | inline Word::~Word () |
---|
70 | { |
---|
71 | Header* h = static_cast<Header*>(ptr_data2); |
---|
72 | if (--(h->ref_count) == 0) allocator.deallocate(h); |
---|
73 | } |
---|
74 | |
---|
75 | inline Word& Word::operator = (Word const& _word) |
---|
76 | { |
---|
77 | if (this != &_word) { |
---|
78 | Header* h = static_cast<Header*>(ptr_data2); |
---|
79 | if (--(h->ref_count) == 0) allocator.deallocate(h); |
---|
80 | ptr_data2 = _word.ptr_data2; |
---|
81 | h = static_cast<Header*>(ptr_data2); |
---|
82 | h->ref_count++; |
---|
83 | } |
---|
84 | return self; |
---|
85 | } |
---|
86 | |
---|
87 | inline size_t Word::get_len () const |
---|
88 | { |
---|
89 | return static_cast<Header*>(ptr_data2)->length; |
---|
90 | } |
---|
91 | |
---|
92 | |
---|
93 | //first symbol in word is '-' res == -1; '+' res == 1, |
---|
94 | //'digit' res == 2; othewise res == 0 |
---|
95 | // |
---|
96 | |
---|
97 | inline int Word::is_number () const |
---|
98 | { |
---|
99 | int res = 0; |
---|
100 | size_t i = 0; |
---|
101 | Header* h = static_cast<Header*>(ptr_data2); |
---|
102 | |
---|
103 | for (; ;) |
---|
104 | if ((h->content[i]) != ' ') |
---|
105 | break; |
---|
106 | else |
---|
107 | i++; |
---|
108 | |
---|
109 | if ((h->content[i]) == '-') res = -1; |
---|
110 | if ((h->content[i]) == '+') res = 1; |
---|
111 | if (iswdigit(h->content[i])) res = 2; |
---|
112 | |
---|
113 | if (res) |
---|
114 | i++; |
---|
115 | |
---|
116 | bool prev = false; |
---|
117 | |
---|
118 | for (; i < h->length; i++) { |
---|
119 | if (iswdigit(h->content[i]) == 0) { |
---|
120 | if ((h->content[i]) == ' ') { |
---|
121 | prev = true; |
---|
122 | continue; |
---|
123 | } |
---|
124 | |
---|
125 | else { |
---|
126 | res = 0; |
---|
127 | break; |
---|
128 | } |
---|
129 | } |
---|
130 | else |
---|
131 | if (prev) { |
---|
132 | res = 0; |
---|
133 | break; |
---|
134 | } |
---|
135 | else continue; |
---|
136 | |
---|
137 | |
---|
138 | } |
---|
139 | return res; |
---|
140 | } |
---|
141 | |
---|
142 | //the method is called only if is_number() function |
---|
143 | //has returned non-zero value |
---|
144 | // |
---|
145 | |
---|
146 | inline Word::NumIterator::NumIterator(Word const& _word) |
---|
147 | { |
---|
148 | Header* h = static_cast<Header*>(_word.ptr_data2); |
---|
149 | |
---|
150 | for (size_t i = 0; i < h->length; i++){ |
---|
151 | if ( *(h->content + i) == ' ') |
---|
152 | continue; |
---|
153 | else { |
---|
154 | iter = h->content + i; |
---|
155 | break; |
---|
156 | } |
---|
157 | } |
---|
158 | |
---|
159 | if (*(h->content) == '+' || *(h->content) == '-') |
---|
160 | iter = h->content + 1; |
---|
161 | |
---|
162 | for (size_t i = h->length - 1; ; i--) |
---|
163 | if (h->content[i] == ' ') |
---|
164 | continue; |
---|
165 | else { |
---|
166 | bound = h->content + i; |
---|
167 | break; |
---|
168 | } |
---|
169 | } |
---|
170 | |
---|
171 | inline Word::NumIterator& Word::NumIterator::operator ++(int) |
---|
172 | { |
---|
173 | iter++; |
---|
174 | return *this; |
---|
175 | }; |
---|
176 | |
---|
177 | inline Word::NumIterator const& Word::NumIterator::operator = (Word const& _word) { |
---|
178 | Header* h = static_cast<Header*>(_word.ptr_data2); |
---|
179 | if (*(h->content) == '+' || *(h->content) == '-') |
---|
180 | iter = h->content + 1; |
---|
181 | else |
---|
182 | iter = h->content; |
---|
183 | return *this; |
---|
184 | }; |
---|
185 | |
---|
186 | inline bool Word::NumIterator::in_bounds () const |
---|
187 | { |
---|
188 | if (iter > bound ) |
---|
189 | return false; |
---|
190 | else |
---|
191 | return true; |
---|
192 | } |
---|
193 | |
---|
194 | inline const char Word::NumIterator::operator * () const |
---|
195 | { |
---|
196 | return *iter - 48; |
---|
197 | } |
---|
198 | |
---|
199 | #if 0 |
---|
200 | Expr Word::create_expr (wchar_t const* _wstr) |
---|
201 | { |
---|
202 | Expr e = Term::create_expr(1); |
---|
203 | Term* p = e.get_first(); |
---|
204 | new(p) Word(_wstr); |
---|
205 | return e; |
---|
206 | } |
---|
207 | |
---|
208 | Expr Word::create_expr (char const* _str, char const* _locale /* = null */) |
---|
209 | { |
---|
210 | Expr e = Term::create_expr(1); |
---|
211 | Term* p = e.get_first(); |
---|
212 | new(p) Word(_str, _locale); |
---|
213 | return e; |
---|
214 | } |
---|
215 | #endif |
---|
216 | } |
---|
217 | |
---|
218 | #endif // __rf_word_ih__ |
---|