#ifndef __rf_word_ih__ #define __rf_word_ih__ #include #include #include #include "rf_word.hh" #include "rf_common.ih" namespace rftype { using namespace rfrt ; inline Word::Word (wchar_t const* _wstr, size_t _len) : Term (type_word) { Header* h = static_cast( allocator->allocate(sizeof(Header) + _len * sizeof(wchar_t))); h->ref_count = 1; h->length = _len; uint32_t hash = 0; for (size_t i = 0; i < _len; i++) { h->content[i] = _wstr[i]; hash = update_hash(hash, h->content + i, sizeof(wchar_t)); } h->hash = finish_hash(hash); ptr_data2 = h; } inline Word::Word (wchar_t const* _wstr) : Term (type_word) { new(this) Word(_wstr, wcslen(_wstr)); } inline Word::Word (pxx::WString const& _wstr) : Term (type_word) { new(this) Word(_wstr.get_data(), _wstr.get_length()); } inline Word::Word (char const* _str, char const* _locale /* = null */) : Term (type_word) { char const* saved_locale = null; if (_locale != null) { saved_locale = setlocale(LC_CTYPE, null); setlocale(LC_CTYPE, _locale); } char const* s = _str; size_t len = mbstowcs(null, s, 0); if (len == (size_t)(-1)) FATAL("Error while converting a string"); Header* h = static_cast( allocator->allocate(sizeof(Header) + len * sizeof(wchar_t))); h->ref_count = 1; h->length = len; uint32_t hash = 0; for (size_t i = 0; i < len; i++) { size_t l = mbtowc(h->content + i, s, MB_CUR_MAX); s += l; hash = update_hash(hash, h->content + i, sizeof(wchar_t)); } h->hash = finish_hash(hash); ptr_data2 = h; if (_locale != null) setlocale(LC_CTYPE, saved_locale); } inline Word::Word (Word const& _word) : Term (type_word) { ptr_data2 = _word.ptr_data2; Header* h = static_cast(ptr_data2); h->ref_count++; } inline Word::~Word () { Header* h = static_cast(ptr_data2); if (--(h->ref_count) == 0) allocator->deallocate(h); } inline Word& Word::operator = (Word const& _word) { if (this != &_word) { Header* h = static_cast(ptr_data2); if (--(h->ref_count) == 0) allocator->deallocate(h); ptr_data2 = _word.ptr_data2; h = static_cast(ptr_data2); h->ref_count++; } return self; } inline size_t Word::get_len () const { return static_cast(ptr_data2)->length; } #if 0 //first symbol in word is '-' res == -1; '+' res == 1, //'digit' res == 2; othewise res == 0 // inline Word::is_number_res Word::is_number () const { is_number_res res = not_a_number; size_t i = 0; Header* h = static_cast(ptr_data2); for (; ;) if ((h->content[i]) != ' ') break; else { i++; res = space_number ;} if ((h->content[i]) == '-') res = minus; else if ((h->content[i]) == '+') res = plus; else if (iswdigit(h->content[i])) res = positive_number; else res = not_a_number; if (res != not_a_number) i++; bool prev = false; if (res == space_number) { i++; prev = true; } for (; i < h->length; i++) { if (iswdigit(h->content[i]) == 0) { if ((h->content[i]) == ' ') { prev = true; continue; } else { res = not_a_number; break; } } else if (prev) { res = not_a_number; break; } else if (res == not_a_number) break; else continue; } return res; } //the method returns 1, if the word has spaces at the beginning, //and returns 2, if the word has spaces at the end; 0, if there are no //spaces in the word // inline int Word::has_spaces () const { Header* h = static_cast(ptr_data2); if ( *(h->content) == ' ') return 1; else if ( *(h->content + h->length) == ' ') return 2; else return 0; } //the method is called only if is_number() function //has returned non-zero value // inline Word::NumIterator::NumIterator(Word const& _word) { Header* h = static_cast(_word.ptr_data2); for (size_t i = 0; i < h->length; i++){ if ( *(h->content + i) == ' ') continue; else { iter = h->content + i; break; } } if (*(h->content) == '+' || *(h->content) == '-') iter = h->content + 1; for (size_t i = h->length - 1; ; i--) if (h->content[i] == ' ') continue; else { bound = h->content + i; break; } } inline Word::NumIterator& Word::NumIterator::operator ++(int) { iter++; return *this; }; inline Word::NumIterator const& Word::NumIterator::operator = (Word const& _word) { Header* h = static_cast(_word.ptr_data2); if (*(h->content) == '+' || *(h->content) == '-') iter = h->content + 1; else iter = h->content; return *this; }; inline bool Word::NumIterator::in_bounds () const { if (iter > bound ) return false; else return true; } inline const char Word::NumIterator::operator * () const { return *iter - 48; } Expr Word::create_expr (wchar_t const* _wstr) { Expr e = Term::create_expr(1); Term* p = e.get_first(); new(p) Word(_wstr); return e; } Expr Word::create_expr (char const* _str, char const* _locale /* = null */) { Expr e = Term::create_expr(1); Term* p = e.get_first(); new(p) Word(_str, _locale); return e; } #endif } #endif // __rf_word_ih__