ROOT logo
//*-- AUTHOR : Ilse Koenig
//*-- Modified : 15/09/2000

//_HADES_CLASS_DESCRIPTION 
/////////////////////////////////////////////////////////////////////////////
// HDbFileIo
//
// Oracle I/O class to load data from a client-side file into an Oracle table
// or to write data from an Oracle table to a client-side file
// (uses the Oracle C/C++ precompiler)
//
// Description  of the program:
//      http://www-hades.gsi.de/persons/ilse/orafileio.htm
// 
/////////////////////////////////////////////////////////////////////////////

#include "hdbfileio.h"
#include "hdbfileutil.h"
#include "hdbtable.h"
#include "hdbcolumn.h"
#include "TStopwatch.h"
#include <unistd.h>
#include <time.h>
 
ClassImp(HDbFileIo)

HDbFileIo::HDbFileIo() {
  // Constructor creates the Oracle connection class, but does not open a connection
  dbConn=new HDbConn;
  dbUtil=0;
  fin=0;
  fout=0;
  colDelim=" ";
  textDelim="'";
  nullValue="null";
  maxBufLen=4000;
  maxStmLen=8000;
  autoCommit=kFALSE;
  autoNull=kTRUE;
  tempTables=new TList;
  refTable=0;
  curTable=0;
  needsCommit=kFALSE;
}


HDbFileIo::~HDbFileIo() {
  // Destructor closes the Oracle connection and a file not yet closed
  if (dbConn) {
    closeDbConn();
    delete dbConn;
  }
  if (tempTables) delete tempTables;
  if (dbUtil) delete dbUtil;
  closeFile();
  if (fin) delete fin;
  if (fout) delete fout;
}

Bool_t HDbFileIo::connectDb(TString userName, TString dbName) {
  // Opens an Oracle connection (e.g.with:  "hades","db-hades")
  if (dbConn->isOpen()) dbConn->closeDbConn();
  Bool_t rc=dbConn->connectDb(userName,dbName);
  if (rc) {
    dbUtil=new HDbFileUtil(dbConn);
    setDateMask();
  }
  return rc;
}   
 
void HDbFileIo::closeDbConn() {
  // Closes the Oracle connection
  // Asks for committing all not yet saved transactions
  if (needsCommit) confirmCommit();
  dbConn->closeDbConn(); // makes rollback automatically
  if (curTable) {
    delete curTable;
    curTable=0;
    defTableName="";
  }
  if (refTable) {
    delete refTable;
    refTable=0;
  }
  if (tempTables) tempTables->Delete();
  if (dbUtil) {
    delete dbUtil;
    dbUtil=0;
  }
}

Bool_t HDbFileIo::openFile(const Char_t* fName,const Char_t* ioMode) {
  // Closes an open file and opens the new file 
  // Possible I/O modes are "in", "out", "app"
  closeFile();
  defTableName="";
  TString m(ioMode);
  m.ToLower();
  if (m.CompareTo("in")==0) return openInput(fName);
  if (m.CompareTo("out")==0 || m.CompareTo("app")==0)
    return openOutput(fName,m.Data());
  Error("HDbFileIo::openFile",
        "Wrong I/O mode! Possible modes are \"in\", \"out\", \"app\""); 
  return kFALSE;
}

void HDbFileIo::closeFile() {
  // Closes the file
  if (fin && fin->rdbuf()->is_open()!=0) fin->close();
  if (fout && fout->rdbuf()->is_open()!=0) fout->close();
}

Bool_t HDbFileIo::fileIsOpen() {
  // Returns kTRUE in case the file is open
  if ((fin && fin->rdbuf()->is_open()!=0) ||
      (fout && fout->rdbuf()->is_open()!=0)) return kTRUE;
  return kFALSE;
}

Bool_t HDbFileIo::fileIsWritable() {
  // Returns kTRUE in case the file is writable
  if (fout && fout->rdbuf()->is_open()!=0) return kTRUE;
  return kFALSE;
}

HDbTable* HDbFileIo::setTableName(const Char_t* tableName) {
  // Sets the name of the Oracle table.
  // Checks if a table with this name exists already.
  // Returns a pointer to a table.
  // For an existing table this form contains all columns of this table. If the
  // table does not exist the list of columns is empty. This table can be used
  // to define the columns for an insert/update.
  // (You can call the HDbTable::clear() function to remove all columns from the
  // list. Then all or only some columns can be added again in the order needed
  // for the file I/O.) 
  clear();
  if (dbConn->isOpen()) {
    TString t(tableName);
    t=t.Strip(t.kBoth);
    t.ToUpper();
    Int_t n=t.First(".");
    if (n<0) {
      t.Insert(0,".");
      t.Insert(0,dbConn->getUserName());
    }
    refTable=getTempTable(t);
    if (!refTable) {
      refTable=new HDbTable(dbConn,dbUtil,t);
      refTable->describeTable();
    }
    curTable=new HDbTable(dbConn,dbUtil,*refTable);
  }
  else Error("HDbFileIo::setTableName","No connection to Oracle");
  return curTable;
}

void HDbFileIo::setColumnDelimiter(const Char_t* s) {
  // Sets the delimiter beween columns (default value: " ")
  colDelim=s;
  if (colDelim.Length()>1) {
    colDelim.Strip(colDelim.kBoth);
    if (colDelim.Length()==0) colDelim=" ";
  } else {
    if (colDelim.Length()==0) {
      Error("HDbFileIo::setColumnDelimiter",
            "\n  Delimter for columns is empty, replaced by default delimiter whitespace");
      colDelim=" ";
    }
  }
}

