Changed LICENSE. Now referenced to web site and file on project root directory
[anna.git] / source / core / util / Tokenizer.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <anna/core/util/Tokenizer.hpp>
10 #include <anna/core/functions.hpp>
11 #include <anna/config/defines.hpp>
12
13 using namespace std;
14 using namespace anna;
15
16 //static
17 const int Tokenizer::MaxItem = 64;
18
19 Tokenizer::Tokenizer() :
20   a_dataBlock(true),
21   a_activateStrip(false) {
22   a_items = new char* [MaxItem];
23   anna_memset(a_items, 0, sizeof(char*) * MaxItem);
24   a_maxItem = 0;
25 }
26
27 Tokenizer::Tokenizer(const char* str, const char* separator) :
28   a_dataBlock(true),
29   a_activateStrip(false) {
30   a_items = new char* [MaxItem];
31   anna_memset(a_items, 0, sizeof(char*) * MaxItem);
32   a_maxItem = 0;
33
34   try {
35     apply(str, separator);
36   } catch(Exception&) {
37   }
38 }
39
40 Tokenizer::Tokenizer(const string& str, const char* separator) :
41   a_dataBlock(true),
42   a_activateStrip(false) {
43   a_items = new char* [MaxItem];
44   anna_memset(a_items, 0, sizeof(char*) * MaxItem);
45
46   try {
47     apply(str.c_str(), separator);
48   } catch(Exception&) {
49   }
50 }
51
52 Tokenizer::~Tokenizer() {
53   delete [] a_items;
54 }
55
56 int Tokenizer::apply(const char* str, const char* separator)
57 throw(RuntimeException) {
58   a_maxItem = 0;
59
60   if(str == NULL)
61     return 0;
62
63   DataBlock mb(str, anna_strlen(str) + 1, false);
64   a_dataBlock = mb;
65   const char* buffer = a_dataBlock.getData();
66   char *token = const_cast <char*>(buffer);
67   char* last;
68
69   while((token = strtok_r(token, separator, &last)) != NULL) {
70     if(a_activateStrip == true)
71       token = strip(token);
72
73     a_items [a_maxItem ++] = token;
74     token = NULL;
75
76     if(a_maxItem == MaxItem) {
77       string msg("Tokenizer::apply | String: ");
78       msg += str;
79       msg += " | Separator: ";
80       msg += separator;
81       msg += " | Tokenizer has not enough space";
82       throw RuntimeException(msg, ANNA_FILE_LOCATION);
83     }
84   }
85
86   return a_maxItem;
87 }
88
89 const char* Tokenizer::at(const int i)
90 throw(RuntimeException) {
91   if(i >= a_maxItem)
92     indexException(i, ANNA_FILE_LOCATION);
93
94   return data(begin() + i);
95 }
96
97 const char* Tokenizer::at(const int i) const
98 throw(RuntimeException) {
99   if(i >= a_maxItem)
100     indexException(i, ANNA_FILE_LOCATION);
101
102   return data(begin() + i);
103 }
104
105 const char* Tokenizer::last() const
106 throw(RuntimeException) {
107   if(a_maxItem == 0)
108     throw RuntimeException("There is any token to select", ANNA_FILE_LOCATION);
109
110   return data(begin() + a_maxItem - 1);
111 }
112
113 char* Tokenizer::strip(char* str)
114 throw() {
115   char* result(str);
116
117   if(str != NULL) {
118     while(*result != 0 && *result == ' ')
119       result ++;
120
121     if(*result != 0) {
122       char* final = result + anna_strlen(result) - 1;
123
124       while(final > result && *final == ' ') {
125         *final = 0;
126         final --;
127       }
128     }
129   }
130
131   return result;
132 }
133
134 void Tokenizer::indexException(const int index, const char* fromFile, const int fromLine) const
135 throw(RuntimeException) {
136   string msg(functions::asString("Index %d out of range [0,%d] | Items: ", index, a_maxItem));
137
138   for(const_iterator ii = begin(), maxii = end(); ii != maxii; ii ++) {
139     msg += data(ii);
140     msg += ' ';
141   }
142
143   throw RuntimeException(msg, fromFile, fromLine);
144 }