typedef struct

Hi, I've written a program that receives some data over a socket connection.  I receive the data as a character array....


char *pData=(char*)calloc(1,USSP_RESSIZE);

while(nError == WSAEWOULDBLOCK)            
{
   nBytes = socket.Receive(pData, USSP_RESSIZE, MSG_PEEK);      
   switch(nBytes)
   {
   case SOCKET_ERROR:
   break;
   default:
      nBytes = socket.Receive(pData, USSP_RESSIZE);
      memcpy(&rec, pData, USSP_RESSIZE);      
   return TRUE;
   break;
   }
}

After receiving the data I do a memcpy to a structure defined below...

typedef struct _HeaderRec{
      long                  messageSize;
      char                  headerType;
      short                  sequenceNumber;
      short                  clientSequenceNumber;
      short                  clientWindowHandle;
      char                  chFill;                  // filler byte ??
      char                  userId[RSKT_LEN_USER_ID];
      char                  securityTicket[RSKT_LEN_SECURITY_TICKET];
      short                  totalMessageCount;
      unsigned short      routerSessionHandle;
      long                  responseTime;
      long                  routerTime;
      long                  dataServerTime;      
      long                  hostTime;
      short                  clientSessionHandle;
      short                  routerDataServerId;
      short                  statusCode;
      short                  returnCode;
      short                  messageCat;
      short                  messageId;
      short                  systemCode;
      char                  effectiveDate[RSKT_LEN_CHARDATE];
      char                  groupNumber[RSKT_LEN_GRPNUM];
      char                  actualDataServer[RSKT_LEN_DATASVR];
      char                  requiredDataServer[RSKT_LEN_DATASVR];

}_HeaderRec,*_HeaderPtr;

This works great but, soon my program will have to support mulitple types of records that may need changes periodically.  Right now it would force me to create a new struct like above and recompile my code for every change.  That sucks.  Is there any way I could dynamically create structures so I can do the memcpy the same way?
LVL 1
perrizoAsked:
Who is Participating?
 
nietodConnect With a Mentor Commented:
>> All that my program needs to do with the
>> structure is populate it to send data and
>> then receive data back and copy the new
>> data back to the structure.
So it doesn't actually use any of the members in the structure?  In that case its very easy to deal with.

You just need tor ead the first 4 bites (long) from the socket.  This tells you the size of the structure to be allocated.  Allocate memory of this size and set the first 4 bytes of it to the length you read. (set the messageSize member).  Then read the rest of the data into the structure.

details follow.
0
 
perrizoAuthor Commented:
Edited text of question.
0
 