Bool_t HDbFileIo::setDateMask(const Char_t* mask) {
  // Sets a date mask in Oracle
  if (dbConn->isOpen()) {
    actDateMask=mask;
    TString stm("begin hades_oper.hdate.set_datemask(");
    if (mask && strlen(mask)>2) stm=stm + "'" + mask + "'); end;";
    else stm=stm + "); end;";
    return dbUtil->executeDirect(stm);
  }
  actDateMask="";
  Error("HDbFileIo::setDateMask","No connection to Oracle");
  return kFALSE;
}

Bool_t HDbFileIo::setSearchDate(const Char_t* time) {
  // Sets the search date in Oracle used to select data from views which
  // require a date specified before retrieving results.
  // The default value is the actual time on the server.
  if (dbConn->isOpen()) {
    TString stm("begin hades_oper.run_query.set_date(");
    stm=stm + "'" + time + "'); end;";
    return dbUtil->executeDirect(stm);
  } else Error("HDbFileIo::setSearchDate","No connection to Oracle");
  return kFALSE;
}

Bool_t HDbFileIo::setRun(const Char_t* daqFile) {
  // Sets the run in Oracle used to select data from views which require
  // a run specified before retrieving results.
  if (dbConn->isOpen()) {
    TString stm("begin hades_oper.run_query.set_run(");
    stm=stm + "'" + daqFile + "'); end;";
    return dbUtil->executeDirect(stm);
  } else Error("HDbFileIo::setRun","No connection to Oracle");
  return kFALSE;
}


HDbTable* HDbFileIo::getTempTable(const Char_t* tableName) {
  // Returns a pointer to a temporary table created inside the current
  // Oracle session
  TString t(tableName);
  t=t.Strip(t.kBoth);
  t.ToUpper();
  HDbTable* table=(HDbTable*)tempTables->FindObject(tableName);
  return table;
}

void HDbFileIo::showTemporaryTables() {
  // Shows all temporary tables created inside the current Oracle session
  if (tempTables->Last()==0) {
    cout<<"The list of temporary tables is empty!"<<endl;
    return;
  }
  TIter next(tempTables);
  HDbTable* t;
  while ((t=(HDbTable*)next())) {
    t->show();
  }
}   

void HDbFileIo::dropTemporaryTable(const Char_t* tableName) {
  // Drops a temporary table created inside the current Oracle session.
  // Each Drop must be confirmed.
  if (needsCommit) confirmCommit();
  Bool_t rc=kFALSE;
  HDbTable* t=getTempTable(tableName);
  if (t) {
    rc=t->dropTable();
    if (rc) removeTempTable(t);
  } else cout<<"Table does not exist or is not a temporary table"<<endl;
}

void HDbFileIo::dropTemporaryTables() {
  // Drops all temporary tables created inside the current Oracle session.
  // Each Drop must be confirmed.
  if (needsCommit) confirmCommit();
  if (tempTables->Last()==0) {
    cout<<"List of temporary tables is empty!"<<endl;
    return;
  }
  TIter next(tempTables);
  HDbTable* t;
  Bool_t rc=kTRUE;
  while ((t=(HDbTable*)next())) {
    rc=t->dropTable();
    if (rc) removeTempTable(t);
  }
}   

void HDbFileIo::commit(void) {
  // Commits Oracle transactions
  if (dbUtil) dbUtil->commit();
  needsCommit=kFALSE;
}

void HDbFileIo::rollback(void) {
  // Rolls back Oracle transactions
  if (dbUtil) dbUtil->rollback();
  needsCommit=kFALSE;
}

void HDbFileIo::showExistingTable() {
  // Shows the table definition of the existing table
  if (refTable) {
    if (refTable->isExisting()) refTable->show();
    else cout<<"Table "<<refTable->GetName()<<
               "is not a permanent table and might not exist."<<endl;
  }
  else cout<<"No table defined"<<endl;
}

void HDbFileIo::clear() {
  // Deletes the actual table objects curTable and refTable
  if (curTable) delete curTable;
  curTable=0;
  if (refTable) delete refTable;
  refTable=0;  
}

void HDbFileIo::showSettings() {
  // Shows the actual parameter settings for the I/O
  TString cD(colDelim);  
  if (cD.Contains(" ")) cD.ReplaceAll(" ","whitespace");
  if (cD.Contains("\t")) cD.ReplaceAll("\t","tab");
  cout<<"------------------------------------------------------"<<endl;
  cout<<"------------------  I/O Parameters  ------------------"<<endl;
  cout<<"------------------------------------------------------"<<endl;
  cout<<"Default table name:           "<<defTableName<<endl;
  cout<<"Delimiter for columns:        "<<cD<<endl;
  cout<<"Text enclosed in:             "<<textDelim<<endl;
  cout<<"Null (no value) in i/o:       "<<nullValue<<endl;
  cout<<"Actual date mask:             "<<actDateMask<<endl;
  cout<<"Automatic add of nulls:       ";
  if (autoNull) cout<<"yes"<<endl; 
  else cout<<"no"<<endl; 
  cout<<"Automatic commit for inserts: ";
  if (autoCommit) cout<<"yes"<<endl; 
  else cout<<"no"<<endl; 
  cout<<"Maximum i/o buffer size:      "<<maxBufLen<<endl;
  cout<<"------------------------------------------------------"<<endl;
}

