Files
MermsEmrWeb/mermsemr/src/core/vars.cc
T
2019-02-19 22:35:27 +00:00

373 lines
7.5 KiB
C++

#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include "safestring.h"
#pragma implementation "vars.h"
#include "vars.h"
//#include <stl_hashtable.h>
//#include <stl_tree.h>
//template _Rb_tree< string const, pair<string const, varstring>, _Select1st<pair<string const, varstring> >, less<string const>, allocator<varstring> >;
//template _Rb_tree<long, pair<long const, long>, _Select1st<pair<long const, long> >, less<long>, allocator<long> >;
using namespace std;
//template class std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, varstring>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, varstring> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, varstring> > >;
// template class _Rb_tree<string const, pair<string const, varstring>, _Select1st<pair<basic_string<char, char_traits<char>, allocator<char> > const, varstring> >, less<basic_string<char, char_traits<char>, allocator<char> > const>, allocator<pair<basic_string<char, char_traits<char>, allocator<char> > const, varstring> > >;
template class _Rb_tree< string const, pair<string const, varstring>, _Select1st<pair<string const, varstring> >, less<string const>, allocator<pair<string const,varstring> > >;
//::operator=(std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, varstring>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, varstring> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, varstring> > > const&);
// default constructor
varstring::varstring() : string()
{
validated = false;
db_var = false;
binary_var = false;
}
varstring::varstring( const char *c ) : string( c )
{
this->validated = false;
db_var = false;
binary_var = false;
}
varstring::varstring(const char* c, int len) : string( c, len )
{
// logfmt( FLOG_MAX, "varstring constructor( c='%s', len=%d )", c, len );
validated = false;
db_var = false;
binary_var = false;
}
// copy constructor
varstring::varstring( const varstring &c ) : string( c )
{
// logfmt( FLOG_MAX, "varstring copy constructor, c.validated=%d, value=%s", c.validated, c.c_str() );
this->validated = c.validated;
this->db_var = c.db_var;
this->binary_var = c.binary_var;
}
varstring::varstring( const string &c ) : string( c )
{
// logfmt( FLOG_MAX, "string->varstring copy constructor, value=%s", c.c_str() );
validated = false;
db_var = false;
binary_var = false;
}
long varstring::Long() const
{
return atol( c_str() );
}
double varstring::Double()
{
return atof( c_str() );
}
varstring& varstring::operator=( const char* c )
{
set_valid( false );
string::operator=( c );
return *this;
};
void varstring::operator=( long l )
{
set_valid( false );
char s[20];
snprintf( s, sizeof(s), "%ld", l );
string::operator=( s );
};
varstring& varstring::operator=( const varstring &c )
{
//set_valid( false );
this->validated = c.validated;
this->binary_var = c.binary_var;
string::operator=( c );
return *this;
};
void varstring::operator=( const string c )
{
set_valid( false );
binary_var = false;
string::operator=( c );
}
varstring::operator long()
{
return this->Long();
}
varstring::operator const char*() // type conversion
{
return this->c_str();
}
bool varstring::valid() const
{
return validated;
}
void varstring::set_valid( bool validated /*= true*/ )
{
this->validated = validated;
}
bool varstring::db() const
{
return db_var;
}
void varstring::set_db( bool db /*= true*/ )
{
this->db_var = db;
}
bool varstring::binary() const
{
return this->binary_var;
}
void varstring::set_binary( bool binary_var /*= true*/ )
{
this->binary_var = binary_var;
}
// ---------------- string_key --------
/*
string_key& string_key::operator=( const char* c )
{
// set_valid( false );
string::operator=( c );
return *this;
};
void string_key::operator=( long l )
{
// set_valid( false );
char s[20];
snprintf( s, sizeof(s), "%ld", l );
string::operator=( s );
};
void string_key::operator=( const string c )
{
// set_valid( false );
string::operator=( c );
};
*/
// ---------------- CVars -------------
CVars& CVars::operator<<( char const *name )
{
//logfmt( FLOG_MAX, "CVars << %s", name );
CVars::iterator i = find( name );
if ( i != end() )
{
i->second.set_db();
}
return *this;
}
CVars& CVars::operator>>( char const *name )
{
//logfmt( FLOG_MAX, "CVars >> %s", name );
CVars::iterator i = find( name );
if ( i != end() )
{
i->second.set_db( false );
}
return *this;
}
void CVars::ClearDB()
{
CVars::iterator i;
for ( i=begin(); i!=end(); i++ )
i->second.set_db( false );
}
/*
FORMAT:
int count;
{
name,value,
bitmap{
bool validated;
bool db_var; // is this variable to be used in DB updates
bool binary_var;
}
*/
//implement << operator??
long CVars::serialize( unsigned char *&buf ) // this will serialize the data into buf and return the resulting size
// it is the responsibility of the caller to free the buffer with free()
{
long len;
CVars::iterator i;
int count = 0; // do NOT change this datatype as this will affect data structure below!!!
unsigned char *c = buf + sizeof(count);
// Calculate the length
for ( i=begin(); i!=end(); i++ )
{
count++;
int size = i->first.size();
c += sizeof(unsigned char); // name should be no longer than 255
c += size;
size = i->second.size();
c += sizeof(int);
c += size;
// record bits
c++;
}
len = c-buf;
buf = (unsigned char*)malloc( len );
if ( !buf ) return 0;
// Populate buf
// first store the number of elements
*(int*)buf = count;
c = buf + sizeof(count);
for ( i=begin(); i!=end(); i++ )
{
int size = *(int*)c = i->first.size();
c += sizeof(unsigned char);
memcpy( c, i->first.data(), size );
c += size;
size = *(int*)c = i->second.size();
c += sizeof(int);
memcpy( c, i->second.data(), size );
c += size;
// record bits
*c = i->second.validated | i->second.db_var << 1 | i->second.binary_var << 2;
c++;
}
return len;
}
int CVars::deserialize( unsigned char *buf, long buf_sz ) // this will initialize the current instance by de-serializing the data from buf
{
// clear out the underlying map / erase any previous data
erase( begin(), end() );
if ( buf_sz < (long)sizeof(int) ) return 0;
unsigned char *c = buf;
int count = *(int*)buf;
c += sizeof( count );
int i = 0;
for ( i=0; i<count; i++ )
{
if ( c-buf >= buf_sz ) return 0;
char name[256];
int size = *(unsigned char*)c;
c += sizeof(unsigned char);
if ( c-buf+size >= buf_sz ) break; // boundary check
strnsafecpy( name, (char*)c, size, sizeof(name) );
c += size;
if ( c-buf+(long)sizeof(int) >= buf_sz ) break; // boundary check
size = *(int*)c;
c += sizeof(int);
if ( c-buf+size+1 > buf_sz ) break; // boundary check
(*this)[name].assign( (char*)c, size );
c += size;
(*this)[name].validated = *c & 1;
(*this)[name].db_var = (*c >> 1) & 1;
(*this)[name].binary_var = (*c >> 2) & 1;
c++;
//printf( "i=%d\n", i );
}
return i; //>0 ? i-1 : 0;
}