//**************************************************************************
#include "dataserver.h"
//**************************************************************************
int packStruct(KeyTable *T, unsigned char **dataptr, int *totsize)
{
static KeyInfo d;
*totsize = sizeof(T->n) + T->n*(sizeof(d.id) + sizeof(d.key) + sizeof(d.description) + sizeof(d.type) + sizeof(d.elem_size) + sizeof(d.num_elems) + sizeof(d.vartype) + sizeof(d.is_locked) + sizeof(d.value) + sizeof(d.perm));
unsigned char *data;
ALLOC1D(&data, *totsize);
*dataptr = data;
int ptr = 0;
PACK_VARIABLE(T->n, data, &ptr);
for (int i = 0; i < T->n; i++)
{
PACK_VARIABLE(T->key[i].id, data, &ptr);
PACK_VARIABLE(T->key[i].elem_size, data, &ptr);
PACK_VARIABLE(T->key[i].num_elems, data, &ptr);
PACK_VARIABLE(T->key[i].vartype, data, &ptr);
PACK_VARIABLE(T->key[i].is_locked, data, &ptr);
PACK_VARIABLE(T->key[i].perm, data, &ptr);
PACK_VARIABLE(T->key[i].description, data, &ptr);
PACK_1D_ARRAY(T->key[i].key, data, &ptr);
PACK_1D_ARRAY(T->key[i].type, data, &ptr);
PACK_1D_ARRAY(T->key[i].value, data, &ptr);
}
return ptr;
}
//**************************************************************************
int unpackStruct(KeyTable *T, unsigned char *data, int size)
{
int ptr = 0;
UNPACK_VARIABLE(&(T->n), data, &ptr);
if (T->key.size())
{
T->key.clear();
}
for (int i = 0; i < T->n; i++)
{
T->Add();
UNPACK_VARIABLE(&(T->key[i].id), data, &ptr);
UNPACK_VARIABLE(&(T->key[i].elem_size), data, &ptr);
UNPACK_VARIABLE(&(T->key[i].num_elems), data, &ptr);
UNPACK_VARIABLE(&(T->key[i].vartype), data, &ptr);
UNPACK_VARIABLE(&(T->key[i].is_locked), data, &ptr);
UNPACK_VARIABLE(&(T->key[i].perm), data, &ptr);
UNPACK_VARIABLE(&(T->key[i].description), data, &ptr);
UNPACK_1D_ARRAY(T->key[i].key, data, &ptr);
UNPACK_1D_ARRAY(T->key[i].type, data, &ptr);
UNPACK_1D_ARRAY(T->key[i].value, data, &ptr);
}
return ptr;
}
//**************************************************************************
KeyTable::KeyTable()
{
n = 0;
}
//**************************************************************************
KeyTable::~KeyTable()
{
for (int i = 0; i < key.size(); i++)
delete key[i].sem;
key.clear();
}
//**************************************************************************
int KeyTable::Add()
{
static KeyInfo dummy;
dummy.ptr = NULL;
dummy.callback = NULL;
key.push_back(dummy);
return key.size();
}
//**************************************************************************
int KeyTable::getKeyHandle(char *keyword)
{
int i;
for (i = 0; i < key.size(); i++)
{
if (strcmp(key[i].key, keyword) == 0)
break;
}
return i;
}
//**************************************************************************
bool KeyTable::isVar(int i)
{
return (key[i].description == VARIABLE);
}
//**************************************************************************
bool KeyTable::isVar(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
return isVar(i);
return false;
}
//**************************************************************************
bool KeyTable::isCharArray(int i)
{
return (key[i].description == STATIC_1D_ARRAY && key[i].vartype == CHAR);
}
//**************************************************************************
bool KeyTable::isCharArray(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
return isCharArray(i);
return false;
}
//**************************************************************************
bool KeyTable::isValidKeyword(char *keyword)
{
return (getKeyHandle(keyword) < n);
}
//**************************************************************************
bool KeyTable::isViewableVar(int i)
{
return (isVar(i) || isCharArray(i));
}
//**************************************************************************
bool KeyTable::isViewableVar(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
return isViewableVar(i);
return false;
}
//**************************************************************************
void KeyTable::List()
{
cout << "==============================================================================" << endl << "\r";
cout << "Keyword\t\tDescription\t\tType\tElem Size (bytes) # elements" << endl << "\r";
cout << "==============================================================================" << endl << "\r";
for (int i = 0; i < key.size(); i++)
{
char desc[24];
int keylen = strlen(key[i].key);
cout << key[i].key;
if (key[i].is_locked)
{
cout << "*";
++keylen;
}
cout << "\t";
if (keylen <= 7) cout << "\t";
if (strlen(Description(i)) > 23)
{
strncpy(desc, Description(i), 23);
desc[23] = '\0';
cout << desc << " ";
}
else
cout << Description(i) << "\t";
if (strlen(Description(i)) <= 15) cout << "\t";
cout << key[i].type << "\t";
if (strlen(key[i].type) < 9) cout << "\t";
cout << key[i].elem_size << "\t\t"
<< key[i].num_elems << endl << "\r";
}
cout << "==============================================================================" << endl << "\r";
cout.flush();
}
//**************************************************************************
void KeyTable::ListValues()
{
int i;
cout << "==============================================================================" << endl << "\r";
int max = 0;
for (i = 0; i < n; i++)
{
if (!isViewableVar(i))
continue;
if (max < strlen(key[i].key))
max = strlen(key[i].key);
}
for (i = 0; i < n; i++)
{
if (!isViewableVar(i))
continue;
cout << key[i].key;
for (int j = 0; j < max-strlen(key[i].key); j++)
cout << " ";
cout << " = " << key[i].value << endl << "\r" << flush;
}
cout << "==============================================================================" << endl << "\r";
}
//**************************************************************************
bool KeyTable::isWritable(int i)
{
return (key[i].perm == KEY_READ_WRITE);
}
//**************************************************************************
bool KeyTable::isWritable(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
return isWritable(i);
return false;
}
//**************************************************************************
bool KeyTable::isArray(int i)
{
return (strstr(Description(i), "Array") != NULL);
}
//**************************************************************************
bool KeyTable::isArray(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
return isArray(i);
return false;
}
//**************************************************************************
bool KeyTable::isStaticArray(int i)
{
return (strstr(Description(i), "Static") != NULL);
}
//**************************************************************************
bool KeyTable::isStaticArray(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
return isStaticArray(i);
return false;
}
//**************************************************************************
void KeyTable::RegisterCallback(char *keyword, void (*cb)(void*), void *data)
{
int i = getKeyHandle(keyword);
if (i == n)
{
cerr << "KeyTable::RegisterCallback: Error! Invalid keyword \"" << keyword << "\"!!" << endl << flush;
return;
}
if (!isWritable(i))
{
cerr << "KeyTable::RegisterCallback: Error! Keyword \"" << keyword << "\" points to read-only data!!" << endl << flush;
return;
}
key[i].callback = cb;
key[i].callbackdata = data;
}
//**************************************************************************
bool KeyTable::hasCallback(int i)
{
return (key[i].callback != NULL);
}
//**************************************************************************
bool KeyTable::hasCallback(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
return hasCallback(i);
return false;
}
//**************************************************************************
void KeyTable::Callback(int i)
{
key[i].callback(key[i].callbackdata);
}
//**************************************************************************
void KeyTable::Callback(char *keyword)
{
int i = getKeyHandle(keyword);
if (i < n)
Callback(i);
}
//**************************************************************************