LCOV - code coverage report
Current view: top level - mvodb - midasodb.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 4.6 % 543 25
Test Date: 2025-11-11 10:26:08 Functions: 7.1 % 70 5

            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              :  */
        

Generated by: LCOV version 2.0-1