⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.cpp

📁 一个经典的词法分析器
💻 CPP
字号:
//
// SCTable: A class to represent a table in memory
//
// 
#include <afxwin.h>
#include "EMBSQL.h"

void *SCTable::operator new(size_t size)
{
	return shared_malloc(size);
}

void SCTable::operator delete(void *ptr)
{
	shared_free((char*)ptr);
}

//
// Create a memory based SQL table
SCTable::SCTable(CString nm, SCColumn *cols[], int sz)
{
	name = new SCString(nm);
	columns = (SCColumn**)shared_malloc(sz * sizeof(SCColumn*));
	for (int i=0;i<sz;i++) {
		columns[i] = new SCColumn(cols[i]->Name(),cols[i]->Type(),cols[i]->Width());
	}
	nCols = sz;
	rows = new SCCollection();
}

//
// Destructor for the memory based SQL table
SCTable::~SCTable()
{
	DeleteAllRows();
	for (int i=0;i<nCols;i++) 
		delete columns[i];
	delete columns;
	delete name;
}

//
// Return the name of this table
CString SCTable::Name()
{
	return name->Value();
}

//
// Return the number of columns in this table
int SCTable::Columns()
{
	return nCols;
}

SCColumn** SCTable::GetColumnInfo()
{
	return (SCColumn**)columns;
}

//
// Given a name, not case sensitive, return the index of the column
int SCTable::Index(CString nm)
{
	for (int i=0;i<nCols;i++) {
		if (nm.CompareNoCase(columns[i]->Name()) == 0)
			return i;
	}
	return -1;
}

//
// Given a non-case sensitive name, return the type of the column
int SCTable::Type(CString nm)
{
	int i = Index(nm);
	if (i < 0) return CUNDEFINED;
	return columns[i]->Type();
}

//
// Given the index, return the type of the column
int SCTable::Type(int n)
{
	if (n >= nCols)
		return CUNDEFINED;
	return columns[n]->Type();
}

//
// Given a non case-sensitive name, return the column
SCColumn* SCTable::Column(CString n)
{
	int i = Index(n);
	if (i < 0) return NULL;
	return (SCColumn*)columns[i];
}
//
// Given an index, return the column
SCColumn* SCTable::Column(int n)
{
	if (n >= nCols)
		return NULL;
	return (SCColumn*)columns[n];
}

//
// Adds a row from an array of columns, the columns being the set used in the
// intitialization of the table itself
bool SCTable::AddRow()
{
	return AddRow((SCColumn**)columns);
}

//
// Adds a row from an array of columns, but note, creates a copy of the input.
// Number of columns must match the table's, and the names and types must match
// too.
bool SCTable::AddRow(SCColumn* cols[])
{
	bool rc;
	void *array[MAX_COLUMNS];
	for (int i=0, j=0;i<nCols;i++) {
		j = Index(cols[i]->Name());
		array[j] = cols[i]->Value();
	}
	rc = AddRow((const void **)array);
	return rc;
}

//
// Adds a row from array of void pointers, but note, creates a copy of the input
//
bool SCTable::AddRow(const void **newRow)
{
	int eType = 0;
	void **n = NULL;
	char *c;
	unsigned *u;
	long *l;
	double *f, *ff;

	if (newRow == NULL)
		return false;
	n = (void **)shared_malloc(sizeof(void*) * nCols);
	for (int i=0;i<nCols;i++) {
		eType = columns[i]->Type();
		switch (eType) {
		case CTIME:
		case CSTRING:			// chars
			c = shared_malloc(columns[i]->Width());
			strcpy(c,(char*)newRow[i]);
			n[i] = (void *)c;
			break;
		case CUNSIGNED:			// unsigned
			u = (unsigned *)shared_malloc(sizeof(unsigned));
			*u = *(unsigned *) newRow[i];
			n[i] = (void *)u;
			break;
		case CLONG:			// long
		case CINT:
			l = (long*)shared_malloc(sizeof(long));
			*l = *(long *) newRow[i];
			n[i] = (void *)l;
			break;
		case CFLOAT:			// float
			f = (double*)shared_malloc(sizeof(double));
			ff = (double*) newRow[i];
			*f = *ff;
			n[i] = (void *)f;
			break;
		}
	}
	rows->Add((CObject*)n);
	return TRUE;
}

//
// Given a list of columns, with values attached, search the row data from 'start'
// and find the first row that matches. 
int SCTable::RecordInTable(SCColumn* col[], int ops[],  int nColumns, int start)
{
	int columnsToCheck[MAX_COLUMNS];
	int present = 0;

	present = 0;							// when present == nColumns, you have a match
	for (int i=0, j = 0;i<nColumns;i++) {	// load up the attribute indexes
		j = Index(col[i]->Name());
		columnsToCheck[i] = j;
	}

	for (i=start;i<rows->GetSize();i++) {			// for each row in the table,
		for (j=0;j<nColumns;j++) {					// and for each attribute within the row
			if (Compare(col[i],columns[j],ops[j]))	// apply the operation to those 2 items
				present++;							// and record in present
		}
		if (present == nColumns)					// if all columns checked match, return here
			return i;
	}
	return -1;										// incomplete or no match anywhere in table
}