Bool_t HDbFileIo::readFile(Int_t nLineStart, Int_t nLineEnd) {
  // Reads a file starting at line nLineStart( default 1) and stopping after
  // line nLineEnd (default 999999) or EOF and inserts the data into an Oracle
  // table. Inserts into an existing table must be confirmed.
  // When the name of the table was not set before, a default table name is
  // generated from the filename. The creation of a temporary table must be
  // confirmed.
  // The file is not closed automatically.
  if (!dbConn->isOpen()) {
    Error("HDbFileIo::readFile","No connection to Oracle");
    return kFALSE;
  }
  if (!fin || fin->rdbuf()->is_open()==0) {
    Error("HDbFileIo::readFile","No file open");
    return kFALSE;
  }
  fin->seekg(0,ios::beg);
  fin->clear();
  TString stm;
  TString insert("insert into ");
  Bool_t all=kFALSE;
  Bool_t tabChecked=kFALSE;
  Int_t nInserts=0;
  Int_t i, nData, nColumns=0, l1=0, l2=0;
  TString line(maxBufLen);
  //  TStopwatch timer;
  //  timer.Reset();
  //  timer.Start();
  do {
    l1=l2;
    i=0;
    stm="begin ";
    while (stm.Length()<maxStmLen && !all) {
      line.ReadLine(*fin);
      l2++;
      if (fin->eof() || l2>nLineEnd) {
        all=kTRUE;
        break;
      }
      if (l2<nLineStart) continue;
      line=line.Strip(line.kBoth);
      if (line[0]!='\0' && line[0]!='/') {
        if (!tabChecked) {
          nData=checkTable(line); 
          if (nData==0) return kFALSE;
          tabChecked=kTRUE;
          insert=insert + curTable->GetName() + "(";
          nColumns=curTable->getNColumns();
          for(Int_t j=0;j<nColumns;j++) {
            insert=insert + curTable->getColumn(j)->GetName();
            if (j<(nColumns-1)) insert=insert + ",";
          }
          insert=insert + ")";
          if (!curTable->isTempTable()) {
            cout<<"-----------------------------------------"<<endl;
            cout<<"-------  Insert in existing table  ------"<<endl;
            cout<<"-----------------------------------------"<<endl;
            cout<<insert<<endl;
            if (!dbUtil->confirm("insert")) return kFALSE;
          }
          insert=insert +" values (";
        }
        else nData=getValues(line,nColumns);
        if (nData==nColumns) stm = stm + insert + line + ");";
        else {
          if (autoNull) {
            stm = stm + insert + line + ",";
            for(Int_t k=++nData;k<nColumns;k++) stm = stm + "null" + ",";
            stm = stm + "null" + ");";
          } else {
            Error("HDbFileIo::readFile",
                  "Number of values too small in line %i",l2);
            return kFALSE;
          }
        }
        i++;
      }
    }
    stm=stm + "end;";
    // cout<<endl<<"SQL: "<<stm<<endl;
    if (i>0) {
      if (dbUtil->executeDirect(stm)==kFALSE) {
        Error("HDbFileInput::readData","Error in lines %i - %i",(l1+1),l2);
        rollback();
        return kFALSE;
      }
      nInserts+=i;
    }
  } while (all==kFALSE);
  cout<<"-----------------------------------------"<<endl;
  cout<<"  "<<nInserts<<" rows inserted in table "<<curTable->GetName()<<endl;
  cout<<"-----------------------------------------"<<endl;
  //  timer.Stop();
  //  cout<<endl<<"Real time:   "<<timer.RealTime()<<endl;
  //  cout<<"Cpu time:    "<<timer.CpuTime()<<endl;
  //  cout<<"Inserts/sec: "<<(nInserts/timer.CpuTime())<<endl;
  checkCommit();
  return kTRUE;
} 

Bool_t HDbFileIo::makeInsert(const Char_t* colNames, const Char_t* colValues) {
  // Inserts one row in the actual table
  // colNames:  comma separated list of columns;
  //            use "*" for an insert with values for all columns
  // colValues: comma separated list of values for the columns 
  TString cols(colNames);
  cols=cols.Strip(cols.kBoth);
  cols.ToUpper();
  TString  stm("insert into ");
  stm=stm + curTable->GetName();
  if (cols[0]=='*') stm=stm + " values (" + colValues + ")";
  else stm=stm + "(" + cols + ") values (" + colValues + ")";
  if (!curTable->isTempTable()) {
    cout<<"-----------------------------------------"<<endl;
    cout<<"-------  Insert in existing table  ------"<<endl;
    cout<<"-----------------------------------------"<<endl;
    cout<<stm<<endl;
    if (!dbUtil->confirm("insert")) return kFALSE;
  }
  if (dbUtil->executeDirect(stm)==kFALSE) {
    rollback();
    return kFALSE;
  }
  checkCommit();
  return kTRUE;
}

Bool_t HDbFileIo::makeUpdate(const Char_t* setVal, const Char_t* condition) {
  // Updates one or more rows in a temporary table
  // setVal   : SET part of an update statement (col1=val1, col2=val2, ...) 
  // condition: Condition for the columns to be updated
  //            WARNING: An empty condition will update all columns!
  if (!curTable->isTempTable()) {
    cout<<"The update of an existing table is forbidden in this program"<<endl;
    return kFALSE;
  }
  TString con(condition);
  con=con.Strip(con.kBoth);
  if (con.Length()==0) cout<<"*****  WARNING: No condition set  *****"<<endl;
  TString  stm("update ");
  stm=stm + curTable->GetName() + " set " + setVal ;
  if (con.Length()>0) stm=stm + " where " + con;
  if (dbUtil->executeDirect(stm)==kFALSE) {
    rollback();
    return kFALSE;
  }
  checkCommit();
  return kTRUE;
}

Bool_t HDbFileIo::writeFile() {
  // Writes the data from an Oracle table into a file
  Bool_t rc=kFALSE;
  if (fout && fout->rdbuf()->is_open()!=0) {
    rc=write(*fout);
    closeFile();
  } else Error("HDbFileIo::writeFile()","No output file open");
  return rc;
}

Bool_t HDbFileIo::printResult() {
  // Prints the data from an Oracle table on the screen
  return write(cout);
}

////////////////////////////  private functions  //////////////////////

