source: to-imperative/trunk/runtime/rf_word.ih @ 773

Last change on this file since 773 was 773, checked in by luba, 18 years ago
  • is_number() method is corrected;
  • has_spaces() method is added;
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.9 KB
Line 
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
11namespace rftype
12{
13
14using namespace rfrt ;
15
16inline 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
33inline 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 
61inline 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 
69inline Word::~Word ()
70{
71  Header* h = static_cast<Header*>(ptr_data2);
72  if (--(h->ref_count) == 0) allocator.deallocate(h);
73}
74
75inline 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
87inline 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
97enum is_number_res {plus, minus, positive_number, not_a_number};
98
99inline int Word::is_number () const
100{
101  enum is_number_res res = not_a_number;
102  size_t i = 0;
103  Header* h = static_cast<Header*>(ptr_data2);
104
105  for (; ;)
106    if (((h->content[i]) != ' '))
107      break;
108    else
109      i++;
110   
111  if ((h->content[i]) == '-') res = minus;
112  if ((h->content[i]) == '+') res = plus;
113  if (iswdigit(h->content[i])) res = positive_number;
114 
115  if (res != not_a_number)
116    i++;
117
118  bool prev = false;
119
120  for (; i < h->length; i++) {
121    if (iswdigit(h->content[i]) == 0) { 
122      if ((h->content[i]) == ' ') {
123        prev = true;
124        continue;
125      }
126
127      else {
128        res = not_a_number;
129        break;
130      }
131    }
132    else
133      if (prev) {
134        res = not_a_number;
135        break;
136      }
137      else continue;
138     
139
140  }
141  return res;
142}
143
144
145//the method returns 1, if the word has spaces at the beginning,
146//and returns 2, if the word has spaces at the end
147//
148inline int Word::has_space () const {
149  Header* h = static_cast<Header*>(ptr_data2);
150  if ( *(h->content) == ' ')
151    return 1;
152  else
153  if ( *(h->content + h->length) == ' ')
154    return 2;
155
156}
157
158
159
160//the method is called only if is_number() function
161//has returned non-zero value
162//
163
164inline Word::NumIterator::NumIterator(Word const& _word)
165{
166  Header* h = static_cast<Header*>(_word.ptr_data2);
167
168  for (size_t i = 0; i < h->length; i++){   
169    if ( *(h->content + i) == ' ')
170      continue;
171    else {
172      iter = h->content + i;
173      break;
174    }
175  }
176
177  if (*(h->content) == '+' || *(h->content) == '-')
178    iter = h->content + 1;
179
180  for (size_t i = h->length - 1; ; i--)
181    if (h->content[i] == ' ')
182      continue;
183    else {
184      bound = h->content + i;
185      break;
186    }
187}
188 
189inline Word::NumIterator& Word::NumIterator::operator ++(int)
190{
191  iter++;     
192  return *this;
193};
194
195inline Word::NumIterator const& Word::NumIterator::operator = (Word const& _word) {
196  Header* h = static_cast<Header*>(_word.ptr_data2);
197  if (*(h->content) == '+' || *(h->content) == '-')
198    iter = h->content + 1;
199  else
200    iter = h->content;
201  return *this;
202};
203
204inline bool Word::NumIterator::in_bounds () const
205{
206  if (iter > bound )
207    return false;
208  else
209    return true;
210}
211
212inline const char Word::NumIterator::operator * () const
213{
214    return *iter - 48;
215}
216
217#if 0
218Expr Word::create_expr (wchar_t const* _wstr)
219 {
220  Expr e = Term::create_expr(1);
221  Term* p = e.get_first();
222  new(p) Word(_wstr);
223  return e;
224}
225
226Expr Word::create_expr (char const* _str, char const* _locale /* = null */)
227{
228  Expr e = Term::create_expr(1);
229  Term* p = e.get_first();
230  new(p) Word(_str, _locale);
231  return e;
232}
233#endif
234}
235
236#endif // __rf_word_ih__
Note: See TracBrowser for help on using the repository browser.