// TSField.cpp: implementation of the TSField class. // ///////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include #include "TSField.h" #include "TSServer.h" TSField::TSField() : schemaType ( 0 ), dataType ( 0 ), charValue ( NULL ), charValueMax ( 0 ), intValue ( 0 ), doubleValue ( 0.0 ), recordList ( NULL ), intList ( NULL ) { fieldType = 0; fieldName[0] = '\0'; } TSField::TSField( const TSField& field ) : schemaType ( field.schemaType ), dataType ( field.dataType ), charValue ( NULL ), charValueMax ( field.charValueMax ), intValue ( field.intValue ), doubleValue ( field.doubleValue ), recordList ( NULL ), intList ( NULL ) { fieldType = field.fieldType; strncpy( fieldName, field.fieldName, sizeof(fieldName) ); if ( field.charValue ) { charValue = strdup( field.charValue ); } if ( field.recordList ) { recordList = new TSRecordList(); *recordList = *( field.recordList ); } if ( field.intList ) { intList = new TSIntList(); *intList = *( field.intList ); } } TSField::~TSField() { if ( charValue ) { delete [] charValue; } if ( recordList ) { recordList->EmptyAndDestroyList(); delete recordList; } if ( intList ) { intList->EmptyAndDestroyList(); delete intList; } } int TSField::ReceiveSchema( TSSocket* socket ) { int tmpInt; int SQLType; int nReturn = socket->ReceiveInt( &schemaType ); int nReturn1 = socket->ReceiveInt( &dataType ); int nReturn2 = socket->ReceiveInt( &fieldType ); int nReturn3 = socket->ReceiveString( fieldName, 64 ); int nReturn4 = socket->ReceiveInt( &tmpInt ); int nReturn5 = socket->ReceiveInt( &tmpInt ); int nReturn6 = socket->ReceiveInt( &SQLType ); int nReturn7 = socket->ReceiveInt( &charValueMax ); int nReturn8 = socket->ReceiveInt( &tmpInt ); if ( nReturn != TS_OK || nReturn1 != TS_OK || nReturn2 != TS_OK || nReturn3 != TS_OK || nReturn4 != TS_OK || nReturn5 != TS_OK || nReturn6 != TS_OK || nReturn7 != TS_OK || nReturn8 != TS_OK ) { // TSErrorCode is set in ReceiveInt() and ReceiveString() return TSGetLastError(); } // SQLType is the type if it's a database column. // Convert the SQL datatype into a TSDataType. if ( schemaType == TS_SCHEMATYPE_DBCOL ) { switch( SQLType ) { 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; } } // Don't allocate the lists here - they would just be destroyed later return TS_OK; } int TSField::Receive( TSSocket* socket, TSServer* server ) { TSString str; switch( dataType ) { case TS_DATATYPE_STRING: if ( socket->ReceiveString( &str ) != TS_OK ) { // TSErrorCode is set in ReceiveString() return TSGetLastError(); } if ( charValue ) { delete [] charValue; charValue = 0; } 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: if ( socket->ReceiveInt( &intValue ) != TS_OK ) { // TSErrorCode is set in ReceiveInt() return TSGetLastError(); } break; case TS_DATATYPE_DOUBLE: if ( socket->ReceiveDouble( &doubleValue ) != TS_OK ) { // TSErrorCode is set in ReceiveDouble() return TSGetLastError(); } break; case TS_DATATYPE_RECORDLIST: if ( recordList ) { recordList->EmptyAndDestroyList(); delete recordList; } if ( schemaType == TS_SCHEMATYPE_TREELIST ) { recordList = new TSTreeList(); } else { recordList = new TSRecordList(); } if ( recordList->Receive( server, socket ) != TS_OK ) { // TSErrorCode is set in Receive() return TSGetLastError(); } break; case TS_DATATYPE_INTLIST: if ( intList ) { intList->EmptyAndDestroyList(); delete intList; } intList = new TSIntList(); if ( intList->Receive( server, socket ) != TS_OK ) { // TSErrorCode is set in Receive() return TSGetLastError(); } break; case TS_DATATYPE_UNKNOWN: TSSetLastError( TS_INVALID_DATATYPE ); return TSGetLastError(); break; } return TS_OK; } TSObject* TSField::NewObject() { return new TSField; } TSObject* TSField::Duplicate( int /*type = 0*/ ) { TSField* obj = new TSField; obj->Copy( this ); return obj; } void TSField::Copy( TSObject* sourceField ) { TSField* newField = static_cast( sourceField ); 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; } if ( newField->intList ) { intList = new TSIntList(); newField->intList->Duplicate( intList ); } else { if ( intList ) { delete intList; } intList = 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: s += "\n"; if ( recursive && intList != NULL ) { s += intList->StringDump( recursive, indentation + " " ); } 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; case TS_FLDTYPE_CONTACT: s = "TS_FLDTYPE_CONTACT"; break; case TS_FLDTYPE_INCIDENT: s = "TS_FLDTYPE_INCIDENT"; break; case TS_FLDTYPE_FOLDER: s = "TS_FLDTYPE_FOLDER"; break; case TS_FLDTYPE_KEYWORDLIST: s = "TS_FLDTYPE_KEYWORDLIST"; break; case TS_FLDTYPE_PRODUCTLIST: s = "TS_FLDTYPE_PRODUCTLIST"; break; case TS_FLDTYPE_RELATIONAL: s = "TS_FLDTYPE_RELATIONAL"; break; case TS_FLDTYPE_SUBRELATIONAL: s = "TS_FLDTYPE_SUBRELATIONAL"; break; case TS_FLDTYPE_MULTIPLE_RELATIONAL: s = "TS_FLDTYPE_MULTIPLE_RELATIONAL"; 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: if ( recordList ) { recordList->SocketString( str ); } break; case TS_DATATYPE_INTLIST: if ( intList ) { intList->SocketString( str ); } break; default: break; } return TS_OK; }