Bool_t HDbFileIo::openInput(const Char_t* fileName) {
  // Opens a file for input and generates the default table name
  if (needsCommit) confirmCommit();
  clear();
  defTableName="";
  if (!fin) fin=new ifstream;
  fin->clear();
  fin->open(fileName,ios::in);
  if (fin && fin->rdbuf()->is_open()!=0) {
    defTableName=fileName;
    defTableName.Remove(0,(defTableName.Last('/')+1));
    Int_t n=defTableName.First('.');
    if (n>0) defTableName.Remove(n,defTableName.Length()-n);
    defTableName.ToUpper();
    defTableName.Insert(0,"TMP_");
    return kTRUE;
  }
  Error("HDbFileIo::openInput","File not found");
  return kFALSE;
}

Bool_t HDbFileIo::openOutput(const Char_t* fileName, const Char_t* oMode) {
  // Opens a file for output
  if (!fout) fout=new ofstream;
  if (strcmp(oMode,"out")==0) {
    if (access(fileName,F_OK)!=0) fout->open(fileName,ios::out);
    else {
      cout<<"File "<<fileName<<" exists already"<<endl;
      if (dbUtil->confirm("Recreate file")==kFALSE) return kFALSE;
      fout->open(fileName,ios::out);
    }
  } else fout->open(fileName,ios::app);
  if (fout && fout->rdbuf()->is_open()!=0) return kTRUE;
  Error("HDbFileIo::openOutput","File not found or not writable");
  return kFALSE;
}

Int_t HDbFileIo::checkTable(TString& line) {
  // Sets the default table name and table definition if necessary. Checks if
  // the table exists and creates it otherwise. A newly created table is added
  // in the list of temporary tables.
  Int_t nData=0;
  Int_t nColumns=0;
  Char_t buf[4];
  if (!curTable) {
    curTable=setTableName(defTableName.Data());
    nColumns=curTable->getNColumns();
    if (nColumns==0) {
      nData=getValues(line,254);        
      TString s1="Col";
      for(Int_t i=1;i<=nData;i++) {
        sprintf(buf,"%i",i);
        TString s=s1 + buf;
        curTable->addColumn(s.Data());
      }
      if (!curTable->createTable()) return 0;
      addTempTable(curTable);
    } else nData=getValues(line,nColumns);        
  } else {
    nColumns=curTable->getNColumns();
    nData=getValues(line,nColumns);
    if (!curTable->isExisting()) {
      if (!curTable->createTable()) return 0;
      addTempTable(curTable); 
    }    
  }  
  return nData;
}
  
void HDbFileIo::addTempTable(HDbTable* table) {
  // Adds a temporary table to the list of temporary tables
  if (!tempTables) tempTables=new TList;
  HDbTable* t=new HDbTable(dbConn,dbUtil,*table);
  tempTables->Add(t);
}

void HDbFileIo::removeTempTable(HDbTable* table) {
  // Removes a table from the list of temporary tables and deletes it.
  // Deletes also the actual tables when they have identical names.
  tempTables->Remove(table);
  if (curTable && strcmp(curTable->GetName(),table->GetName())==0) {
    delete curTable;
    curTable=0;
    delete refTable;
    refTable=0;
  }
  delete table;
  table=0;
}

Int_t HDbFileIo::getValues(TString& str, Int_t nColumns) {
  // Gets the column values from a line read from file
  TString s1(str.Strip(str.kBoth));
  Int_t slen=s1.Length();
  if (slen==0) return 0;
  TString s2, s3;
  Int_t n=0;
  str="";
  while (slen>0 && n<nColumns) {
    if (s1[0]==textDelim[0]) {
      s1=s1.Remove(0,1);
      slen=dbUtil->getTokString(s1,s2,textDelim);
      str=str + "'" + s2 + "'";
      if (slen>0 && colDelim[0]!=' ') {
        s1.Remove(0,colDelim.Length()); // remove delimiter
        s1=s1.Strip(s1.kLeading,' ');
        slen=s1.Length();
      }
    } else {
      slen=dbUtil->getTokString(s1,s2,colDelim);
      if (s2.Length()==0 || s2.CompareTo(nullValue)==0) str=str + "null";
      else str=str + "'" + s2 + "'";
    }
    n++;
    if (slen>0 && n<nColumns) str=str + ",";
  }
  return n;
}

Bool_t HDbFileIo::write(ostream& pout) {
  // Writes the table content to a file or to stdout
  if (!curTable) {
    Error("HDbFileIo::write","No table defined!");
    return kFALSE;
  }
  if (!curTable->isExisting()) {
    Error("HDbFileIo::write","Table does not exist!");
    return kFALSE;
  }
  Int_t n=curTable->getNColumns();
  Int_t r=refTable->getNColumns();
  if (r>0) {
    if (n>0) {
      for(Int_t i=0;i<n;i++) {
        HDbColumn* col=curTable->getColumn(i);
        HDbColumn* refCol=refTable->getColumn(col->GetName());
        if (refCol) col->copyColumn(refCol);
        else {
          Error("HDbFileIo::write","Column %s does not exist!",col->GetName());
          return kFALSE;
        }
      }
    } else {
      for(Int_t i=0;i<r;i++) {
        HDbColumn* refCol=refTable->getColumn(i);
        HDbColumn* col=curTable->addColumn(refCol->GetName());
        col->copyColumn(refCol);
      }
    }
  }
  pout<<"// -----------------------------------------"<<endl;
  pout<<"// Result of Oracle table "<<curTable->GetName()<<endl;
  pout<<"// Date: "<<getActDate()<<"// Columns:"<<endl<<"//    ";
  for(Int_t i=0;i<n-1;i++) pout<<curTable->getColumn(i)->GetName()<<"  ";
  pout<<curTable->getColumn(n-1)->GetName()<<endl;
  pout<<"// -----------------------------------------"<<endl;
  Int_t l=curTable->writeTable(pout,colDelim.Data(),textDelim.Data(),
                               nullValue.Data());
  if (l<0) return kFALSE;
  cout<<"-----------------------------------------"<<endl;
  cout<<"  "<<l<<" rows selected from table "<<curTable->GetName()<<endl;
  cout<<"-----------------------------------------"<<endl;
  return kTRUE; 
}

