00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00037
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
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