2005-07-31 06:07:48 +00:00
|
|
|
#include <stdio.h>
|
2006-11-22 05:30:58 +00:00
|
|
|
#include <stdarg.h>
|
2013-02-13 07:14:37 +00:00
|
|
|
#if defined(__linux__) || defined(__APPLE__)
|
2006-06-04 07:49:07 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
2005-07-31 06:07:48 +00:00
|
|
|
#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)
|
2006-08-18 22:46:07 +00:00
|
|
|
{
|
2005-07-31 06:07:48 +00:00
|
|
|
return -1;
|
2006-08-18 22:46:07 +00:00
|
|
|
}
|
2005-07-31 06:07:48 +00:00
|
|
|
|
|
|
|
BinaryReader br(m_fp);
|
|
|
|
|
2006-11-22 05:30:58 +00:00
|
|
|
uint8_t len8;
|
|
|
|
uint16_t len16;
|
2005-07-31 06:07:48 +00:00
|
|
|
char *key = NULL;
|
|
|
|
char *val = NULL;
|
|
|
|
String sKey;
|
|
|
|
String sVal;
|
|
|
|
time_t stamp;
|
|
|
|
JOp op;
|
|
|
|
int ops = 0;
|
2008-03-04 19:06:39 +00:00
|
|
|
uint8_t temp8;
|
|
|
|
|
|
|
|
uint32_t itemp;
|
2005-07-31 06:07:48 +00:00
|
|
|
|
2008-03-04 19:06:39 +00:00
|
|
|
// try
|
|
|
|
// {
|
|
|
|
do
|
2005-07-31 06:07:48 +00:00
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
if (!br.ReadUInt8(temp8)) goto fail;
|
|
|
|
op = static_cast<JOp>(temp8);
|
|
|
|
if (op == Journal_Clear)
|
2005-07-31 06:07:48 +00:00
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
pMap->Clear();
|
|
|
|
} else if (op == Journal_Prune) {
|
|
|
|
time_t start;
|
|
|
|
time_t end;
|
|
|
|
|
|
|
|
if (!br.ReadUInt32(itemp)) goto fail;
|
|
|
|
start = static_cast<time_t>(itemp);
|
|
|
|
|
|
|
|
if (!br.ReadUInt32(itemp)) goto fail;
|
|
|
|
end = static_cast<time_t>(itemp);
|
|
|
|
|
|
|
|
pMap->Prune(start, end);
|
|
|
|
|
|
|
|
} else if (op == Journal_Insert) {
|
|
|
|
|
|
|
|
|
|
|
|
if (!br.ReadUInt32(itemp)) goto fail;
|
|
|
|
stamp = static_cast<time_t>(itemp);
|
|
|
|
|
|
|
|
if (!br.ReadUInt8(len8)) goto fail;
|
|
|
|
|
|
|
|
key = new char[len8+1];
|
|
|
|
if (!br.ReadChars(key, len8)) goto fail;
|
|
|
|
|
|
|
|
if (!br.ReadUInt16(len16)) goto fail;
|
|
|
|
val = new char[len16+1];
|
|
|
|
|
|
|
|
if (!br.ReadChars(val, len16)) goto fail;
|
|
|
|
|
|
|
|
key[len8] = '\0';
|
|
|
|
val[len16] = '\0';
|
|
|
|
sKey.assign(key);
|
|
|
|
sVal.assign(val);
|
|
|
|
pMap->Insert(sKey, sVal, stamp);
|
|
|
|
//clean up
|
2005-07-31 06:07:48 +00:00
|
|
|
delete [] key;
|
|
|
|
key = NULL;
|
|
|
|
delete [] val;
|
|
|
|
val = NULL;
|
2008-03-04 19:06:39 +00:00
|
|
|
} else if (op == Journal_Remove) {
|
|
|
|
|
|
|
|
if (!br.ReadUInt8(len8)) goto fail;
|
|
|
|
|
|
|
|
key = new char[len8+1];
|
|
|
|
if (!br.ReadChars(key, len8)) goto fail;
|
|
|
|
key[len8] = '\0';
|
|
|
|
sKey.assign(key);
|
|
|
|
pMap->Remove(sKey);
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
2008-03-04 19:06:39 +00:00
|
|
|
ops++;
|
|
|
|
} while (op < Journal_TotalOps && op);
|
|
|
|
goto success;
|
|
|
|
// } catch (...) {
|
|
|
|
|
|
|
|
fail:
|
|
|
|
//journal is done
|
|
|
|
if (key)
|
|
|
|
{
|
|
|
|
delete [] key;
|
|
|
|
key = NULL;
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
2008-03-04 19:06:39 +00:00
|
|
|
if (val)
|
|
|
|
{
|
|
|
|
delete [] val;
|
|
|
|
val = NULL;
|
|
|
|
}
|
|
|
|
// }
|
2005-07-31 06:07:48 +00:00
|
|
|
|
2008-03-04 19:06:39 +00:00
|
|
|
success:
|
2005-07-31 06:07:48 +00:00
|
|
|
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()
|
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
// try
|
|
|
|
// {
|
|
|
|
if (!WriteOp(Journal_Clear)) goto fail;
|
2005-07-31 06:07:48 +00:00
|
|
|
return true;
|
2008-03-04 19:06:39 +00:00
|
|
|
// } catch (...) {
|
|
|
|
fail:
|
2005-07-31 06:07:48 +00:00
|
|
|
return false;
|
2008-03-04 19:06:39 +00:00
|
|
|
// }
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Journal::Write_Insert(const char *key, const char *val, time_t stamp)
|
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
// try
|
|
|
|
// {
|
|
|
|
if (!WriteOp(Journal_Insert)) goto fail;
|
|
|
|
if (!WriteInt32(static_cast<int32_t>(stamp))) goto fail;
|
|
|
|
if (!WriteString(key, Encode_Small)) goto fail;
|
|
|
|
if (!WriteString(val, Encode_Medium)) goto fail;
|
2005-07-31 06:07:48 +00:00
|
|
|
return true;
|
2008-03-04 19:06:39 +00:00
|
|
|
// } catch (...) {
|
|
|
|
fail:
|
2005-07-31 06:07:48 +00:00
|
|
|
return false;
|
2008-03-04 19:06:39 +00:00
|
|
|
// }
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Journal::Write_Prune(time_t start, time_t end)
|
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
// try
|
|
|
|
// {
|
|
|
|
if (!WriteOp(Journal_Prune)) goto fail;
|
|
|
|
if (!WriteInt32(static_cast<int32_t>(start))) goto fail;
|
|
|
|
if (!WriteInt32(static_cast<int32_t>(end))) goto fail;
|
2005-07-31 06:07:48 +00:00
|
|
|
return true;
|
2008-03-04 19:06:39 +00:00
|
|
|
// } catch (...) {
|
|
|
|
|
|
|
|
fail:
|
2005-07-31 06:07:48 +00:00
|
|
|
return false;
|
2008-03-04 19:06:39 +00:00
|
|
|
// }
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Journal::Write_Remove(const char *key)
|
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
// try
|
|
|
|
// {
|
|
|
|
if (!WriteOp(Journal_Remove)) goto fail;
|
|
|
|
if (!WriteString(key, Encode_Small)) goto fail;
|
2005-07-31 06:07:48 +00:00
|
|
|
return true;
|
2008-03-04 19:06:39 +00:00
|
|
|
// } catch (...) {
|
|
|
|
|
|
|
|
fail:
|
2005-07-31 06:07:48 +00:00
|
|
|
return false;
|
2008-03-04 19:06:39 +00:00
|
|
|
// }
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
|
|
|
|
2008-03-04 19:06:39 +00:00
|
|
|
bool Journal::WriteInt32(int num)
|
2005-07-31 06:07:48 +00:00
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
return m_Bw.WriteInt32(num);
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
|
|
|
|
2008-03-04 19:06:39 +00:00
|
|
|
bool Journal::WriteOp(JOp op)
|
2005-07-31 06:07:48 +00:00
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
return m_Bw.WriteUInt8(static_cast<uint8_t>(op));
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
|
|
|
|
2008-03-04 19:06:39 +00:00
|
|
|
bool Journal::WriteString(const char *str, Encode enc)
|
2005-07-31 06:07:48 +00:00
|
|
|
{
|
|
|
|
size_t len = strlen(str);
|
|
|
|
if (enc == Encode_Small)
|
|
|
|
{
|
2008-03-04 19:06:39 +00:00
|
|
|
if (!m_Bw.WriteUInt8(static_cast<uint8_t>(len))) return false;
|
2005-07-31 06:07:48 +00:00
|
|
|
} else if (enc == Encode_Medium) {
|
2008-03-04 19:06:39 +00:00
|
|
|
if (!m_Bw.WriteUInt16(static_cast<uint16_t>(len))) return false;
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
2008-03-04 19:06:39 +00:00
|
|
|
return m_Bw.WriteChars(str, len);
|
|
|
|
|
|
|
|
|
2005-07-31 06:07:48 +00:00
|
|
|
}
|
|
|
|
|