TString HDbFileIo::getActDate() {
  // Returns the actual date and time
  struct tm *newtime;
  time_t t;
  time(&t);
  newtime=localtime(&t);
  TString s(asctime(newtime));
  return s;
}

void HDbFileIo::checkCommit() {
  // Calls commit() when flag autoCommit is kTRUE
  if (autoCommit) commit();
  else {
    needsCommit=kTRUE;
    cout<<"***************************************"<<endl;
    cout<<"*****  Transaction needs commit.  *****"<<endl;
    cout<<"***************************************"<<endl;
  }
}

void HDbFileIo::confirmCommit() {
  // Ask to confirm uncommitted transactions
  cout<<"************************************************"<<endl;
  cout<<"*****  There are uncommitted transactions  *****"<<endl;
  if (dbUtil && dbUtil->confirm("commit")) commit();
  else rollback();
}
 hdbfileio.cc:1
 hdbfileio.cc:2
 hdbfileio.cc:3
 hdbfileio.cc:4
 hdbfileio.cc:5
 hdbfileio.cc:6
 hdbfileio.cc:7
 hdbfileio.cc:8
 hdbfileio.cc:9
 hdbfileio.cc:10
 hdbfileio.cc:11
 hdbfileio.cc:12
 hdbfileio.cc:13
 hdbfileio.cc:14
 hdbfileio.cc:15
 hdbfileio.cc:16
 hdbfileio.cc:17
 hdbfileio.cc:18
 hdbfileio.cc:19
 hdbfileio.cc:20
 hdbfileio.cc:21
 hdbfileio.cc:22
 hdbfileio.cc:23
 hdbfileio.cc:24
 hdbfileio.cc:25
 hdbfileio.cc:26
 hdbfileio.cc:27
 hdbfileio.cc:28
 hdbfileio.cc:29
 hdbfileio.cc:30
 hdbfileio.cc:31
 hdbfileio.cc:32
 hdbfileio.cc:33
 hdbfileio.cc:34
 hdbfileio.cc:35
 hdbfileio.cc:36
 hdbfileio.cc:37
 hdbfileio.cc:38
 hdbfileio.cc:39
 hdbfileio.cc:40
 hdbfileio.cc:41
 hdbfileio.cc:42
 hdbfileio.cc:43
 hdbfileio.cc:44
 hdbfileio.cc:45
 hdbfileio.cc:46
 hdbfileio.cc:47
 hdbfileio.cc:48
 hdbfileio.cc:49
 hdbfileio.cc:50
 hdbfileio.cc:51
 hdbfileio.cc:52
 hdbfileio.cc:53
 hdbfileio.cc:54
 hdbfileio.cc:55
 hdbfileio.cc:56
 hdbfileio.cc:57
 hdbfileio.cc:58
 hdbfileio.cc:59
 hdbfileio.cc:60
 hdbfileio.cc:61
 hdbfileio.cc:62
 hdbfileio.cc:63
 hdbfileio.cc:64
 hdbfileio.cc:65
 hdbfileio.cc:66
 hdbfileio.cc:67
 hdbfileio.cc:68
 hdbfileio.cc:69
 hdbfileio.cc:70
 hdbfileio.cc:71
 hdbfileio.cc:72
 hdbfileio.cc:73
 hdbfileio.cc:74
 hdbfileio.cc:75
 hdbfileio.cc:76
 hdbfileio.cc:77
 hdbfileio.cc:78
 hdbfileio.cc:79
 hdbfileio.cc:80
 hdbfileio.cc:81
 hdbfileio.cc:82
 hdbfileio.cc:83
 hdbfileio.cc:84
 hdbfileio.cc:85
 hdbfileio.cc:86
 hdbfileio.cc:87
 hdbfileio.cc:88
 hdbfileio.cc:89
 hdbfileio.cc:90
 hdbfileio.cc:91
 hdbfileio.cc:92
 hdbfileio.cc:93
 hdbfileio.cc:94
 hdbfileio.cc:95
 hdbfileio.cc:96
 hdbfileio.cc:97
 hdbfileio.cc:98
 hdbfileio.cc:99
 hdbfileio.cc:100
 hdbfileio.cc:101
 hdbfileio.cc:102
 hdbfileio.cc:103
 hdbfileio.cc:104
 hdbfileio.cc:105
 hdbfileio.cc:106
 hdbfileio.cc:107
 hdbfileio.cc:108
 hdbfileio.cc:109
 hdbfileio.cc:110
 hdbfileio.cc:111
 hdbfileio.cc:112
 hdbfileio.cc:113
 hdbfileio.cc:114
 hdbfileio.cc:115
 hdbfileio.cc:116
 hdbfileio.cc:117
 hdbfileio.cc:118
 hdbfileio.cc:119
 hdbfileio.cc:120
 hdbfileio.cc:121
 hdbfileio.cc:122
 hdbfileio.cc:123
 hdbfileio.cc:124
 hdbfileio.cc:125
 hdbfileio.cc:126
 hdbfileio.cc:127
 hdbfileio.cc:128
 hdbfileio.cc:129
 hdbfileio.cc:130
 hdbfileio.cc:131
 hdbfileio.cc:132
 hdbfileio.cc:133
 hdbfileio.cc:134
 hdbfileio.cc:135
 hdbfileio.cc:136
 hdbfileio.cc:137
 hdbfileio.cc:138
 hdbfileio.cc:139
 hdbfileio.cc:140
 hdbfileio.cc:141
 hdbfileio.cc:142
 hdbfileio.cc:143
 hdbfileio.cc:144
 hdbfileio.cc:145
 hdbfileio.cc:146
 hdbfileio.cc:147
 hdbfileio.cc:148
 hdbfileio.cc:149
 hdbfileio.cc:150
 hdbfileio.cc:151
 hdbfileio.cc:152
 hdbfileio.cc:153
 hdbfileio.cc:154
 hdbfileio.cc:155
 hdbfileio.cc:156
 hdbfileio.cc:157
 hdbfileio.cc:158
 hdbfileio.cc:159
 hdbfileio.cc:160
 hdbfileio.cc:161
 hdbfileio.cc:162
 hdbfileio.cc:163
 hdbfileio.cc:164
 hdbfileio.cc:165
 hdbfileio.cc:166
 hdbfileio.cc:167
 hdbfileio.cc:168
 hdbfileio.cc:169
 hdbfileio.cc:170
 hdbfileio.cc:171
 hdbfileio.cc:172
 hdbfileio.cc:173
 hdbfileio.cc:174
 hdbfileio.cc:175
 hdbfileio.cc:176
 hdbfileio.cc:177
 hdbfileio.cc:178
 hdbfileio.cc:179
 hdbfileio.cc:180
 hdbfileio.cc:181
 hdbfileio.cc:182
 hdbfileio.cc:183
 hdbfileio.cc:184
 hdbfileio.cc:185
 hdbfileio.cc:186
 hdbfileio.cc:187
 hdbfileio.cc:188
 hdbfileio.cc:189
 hdbfileio.cc:190
 hdbfileio.cc:191
 hdbfileio.cc:192
 hdbfileio.cc:193
 hdbfileio.cc:194
 hdbfileio.cc:195
 hdbfileio.cc:196
 hdbfileio.cc:197
 hdbfileio.cc:198
 hdbfileio.cc:199
 hdbfileio.cc:200
 hdbfileio.cc:201
 hdbfileio.cc:202
 hdbfileio.cc:203
 hdbfileio.cc:204
 hdbfileio.cc:205
 hdbfileio.cc:206
 hdbfileio.cc:207
 hdbfileio.cc:208
 hdbfileio.cc:209
 hdbfileio.cc:210
 hdbfileio.cc:211
 hdbfileio.cc:212
 hdbfileio.cc:213
 hdbfileio.cc:214
 hdbfileio.cc:215
 hdbfileio.cc:216
 hdbfileio.cc:217
 hdbfileio.cc:218
 hdbfileio.cc:219
 hdbfileio.cc:220
 hdbfileio.cc:221
 hdbfileio.cc:222
 hdbfileio.cc:223
 hdbfileio.cc:224
 hdbfileio.cc:225
 hdbfileio.cc:226
 hdbfileio.cc:227
 hdbfileio.cc:228
 hdbfileio.cc:229
 hdbfileio.cc:230
 hdbfileio.cc:231
 hdbfileio.cc:232
 hdbfileio.cc:233
 hdbfileio.cc:234
 hdbfileio.cc:235
 hdbfileio.cc:236
 hdbfileio.cc:237
 hdbfileio.cc:238
 hdbfileio.cc:239
 hdbfileio.cc:240
 hdbfileio.cc:241
 hdbfileio.cc:242
 hdbfileio.cc:243
 hdbfileio.cc:244
 hdbfileio.cc:245
 hdbfileio.cc:246
 hdbfileio.cc:247
 hdbfileio.cc:248
 hdbfileio.cc:249
 hdbfileio.cc:250
 hdbfileio.cc:251
 hdbfileio.cc:252
 hdbfileio.cc:253
 hdbfileio.cc:254
 hdbfileio.cc:255
 hdbfileio.cc:256
 hdbfileio.cc:257
 hdbfileio.cc:258
 hdbfileio.cc:259
 hdbfileio.cc:260
 hdbfileio.cc:261
 hdbfileio.cc:262
 hdbfileio.cc:263
 hdbfileio.cc:264
 hdbfileio.cc:265
 hdbfileio.cc:266
 hdbfileio.cc:267
 hdbfileio.cc:268
 hdbfileio.cc:269
 hdbfileio.cc:270
 hdbfileio.cc:271
 hdbfileio.cc:272
 hdbfileio.cc:273
 hdbfileio.cc:274
 hdbfileio.cc:275
 hdbfileio.cc:276
 hdbfileio.cc:277
 hdbfileio.cc:278
 hdbfileio.cc:279
 hdbfileio.cc:280
 hdbfileio.cc:281
 hdbfileio.cc:282
 hdbfileio.cc:283
 hdbfileio.cc:284
 hdbfileio.cc:285
 hdbfileio.cc:286
 hdbfileio.cc:287
 hdbfileio.cc:288
 hdbfileio.cc:289
 hdbfileio.cc:290
 hdbfileio.cc:291
 hdbfileio.cc:292
 hdbfileio.cc:293
 hdbfileio.cc:294
 hdbfileio.cc:295
 hdbfileio.cc:296
 hdbfileio.cc:297
 hdbfileio.cc:298
 hdbfileio.cc:299
 hdbfileio.cc:300
 hdbfileio.cc:301
 hdbfileio.cc:302
 hdbfileio.cc:303
 hdbfileio.cc:304
 hdbfileio.cc:305
 hdbfileio.cc:306
 hdbfileio.cc:307
 hdbfileio.cc:308
 hdbfileio.cc:309
 hdbfileio.cc:310
 hdbfileio.cc:311
 hdbfileio.cc:312
 hdbfileio.cc:313
 hdbfileio.cc:314
 hdbfileio.cc:315
 hdbfileio.cc:316
 hdbfileio.cc:317
 hdbfileio.cc:318
 hdbfileio.cc:319
 hdbfileio.cc:320
 hdbfileio.cc:321
 hdbfileio.cc:322
 hdbfileio.cc:323
 hdbfileio.cc:324
 hdbfileio.cc:325
 hdbfileio.cc:326
 hdbfileio.cc:327
 hdbfileio.cc:328
 hdbfileio.cc:329
 hdbfileio.cc:330
 hdbfileio.cc:331
 hdbfileio.cc:332
 hdbfileio.cc:333
 hdbfileio.cc:334
 hdbfileio.cc:335
 hdbfileio.cc:336
 hdbfileio.cc:337
 hdbfileio.cc:338
 hdbfileio.cc:339
 hdbfileio.cc:340
 hdbfileio.cc:341
 hdbfileio.cc:342
 hdbfileio.cc:343
 hdbfileio.cc:344
 hdbfileio.cc:345
 hdbfileio.cc:346
 hdbfileio.cc:347
 hdbfileio.cc:348
 hdbfileio.cc:349
 hdbfileio.cc:350
 hdbfileio.cc:351
 hdbfileio.cc:352
 hdbfileio.cc:353
 hdbfileio.cc:354
 hdbfileio.cc:355
 hdbfileio.cc:356
 hdbfileio.cc:357
 hdbfileio.cc:358
 hdbfileio.cc:359
 hdbfileio.cc:360
 hdbfileio.cc:361
 hdbfileio.cc:362
 hdbfileio.cc:363
 hdbfileio.cc:364
 hdbfileio.cc:365
 hdbfileio.cc:366
 hdbfileio.cc:367
 hdbfileio.cc:368
 hdbfileio.cc:369
 hdbfileio.cc:370
 hdbfileio.cc:371
 hdbfileio.cc:372
 hdbfileio.cc:373
 hdbfileio.cc:374
 hdbfileio.cc:375
 hdbfileio.cc:376
 hdbfileio.cc:377
 hdbfileio.cc:378
 hdbfileio.cc:379
 hdbfileio.cc:380
 hdbfileio.cc:381
 hdbfileio.cc:382
 hdbfileio.cc:383
 hdbfileio.cc:384
 hdbfileio.cc:385
 hdbfileio.cc:386
 hdbfileio.cc:387
 hdbfileio.cc:388
 hdbfileio.cc:389
 hdbfileio.cc:390
 hdbfileio.cc:391
 hdbfileio.cc:392
 hdbfileio.cc:393
 hdbfileio.cc:394
 hdbfileio.cc:395
 hdbfileio.cc:396
 hdbfileio.cc:397
 hdbfileio.cc:398
 hdbfileio.cc:399
 hdbfileio.cc:400
 hdbfileio.cc:401
 hdbfileio.cc:402
 hdbfileio.cc:403
 hdbfileio.cc:404
 hdbfileio.cc:405
 hdbfileio.cc:406
 hdbfileio.cc:407
 hdbfileio.cc:408
 hdbfileio.cc:409
 hdbfileio.cc:410
 hdbfileio.cc:411
 hdbfileio.cc:412
 hdbfileio.cc:413
 hdbfileio.cc:414
 hdbfileio.cc:415
 hdbfileio.cc:416
 hdbfileio.cc:417
 hdbfileio.cc:418
 hdbfileio.cc:419
 hdbfileio.cc:420
 hdbfileio.cc:421
 hdbfileio.cc:422
 hdbfileio.cc:423
 hdbfileio.cc:424
 hdbfileio.cc:425
 hdbfileio.cc:426
 hdbfileio.cc:427
 hdbfileio.cc:428
 hdbfileio.cc:429
 hdbfileio.cc:430
 hdbfileio.cc:431
 hdbfileio.cc:432
 hdbfileio.cc:433
 hdbfileio.cc:434
 hdbfileio.cc:435
 hdbfileio.cc:436
 hdbfileio.cc:437
 hdbfileio.cc:438
 hdbfileio.cc:439
 hdbfileio.cc:440
 hdbfileio.cc:441
 hdbfileio.cc:442
 hdbfileio.cc:443
 hdbfileio.cc:444
 hdbfileio.cc:445
 hdbfileio.cc:446
 hdbfileio.cc:447
 hdbfileio.cc:448
 hdbfileio.cc:449
 hdbfileio.cc:450
 hdbfileio.cc:451
 hdbfileio.cc:452
 hdbfileio.cc:453
 hdbfileio.cc:454
 hdbfileio.cc:455
 hdbfileio.cc:456
 hdbfileio.cc:457
 hdbfileio.cc:458
 hdbfileio.cc:459
 hdbfileio.cc:460
 hdbfileio.cc:461
 hdbfileio.cc:462
 hdbfileio.cc:463
 hdbfileio.cc:464
 hdbfileio.cc:465
 hdbfileio.cc:466
 hdbfileio.cc:467
 hdbfileio.cc:468
 hdbfileio.cc:469
 hdbfileio.cc:470
 hdbfileio.cc:471
 hdbfileio.cc:472
 hdbfileio.cc:473
 hdbfileio.cc:474
 hdbfileio.cc:475
 hdbfileio.cc:476
 hdbfileio.cc:477
 hdbfileio.cc:478
 hdbfileio.cc:479
 hdbfileio.cc:480
 hdbfileio.cc:481
 hdbfileio.cc:482
 hdbfileio.cc:483
 hdbfileio.cc:484
 hdbfileio.cc:485
 hdbfileio.cc:486
 hdbfileio.cc:487
 hdbfileio.cc:488
 hdbfileio.cc:489
 hdbfileio.cc:490
 hdbfileio.cc:491
 hdbfileio.cc:492
 hdbfileio.cc:493
 hdbfileio.cc:494
 hdbfileio.cc:495
 hdbfileio.cc:496
 hdbfileio.cc:497
 hdbfileio.cc:498
 hdbfileio.cc:499
 hdbfileio.cc:500
 hdbfileio.cc:501
 hdbfileio.cc:502
 hdbfileio.cc:503
 hdbfileio.cc:504
 hdbfileio.cc:505
 hdbfileio.cc:506
 hdbfileio.cc:507
 hdbfileio.cc:508
 hdbfileio.cc:509
 hdbfileio.cc:510
 hdbfileio.cc:511
 hdbfileio.cc:512
 hdbfileio.cc:513
 hdbfileio.cc:514
 hdbfileio.cc:515
 hdbfileio.cc:516
 hdbfileio.cc:517
 hdbfileio.cc:518
 hdbfileio.cc:519
 hdbfileio.cc:520
 hdbfileio.cc:521
 hdbfileio.cc:522
 hdbfileio.cc:523
 hdbfileio.cc:524
 hdbfileio.cc:525
 hdbfileio.cc:526
 hdbfileio.cc:527
 hdbfileio.cc:528
 hdbfileio.cc:529
 hdbfileio.cc:530
 hdbfileio.cc:531
 hdbfileio.cc:532
 hdbfileio.cc:533
 hdbfileio.cc:534
 hdbfileio.cc:535
 hdbfileio.cc:536
 hdbfileio.cc:537
 hdbfileio.cc:538
 hdbfileio.cc:539
 hdbfileio.cc:540
 hdbfileio.cc:541
 hdbfileio.cc:542
 hdbfileio.cc:543
 hdbfileio.cc:544
 hdbfileio.cc:545
 hdbfileio.cc:546
 hdbfileio.cc:547
 hdbfileio.cc:548
 hdbfileio.cc:549
 hdbfileio.cc:550
 hdbfileio.cc:551
 hdbfileio.cc:552
 hdbfileio.cc:553
 hdbfileio.cc:554
 hdbfileio.cc:555
 hdbfileio.cc:556
 hdbfileio.cc:557
 hdbfileio.cc:558
 hdbfileio.cc:559
 hdbfileio.cc:560
 hdbfileio.cc:561
 hdbfileio.cc:562
 hdbfileio.cc:563
 hdbfileio.cc:564
 hdbfileio.cc:565
 hdbfileio.cc:566
 hdbfileio.cc:567
 hdbfileio.cc:568
 hdbfileio.cc:569
 hdbfileio.cc:570
 hdbfileio.cc:571
 hdbfileio.cc:572
 hdbfileio.cc:573
 hdbfileio.cc:574
 hdbfileio.cc:575
 hdbfileio.cc:576
 hdbfileio.cc:577
 hdbfileio.cc:578
 hdbfileio.cc:579
 hdbfileio.cc:580
 hdbfileio.cc:581
 hdbfileio.cc:582
 hdbfileio.cc:583
 hdbfileio.cc:584
 hdbfileio.cc:585
 hdbfileio.cc:586
 hdbfileio.cc:587
 hdbfileio.cc:588
 hdbfileio.cc:589
 hdbfileio.cc:590
 hdbfileio.cc:591
 hdbfileio.cc:592
 hdbfileio.cc:593
 hdbfileio.cc:594
 hdbfileio.cc:595
 hdbfileio.cc:596
 hdbfileio.cc:597
 hdbfileio.cc:598
 hdbfileio.cc:599
 hdbfileio.cc:600
 hdbfileio.cc:601
 hdbfileio.cc:602
 hdbfileio.cc:603
 hdbfileio.cc:604
 hdbfileio.cc:605
 hdbfileio.cc:606
 hdbfileio.cc:607
 hdbfileio.cc:608
 hdbfileio.cc:609
 hdbfileio.cc:610
 hdbfileio.cc:611
 hdbfileio.cc:612
 hdbfileio.cc:613
 hdbfileio.cc:614
 hdbfileio.cc:615
 hdbfileio.cc:616
 hdbfileio.cc:617
 hdbfileio.cc:618
 hdbfileio.cc:619
 hdbfileio.cc:620
 hdbfileio.cc:621
 hdbfileio.cc:622
 hdbfileio.cc:623
 hdbfileio.cc:624
 hdbfileio.cc:625
 hdbfileio.cc:626
 hdbfileio.cc:627
 hdbfileio.cc:628
 hdbfileio.cc:629
 hdbfileio.cc:630
 hdbfileio.cc:631
 hdbfileio.cc:632
 hdbfileio.cc:633
 hdbfileio.cc:634
 hdbfileio.cc:635
 hdbfileio.cc:636
 hdbfileio.cc:637
 hdbfileio.cc:638
 hdbfileio.cc:639
 hdbfileio.cc:640
 hdbfileio.cc:641
 hdbfileio.cc:642
 hdbfileio.cc:643
 hdbfileio.cc:644
 hdbfileio.cc:645
 hdbfileio.cc:646
 hdbfileio.cc:647
 hdbfileio.cc:648
 hdbfileio.cc:649
 hdbfileio.cc:650
 hdbfileio.cc:651
 hdbfileio.cc:652
 hdbfileio.cc:653
 hdbfileio.cc:654
 hdbfileio.cc:655
 hdbfileio.cc:656
 hdbfileio.cc:657
 hdbfileio.cc:658
 hdbfileio.cc:659
 hdbfileio.cc:660
 hdbfileio.cc:661
 hdbfileio.cc:662
 hdbfileio.cc:663
 hdbfileio.cc:664
 hdbfileio.cc:665
 hdbfileio.cc:666
 hdbfileio.cc:667
 hdbfileio.cc:668
 hdbfileio.cc:669
 hdbfileio.cc:670
 hdbfileio.cc:671
 hdbfileio.cc:672
 hdbfileio.cc:673
 hdbfileio.cc:674