fld.cpp
// MField - example field classes, version 1
//
//
#include <fstream.h>
#include <assert.h>
#include <string.h> // for memset and strlen
#include <stdio.h> // for sprintf
#include <stdlib.h> // for atoi
#include <ctype.h> // for isdigit
// Our base class - MField
class MField
{
public:
// Constructor and destructor
MField( char *NewName=0, int NewSize=0, int NewOffset=0 );
virtual ~MField() { delete [] Data; delete [] Name; }
// Data getting and setting
virtual char* GetAsString() const =0; // Pure virtual
virtual void SetFromString(char* Src) =0; // Pure virtual
// Basic interface routines
char *GetName() { return(Name?Name:""); }
int GetSize() { return( Size ); }
void Clear() { memset( Data, 0, Size ); }
// A routine to help identify data type
virtual char * GetType() const = 0; // Pure virtual function, MField is 'abstract'
protected:
// Can be called only by this and derived classes
void SetName( char* NewName );
void* GetDataPntr() const { return( Data ); }
private:
int Offset, Size;
char * Data; // char * instead of void pointer, for simplicity
char * Name;
};
// Constructor
MField::MField( char *NewName, int NewSize, int NewOffset )
{
Name = 0;
SetName(NewName);
Data = new char[ NewSize ];
assert( Data != 0 );
Size = NewSize;
Offset = NewOffset;
Clear();
}
void MField::SetName( char* NewName )
{
assert( NewName!=0 && *NewName!='\0' );
delete [] Name;
Name = new char[ strlen( NewName ) + 1 ];
assert( Name!= 0 );
strcpy( Name, NewName );
}
////////////////////////////////////////////////////////////////////////
class MDateField : public MField
{
typedef struct { short Y; char M, D; } MyDate;
public:
MDateField( char* NewName=0, int Offset=0 ) : MField(NewName, sizeof(MyDate), Offset ) {}
// Provide the functions that are pure virtual in our class:
virtual char* GetAsString() const;
virtual void SetFromString(char* Src);
virtual char * GetType() const { return( "Date" ); }
};
// Returns a char pointer for the contents of the field
char* MDateField::GetAsString() const
{
static char Perm[11];
MyDate * Tmp = (MyDate*)GetDataPntr();
sprintf( Perm, "%02d/%02d/%04d", Tmp->M, Tmp->D, Tmp->Y );
return( Perm );
}
void MDateField::SetFromString(char* Src)
{
MyDate * Tmp = (MyDate*)GetDataPntr();
Tmp->M = Tmp->D = 0;
Tmp->Y = 0;
Tmp->M = atoi(Src);
while( isdigit(*Src) )
Src++;
while( *Src && !isdigit( *Src ) )
Src++;
Tmp->D = atoi(Src);
while( isdigit(*Src) )
Src++;
while( *Src && !isdigit( *Src ) )
Src++;
Tmp->Y = atoi(Src);
}
///////////////////////////////////////////////////////////////////////
class MShortField : public MField
{
public:
MShortField( char* NewName=0, int NewOffset=0 ) : MField(NewName, sizeof(short), NewOffset ) {}
char* GetAsString() const;
void SetFromString(char* Src);
virtual char * GetType() const { return( "Short" ); }
};
char* MShortField::GetAsString() const
{
static char Perm[7];
sprintf( Perm, "%d", *(short*) GetDataPntr() );
return( Perm );
}
void MShortField::SetFromString(char* Src)
{
*(short*) GetDataPntr() = atoi(Src);
}
///////////////////////////////////////////////////////////////////////
void main()
{
MField * Record[2];
Record[0] = new MDateField( "BDay");
Record[1] = new MShortField( "Qty" );
Record[0]->SetFromString("1/1/1997");
Record[1]->SetFromString("12");
cout << "[" << Record[0]->GetAsString() << "]" << endl;
Record[0]->Clear();
cout << "[" << Record[0]->GetAsString() << "]" << endl;
}