HCE project C++ developers source code library  1.1.1
HCE project developer library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
AStorageHandler.cpp
Go to the documentation of this file.
1 #include <AStorageHandler.h>
2 #include <ErrorNo.h>
3 int StorageHash::dump(const char* filename)
4 {
5  FileWriter fd;
6  if(!fd.open(filename))
7  {
8  return fd.getLastErrNo();
9  }
10  for(unsigned long i = 0; i < count; i++)
11  {
12  Items *buf = items[i];
13  while(buf)
14  {
15  unsigned int len = buf->key.length();
16  if(!fd.write(&len, sizeof(len)))return fd.getLastErrNo();
17  if(!fd.write((void*)buf->key.c_str(), len))return fd.getLastErrNo();
18  if(!fd.write(&(buf->data.count), sizeof(buf->data.count)))return fd.getLastErrNo();
19  for(int j = 0; j < buf->data.count; j++)
20  {
21  if(!fd.write(&(buf->data.type[j]), sizeof(buf->data.type[j])))return fd.getLastErrNo();
22  switch(buf->data.type[j])
23  {
24  case StorageData::EMPTY: break;
26  {
27  if(!fd.write(&(buf->data.data[j].integer), sizeof(buf->data.data[j].integer)))return fd.getLastErrNo();
28  break;
29  }
30  case StorageData::REAL:
31  {
32  if(!fd.write(&(buf->data.data[j].real), sizeof(buf->data.data[j].real)))return fd.getLastErrNo();
33  break;
34  }
36  {
37  char *str = buf->data.data[j].string;
38  len = strlen(str);
39  if(!fd.write(&(len), sizeof(len)))return fd.getLastErrNo();
40  if(!fd.write(str, len))return fd.getLastErrNo();
41  break;
42  }
43  }
44  }
45  buf = buf->next;
46  }
47  }
48  fd.close();
49  return 0;
50 }
51 
52 bool StorageHash::load(const char* filename)
53 {
54  int fd = open(filename, O_RDONLY);
55  if(fd > 0)
56  {
57  unsigned long oldCount = count;
58  destroy();
59  count = oldCount;
60  memset(items, 0, sizeof(Items*) * count);
61  unsigned int bufLen = 256;
62  char *buf = (char*)malloc(bufLen);
63  unsigned int len = 0;
64  while(1)
65  {
66  if(read(fd, &len, sizeof(len)) != sizeof(len))break;
67  if(bufLen < len){bufLen = len; buf = (char*)realloc(buf, bufLen);}
68  if(read(fd, buf, len) != (int)len)break;
69  String key(buf, len);
71  if(read(fd, &data.count, sizeof(data.count)) != sizeof(data.count))break;
72  if(data.count)
73  {
74  data.data = (StorageData::_Data*)malloc(sizeof(StorageData::_Data) * data.count);
75  data.type = (StorageData::DataType*)malloc(sizeof(StorageData::DataType) * data.count);
76  if(data.data && data.type)
77  {
78  for(int j = 0; j < data.count; j++)
79  {
80  if(read(fd, &data.type[j], sizeof(data.type[j])) != sizeof(data.type[j]))break;
81  switch(data.type[j])
82  {
83  case StorageData::EMPTY:break;
85  {
86  read(fd, &(data.data[j].integer), sizeof(data.data[j].integer));
87  break;
88  }
89  case StorageData::REAL:
90  {
91  read(fd, &(data.data[j].real), sizeof(data.data[j].real));
92  break;
93  }
95  {
96  read(fd, &(len), sizeof(len));
97  if(bufLen < len + 1){bufLen = len + 1; buf = (char*)realloc(buf, bufLen);}
98  read(fd, buf, len);
99  buf[len] = '\0';
100  data.data[j].string = strdup(buf);
101  break;
102  }
103  }
104  }
105  insert(key, data);
106  }
107  }
108  }
109  close(fd);
110  free(buf);
111  return true;
112  }
113  return false;
114 }
115 
116 void* AStorageHandler::handle(char code, ...)
117 {
118  va_list list;
119  va_start(list, code);
120  void *ret = handle(code, list);
121  va_end(list);
122  return ret;
123 }
124 
125 void* AStorageHandler::handle(char code, va_list &list)
126 {
127  char *name = va_arg(list, char*);
128  String sname(name);
129  sname.urlDecode();
130  String **params = sname.split(",");
131  String retVal;
132  String comma(","), commaL(";");
133  String null("NULL");
134  for(unsigned int i = 0; params[i]; i++)
135  {
136  StorageData *data = hash.find(*(params[i]));
137  delete params[i];
138  String ret;
139  if(data)
140  {
141  for(int j = 0; j < data->count; j++)
142  {
143  String buf;
144  switch(data->type[j])
145  {
146  case StorageData::EMPTY:break;
148  {
149  buf.fromInt64(data->data[j].integer);
150  break;
151  }
152  case StorageData::REAL:
153  {
154  char buffer[80];
155  sprintf(buffer, "%f", data->data[j].real);
156  buf = String(buffer);
157  buf.urlEncode();
158  break;
159  }
160  default:
161  {
162  buf = String(data->data[j].string);
163  buf.urlEncode();
164  }
165  }
166  if(buf.length() && j < data->count - 1)
167  {
168  buf = buf + commaL;
169  }
170  ret = ret + buf;
171  }
172  }
173  if(ret.length())
174  {
175  retVal = retVal + ret + comma;
176  }
177  else
178  {
179  retVal = retVal + null + comma;
180  }
181  }
182  delete []params;
183  char *ret = new(std::nothrow) char[retVal.length() + 1];
184  if(!ret)
185  {
186  setError(E_MEMORY, "No memory");
187  return NULL;
188  }
189  memcpy(ret, retVal.c_str(), retVal.length());
190  ret[retVal.length()] = '\0';
191  return ret;
192 }
193 
194 void AStorageHandler::setValue(const char *name, long long value, int slot)
195 {
196  if(!name || !*name)return;
197  StorageData data, *old = NULL;
198  mutex.lock();
199  if((old = hash.find(String(name))) == NULL)
200  {
201  data.init(slot + 1);
202  data.type[slot] = StorageData::INTEGER;
203  data.data[slot].integer = value;
204  hash.insert(String(name), data);
205  }
206  else
207  {
208  if(old->count < slot + 1)
209  {
210  old->resize(slot + 1);
211  old->type[slot] = StorageData::INTEGER;
212  }
213  if(old->type[slot] == StorageData::INTEGER)
214  {
215  old->data[slot].integer = value;
216  }
217  }
218  mutex.unlock();
219 }
220 
221 void AStorageHandler::setValue(const char *name, double value, int slot)
222 {
223  if(!name || !*name)return;
224  StorageData data, *old = NULL;
225  mutex.lock();
226  if((old = hash.find(String(name))) == NULL)
227  {
228  data.init(slot + 1);
229  data.type[slot] = StorageData::REAL;
230  data.data[slot].real = isnan(value)!=0 ? 0.0:value;
231  hash.insert(String(name), data);
232  }
233  else
234  {
235  if(old->count < slot + 1)
236  {
237  old->resize(slot + 1);
238  old->type[slot] = StorageData::REAL;
239  }
240  if(old->type[slot] == StorageData::REAL && !isnan(value) && !isinf(value))
241  {
242  old->data[slot].real = value;
243  }
244  }
245  mutex.unlock();
246 }
247 
248 void AStorageHandler::setValue(const char *name, const char *value, int slot)
249 {
250  if(!value || !name || !*name)return;
251  StorageData data, *old = NULL;
252  mutex.lock();
253  if((old = hash.find(String(name))) == NULL)
254  {
255  data.init(slot + 1);
256  data.type[slot] = StorageData::STRING;
257  data.data[slot].string = strdup(value);
258  hash.insert(String(name), data);
259  }
260  else
261  {
262  if(old->count < slot + 1)
263  {
264  old->resize(slot + 1);
265  old->type[slot] = StorageData::STRING;
266  }
267  if(old->type[slot] == StorageData::STRING)
268  {
269  free(old->data[slot].string);
270  old->data[slot].string = strdup(value);
271  }
272  }
273  mutex.unlock();
274 }
275 
276 bool AStorageHandler::addToValue(const char *name, long long delta, int slot)
277 {
278  mutex.lock();
279  StorageData *data = hash.find(String(name));
280  if(data != NULL && slot < data->count)
281  {
282  if(data->type[slot] == StorageData::INTEGER)
283  {
284  data->data[slot].integer += delta;
285  mutex.unlock();
286  return true;
287  }
288  if(data->type[slot] == StorageData::REAL)
289  {
290  data->data[slot].real += delta;
291  mutex.unlock();
292  return true;
293  }
294  }
295  mutex.unlock();
296  return false;
297 }
298 
299 bool AStorageHandler::addToValue(const char *name, double delta, int slot)
300 {
301  mutex.lock();
302  StorageData *data = hash.find(String(name));
303  if(data != NULL && slot < data->count)
304  {
305  if(data->type[slot] == StorageData::REAL && !isnan(delta) && !isinf(delta))
306  {
307  data->data[slot].real += delta;
308  mutex.unlock();
309  return true;
310  }
311  }
312  mutex.unlock();
313  return false;
314 }
315 
316 long long AStorageHandler::getInteger(const char *name, int slot)
317 {
318  mutex.lock();
319  StorageData *data = hash.find(String(name));
320  mutex.unlock();
321  if(data && slot < data->count)
322  {
323  return data->data[slot].integer;
324  }
325  return 0;
326 }
327 
328 double AStorageHandler::getFloat(const char *name, int slot)
329 {
330  mutex.lock();
331  StorageData *data = hash.find(String(name));
332  mutex.unlock();
333  if(data && slot < data->count)
334  {
335  if(isnan(data->data[slot].real) || isinf(data->data[slot].real))
336  {
337  data->data[slot].real = 0.0;
338  }
339  return data->data[slot].real;
340  }
341  return 0.0f;
342 }
343 
344 char* AStorageHandler::getString(const char *name, int slot)
345 {
346  mutex.lock();
347  StorageData *data = hash.find(String(name));
348  mutex.unlock();
349  if(data && slot < data->count)
350  {
351  if(data->type[slot] == StorageData::STRING)
352  return data->data[slot].string;
353  }
354  return NULL;
355 }
356