libs/EDoc/BinaryPersistence.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003    Copyright (C) 2007 by Brendon Costa
00004 
00005    This library is free software; you can redistribute it and/or modify 
00006    it under the terms of the "LGPL Like" License defined in the file COPYING 
00007    that should have been distributed along with this source.
00008 
00009    This library is distributed in the hope that it will be useful, 
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013    You should have received a copy of the "LGPL Like" License 
00014    along with this library; see the file COPYING. if not, it can be 
00015    obtained from the EDoc++ website: 
00016    http://edoc.sourceforge.net/license.html
00017 
00018 *******************************************************************************/
00019 #include "config.h"
00020 
00021 #include "EDoc/BinaryPersistence.h"
00022 #include "EDoc/persistence_data.h"
00023 #include "EDoc/exceptions.h"
00024 #include "EDoc/utils.h"
00025 
00026 #include <iostream>
00027 
00028 #ifdef HAVE_STRING_H
00029    #include <string.h>
00030 #endif
00031 
00032 #ifdef HAVE_ERRNO_H
00033    #include <errno.h>
00034 #endif
00035 
00036 //#define EDOC_LOG_LEVEL EDOC_LOG_LEVEL_FINE
00037 //#include "EDoc/Logger.h"
00038 
00039 namespace EDoc
00040 {
00041    //===========================================================================
00042    BinaryPersistence::BinaryPersistence(bool reading_in, 
00043          std::string filename_in) :
00044 
00045       reading(reading_in),
00046       filename(filename_in)
00047    {
00048    }
00049    //===========================================================================
00050    BinaryPersistence::~BinaryPersistence()
00051    {
00052       Close();
00053    }
00054    //===========================================================================
00055    void BinaryPersistence::Open()
00056    {
00057       if (reading)
00058       {
00059          EDOC_Debug("Opening file: " << filename << " for reading.");
00060          file.open(filename.c_str(), std::ios::in | std::ios::binary);
00061 
00062          char temp[10];
00063          // Read the 1st 9 characters
00064          file.read(temp, 9);
00065          if (!file)
00066          {
00067             EDOC_THROW_EXCEPTION(FileIOException, 
00068                "Failed reading file header.", 
00069                "filename: " << filename 
00070                << ", reason: " << strerror(errno));
00071          }
00072 
00073          temp[9] = 0;
00074          EDOC_Debug("File header contains: " << temp);
00075          if (strcmp(temp, "EDoc: BIN"))
00076          {
00077             EDOC_THROW_EXCEPTION(FileIOException, 
00078                "File header was not valid.",
00079                "read: " << temp << ", expected: " << "EDoc: TXT");
00080          }
00081       }
00082       else
00083       {
00084          file.open(filename.c_str(), std::ios::out | std::ios::binary);
00085          file << "EDoc: BIN" << std::flush;
00086       }
00087    }
00088    //===========================================================================
00089    void BinaryPersistence::Close()
00090    {
00091       file.close();
00092    }
00093    //===========================================================================
00094    void BinaryPersistence::ReadData(char* buffer, size_t amount, 
00095       const char* key)
00096    {
00097       EDOC_Finest("Reading " << amount << " bytes of data for key: " << key);
00098       file.read(buffer, amount);
00099       if (file.eof())
00100       {
00101          EDOC_THROW_EXCEPTION(EOFException, 
00102             "End Of File encountered.",
00103             "key: " << key);
00104       }
00105       else if (!file)
00106       {
00107          EDOC_THROW_EXCEPTION(FileIOException, 
00108             "Failed reading key: " << key, 
00109             "filename: " << filename 
00110             << ", reason: " << strerror(errno));
00111       }
00112    }
00113    //===========================================================================
00114    std::string BinaryPersistence::ReadString(const char* key)
00115    {
00116       EDOC_Finer("Read string: " << key);
00117       if (!reading)
00118       {
00119          EDOC_THROW_EXCEPTION(BugException, 
00120             "Reading from a write only persistence layer.",
00121             "key: " << key);
00122       }
00123 
00124       uint32_t size = ReadUInt32("size");
00125       char* buffer = new char[size];
00126       try
00127       {
00128          ReadData(buffer, size, key);
00129       }
00130       catch(...)
00131       {
00132          delete [] buffer;
00133          throw;
00134       }
00135       std::string ret(buffer, size);
00136       delete [] buffer;
00137       EDOC_Fine("Read string: " << key << ", value: " << ret);
00138       return ret;
00139    }
00140    //===========================================================================
00141    bool BinaryPersistence::ReadBoolean(const char* key)
00142    {
00143       EDOC_Finer("Read boolean: " << key);
00144       if (!reading)
00145       {
00146          EDOC_THROW_EXCEPTION(BugException, 
00147             "Reading from a write only persistence layer.",
00148             "key: " << key);
00149       }
00150       
00151       uint8_t data = 0;
00152       file.read((char*)&data, 1);
00153       if (!file)
00154       {
00155          EDOC_THROW_EXCEPTION(FileIOException, 
00156             "Failed reading key: " << key, 
00157             "filename: " << filename 
00158             << ", reason: " << strerror(errno));
00159       }
00160       
00161       if (data == 0x00)
00162       {
00163          EDOC_Fine("Read boolean: " << key << ", value: " << "FALSE");
00164          return false;
00165       }
00166       else if (data == 0xFF)
00167       {
00168          EDOC_Fine("Read boolean: " << key << ", value: " << "TRUE");
00169          return true;
00170       }
00171       else
00172       {
00173          EDOC_THROW_EXCEPTION(FileIOException, 
00174             "Invalid data for a boolean type.", 
00175             "filename: " << filename 
00176             << ", data: " << (unsigned int)data);
00177       }
00178    }
00179    //===========================================================================
00180    uint8_t BinaryPersistence::ReadUInt8(const char* key)
00181    {
00182       EDOC_Finer("Read uint8: " << key);
00183       if (!reading)
00184       {
00185          EDOC_THROW_EXCEPTION(BugException, 
00186             "Reading from a write only persistence layer.",
00187             "key: " << key);
00188       }
00189 
00190       uint8_t data = 0;
00191       ReadData((char*)&data, 1, key);
00192       EDOC_Fine("Read uint8: " << key << ", value: " << (unsigned int)data);
00193       return data;
00194    }
00195    //===========================================================================
00196    int32_t BinaryPersistence::ReadInt32(const char* key)
00197    {
00198       EDOC_Finer("Read int32: " << key);
00199       return ReadUInt32(key);
00200    }
00201    //===========================================================================
00202    uint32_t BinaryPersistence::ReadUInt32(const char* key)
00203    {
00204       EDOC_Finer("Read uint32: " << key);
00205       if (!reading)
00206       {
00207          EDOC_THROW_EXCEPTION(BugException, 
00208             "Reading from a write only persistence layer.",
00209             "key: " << key);
00210       }
00211 
00212       uint32_t data = 0;
00213       uint8_t temp[4];
00214       ReadData((char*)&temp, 4, key);
00215       data = (temp[3]) |
00216              (temp[2] << 8) |
00217              (temp[1] << 16) |
00218              (temp[0] << 24);
00219       EDOC_Fine("Read uint32: " << key << ", value: " << data);
00220       return data;
00221    }
00222    //===========================================================================
00223    uint8_t BinaryPersistence::ReadRecordType()
00224    {
00225       EDOC_Finer("Read record type: " << KEY_RECORD_TYPE);
00226       return ReadUInt8(KEY_RECORD_TYPE);
00227    }
00228    //===========================================================================
00229    void BinaryPersistence::WriteString(const char* key, std::string value)
00230    {
00231       EDOC_Fine("Write string: " << key << ", value: " << value);
00232       if (reading)
00233       {
00234          EDOC_THROW_EXCEPTION(BugException, 
00235             "Writing to a read only persistence layer.",
00236             "key: " << key << ", value: " << value);
00237       }
00238 
00239       uint32_t size = value.size();
00240       WriteUInt32("size", size);
00241       file.write(value.c_str(), size);
00242       if (!file)
00243       {
00244          EDOC_THROW_EXCEPTION(FileIOException, 
00245             "Failed writing key: " << key, 
00246             "filename: " << filename 
00247             << ", reason: " << strerror(errno));
00248       }
00249    }
00250    //===========================================================================
00251    void BinaryPersistence::WriteBoolean(const char* key, bool value)
00252    {
00253       EDOC_Fine("Write boolean: " << key << ", value: " << value);
00254       if (reading)
00255       {
00256          EDOC_THROW_EXCEPTION(BugException, 
00257             "Writing to a read only persistence layer.",
00258             "key: " << key << ", value: " << value);
00259       }
00260 
00261       uint8_t data = 0;
00262       if (value)
00263       {
00264          data = 0xFF;
00265       }
00266       
00267       file.write((char*)&data, 1);
00268       if (!file)
00269       {
00270          EDOC_THROW_EXCEPTION(FileIOException, 
00271             "Failed writing key: " << key, 
00272             "filename: " << filename 
00273             << ", reason: " << strerror(errno));
00274       }
00275    }
00276    //===========================================================================
00277    void BinaryPersistence::WriteUInt8(const char* key, uint8_t value)
00278    {
00279       EDOC_Fine("Write uint8: " << key << ", value: " << value);
00280       if (reading)
00281       {
00282          EDOC_THROW_EXCEPTION(BugException, 
00283             "Writing to a read only persistence layer.",
00284             "key: " << key << ", value: " << value);
00285       }
00286 
00287       file.write((char*)&value, 1);
00288       if (!file)
00289       {
00290          EDOC_THROW_EXCEPTION(FileIOException, 
00291             "Failed writing key: " << key, 
00292             "filename: " << filename 
00293             << ", reason: " << strerror(errno));
00294       }
00295    }
00296    //===========================================================================
00297    void BinaryPersistence::WriteInt32(const char* key, int32_t value)
00298    {
00299       EDOC_Fine("Write int32: " << key << ", value: " << value);
00300       WriteUInt32(key, value);
00301    }
00302    //===========================================================================
00303    void BinaryPersistence::WriteUInt32(const char* key, uint32_t value)
00304    {
00305       EDOC_Fine("Write uint32: " << key << ", value: " << value);
00306       if (reading)
00307       {
00308          EDOC_THROW_EXCEPTION(BugException, 
00309             "Writing to a read only persistence layer.",
00310             "key: " << key << ", value: " << value);
00311       }
00312 
00313 
00314       uint8_t temp[4];
00315       temp[3] = value & 0x000000FF;
00316       temp[2] = (value & 0x0000FF00) >> 8;
00317       temp[1] = (value & 0x00FF0000) >> 16;
00318       temp[0] = (value & 0xFF000000) >> 24;
00319       
00320       file.write((char*)temp, 4);
00321       if (!file)
00322       {
00323          EDOC_THROW_EXCEPTION(FileIOException, 
00324             "Failed writing key: " << key, 
00325             "filename: " << filename 
00326             << ", reason: " << strerror(errno));
00327       }
00328    }
00329    //===========================================================================
00330    void BinaryPersistence::WriteUInt32Debug(const char* key, uint32_t value, 
00331       std::string EDOC_UNUSED(debug_text))
00332    {
00333       WriteUInt32(key, value);
00334    }
00335    //===========================================================================
00336    void BinaryPersistence::WriteInt32Debug(const char* key, int32_t value, 
00337       std::string EDOC_UNUSED(debug_text))
00338    {
00339       WriteInt32(key, value);
00340    }
00341    //===========================================================================
00342    void BinaryPersistence::WriteRecordType(uint8_t value)
00343    {
00344       EDOC_Fine("Write record type: " << KEY_RECORD_TYPE << ", value: " 
00345          << (unsigned int) value);
00346       if (reading)
00347       {
00348          EDOC_THROW_EXCEPTION(BugException, 
00349             "Writing to a read only persistence layer.",
00350             "key: " << KEY_RECORD_TYPE << ", value: " << value);
00351       }
00352 
00353       WriteUInt8(KEY_RECORD_TYPE, value);
00354    }
00355    //===========================================================================
00356 }
00357 

Generated on Tue Jan 20 18:26:07 2009 for EDoc-0.2.1 by  doxygen 1.5.1