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 () { |
---|
88 | return static_cast<Header*>(ptr_data2)->length; |
---|
89 | } |
---|
90 | |
---|
91 | inline int Word::is_number () { |
---|
92 | int res = 1; |
---|
93 | size_t i = 0; |
---|
94 | Header* h = static_cast<Header*>(ptr_data2); |
---|
95 | |
---|
96 | if ((h->content[i]) == '-') res = -1; |
---|
97 | if ((h->content[i]) == '+') res = 1; |
---|
98 | if (res) i = 1; |
---|
99 | for (; i < h->length; i++) |
---|
100 | if (iswdigit(h->content[i]) == 0) { |
---|
101 | res = 0; break; |
---|
102 | } |
---|
103 | return res; |
---|
104 | } |
---|
105 | |
---|
106 | //the method is called only if is_number() function |
---|
107 | //has returned non-zero value |
---|
108 | // |
---|
109 | |
---|
110 | inline Word::NumIterator::NumIterator(Word const& _word) { |
---|
111 | Header* h = static_cast<Header*>(_word.ptr_data2); |
---|
112 | if (*(h->content) == '+' || *(h->content) == '-') |
---|
113 | iter = h->content + 1; |
---|
114 | else |
---|
115 | iter = h->content; |
---|
116 | bound = h->content + h->length; |
---|
117 | } |
---|
118 | |
---|
119 | inline Word::NumIterator& Word::NumIterator::operator ++() { |
---|
120 | iter++; |
---|
121 | return *this; |
---|
122 | }; |
---|
123 | |
---|
124 | inline Word::NumIterator const& Word::NumIterator::operator = (Word const& _word) { |
---|
125 | Header* h = static_cast<Header*>(_word.ptr_data2); |
---|
126 | if (*(h->content) == '+' || *(h->content) == '-') |
---|
127 | iter = h->content + 1; |
---|
128 | else |
---|
129 | iter = h->content; |
---|
130 | return *this; |
---|
131 | }; |
---|
132 | |
---|
133 | inline bool Word::NumIterator::in_bounds () { |
---|
134 | if (iter > bound ) return false; |
---|
135 | else return true; |
---|
136 | } |
---|
137 | |
---|
138 | inline const wchar_t Word::NumIterator::operator * () { |
---|
139 | return *iter; |
---|
140 | } |
---|
141 | |
---|
142 | #if 0 |
---|
143 | Expr Word::create_expr (wchar_t const* _wstr) |
---|
144 | { |
---|
145 | Expr e = Term::create_expr(1); |
---|
146 | Term* p = e.get_first(); |
---|
147 | new(p) Word(_wstr); |
---|
148 | return e; |
---|
149 | } |
---|
150 | |
---|
151 | Expr Word::create_expr (char const* _str, char const* _locale /* = null */) |
---|
152 | { |
---|
153 | Expr e = Term::create_expr(1); |
---|
154 | Term* p = e.get_first(); |
---|
155 | new(p) Word(_str, _locale); |
---|
156 | return e; |
---|
157 | } |
---|
158 | #endif |
---|
159 | } |
---|
160 | |
---|
161 | #endif // __rf_word_ih__ |
---|