nietodCommented:
>>  Is there any way I could dynamically
>> create structures so I can do the
>> memcpy the same way?
What do you mean by this?  Do you want the pogram to be able to handle new structure without have any changes made to the code.  i.e you write the program today and send it out and tommorrow a new structure is developed and the programs you distributed need to handle it?  Yes, that can be done, but it can be very difficult.  (And it will depend a lot on what the program needs to do with the structure.

Or do you mean the program needs to be able to handle several different types of structures and its needs to look at the data that comes in and from there decide what type of structure to create?

Or something else?

In any case, get rid of that calloc() call.  use "new" in C++.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
perrizoAuthor Commented:
Okay I'll get rid of calloc.  But, I am interested in the first meaning.  Develop it and allow the code to adapt to changes in the structure or whole new changes in the structure.  I am also open to completely eliminating the struct thing altogether.  

All that my program needs to do with the structure is populate it to send data and then receive data back and copy the new data back to the structure.

Any ideas?
0
 
nietodCommented:
long StructSize;
nBytes = socket.Receive(&StructSize,sizeof(long), MSG_PEEK);
// check that nBytes is okay.

char *BufferPtr = new char[StructSize];

// Set the size member of the structure.
*(long *)BufferPtr  = StructSize;

// Read rest of structure.
nBytes = socket.Receive(BufferPtr + sizeof(long),StructSize - sizeof(long), MSG_PEEK);

Let me know if you have any questions.                      
0
 
perrizoAuthor Commented:
>> So it doesn't actually use any of the members in the structure?  

The only thing I really need to do is populate it and read from it later on.

>> Allocate memory of this size and set the first 4 bytes of it to the length you read.

This gets me the size of the structure but, I'm unclear how this helps me modify the structure?
0
 
nietodCommented:
Is it clear now?  Does that meet your needs?
0
 
perrizoAuthor Commented:
Still foggy?  This does allow me to receive all of the data but, referencing it may be difficult to do.  I guess I mispoke when I said all it had to do was read it in.  I also need to be able to reference the parts of the structure in some way.  Suppose I am making it a tougher question.  I've increased the points a little.
0
 
nietodCommented:
You may be making it MUCH thougher.  Or you might not be.  

The issue is how do you know what member of the structure you need to accces?  i.e if the structure changes, how do you know that what you want is there?

In a simple case, the early part of the structure won't change. That is the structure always begins with the same X number of data members that are always the same size and these are the ones you need to work with. but after these there are additional data members that may change, but you don't need to access them.  

Is that the case you have?  If not, then what do you have?
0
 
perrizoAuthor Commented:
Okay here goes.  The program I am writing uses active scripting to control a the ins and outs of the program.  What I would like is the ability to define the structures in the script.  I have the script running and performing all the necessary tasks with the socket except for building the structure.  What I would like to do is something like below...

Sub Socket_OnInit()
   Socket.AddToStruct("messageSize", "long")
   Socket.AddToStruct("headerType", "char")
End Sub

By defining the structure throught the script I would never have to create static structs in my code.  Whenever a change needs to be made all I have to do is change some simple VBScript.  Sounds to difficult?  I thought the AddToStruct Function would add a new member to a linked list that stored the name and pointed to the data?  So in the end I can reference the data maybe like...

Sub SaveImportantData()
   Dim A
   A = Socket.GetData("messageSize")
   DoSomethingWithData(A)
End Sub

Make sense?  They may seem like big dreams but, I am a one programmer shop around here and I have projects stacking up.  Changing my code for different templates is going to suck my time.  Any Ideas?  If you do and you don't think the points are enough let me know?
0
 
nietodCommented:
>> What I would like is the
>> ability to define the structures in the script.
That is precisely what I eluded to in my first comment when I said

>> Yes, that can be done, but it can be
>> very difficult.  

>>  I thought the AddToStruct Function would add
>> a new member to a linked list that stored the
>> name and pointed to the data
Yeah, that's bassically the right idea.
One small change I would make is to use an STL container (vector<> or list<>) instead of your own linked list, (maybe that's waht you had in mind).
Another point would be to have the container store a class or structure, Again that imay have been what you were thinking.
The class/structure stored in the container probably nees to record the name of the data member in the "dynamic structure" and it needs to record the size of the data member (or its type (char, long, int, double, etc))  (You might want to use an enum to record the different types.)  It will also want to store the offset of the data member.  This is the offset of the cooresponding data member in the "dynamic strucutre"  from the start of the "dyamic structure". This value will be calculated as the offset of the previous item in the data structure pluss the size of that previous item   (The first item's offset is 0).  (This assumes there is no padding.  I think that is probalby safe, right?)

Then when you have an instance of this dynamic structure you can get access to a particular member by obtaining that member's offset and adding it onto the pointer to the structure.

Does that make sense?  You were really on the right tracik.   There are a lot of OOP things you can do to make this easier.  Unfortuanately, I have to go now and can't elaborate on these until tommorrow.

(As you can see, this approach is a little complex, but it is not impossible.)
0
 
nietodCommented:
Just to sketch out a few things.

enum MbrDatTyp // Member data types.
{
   MbrDatTypByt, // Byte.
   MbrDatTypWrd, // Word.
   MbrDatTypDbll, // Doubleword.
// add you own.
}

// Must be in same order as MbrDatTyp's enums.
static int DatTypSizTbl[] = {sizeof(BYTE},sizeof(WORD),sizeof(DWORD)}

struct MbrDat  // Member data.
{
   string MbrNam; // member Name;
   MbrDatTyp DatTyp; // Data type
   int Off; // Offset to data member.
};

class StrDef // Stucture definition class.
{
    vector <MbrDat> MbrLst;  // List of members, in order.
public:

   // return the size of the structure currently defined.
   int GetStrSiz() const
   {
       int Siz = 0;
       int MbrCnt = MbrLst.size();

       if (MbrCnt)
       {
          const MbrDat &Dat = MbrLst[MbrCnt];
          Siz = Dat.Off + DatTypSizTbl[Dat.DatTyp]
       }
       return Siz;
   }

   void AddMbrDef(const string &Nam,MbrDatTyp Typ)
   {
      int Off = GetStrSiz();

      MbrDat Dat = {Nam,Typ,Off};
      MbrLst.push_back(Dat);
   };

   // Get data for member with specified name.
   const MbrDat *GetMbr(const string &Nam) const
   {
       vector<MbrDat>::const_iterator Itr;
       for (Itr = MbrLst.begin(); Itr != MbrLst.end(); ++Itr)
       {
            if (Itr->MbrNam == Nam)
               return Itr;
       }
       return NULL;
   };

   int GetOff(const string &Nam) const
   {
       int Off = -1;
       const MbrDat *MbrPtr = GetMbr(Nam)
       if (MbrPtr)
          Off = MbrPtr->Off;
       return Off;
   };
   void *GetPtrTo(void *StrPtr,const string &Nam) const
   {
      int Off = GetOff(Nam);

      if (Off < 0)
         return NULL;
      return (char *)StrPtr + Off;
   }

   BYTE *GetBytPtrTo(void *StrPtr,const string &Nam) const
   {
       return (BYTE *) GetPtrTo(StrPtr,Nam);
   }

   WORD *GetWrdPtrTo(void *StrPtr,const string &Nam) const
   {
       return (WORD *) GetPtrTo(StrPtr,Nam);
   }

};

That shoudl get you started.
0
 
perrizoAuthor Commented:
Okay here goes.  The program I am writing uses active scripting to control a the ins and outs of the program.  What I would like is the ability to define the structures in the script.  I have the script running and performing all the necessary tasks with the socket except for building the structure.  What I would like to do is something like below...

Sub Socket_OnInit()
   Socket.AddToStruct("messageSize", "long")
   Socket.AddToStruct("headerType", "char")
End Sub

By defining the structure throught the script I would never have to create static structs in my code.  Whenever a change needs to be made all I have to do is change some simple VBScript.  Sounds to difficult?  I thought the AddToStruct Function would add a new member to a linked list that stored the name and pointed to the data?  So in the end I can reference the data maybe like...

Sub SaveImportantData()
   Dim A
   A = Socket.GetData("messageSize")
   DoSomethingWithData(A)
End Sub

Make sense?  They may seem like big dreams but, I am a one programmer shop around here and I have projects stacking up.  Changing my code for different templates is going to suck my time.  Any Ideas?  If you do and you don't think the points are enough let me know?
0
 
perrizoAuthor Commented:
Sorry for the delay!  Had to see whether I had any more questions or not.  thanks!
0
All Courses

From novice to tech pro — start learning today.