#include #include #if defined __linux__ #include #endif #include "Journal.h" Journal::Journal(const char *file) { m_File.assign(file); } bool Journal::Erase() { return (unlink(m_File.c_str()) == 0); } int Journal::Replay(VaultMap *pMap) { m_fp = fopen(m_File.c_str(), "rb"); if (!m_fp) { return -1; } BinaryReader br(m_fp); uint8_t len8; uint16_t len16; char *key = NULL; char *val = NULL; String sKey; String sVal; time_t stamp; JOp op; int ops = 0; try { do { op = static_cast(br.ReadUInt8()); if (op == Journal_Clear) { pMap->Clear(); } else if (op == Journal_Prune) { time_t start; time_t end; start = static_cast(br.ReadUInt32()); end = static_cast(br.ReadUInt32()); pMap->Prune(start, end); } else if (op == Journal_Insert) { stamp = static_cast(br.ReadUInt32()); len8 = br.ReadUInt8(); key = new char[len8+1]; br.ReadChars(key, len8); len16 = br.ReadUInt16(); val = new char[len16+1]; br.ReadChars(val, len16); key[len8] = '\0'; val[len16] = '\0'; sKey.assign(key); sVal.assign(val); pMap->Insert(sKey, sVal, stamp); //clean up delete [] key; key = NULL; delete [] val; val = NULL; } else if (op == Journal_Remove) { len8 = br.ReadUInt8(); key = new char[len8+1]; br.ReadChars(key, len8); key[len8] = '\0'; sKey.assign(key); pMap->Remove(sKey); } ops++; } while (op < Journal_TotalOps && op); } catch (...) { //journal is done if (key) { delete [] key; key = NULL; } if (val) { delete [] val; val = NULL; } } fclose(m_fp); return ops; } bool Journal::Begin() { m_fp = fopen(m_File.c_str(), "wb"); m_Bw.SetFilePtr(m_fp); return (m_fp != NULL); } bool Journal::End() { fclose(m_fp); m_Bw.SetFilePtr(NULL); return true; } bool Journal::Write_Clear() { try { WriteOp(Journal_Clear); return true; } catch (...) { return false; } } bool Journal::Write_Insert(const char *key, const char *val, time_t stamp) { try { WriteOp(Journal_Insert); WriteInt32(static_cast(stamp)); WriteString(key, Encode_Small); WriteString(val, Encode_Medium); return true; } catch (...) { return false; } } bool Journal::Write_Prune(time_t start, time_t end) { try { WriteOp(Journal_Prune); WriteInt32(static_cast(start)); WriteInt32(static_cast(end)); return true; } catch (...) { return false; } } bool Journal::Write_Remove(const char *key) { try { WriteOp(Journal_Remove); WriteString(key, Encode_Small); return true; } catch (...) { return false; } } void Journal::WriteInt32(int num) { m_Bw.WriteInt32(num); } void Journal::WriteOp(JOp op) { m_Bw.WriteUInt8(static_cast(op)); } void Journal::WriteString(const char *str, Encode enc) { size_t len = strlen(str); if (enc == Encode_Small) { m_Bw.WriteUInt8(static_cast(len)); } else if (enc == Encode_Medium) { m_Bw.WriteUInt16(static_cast(len)); } m_Bw.WriteChars(str, len); }