📄 elemdbm.cpp
字号:
#include <string.h>
#include <fstream.h>
#include "elemdbm.h"
// element type registration
static int chunksize = 16;
int mgcElementDBM::maxregistered = 0;
int mgcElementDBM::registered = 0;
mgcElementDBM::ElementRecord* mgcElementDBM::record = 0;
mgcElementDBM::UnresolvedConvert* mgcElementDBM::cnvlist = 0;
// error handling
int mgcElementDBM::verbose = 0;
unsigned mgcElementDBM::error = 0;
const unsigned mgcElementDBM::allocation_failed = 0x00000001;
const unsigned mgcElementDBM::unknown_ordering = 0x00000002;
const unsigned mgcElementDBM::exceeded_maximum = 0x00000004;
const char* mgcElementDBM::message[3] = {
"allocation failed",
"unknown byte ordering",
"exceeded maximum element types (contact eberly@cs.unc.edu)"
};
//===========================================================================
int mgcElementDBM::
CreateDataBase ()
{
// guarantee call succeeds exactly once
static int first_time = 1;
if ( first_time == 0 )
return 0;
first_time = 0;
// initial allocation of data base records
maxregistered = chunksize;
record = new ElementRecord[maxregistered];
if ( record == 0 ) {
Report(allocation_failed);
return -1;
}
memset(record,0,maxregistered*sizeof(ElementRecord));
for (int i = 0; i < maxregistered; i++) {
record[i].convert_to = new EFconvert[maxregistered];
if ( record[i].convert_to == 0 ) {
Report(allocation_failed);
return -1;
}
}
return 1;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
DestroyDataBase ()
{
while ( cnvlist ) {
UnresolvedConvert* front = cnvlist;
cnvlist = cnvlist->next;
delete front;
}
delete[] record;
record = 0;
maxregistered = 0;
registered = 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
AddType (const ElementRecord& er)
{
if ( registered >= maxregistered ) { // reallocate needs to be done
Report(exceeded_maximum);
return -1;
}
// update data base
record[registered].addrtype = er.addrtype;
record[registered].description = er.description;
record[registered].memory_size = er.memory_size;
record[registered].packed_size = er.packed_size;
record[registered].input = er.input;
record[registered].output = er.output;
record[registered].reverse = er.reverse;
record[registered].pack = er.pack;
record[registered].unpack = er.unpack;
// Update "const int Derived::type". Typecasting addrtype circumvents
// the "const" protection.
*(int*)record[registered].addrtype = registered;
// update conversions
for (UnresolvedConvert* unr = cnvlist, *prev = 0; unr; ) {
int src_exists = 0, trg_exists = 0;
for (int i = 0; i <= registered; i++) {
if ( unr->srctype == record[i].addrtype )
src_exists = 1;
if ( unr->trgtype == record[i].addrtype )
trg_exists = 1;
}
if ( src_exists && trg_exists ) {
int srctype;
if ( unr->srctype == record[registered].addrtype )
srctype = registered;
else
srctype = *unr->srctype;
int trgtype;
if ( unr->trgtype == record[registered].addrtype )
trgtype = registered;
else
trgtype = *unr->trgtype;
record[srctype].convert_to[trgtype] = unr->convert_to;
UnresolvedConvert* temp = unr;
if ( prev == 0 ) {
cnvlist = unr->next;
unr = unr->next;
}
else {
prev->next = unr->next;
unr = unr->next;
}
delete temp;
}
else {
prev = unr;
unr = unr->next;
}
}
return registered++;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
AddConvert (const int& srctype, const int& trgtype, EFconvert f)
{
// Both srctype and trgtype must be in data base before adding conversion
// to the proper record. Otherwise the conversion is put on a list of
// unresolved conversions and (probably) added later.
int src_exists = 0, trg_exists = 0;
for (int i = 0; i < registered; i++) {
if ( &srctype == record[i].addrtype )
src_exists = 1;
if ( &trgtype == record[i].addrtype )
trg_exists = 1;
}
if ( src_exists && trg_exists )
record[srctype].convert_to[trgtype] = f;
else {
// place conversion on the unresolved list
UnresolvedConvert* unr = new UnresolvedConvert;
if ( unr == 0 ) {
Report(allocation_failed);
return 0;
}
unr->srctype = &srctype;
unr->trgtype = &trgtype;
unr->convert_to = f;
unr->next = cnvlist;
cnvlist = unr;
}
return 1;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Valid (int type)
{
return 0 <= type && type < registered;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Type (const char* description)
{
for (int type = 0; type < registered; type++) {
int i;
for (i = 0; description[i]; i++)
if ( description[i] != record[type].description[i] )
break;
if ( description[i] == 0 )
return type;
}
return -1;
}
//---------------------------------------------------------------------------
const char* mgcElementDBM::
Description (int type)
{
return Valid(type) ? record[type].description : 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
MemorySize (int type)
{
return Valid(type) ? record[type].memory_size : 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
PackedSize (int type)
{
return Valid(type) ? record[type].packed_size : 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
ByteOrder ()
{
static int byte_order = -1;
if ( byte_order == -1 ) { // determine memory byte order
long deadbeef = 0xdeadbeefL;
if ( *(unsigned char*)&deadbeef == 0xef ) // ibm pc, dec mips
byte_order = 0;
else if ( *(unsigned char*)&deadbeef == 0xde ) // sparc, hp-pa
byte_order = 1;
else { // unknown ordering (if ever happens, need to modify code)
byte_order = -1;
Report(unknown_ordering);
}
}
return byte_order;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Reverse2 (int quantity, void* src)
{
unsigned char* usrc = (unsigned char*) src;
for (
int i0=0, i1=1;
i0 < 2*quantity;
i0+=2, i1+=2)
{
usrc[i1] ^= usrc[i0];
usrc[i0] ^= usrc[i1];
usrc[i1] ^= usrc[i0];
}
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Reverse4 (int quantity, void* src)
{
unsigned char* usrc = (unsigned char*) src;
for (
int i0=0, i1=1, i2=2, i3=3;
i0 < 4*quantity;
i0+=4, i1+=4, i2+=4, i3+=4)
{
usrc[i3] ^= usrc[i0];
usrc[i0] ^= usrc[i3];
usrc[i3] ^= usrc[i0];
usrc[i2] ^= usrc[i1];
usrc[i1] ^= usrc[i2];
usrc[i2] ^= usrc[i1];
}
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Reverse8 (int quantity, void* src)
{
unsigned char* usrc = (unsigned char*) src;
for (
int i0=0, i1=1, i2=2, i3=3, i4=4, i5=5, i6=6, i7=7;
i0 < 8*quantity;
i0+=8, i1+=8, i2+=8, i3+=8, i4+=8, i5+=8, i6+=8, i7+=8 )
{
usrc[i7] ^= usrc[i0];
usrc[i0] ^= usrc[i7];
usrc[i7] ^= usrc[i0];
usrc[i6] ^= usrc[i1];
usrc[i1] ^= usrc[i6];
usrc[i6] ^= usrc[i1];
usrc[i5] ^= usrc[i2];
usrc[i2] ^= usrc[i5];
usrc[i5] ^= usrc[i2];
usrc[i4] ^= usrc[i3];
usrc[i3] ^= usrc[i4];
usrc[i4] ^= usrc[i3];
}
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Reversible (int type)
{
return Valid(type) && record[type].reverse;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Reverse (int quantity, int type, void* src)
{
if ( Reversible(type) ) {
record[type].reverse(quantity,src);
return 1;
}
else
return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Packable (int type)
{
return Valid(type) && record[type].pack;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Pack (int quantity, int type, void* src)
{
if ( Packable(type) ) {
record[type].pack(quantity,src);
return 1;
}
else
return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Unpackable (int type)
{
return Valid(type) && record[type].unpack;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Unpack (int quantity, int type, void* src)
{
if ( Unpackable(type) ) {
record[type].unpack(quantity,src);
return 1;
}
else
return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Convertible (int srctype, int trgtype)
{
return Valid(srctype) &&
Valid(trgtype) &&
record[srctype].convert_to[trgtype];
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Convert (int quantity, int srctype, void* src, int trgtype, void* trg)
{
if ( Convertible(srctype,trgtype) ) {
record[srctype].convert_to[trgtype](quantity,src,trg);
return 1;
}
else
return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Number (unsigned single_error)
{
int result;
for (result = -1; single_error; single_error >>= 1)
result++;
return result;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Report (unsigned single_error)
{
if ( verbose )
cout << "mgcElementDBM: " << message[Number(single_error)] << endl;
else
ofstream("element.err",ios::out|ios::app)
<< "mgcElementDBM: " << message[Number(single_error)] << endl;
error |= single_error;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Report (ostream& ostr)
{
for (unsigned single_error = 1; single_error; single_error <<= 1)
if ( error & single_error )
ostr << "mgcElementDBM: " << message[Number(single_error)] << endl;
error = 0;
}
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -