#include "stdafx.h" #include #include "TSServer.h" #include "TSField.h" 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 = static_cast( 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; }