#include "stdafx.h" #include #include "TSServer.h" #include "TSField.h" #include "da.h" /* Debugging allocator -- GDR 2000-09-01 */ TSField::TSField() { schemaType = 0; fieldName[0] = '\0'; dataType = 0; schemaType = 0; fieldType = 0; charValue = NULL; charValueMax = 0; intValue = 0; doubleValue = 0.0; recordList = NULL; } TSField::TSField(const TSField &/*field*/) { } TSField::~TSField() { if (charValue) delete charValue; if (recordList) { recordList->EmptyAndDestroyList(); delete recordList; } } int TSField::ReceiveSchema(TSSocket *socket) { int tmpInt; socket->ReceiveInt(&schemaType); socket->ReceiveInt(&dataType); socket->ReceiveInt(&fieldType); socket->ReceiveString(fieldName,64); socket->ReceiveInt(&tmpInt); socket->ReceiveInt(&tmpInt); // This one is the type if it's a database column. // Convert the SQL datatype into a TSDataType. socket->ReceiveInt(&tmpInt); if(schemaType == TS_SCHEMATYPE_DBCOL) { switch(tmpInt) { case SQL_INTEGER: dataType = TS_DATATYPE_INTEGER; break; case SQL_CHAR: case SQL_VARCHAR: case SQL_LONGVARCHAR: case SQL_LONGVARCHAR1: case SQL_LONGVARCHAR2: dataType = TS_DATATYPE_STRING; break; case SQL_DOUBLE: dataType = TS_DATATYPE_DOUBLE; break; default: dataType = TS_DATATYPE_UNKNOWN; } } else if(schemaType == TS_SCHEMATYPE_LIST) { recordList = new TSRecordList(); } else if(schemaType == TS_SCHEMATYPE_TREELIST) { recordList = new TSTreeList(); } socket->ReceiveInt(&charValueMax); socket->ReceiveInt(&tmpInt); return TS_OK; } int TSField::Receive(TSSocket *socket, TSServer *server) { TSString str; switch(dataType) { case TS_DATATYPE_STRING: socket->ReceiveString(&str); if(charValue) delete charValue; if(charValueMax > 0) { charValue = new char[charValueMax]; strncpy(charValue, str.GetBuffer(), charValueMax); // Ensure that it's NULL terminated, even if we have to chop off // characters. if(str.Length() == charValueMax) charValue[charValueMax-1] = '\0'; } else { if(str.Length() == 0) { charValue = new char[1]; charValue[0] = '\0'; } else { charValue = new char[str.Length()+1]; strcpy(charValue,str.GetBuffer()); } } break; case TS_DATATYPE_INTEGER: case TS_DATATYPE_BOOL: socket->ReceiveInt(&intValue); break; case TS_DATATYPE_DOUBLE: socket->ReceiveDouble(&doubleValue); break; case TS_DATATYPE_RECORDLIST: if (recordList) { recordList->EmptyAndDestroyList(); delete recordList; } if( schemaType == TS_SCHEMATYPE_TREELIST ) { recordList = new TSTreeList(); } else { recordList = new TSRecordList(); } recordList->Receive(server, socket); break; case TS_DATATYPE_INTLIST: case TS_DATATYPE_UNKNOWN: return TS_ERROR; break; } return TS_OK; } TSObject *TSField::NewObject() { return new TSField; } TSObject *TSField::Duplicate() { TSField *obj = new TSField; obj->Copy(this); return obj; } void TSField::Copy(TSObject *newObj) { TSField *newField = (TSField *)newObj; schemaType = newField->schemaType; dataType = newField->dataType; fieldType = newField->fieldType; strcpy(fieldName, newField->fieldName); if(charValue != NULL) { delete charValue; charValue = NULL; } if(newField->charValue) { charValue = new char[strlen(newField->charValue)+1]; strcpy(charValue, newField->charValue); } else { charValue = NULL; } intValue = newField->intValue; doubleValue = newField->doubleValue; if(newField->recordList) { if( schemaType == TS_SCHEMATYPE_TREELIST ) { recordList = new TSTreeList(); } else { recordList = new TSRecordList(); } newField->recordList->Duplicate(recordList); } else { recordList = NULL; } } TSString TSField::StringDump(int recursive, TSString indentation) { TSString s = indentation + fieldName + " = "; char tmpBuf[64]; switch(dataType) { case TS_DATATYPE_STRING: s += "\""; s += charValue; s += "\""; s += "\n"; break; case TS_DATATYPE_BOOL: if(intValue) s += "TRUE\n"; else s += "FALSE\n"; break; case TS_DATATYPE_INTEGER: sprintf(tmpBuf, "%ld",intValue); s += tmpBuf; s += "\n"; break; case TS_DATATYPE_DOUBLE: sprintf(tmpBuf,"%.16g",doubleValue); s += tmpBuf; s += "\n"; break; case TS_DATATYPE_RECORDLIST: s += "\n"; if(recursive && recordList != NULL) { s += recordList->StringDump(recursive, indentation + " "); } break; case TS_DATATYPE_INTLIST: // Unused in 4.0 break; default: break; } return s; } TSString TSField::DumpSchema(TSString indentation) { char tmpBuf[64]; TSString locindentation = indentation + " "; TSString s = indentation + fieldName; s += ":\n"; sprintf(tmpBuf, "%d", dataType); s += locindentation + "Data Type = " + tmpBuf + "\n"; sprintf(tmpBuf, "%d", schemaType); s += locindentation + "Schema Type = " + tmpBuf + "\n"; sprintf(tmpBuf, "%d", fieldType); s += locindentation + "Class Type = (" + tmpBuf + ") " + FieldTypeToName(fieldType) + "\n"; return s; } TSString TSField::FieldTypeToName(int fieldType) { TSString s; switch(fieldType) { case 0: s = ""; break; case TS_FLDTYPE_NUMERIC: s = "TS_FLDTYPE_NUMERIC"; break; case TS_FLDTYPE_TEXT: s = "TS_FLDTYPE_TEXT"; break; case TS_FLDTYPE_MEMO: s = "TS_FLDTYPE_MEMO"; break; case TS_FLDTYPE_DATETIME: s = "TS_FLDTYPE_DATETIME"; break; case TS_FLDTYPE_SELECTION: s = "TS_FLDTYPE_SELECTION"; break; case TS_FLDTYPE_BINARY: s = "TS_FLDTYPE_BINARY"; break; case TS_FLDTYPE_STATE: s = "TS_FLDTYPE_STATE"; break; case TS_FLDTYPE_USER: s = "TS_FLDTYPE_USER"; break; case TS_FLDTYPE_PROJECT: s = "TS_FLDTYPE_PROJECT"; break; case TS_FLDTYPE_SUMMATION: s = "TS_FLDTYPE_SUMMATION"; break; case TS_FLDTYPE_MULTIPLE_SELECTION: s = "TS_FLDTYPE_MULTIPLE_SELECTION"; break; default: s = "INVALID CLASS TYPE"; break; } return s; } int TSField::SocketString(TSString &str) { str = ""; switch(dataType) { case TS_DATATYPE_STRING: TSEncodeString(charValue, str); break; case TS_DATATYPE_BOOL: case TS_DATATYPE_INTEGER: TSEncodeInt(intValue, str); break; case TS_DATATYPE_DOUBLE: TSEncodeDouble(doubleValue, str); break; case TS_DATATYPE_RECORDLIST: recordList->SocketString(str); break; case TS_DATATYPE_INTLIST: // Unused in 4.0 break; default: break; } return TS_OK; }