-
February 18th, 2009, 09:54 AM
#1
Memcpy Manipulation into a Struct
My program reads in data from a formatted data file and uses the data to fill in some structures with the correct data. There are several types of structures so I am trying to do this in a general fashion, rather than hundreds of a = b lines. If this is just not a good idea, please tell me and I can just abandon this approach. With each piece of data read in from the file I know how big the structure is supposed to be, and how big each field of data is. My Problem is that while a lot of the data seems to be filled out correctly in the structure, a lot of it seems like garbage or not what it is supposed to be. Constructive advice would be appreciated!
--Message Format
# Message Name
Message Number
Message Length
Field Size Min Max Default
Field Size Min Max Default
(Cont.)
--Sample of Example of file the am reading data in from.
# Player Update
5
220
4 1 8 1
4 1 512 1
2 1 128 1
2 0 1 0
8 0 100000 0
8 -90.0 90.0 0
8 -180.0 180.0 0
4 -1000 60000 0
.......
--Code From Project
//At this point we have already processed the message number and length
Code:
void CRangeCheck::ReadPlayerUpdate(std::ifstream* file, int nLen)
{
char buffer[256];
char seps[] = "\t\n";
char *nextTok;
int currPos = 0;
while(nLen - currPos > 0)
{
file->getline(buffer,24);
int fieldSz = atoi(strtok_s( buffer, seps, &nextTok ));
for(int i = 0; i < 3; i++)
{
char *fieldBuff = strtok_s( NULL, seps, &nextTok );
if(fieldSz == 8)
{
double buff = atof(fieldBuff);
memcpy(((unsigned char*)(&pduArray[i]->tPlayerData) + currPos), &buff, fieldSz) ;
}
else
{
int buff = atoi(fieldBuff);
memcpy(((unsigned char*)(&pduArray[i]->tPlayerData) + currPos), &buff, fieldSz) ;
}
}
currPos += fieldSz;
}
}
--Structure Being Written Into
Code:
typedef struct
{
int_4 id;
int_2 type;
int_2 team;
float_8 time;
float_8 lat;
float_8 lon;
float_4 alt;
float_4 pos_n;
float_4 pos_e;
float_4 pos_d;
float_4 vel_n;
float_4 vel_e;
float_4 vel_d;
float_4 yaw;
float_4 pitch;
float_4 roll;
int_2 plume_flag;
int_2 detonate_flag;
int_4 fired_wpn_id;
int_4 pad2;
int_4 pad3;
int_2 emit_flag;
int_2 firing_flag;
int_2 os_los_flag;
int_2 damage;
int_4 part1_type;
float_4 part1_az;
float_4 part1_el;
int_4 part2_type;
float_4 part2_az;
float_4 part2_el;
int_4 part3_type;
float_4 part3_az;
float_4 part3_el;
int_2 weapon_status;
int_2 pad1;
T_Articulation Articulations[MAX_ARTICULATIONS]; // Index should be even to end on double word boundary
} T_player_data;
-
February 18th, 2009, 10:34 AM
#2
Re: Memcpy Manipulation into a Struct
There are serialization libraries which might help you with this task or even give you some ideas. My vote goes as always to boost, check serialization there.
-
February 18th, 2009, 10:48 AM
#3
Re: Memcpy Manipulation into a Struct
Can you not just write ostream & istream overloads for the structure?
BTW in C++ you don't need to use a typedef for the structure.
Code:
struct T_player_data
{
int_4 id;
int_2 type;
int_2 team;
float_8 time;
float_8 lat;
float_8 lon;
float_4 alt;
float_4 pos_n;
float_4 pos_e;
float_4 pos_d;
float_4 vel_n;
float_4 vel_e;
float_4 vel_d;
float_4 yaw;
float_4 pitch;
float_4 roll;
int_2 plume_flag;
int_2 detonate_flag;
int_4 fired_wpn_id;
int_4 pad2;
int_4 pad3;
int_2 emit_flag;
int_2 firing_flag;
int_2 os_los_flag;
int_2 damage;
int_4 part1_type;
float_4 part1_az;
float_4 part1_el;
int_4 part2_type;
float_4 part2_az;
float_4 part2_el;
int_4 part3_type;
float_4 part3_az;
float_4 part3_el;
int_2 weapon_status;
int_2 pad1;
T_Articulation Articulations[MAX_ARTICULATIONS]; // Index should be even to end on double word boundary
};
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
February 18th, 2009, 10:54 AM
#4
Re: Memcpy Manipulation into a Struct
Code:
std::ostream &operator << (std::ostream &os, const T_player_data &player)
{
os << player.id << " "
<< player.type << " "
<< player.team << " "
etc......
return os;
}
std::istream &operator >> (std::istream &is, T_player_data &player)
{
is >> player.id
>> player.type
>> player.team
etc......
return is;
}
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
February 18th, 2009, 11:06 AM
#5
Re: Memcpy Manipulation into a Struct
I don't know how well overloading istream for the structure would mesh with this project.
The big reason I was attempting to do all this memcpy() manipulation was so I could lessen the lines of code. There are many more data and types of structs to be done. If doing this with memcpy and pointer math isn't going to work out cleanly, then I will just have to have many lines of copying normally like you suggest.
-
February 18th, 2009, 11:33 AM
#6
Re: Memcpy Manipulation into a Struct
Well, one potential problem is if someone in the future adds a non-POD item to a structure. Then the memcpy method will fail.
Another is that compiler options change the alignment of data.
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
February 18th, 2009, 11:42 AM
#7
Re: Memcpy Manipulation into a Struct
I wish I could get it to work 100% and not 60% of the time, I don't have a good way to loop so doing it all row by row is going to look bloated :-\
-
February 18th, 2009, 11:49 AM
#8
Re: Memcpy Manipulation into a Struct
Originally Posted by Draznar
I wish I could get it to work 100% and not 60% of the time, I don't have a good way to loop so doing it all row by row is going to look bloated :-\
Then memcpy is the worst thing you can do. As John already pointed out you will get into trouble when adding some non-POD members to you struct, resulting in undefined behaviour. That´s the worst you can get, because you really don´t know what´s going on from then. UD is the hardest to track down, so take the advice given and overload the stream operators or use a serialization library.
Just my 2 cent.
- Guido
-
February 18th, 2009, 11:56 AM
#9
Re: Memcpy Manipulation into a Struct
Ok, so I will abandon the memcpy route, but one more newish question, what does POD and UD stand for?
-
February 18th, 2009, 12:00 PM
#10
Re: Memcpy Manipulation into a Struct
Originally Posted by Draznar
what does POD and UD stand for?
"Plain Old Data" and "Undefined Behaviour", though the latter abbreviation is not actually used in the C++ Standard (and it should be UB, not UD, methinks).
Last edited by laserlight; February 18th, 2009 at 12:02 PM.
Reason: Added links, UD -> UB.
-
February 18th, 2009, 12:31 PM
#11
Re: Memcpy Manipulation into a Struct
Couple of suggestions.....
1) You could look into auto-generating the IO routines. There are various ways to do that. For the most part they're more trouble than they're worth, though, until you start getting to the point where you have a hundred different structs with a hundred different fields each.
2) If you're worried about code looking bloated, hide all the struct manipulation routines away in a separate file. You can then write them once and forget about them.
-
February 19th, 2009, 03:49 AM
#12
Re: Memcpy Manipulation into a Struct
Originally Posted by laserlight
Of course it´s UB, it´s a typo in my previous post.
- Guido
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|