Line data Source code
1 : /********************************************************************\
2 :
3 : Name: midasodb.cxx
4 : Created by: K.Olchanski
5 :
6 : Contents: MIDAS implementation of MVOdb ODB interface
7 :
8 : \********************************************************************/
9 :
10 : #include <stdio.h>
11 : #include <string.h> // strlen()
12 : #include <assert.h>
13 : #include <stdlib.h> // malloc()
14 :
15 : #include "mvodb.h"
16 : #include "midas.h"
17 : #include "mstrlcpy.h"
18 :
19 0 : static std::string toString(int value)
20 : {
21 : char buf[256];
22 0 : sprintf(buf, "%d", value);
23 0 : return buf;
24 : }
25 :
26 : class MidasOdb: public MVOdb
27 : {
28 : public:
29 : HNDLE fDB = 0;
30 : std::string fRoot;
31 : bool fPrintError = true;
32 : bool fPrintWarning = false;
33 :
34 : public:
35 1 : MidasOdb(HNDLE hDB, const char* root)
36 1 : {
37 1 : fDB = hDB;
38 1 : fRoot = root;
39 1 : }
40 :
41 0 : ~MidasOdb() // dtor
42 0 : {
43 : // poison the data members
44 0 : fDB = 0;
45 0 : }
46 :
47 2 : std::string Path(const char* varname)
48 : {
49 2 : std::string path;
50 2 : path += fRoot;
51 2 : path += "/";
52 2 : path += varname;
53 2 : return path;
54 0 : }
55 :
56 0 : void SetPrintError(bool v)
57 : {
58 0 : fPrintError = v;
59 0 : }
60 :
61 0 : bool GetPrintError() const
62 : {
63 0 : return fPrintError;
64 : }
65 :
66 0 : bool IsReadOnly() const
67 : {
68 0 : return false;
69 : }
70 :
71 0 : MVOdb* Chdir(const char* subdir, bool create, MVOdbError* error)
72 : {
73 0 : std::string path = Path(subdir);
74 : HNDLE hkey;
75 0 : int status = db_find_key(fDB, 0, path.c_str(), &hkey);
76 0 : if (status == DB_SUCCESS) {
77 : KEY key;
78 0 : status = db_get_key(fDB, hkey, &key);
79 0 : if (status != DB_SUCCESS) {
80 0 : SetMidasStatus(error, fPrintError, path, "db_get_key", status);
81 0 : return MakeNullOdb();
82 : }
83 0 : if (key.type != TID_KEY) {
84 0 : SetError(error, fPrintError, path, "ODB path is not a directory");
85 0 : if (create)
86 0 : return MakeNullOdb();
87 : else
88 0 : return NULL;
89 : }
90 0 : return new MidasOdb(fDB, path.c_str());
91 0 : } else if (!create) {
92 0 : SetMidasStatus(error, fPrintWarning, path, "db_find_key", status);
93 0 : return NULL;
94 : } else {
95 0 : status = db_create_key(fDB, 0, path.c_str(), TID_KEY);
96 0 : if (status != DB_SUCCESS) {
97 0 : SetMidasStatus(error, fPrintError, path, "db_create_key", status);
98 0 : return MakeNullOdb();
99 : }
100 0 : return new MidasOdb(fDB, path.c_str());
101 : }
102 0 : }
103 :
104 0 : void RAInfo(const char* varname, int* num_elements, int* element_size, MVOdbError* error)
105 : {
106 0 : std::string path = Path(varname);
107 :
108 0 : if (num_elements)
109 0 : *num_elements = 0;
110 0 : if (element_size)
111 0 : *element_size = 0;
112 :
113 : int status;
114 : HNDLE hkey;
115 0 : status = db_find_key(fDB, 0, path.c_str(), &hkey);
116 0 : if (status != DB_SUCCESS)
117 0 : return;
118 :
119 : KEY key;
120 0 : status = db_get_key(fDB, hkey, &key);
121 0 : if (status != DB_SUCCESS)
122 0 : return;
123 :
124 0 : if (num_elements)
125 0 : *num_elements = key.num_values;
126 :
127 0 : if (element_size)
128 0 : *element_size = key.item_size;
129 0 : }
130 :
131 0 : void ReadKey(const char* varname, int *tid, int *num_values, int *total_size, int *item_size, MVOdbError* error)
132 : {
133 0 : if (tid) *tid = 0;
134 0 : if (num_values) *num_values = 0;
135 0 : if (total_size) *total_size = 0;
136 0 : if (item_size) *item_size = 0;
137 :
138 0 : std::string path = Path(varname);
139 :
140 : int status;
141 : HNDLE hkey;
142 :
143 0 : status = db_find_key(fDB, 0, path.c_str(), &hkey);
144 0 : if (status != DB_SUCCESS) {
145 0 : SetMidasStatus(error, fPrintWarning, path, "db_find_key", status);
146 0 : return;
147 : }
148 :
149 : KEY key;
150 0 : status = db_get_key(fDB, hkey, &key);
151 0 : if (status != DB_SUCCESS) {
152 0 : SetMidasStatus(error, fPrintError, path, "db_get_key", status);
153 0 : return;
154 : }
155 :
156 0 : if (tid)
157 0 : *tid = key.type;
158 :
159 0 : if (num_values)
160 0 : *num_values = key.num_values;
161 :
162 0 : if (total_size)
163 0 : *total_size = key.total_size;
164 :
165 0 : if (item_size)
166 0 : *item_size = key.item_size;
167 :
168 0 : SetOk(error);
169 0 : }
170 :
171 0 : void ReadKeyLastWritten(const char* varname, int *last_written, MVOdbError* error)
172 : {
173 0 : if (last_written) *last_written = 0;
174 :
175 0 : std::string path = Path(varname);
176 :
177 : int status;
178 : HNDLE hkey;
179 :
180 0 : status = db_find_key(fDB, 0, path.c_str(), &hkey);
181 0 : if (status != DB_SUCCESS) {
182 0 : SetMidasStatus(error, fPrintWarning, path, "db_find_key", status);
183 0 : return;
184 : }
185 :
186 : KEY key;
187 0 : status = db_get_key(fDB, hkey, &key);
188 0 : if (status != DB_SUCCESS) {
189 0 : SetMidasStatus(error, fPrintError, path, "db_get_key", status);
190 0 : return;
191 : }
192 :
193 0 : if (last_written)
194 0 : *last_written = key.last_written;
195 :
196 0 : SetOk(error);
197 0 : }
198 :
199 0 : void ReadDir(std::vector<std::string>* varname, std::vector<int> *tid, std::vector<int> *num_values, std::vector<int> *total_size, std::vector<int> *item_size, MVOdbError* error)
200 : {
201 : // FIXME: incomplete!
202 0 : SetOk(error);
203 0 : }
204 :
205 0 : void ResizeArray(const char* varname, int new_size, MVOdbError* error)
206 : {
207 0 : std::string path = Path(varname);
208 :
209 : int status;
210 : HNDLE hkey;
211 :
212 0 : status = db_find_key(fDB, 0, path.c_str(), &hkey);
213 :
214 0 : if (status != DB_SUCCESS) {
215 0 : SetMidasStatus(error, fPrintWarning, path, "db_find_key", status);
216 0 : return;
217 : }
218 :
219 0 : status = db_set_num_values(fDB, hkey, new_size);
220 0 : if (status != SUCCESS) {
221 0 : SetMidasStatus(error, fPrintError, path, "db_set_num_values", status);
222 0 : return;
223 : }
224 :
225 0 : SetOk(error);
226 0 : }
227 :
228 0 : void ResizeStringArray(const char* varname, int new_size, int new_string_length, MVOdbError* error)
229 : {
230 0 : std::string path = Path(varname);
231 :
232 0 : int status = db_resize_string(fDB, 0, path.c_str(), new_size, new_string_length);
233 0 : if (status != SUCCESS) {
234 0 : SetMidasStatus(error, fPrintError, path, "db_resize_string", status);
235 0 : return;
236 : }
237 :
238 0 : SetOk(error);
239 0 : }
240 :
241 2 : bool R(const char* varname, int tid, void *value, int size, bool create, MVOdbError* error)
242 : {
243 2 : assert(value);
244 2 : std::string path = Path(varname);
245 2 : int status = db_get_value(fDB, 0, path.c_str(), value, &size, tid, create);
246 2 : if (status != DB_SUCCESS) {
247 2 : SetMidasStatus(error, fPrintError, path, "db_get_value", status);
248 2 : return false;
249 : }
250 0 : SetOk(error);
251 0 : return true;
252 2 : }
253 :
254 2 : void RI(const char* varname, int *value, bool create, MVOdbError* error)
255 : {
256 2 : R(varname, TID_INT, value, sizeof(int), create, error);
257 2 : }
258 :
259 0 : void RU16(const char* varname, uint16_t *value, bool create, MVOdbError* error)
260 : {
261 0 : R(varname, TID_WORD, value, sizeof(uint16_t), create, error);
262 0 : }
263 :
264 0 : void RU32(const char* varname, uint32_t *value, bool create, MVOdbError* error)
265 : {
266 0 : R(varname, TID_DWORD, value, sizeof(uint32_t), create, error);
267 0 : }
268 :
269 0 : void RD(const char* varname, double *value, bool create, MVOdbError* error)
270 : {
271 0 : bool ok = R(varname, TID_DOUBLE, value, sizeof(double), create, error);
272 0 : if (!ok) {
273 0 : float fvalue = *value;
274 0 : ok = R(varname, TID_FLOAT, &fvalue, sizeof(float), create, error);
275 0 : if (fPrintError && ok) {
276 0 : std::string path = Path(varname);
277 0 : fprintf(stderr, "MVOdb::RD: Sucessfully read ODB \"%s\" of type FLOAT instead of DOUBLE\n", path.c_str());
278 0 : }
279 0 : *value = fvalue;
280 : }
281 0 : }
282 :
283 0 : void RF(const char* varname, float *value, bool create, MVOdbError* error)
284 : {
285 0 : R(varname, TID_FLOAT, value, sizeof(float), create, error);
286 0 : }
287 :
288 0 : void RB(const char* varname, bool *value, bool create, MVOdbError* error)
289 : {
290 0 : assert(value);
291 0 : BOOL v = *value;
292 0 : R(varname, TID_BOOL, &v, sizeof(BOOL), create, error);
293 0 : *value = v;
294 0 : }
295 :
296 0 : void RS(const char* varname, std::string* value, bool create, int create_string_length, MVOdbError* error)
297 : {
298 0 : assert(value);
299 0 : std::string path = Path(varname);
300 :
301 : #ifdef HAVE_DB_GET_VALUE_STRING_CREATE_STRING_LENGTH
302 0 : int status = db_get_value_string(fDB, 0, path.c_str(), 0, value, create, create_string_length);
303 : #else
304 : #warning This MIDAS has an old version of db_get_value_string() and RS() will ignore the create_string_length argument.
305 : int status = db_get_value_string(fDB, 0, path.c_str(), 0, value, create);
306 : #endif
307 :
308 0 : if (status != DB_SUCCESS) {
309 0 : SetMidasStatus(error, fPrintError, path, "db_get_value_string", status);
310 0 : return;
311 : }
312 :
313 0 : SetOk(error);
314 0 : }
315 :
316 0 : void RAI(const char* varname, int index, int tid, void *value, int size, MVOdbError* error)
317 : {
318 0 : assert(value);
319 0 : std::string path = Path(varname);
320 0 : path += "[";
321 0 : path += toString(index);
322 0 : path += "]";
323 0 : if (index < 0) {
324 0 : SetError(error, fPrintError, path, "RxAI() called with negative array index");
325 0 : return;
326 : }
327 0 : int status = db_get_value(fDB, 0, path.c_str(), value, &size, tid, FALSE);
328 0 : if (status != DB_SUCCESS) {
329 0 : SetMidasStatus(error, fPrintError, path, "db_get_value", status);
330 0 : return;
331 : }
332 0 : SetOk(error);
333 0 : }
334 :
335 0 : void RIAI(const char* varname, int index, int *value, MVOdbError* error)
336 : {
337 0 : RAI(varname, index, TID_INT, value, sizeof(int), error);
338 0 : }
339 :
340 0 : void RU16AI(const char* varname, int index, uint16_t *value, MVOdbError* error)
341 : {
342 0 : RAI(varname, index, TID_WORD, value, sizeof(uint16_t), error);
343 0 : }
344 :
345 0 : void RU32AI(const char* varname, int index, uint32_t *value, MVOdbError* error)
346 : {
347 0 : RAI(varname, index, TID_DWORD, value, sizeof(uint32_t), error);
348 0 : }
349 :
350 0 : void RDAI(const char* varname, int index, double *value, MVOdbError* error)
351 : {
352 0 : RAI(varname, index, TID_DOUBLE, value, sizeof(double), error);
353 0 : }
354 :
355 0 : void RFAI(const char* varname, int index, float *value, MVOdbError* error)
356 : {
357 0 : RAI(varname, index, TID_FLOAT, value, sizeof(float), error);
358 0 : }
359 :
360 0 : void RBAI(const char* varname, int index, bool *value, MVOdbError* error)
361 : {
362 0 : assert(value);
363 0 : BOOL v = *value;
364 0 : RAI(varname, index, TID_BOOL, &v, sizeof(BOOL), error);
365 0 : *value = v;
366 0 : }
367 :
368 0 : void RSAI(const char* varname, int index, std::string* value, MVOdbError* error)
369 : {
370 0 : assert(value);
371 0 : std::string path = Path(varname);
372 :
373 0 : if (index < 0) {
374 0 : SetError(error, fPrintError, path, "RSAI() called with negative array index");
375 0 : return;
376 : }
377 :
378 0 : int status = db_get_value_string(fDB, 0, path.c_str(), index, value, FALSE);
379 :
380 0 : if (status != DB_SUCCESS) {
381 0 : SetMidasStatus(error, fPrintError, path, "db_get_value_string", status);
382 0 : return;
383 : }
384 :
385 0 : SetOk(error);
386 0 : }
387 :
388 0 : bool RA(const std::string& path, int tid, void* buf, int size, MVOdbError* error)
389 : {
390 0 : int status = db_get_value(fDB, 0, path.c_str(), buf, &size, tid, FALSE);
391 :
392 0 : if (status != DB_SUCCESS) {
393 0 : SetMidasStatus(error, fPrintError, path, "db_get_value", status);
394 0 : return false;
395 : }
396 :
397 0 : SetOk(error);
398 0 : return true;
399 : }
400 :
401 0 : void GetArraySize(const char* varname, int* pnum_values, int* pitem_size, MVOdbError* error)
402 : {
403 0 : int xtid = 0;
404 : //int xnum_values = 0;
405 0 : int xtotal_size = 0;
406 : //int xitem_size = 0;
407 :
408 0 : ReadKey(varname, &xtid, pnum_values, &xtotal_size, pitem_size, error);
409 :
410 0 : if (xtid == TID_KEY) {
411 0 : *pnum_values = -1;
412 0 : *pitem_size = -1;
413 : }
414 :
415 0 : if (xtid == 0) {
416 0 : *pnum_values = -1;
417 0 : *pitem_size = -1;
418 : }
419 0 : }
420 :
421 0 : template <class X> bool RXA(const char* varname, int tid, std::vector<X> *value, bool create, int create_size, MVOdbError* error)
422 : {
423 0 : std::string path = Path(varname);
424 :
425 0 : int num_values = 0;
426 0 : int item_size = 0;
427 :
428 0 : GetArraySize(varname, &num_values, &item_size, error);
429 :
430 0 : if (value == NULL) {
431 0 : if (create && create_size > 0) {
432 0 : if (num_values < 0) {
433 : // does not exist, create it
434 0 : X v = 0;
435 0 : W(varname, tid, &v, sizeof(X), error);
436 0 : if (error && error->fError)
437 0 : return false;
438 0 : ResizeArray(varname, create_size, error);
439 0 : } else if (num_values != create_size) {
440 : // wrong size, resize it
441 0 : ResizeArray(varname, create_size, error);
442 0 : return true;
443 : }
444 : }
445 0 : return true;
446 : }
447 :
448 0 : if (num_values > 0) { // array exists
449 0 : value->resize(num_values);
450 0 : return RA(path, tid, &((*value)[0]), num_values*sizeof(X), error);
451 : }
452 :
453 : // array does not exist
454 :
455 0 : if (!create)
456 0 : return false;
457 :
458 0 : WA(varname, tid, &((*value)[0]), value->size()*sizeof(X), value->size(), error);
459 :
460 0 : if (error && error->fError)
461 0 : return true;
462 :
463 0 : if (create_size > 0) {
464 0 : if (create_size != (int)value->size()) {
465 0 : ResizeArray(varname, create_size, error);
466 : }
467 : }
468 :
469 0 : return true;
470 0 : }
471 :
472 0 : void RIA(const char* varname, std::vector<int> *value, bool create, int create_size, MVOdbError* error)
473 : {
474 0 : RXA<int>(varname, TID_INT, value, create, create_size, error);
475 0 : }
476 :
477 0 : void RFA(const char* varname, std::vector<float> *value, bool create, int create_size, MVOdbError* error)
478 : {
479 0 : RXA<float>(varname, TID_FLOAT, value, create, create_size, error);
480 0 : }
481 :
482 0 : void RDA(const char* varname, std::vector<double> *value, bool create, int create_size, MVOdbError* error)
483 : {
484 0 : bool ok = RXA<double>(varname, TID_DOUBLE, value, create, create_size, error);
485 0 : if (!ok) {
486 0 : std::vector<float> fvalue;
487 0 : std::vector<float> *fvalue_ptr = NULL;
488 0 : if (value) {
489 0 : fvalue_ptr = &fvalue;
490 0 : for (size_t i=0; i<value->size(); i++) {
491 0 : fvalue.push_back((*value)[i]);
492 : }
493 : }
494 0 : ok = RXA<float>(varname, TID_FLOAT, fvalue_ptr, create, create_size, error);
495 0 : if (ok && fvalue_ptr) {
496 0 : if (fPrintError) {
497 0 : std::string path = Path(varname);
498 0 : fprintf(stderr, "MVOdb::RDA: Sucessfully read ODB \"%s\" of type FLOAT instead of DOUBLE\n", path.c_str());
499 0 : }
500 0 : value->clear();
501 0 : for (size_t i=0; i<fvalue.size(); i++) {
502 0 : value->push_back(fvalue[i]);
503 : }
504 : }
505 0 : }
506 0 : }
507 :
508 0 : void RU16A(const char* varname, std::vector<uint16_t> *value, bool create, int create_size, MVOdbError* error)
509 : {
510 0 : RXA<uint16_t>(varname, TID_WORD, value, create, create_size, error);
511 0 : }
512 :
513 0 : void RU32A(const char* varname, std::vector<uint32_t> *value, bool create, int create_size, MVOdbError* error)
514 : {
515 0 : RXA<uint32_t>(varname, TID_DWORD, value, create, create_size, error);
516 0 : }
517 :
518 0 : void RBA(const char* varname, std::vector<bool> *value, bool create, int create_size, MVOdbError* error)
519 : {
520 0 : std::vector<BOOL> xvalue;
521 0 : std::vector<BOOL> *xvalue_ptr = NULL;
522 :
523 0 : if (value) {
524 0 : for (std::size_t i=0; i<value->size(); i++) {
525 0 : if ((*value)[i])
526 0 : xvalue.push_back(TRUE);
527 : else
528 0 : xvalue.push_back(FALSE);
529 : }
530 0 : xvalue_ptr = &xvalue;
531 : }
532 :
533 0 : RXA<BOOL>(varname, TID_BOOL, xvalue_ptr, create, create_size, error);
534 :
535 0 : if (value) {
536 0 : value->clear();
537 0 : for (std::size_t i=0; i<xvalue.size(); i++) {
538 0 : if (xvalue[i])
539 0 : value->push_back(true);
540 : else
541 0 : value->push_back(false);
542 : }
543 : }
544 0 : }
545 :
546 0 : void RSA(const char* varname, std::vector<std::string> *value, bool create, int create_size, int create_string_length, MVOdbError* error)
547 : {
548 0 : std::string path = Path(varname);
549 :
550 0 : int num_values = 0;
551 0 : int item_size = 0;
552 :
553 0 : GetArraySize(varname, &num_values, &item_size, error);
554 :
555 0 : if (value == NULL) {
556 0 : if (create && (create_size > 0) && (create_string_length > 0)) {
557 0 : if (num_values < 0) {
558 : // does not exist, create it
559 0 : WS(varname, "", create_string_length, error);
560 0 : if (error && error->fError)
561 0 : return;
562 0 : ResizeStringArray(varname, create_size, create_string_length, error);
563 0 : } else if ((num_values != create_size) || (item_size != create_string_length)) {
564 : // wrong size, resize it
565 0 : ResizeStringArray(varname, create_size, create_string_length, error);
566 0 : return;
567 : }
568 : }
569 0 : return;
570 : }
571 :
572 : // array exists, read it
573 :
574 0 : if (num_values > 0) {
575 0 : value->clear();
576 0 : int bufsize = num_values*item_size;
577 0 : char* buf = (char*)malloc(bufsize);
578 0 : assert(buf != NULL);
579 0 : memset(buf, 0, bufsize);
580 0 : RA(path, TID_STRING, buf, bufsize, error);
581 0 : for (int i=0; i<num_values; i++) {
582 0 : value->push_back(buf+i*item_size);
583 : }
584 0 : free(buf);
585 0 : buf = NULL;
586 0 : return;
587 : }
588 :
589 : // array does not exist
590 :
591 0 : if (!create)
592 0 : return;
593 :
594 : //if (!(create_string_length > 0)) {
595 : // SetError(error, fPrintError, path, "RSA() with create==true must have create_string_length>0");
596 : // return;
597 : //}
598 :
599 0 : int string_length = 0;
600 0 : for (size_t i = 0; i < value->size(); i++) {
601 0 : if (((int)(*value)[i].length()) > string_length)
602 0 : string_length = (*value)[i].length();
603 : }
604 0 : string_length += 1; // add space for string terminator NUL character '\0'
605 :
606 0 : if (create_string_length > string_length)
607 0 : string_length = create_string_length;
608 :
609 0 : char* buf = NULL;
610 :
611 0 : int bufsize = value->size()*string_length;
612 :
613 0 : if (bufsize > 0) {
614 0 : buf = (char*)malloc(bufsize);
615 0 : assert(buf != NULL);
616 0 : memset(buf, 0, bufsize);
617 :
618 0 : for (size_t i=0; i<value->size(); i++) {
619 0 : mstrlcpy(buf+i*string_length, (*value)[i].c_str(), string_length);
620 : }
621 : }
622 :
623 0 : WA(varname, TID_STRING, buf, bufsize, value->size(), error);
624 :
625 0 : if (buf) {
626 0 : free(buf);
627 0 : buf = NULL;
628 : }
629 :
630 0 : if (error && error->fError)
631 0 : return;
632 :
633 0 : if ((create_size > 0) && (create_string_length > 0)) {
634 0 : if ((((int)value->size()) != create_size) || (string_length != create_string_length)) {
635 : // wrong size, resize it
636 0 : ResizeStringArray(varname, create_size, create_string_length, error);
637 : }
638 : }
639 0 : }
640 :
641 0 : void W(const char* varname, int tid, const void* v, int size, MVOdbError* error)
642 : {
643 0 : std::string path = Path(varname);
644 :
645 0 : int status = db_set_value(fDB, 0, path.c_str(), v, size, 1, tid);
646 :
647 0 : if (status == DB_TYPE_MISMATCH) {
648 0 : if (fPrintError) {
649 0 : fprintf(stderr, "MVOdb::W: Data type mismatch when writing to ODB \"%s\", deleting the old entry\n", path.c_str());
650 : }
651 :
652 0 : Delete(varname, error);
653 :
654 0 : status = db_set_value(fDB, 0, path.c_str(), v, size, 1, tid);
655 : }
656 :
657 0 : if (status != DB_SUCCESS) {
658 0 : SetMidasStatus(error, fPrintError, path, "db_set_value", status);
659 0 : return;
660 : }
661 :
662 0 : SetOk(error);
663 0 : return;
664 0 : }
665 :
666 0 : void WB(const char* varname, bool v, MVOdbError* error)
667 : {
668 0 : BOOL vv = v;
669 0 : W(varname, TID_BOOL, &vv, sizeof(BOOL), error);
670 0 : }
671 :
672 0 : void WI(const char* varname, int v, MVOdbError* error)
673 : {
674 0 : W(varname, TID_INT, &v, sizeof(int), error);
675 0 : }
676 :
677 0 : void WU16(const char* varname, uint16_t v, MVOdbError* error)
678 : {
679 0 : W(varname, TID_WORD, &v, sizeof(uint16_t), error);
680 0 : }
681 :
682 0 : void WU32(const char* varname, uint32_t v, MVOdbError* error)
683 : {
684 0 : W(varname, TID_DWORD, &v, sizeof(uint32_t), error);
685 0 : }
686 :
687 0 : void WD(const char* varname, double v, MVOdbError* error)
688 : {
689 0 : W(varname, TID_DOUBLE, &v, sizeof(double), error);
690 0 : }
691 :
692 0 : void WF(const char* varname, float v, MVOdbError* error)
693 : {
694 0 : W(varname, TID_FLOAT, &v, sizeof(float), error);
695 0 : }
696 :
697 0 : void WS(const char* varname, const char* v, int string_length, MVOdbError* error)
698 : {
699 0 : if (string_length > 0) {
700 0 : char* buf = (char*)malloc(string_length);
701 0 : assert(buf);
702 0 : mstrlcpy(buf, v, string_length);
703 0 : W(varname, TID_STRING, buf, string_length, error);
704 0 : free(buf);
705 : } else {
706 0 : int len = strlen(v);
707 0 : W(varname, TID_STRING, v, len+1, error);
708 : }
709 0 : }
710 :
711 0 : void WAI(const char* varname, int index, int tid, const void* v, int size, MVOdbError* error)
712 : {
713 0 : std::string path = Path(varname);
714 :
715 0 : if (index < 0) {
716 0 : SetError(error, fPrintError, path, "WxAI() called with negative array index");
717 0 : return;
718 : }
719 :
720 : //printf("WAI(\"%s\", [%d], %d) path [%s], size %d\n", varname, index, tid, path.c_str(), size);
721 :
722 : int status;
723 : HNDLE hkey;
724 :
725 0 : status = db_find_key(fDB, 0, path.c_str(), &hkey);
726 :
727 0 : if (status != DB_SUCCESS) {
728 0 : SetMidasStatus(error, fPrintError, path, "db_find_key", status);
729 0 : return;
730 : }
731 :
732 0 : status = db_set_data_index(fDB, hkey, v, size, index, tid);
733 :
734 0 : if (status != DB_SUCCESS) {
735 0 : SetMidasStatus(error, fPrintError, path, "db_set_value", status);
736 0 : return;
737 : }
738 :
739 0 : SetOk(error);
740 0 : }
741 :
742 0 : void WBAI(const char* varname, int index, bool v, MVOdbError* error)
743 : {
744 0 : BOOL vv = v;
745 0 : WAI(varname, index, TID_BOOL, &vv, sizeof(BOOL), error);
746 0 : }
747 :
748 0 : void WIAI(const char* varname, int index, int v, MVOdbError* error)
749 : {
750 0 : WAI(varname, index, TID_INT, &v, sizeof(int), error);
751 0 : }
752 :
753 0 : void WU16AI(const char* varname, int index, uint16_t v, MVOdbError* error)
754 : {
755 0 : WAI(varname, index, TID_WORD, &v, sizeof(uint16_t), error);
756 0 : }
757 :
758 0 : void WU32AI(const char* varname, int index, uint32_t v, MVOdbError* error)
759 : {
760 0 : WAI(varname, index, TID_DWORD, &v, sizeof(uint32_t), error);
761 0 : }
762 :
763 0 : void WDAI(const char* varname, int index, double v, MVOdbError* error)
764 : {
765 0 : WAI(varname, index, TID_DOUBLE, &v, sizeof(double), error);
766 0 : }
767 :
768 0 : void WFAI(const char* varname, int index, float v, MVOdbError* error)
769 : {
770 0 : WAI(varname, index, TID_FLOAT, &v, sizeof(float), error);
771 0 : }
772 :
773 0 : void WSAI(const char* varname, int index, const char* v, MVOdbError* error)
774 : {
775 0 : int num_elements = 0;
776 0 : int element_size = 0;
777 0 : RAInfo(varname, &num_elements, &element_size, error);
778 0 : if (error && error->fError)
779 0 : return;
780 0 : if (element_size <= 0)
781 0 : return;
782 0 : char* buf = (char*)malloc(element_size);
783 0 : assert(buf);
784 0 : mstrlcpy(buf, v, element_size);
785 0 : WAI(varname, index, TID_STRING, buf, element_size, error);
786 0 : free(buf);
787 : }
788 :
789 0 : void WA(const char* varname, int tid, const void* v, int size, int count, MVOdbError* error)
790 : {
791 0 : std::string path = Path(varname);
792 :
793 : //printf("WA(tid %d, size %d, count %d)\n", tid, size, count);
794 :
795 0 : if (size == 0) {
796 0 : int status = db_create_key(fDB, 0, path.c_str(), tid);
797 :
798 0 : if (status == DB_TYPE_MISMATCH) {
799 0 : if (fPrintError) {
800 0 : fprintf(stderr, "MVOdb::WA: Data type mismatch when writing to ODB \"%s\", deleting the old entry\n", path.c_str());
801 : }
802 :
803 0 : Delete(varname, error);
804 :
805 0 : status = db_create_key(fDB, 0, path.c_str(), tid);
806 : }
807 :
808 0 : if (status != DB_SUCCESS) {
809 0 : SetMidasStatus(error, fPrintError, path, "db_create_key", status);
810 0 : return;
811 : }
812 : } else {
813 0 : int status = db_set_value(fDB, 0, path.c_str(), v, size, count, tid);
814 :
815 : //printf("WA db_set_value(tid %d, size %d, count %d) status %d\n", tid, size, count, status);
816 :
817 0 : if (status == DB_TYPE_MISMATCH) {
818 0 : if (fPrintError) {
819 0 : fprintf(stderr, "MVOdb::WA: Data type mismatch when writing to ODB \"%s\", deleting the old entry\n", path.c_str());
820 : }
821 :
822 0 : Delete(varname, error);
823 :
824 0 : status = db_set_value(fDB, 0, path.c_str(), v, size, count, tid);
825 : }
826 :
827 0 : if (status != DB_SUCCESS) {
828 0 : SetMidasStatus(error, fPrintError, path, "db_set_value", status);
829 0 : return;
830 : }
831 : }
832 :
833 0 : SetOk(error);
834 0 : }
835 :
836 0 : void WBA(const char* varname, const std::vector<bool>& v, MVOdbError* error)
837 : {
838 0 : unsigned num = v.size();
839 0 : BOOL val[num];
840 :
841 0 : for (unsigned i=0; i<num; i++) {
842 0 : val[i] = v[i];
843 : }
844 :
845 0 : WA(varname, TID_BOOL, val, num*sizeof(BOOL), num, error);
846 0 : }
847 :
848 0 : void WU16A(const char* varname, const std::vector<uint16_t>& v, MVOdbError* error)
849 : {
850 0 : WA(varname, TID_WORD, &v[0], v.size()*sizeof(uint16_t), v.size(), error);
851 0 : }
852 :
853 0 : void WU32A(const char* varname, const std::vector<uint32_t>& v, MVOdbError* error)
854 : {
855 0 : WA(varname, TID_DWORD, &v[0], v.size()*sizeof(uint32_t), v.size(), error);
856 0 : }
857 :
858 0 : void WIA(const char* varname, const std::vector<int>& v, MVOdbError* error)
859 : {
860 0 : WA(varname, TID_INT, &v[0], v.size()*sizeof(int), v.size(), error);
861 0 : }
862 :
863 0 : void WFA(const char* varname, const std::vector<float>& v, MVOdbError* error)
864 : {
865 0 : WA(varname, TID_FLOAT, &v[0], v.size()*sizeof(float), v.size(), error);
866 0 : }
867 :
868 0 : void WDA(const char* varname, const std::vector<double>& v, MVOdbError* error)
869 : {
870 0 : WA(varname, TID_DOUBLE, &v[0], v.size()*sizeof(double), v.size(), error);
871 0 : }
872 :
873 0 : void WSA(const char* varname, const std::vector<std::string>& v, int odb_string_size, MVOdbError* error)
874 : {
875 0 : unsigned num = v.size();
876 0 : unsigned length = odb_string_size;
877 :
878 0 : if (length == 0) {
879 0 : for (unsigned i=0; i<v.size(); i++) {
880 0 : if (v[i].length() > length)
881 0 : length = v[i].length();
882 : }
883 0 : length += 1; // for the string terminator NUL character
884 : }
885 :
886 0 : char val[length*num];
887 0 : memset(val, 0, length*num);
888 :
889 0 : for (unsigned i=0; i<num; i++)
890 0 : mstrlcpy(val+length*i, v[i].c_str(), length);
891 :
892 0 : WA(varname, TID_STRING, val, num*length, num, error);
893 0 : }
894 :
895 0 : void Delete(const char* odbname, MVOdbError* error)
896 : {
897 0 : std::string path = Path(odbname);
898 :
899 : //printf("Delete(%s)\n", path.c_str());
900 :
901 : HNDLE hKey;
902 0 : int status = db_find_key(fDB, 0, path.c_str(), &hKey);
903 :
904 0 : if (status == DB_NO_KEY) {
905 0 : SetOk(error);
906 0 : return;
907 : }
908 :
909 0 : if (status != DB_SUCCESS) {
910 0 : SetMidasStatus(error, fPrintError, path, "db_find_key", status);
911 0 : return;
912 : }
913 :
914 0 : status = db_delete_key(fDB, hKey, FALSE);
915 :
916 0 : if (status != DB_SUCCESS) {
917 0 : SetMidasStatus(error, fPrintError, path, "db_delete_key", status);
918 0 : return;
919 : }
920 :
921 0 : SetOk(error);
922 0 : };
923 : };
924 :
925 1 : MVOdb* MakeMidasOdb(int hDB, MVOdbError* error)
926 : {
927 1 : SetOk(error);
928 1 : return new MidasOdb(hDB, "");
929 : }
930 :
931 : /* emacs
932 : * Local Variables:
933 : * tab-width: 8
934 : * c-basic-offset: 3
935 : * indent-tabs-mode: nil
936 : * End:
937 : */
|