Initial import of new version :]
This commit is contained in:
262
dlls/nvault/NVault.cpp
Executable file
262
dlls/nvault/NVault.cpp
Executable file
@ -0,0 +1,262 @@
|
||||
#include "NVault.h"
|
||||
#include "Binary.h"
|
||||
|
||||
template <class K>
|
||||
int HashFunction<String>(const K & k)
|
||||
{
|
||||
unsigned long hash = 5381;
|
||||
const char *str = k.c_str();
|
||||
char c;
|
||||
while (c = *str++) hash = ((hash << 5) + hash) + c; // hash*33 + c
|
||||
return hash;
|
||||
}
|
||||
|
||||
template <class K>
|
||||
bool Compare<String>(const K & k1, const K & k2)
|
||||
{
|
||||
return (strcmp(k1.c_str(),k2.c_str())==0);
|
||||
}
|
||||
|
||||
NVault::NVault(const char *file)
|
||||
{
|
||||
m_File.assign(file);
|
||||
m_Journal = NULL;
|
||||
m_Open = false;
|
||||
}
|
||||
|
||||
NVault::~NVault()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
VaultError NVault::_ReadFromFile()
|
||||
{
|
||||
FILE *fp = fopen(m_File.c_str(), "rb");
|
||||
|
||||
if (!fp)
|
||||
return Vault_NoFile;
|
||||
//this is a little more optimized than the other version in the journal <_<
|
||||
//I could optimize this more by embedding the position in the hash table but...
|
||||
// the hash function can be changed. this could be fixed by storing a string and its
|
||||
// resulting hash, and the entries could be ignored therein, but not right now.
|
||||
//Also the string class could have embedded binary reading (like it does for text files)
|
||||
BinaryReader br(fp);
|
||||
|
||||
uint8_t oldkeylen=0;
|
||||
uint16_t oldvallen=0;
|
||||
uint8_t keylen;
|
||||
uint16_t vallen;
|
||||
time_t stamp;
|
||||
char *key = NULL;
|
||||
char *val = NULL;
|
||||
String sKey;
|
||||
String sVal;
|
||||
|
||||
try
|
||||
{
|
||||
int32_t magic = br.ReadUInt32();
|
||||
if (magic != VAULT_MAGIC)
|
||||
return Vault_BadFile;
|
||||
int16_t version = br.ReadUInt16();
|
||||
if (version != VAULT_VERSION)
|
||||
return Vault_OldFile;
|
||||
int32_t entries = br.ReadUInt32();
|
||||
for (int32_t i=0; i<entries; i++)
|
||||
{
|
||||
stamp = static_cast<time_t>(br.ReadInt32());
|
||||
keylen = br.ReadUInt8();
|
||||
vallen = br.ReadUInt16();
|
||||
if (keylen > oldkeylen)
|
||||
{
|
||||
if (key)
|
||||
delete [] key;
|
||||
key = new char[keylen + 1];
|
||||
oldkeylen = keylen;
|
||||
}
|
||||
if (vallen > oldvallen)
|
||||
{
|
||||
if (val)
|
||||
delete [] val;
|
||||
val = new char[vallen + 1];
|
||||
oldvallen = vallen;
|
||||
}
|
||||
br.ReadChars(key, keylen);
|
||||
br.ReadChars(val, vallen);
|
||||
key[keylen] = '\0';
|
||||
val[vallen] = '\0';
|
||||
sKey.assign(key);
|
||||
sVal.assign(val);
|
||||
m_Hash.Insert(sKey, sVal, stamp);
|
||||
}
|
||||
} catch (...) {
|
||||
if (key)
|
||||
{
|
||||
delete [] key;
|
||||
key = NULL;
|
||||
}
|
||||
if (val)
|
||||
{
|
||||
delete [] val;
|
||||
val = NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
return Vault_Read;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return Vault_Ok;
|
||||
}
|
||||
|
||||
bool NVault::_SaveToFile()
|
||||
{
|
||||
FILE *fp = fopen(m_File.c_str(), "wb");
|
||||
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
BinaryWriter bw(fp);
|
||||
|
||||
try
|
||||
{
|
||||
int32_t magic = VAULT_MAGIC;
|
||||
int16_t version = VAULT_VERSION;
|
||||
|
||||
bw.WriteUInt32(magic);
|
||||
bw.WriteUInt16(version);
|
||||
|
||||
bw.WriteUInt32( m_Hash.Size() );
|
||||
|
||||
time_t stamp;
|
||||
String key;
|
||||
String val;
|
||||
|
||||
NHash<String,String>::iterator iter = m_Hash.GetIter();
|
||||
while (!iter.Done())
|
||||
{
|
||||
key = iter.GetKey();
|
||||
val = iter.GetVal();
|
||||
stamp = iter.GetStamp();
|
||||
bw.WriteInt32(stamp);
|
||||
bw.WriteUInt8( key.size() );
|
||||
bw.WriteUInt16( val.size() );
|
||||
bw.WriteChars( key.c_str(), key.size() );
|
||||
bw.WriteChars( val.c_str(), val.size() );
|
||||
iter.Next();
|
||||
}
|
||||
} catch (...) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NVault::Open()
|
||||
{
|
||||
_ReadFromFile();
|
||||
|
||||
char *journal_name = new char[m_File.size() + 10];
|
||||
strcpy(journal_name, m_File.c_str());
|
||||
|
||||
char *pos = strstr(journal_name, ".vault");
|
||||
if (pos)
|
||||
{
|
||||
strcpy(pos, ".journal");
|
||||
} else {
|
||||
strcat(journal_name, ".journal");
|
||||
}
|
||||
|
||||
m_Journal = new Journal(journal_name);
|
||||
delete [] journal_name;
|
||||
|
||||
m_Journal->Replay(&m_Hash);
|
||||
m_Journal->Erase();
|
||||
m_Journal->Begin();
|
||||
|
||||
m_Open = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NVault::Close()
|
||||
{
|
||||
if (!m_Open)
|
||||
return false;
|
||||
|
||||
_SaveToFile();
|
||||
m_Journal->End();
|
||||
m_Journal->Erase();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NVault::SetValue(const char *key, const char *val)
|
||||
{
|
||||
if (m_Journal)
|
||||
m_Journal->Write_Insert(key, val, time(NULL));
|
||||
String sKey;
|
||||
String sVal;
|
||||
sKey.assign(key);
|
||||
sVal.assign(val);
|
||||
m_Hash.Insert(sKey, sVal);
|
||||
}
|
||||
|
||||
void NVault::SetValue(const char *key, const char *val, time_t stamp)
|
||||
{
|
||||
if (m_Journal)
|
||||
m_Journal->Write_Insert(key, val, stamp);
|
||||
String sKey;
|
||||
String sVal;
|
||||
sKey.assign(key);
|
||||
sVal.assign(val);
|
||||
m_Hash.Insert(sKey, sVal, stamp);
|
||||
}
|
||||
|
||||
void NVault::Remove(const char *key)
|
||||
{
|
||||
if (m_Journal)
|
||||
m_Journal->Write_Remove(key);
|
||||
String sKey(key);
|
||||
m_Hash.Remove(sKey);
|
||||
}
|
||||
|
||||
void NVault::Clear()
|
||||
{
|
||||
if (m_Journal)
|
||||
m_Journal->Write_Clear();
|
||||
m_Hash.Clear();
|
||||
}
|
||||
|
||||
size_t NVault::Items()
|
||||
{
|
||||
return m_Hash.Size();
|
||||
}
|
||||
|
||||
size_t NVault::Prune(time_t start, time_t end)
|
||||
{
|
||||
if (m_Journal)
|
||||
m_Journal->Write_Prune(start, end);
|
||||
return m_Hash.Prune(start, end);
|
||||
}
|
||||
|
||||
bool NVault::GetValue(const char *key, time_t &stamp, char buffer[], size_t len)
|
||||
{
|
||||
String sKey(key);
|
||||
if (!m_Hash.Exists(sKey))
|
||||
{
|
||||
buffer[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
time_t st;
|
||||
String sVal;
|
||||
|
||||
sVal = m_Hash.Retrieve(sKey, st);
|
||||
stamp = st;
|
||||
_snprintf(buffer, len, "%s", sVal.c_str());
|
||||
|
||||
return true;
|
||||
}
|
Reference in New Issue
Block a user