//
// Given columns a and b, compare using operator op
int SCTable::Compare(SCColumn *a, SCColumn *b, int op)
{
	int *inta = NULL, *intb = NULL;
	double *da = NULL, *db = NULL;
	unsigned *ua = NULL, *ub = NULL;
	char *ca = NULL, *cb = NULL;
	int c = 0;

	if (a->Type() != b->Type())						// type mismatch, don't bother
		return -1;
//
// Get the values to compare and do an equivalence match
//
	switch(a->Type()) {
	case CTIME:
	case CSTRING:
		ca = (char *)a->Value();
		cb = (char *)b->Value();
		c = strcmp(ca,cb);
		break;
	case CFLOAT:
		da = (double* )a->Value();
		db = (double* )b->Value();
		c = (*da == *db);
		break;
	case CLONG:
	case CINT:
		inta = (int *)a->Value();
		intb = (int *)b->Value();
		c = (*inta == *intb);
		break;
	case CUNSIGNED:
		ua = (unsigned *)a->Value();
		ub = (unsigned *)b->Value();
		c = (*ua == *ub);
		break;
	default:
		return -2;
	}
//
// Do the operation on the 2 values, based on the return values of the comparison
// and the type of attributes we are dealing with
//
	switch(op) {
	case CLT: 
		if (c < 0) return 1;
		return 0;
	case CLE:
		if (c < 0 || c == 0) return 1;
		return 0;
	case CEQ:
		if (c == 0) return 1;
		return 0;
	case CGT:
		if (c > 0 || c == 0) return 1;
		return 0;
	case CGE:
		if (c > 0) return 1;
	}
	return 0;								// no match
}

//
// Return an array of data, representing one row in the table
void **SCTable::GetRow(int i)
{
	void **r = NULL;
	r = (void **)rows->GetAt(i);
	return r;
}

//
// Delete a row in the table. Each row is an array of pointers. So, delete
// the pointers in the array, then the array itself. Then adjust the size
// of the row collection itself
bool SCTable::DeleteRow(int i)
{
	void **rr = NULL;
	if (i < 0 || i > rows->GetSize())
		return false;
	rr = (void **)rows->GetAt(i);
	for (int j = 0;j<nCols;j++)
		shared_free((char*)rr[j]);
	shared_free((char*)rr);;
	rows->RemoveAt(i);
	return true;
}

//
// Delete all rows in the table
void SCTable::DeleteAllRows()
{
	while(rows->GetSize() > 0)
		DeleteRow(0);
}

//
// Return the number of rows int he table
int SCTable::NRows()
{
	return rows->GetSize();
}

//
// Given a type and a void pointer, interpret as a floating point number
double SCTable::InterpretAsFloat(int type, void *ptr)
{
	int inta = 0;
	unsigned ua = 0;
	switch(type) {
	case CTIME:
	case CSTRING:
		return 0.0;
	case CFLOAT:
		return *(double *)ptr;
	case CLONG:
	case CINT:
		inta = *(int *)ptr;
		return (double) inta;
	case CUNSIGNED:
		ua = *(unsigned *)ptr;
		return (double)ua;
	}
	return 0.0;
}

//
// Given a type and a void pointer, interpret as a string
CString* SCTable::InterpretAsString(int type, void *ptr)
{
	char cbuf[128] = {""};
	switch(type) {
	case CTIME:
	case CSTRING:
		 return new CString((char *)ptr);
	case CFLOAT:
		sprintf(cbuf,"%f", *(double *)ptr);
		return new CString(cbuf);
	case CLONG:
	case CINT:
		sprintf(cbuf,"%d",*(int *)ptr);
		return new CString(cbuf);
	case CUNSIGNED:
		sprintf(cbuf,"%u",*(unsigned *)ptr);
		return new CString(cbuf);
	}
	return new CString("");
}

//
// Print the indicated row in the table
bool SCTable::PrintRow(int which)
{
	CString *s = NULL;
	char format[128] = {""};
	void *ptr = NULL, **row = NULL;

	row = (void**)GetRow(which);
	for (int i=0;i<nCols;i++) {
		ptr = row[i];
		s = InterpretAsString(columns[i]->Type(),ptr);
		printf("%s\t",(LPCSTR)s);
		delete s;
	}
	printf("\n");
	return true;
}

//
// Given the row, print it using the columns of this table
bool SCTable::PrintRow(void **row)
{
	CString *s = NULL;
	char format[128] = {""};
	void *ptr = NULL;

	double f;

	for (int i=0;i<nCols;i++) {
		ptr = row[i];
		f = *((double*)row[i]);
		s = InterpretAsString(columns[i]->Type(),ptr);
		printf("%s\t",(LPCSTR)*s);
		delete s;
	}
	printf("\n");
	return true;
}

//
// Given a column array, prrint the given row
bool SCTable::PrintRow(SCColumn** cols, int nC, void **row)
{
	CString *s = NULL;
	char format[128] = {""}, wid[16] = {""};
	void *ptr = NULL;

	if (!row || nC < 0) return false;
	for (int i=0;i<nC;i++) {
		ptr = row[i];
		s = InterpretAsString(cols[i]->Type(),ptr);
		sprintf(wid,"%d",cols[i]->Width());
		strcpy(format,"% ");
		strcat(format,wid);
		strcat(format,"s ");
		printf(format,*s);
		delete s;
	}
	printf("\n");
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -