Board index » cppbuilder » structure writing question

structure writing question


2008-05-01 01:22:00 AM
cppbuilder17
hi,
I have a structure :
struct SAMPLE_BLOCK
{
INT8U channelID; // Channel (band) ID for this blocks I/Q data
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};
I want to write this block to file, except the channelID byte.
So, I just want to write the last four byte in a sample.
How can one do that? I have tried the following, but that don't work
SAMPLE_BLOCK* aSample .....;
fOut->write((char*) &( *(aSample + 1) ), sizeof( *(aSample)) - 1 );
any suggestions?
-totte
 
 

Re:structure writing question

"Totte Karlsson" < XXXX@XXXXX.COM >wrote in message
Quote
I want to write this block to file, except the channelID byte.
So, I just want to write the last four byte in a sample.

How can one do that?
Like this:
SAMPLE_BLOCK* aSample .....;
fOut->write(&(aSample->sampleI), sizeof(*aSample)-1);
Gambit
 

Re:structure writing question

Remy Lebeau (TeamB) wrote:
Quote
fOut->write(&(aSample->sampleI), sizeof(*aSample)-1);


I wouldn't use the explicit -1, but rather sizeof of the first member.
 

{smallsort}

Re:structure writing question

Alex Bakaev [TeamB] wrote:
Quote
Remy Lebeau (TeamB) wrote:

>fOut->write(&(aSample->sampleI), sizeof(*aSample)-1);
I wouldn't use the explicit -1, but rather sizeof of the first member.
Or the sizes of the 2 fields actually being written.
Both 1 and sizeof(firstfield) could be incorrect with alignment>1
sizeof( *aSample ) - ( &aSample->sampleI - aSample )
 

Re:structure writing question

Bob Gonder < XXXX@XXXXX.COM >wrote:
Quote
Alex Bakaev [TeamB] wrote:
>Remy Lebeau (TeamB) wrote:
>
>>fOut->write(&(aSample->sampleI), sizeof(*aSample)-1);

>I wouldn't use the explicit -1, but rather sizeof of the first member.

Or the sizes of the 2 fields actually being written.
Both 1 and sizeof(firstfield) could be incorrect with alignment>1

sizeof( *aSample ) - ( &aSample->sampleI - aSample )
Is it going to be appreciably slower to write the two elements
separately?
fOut->write(&(aSample->sampleI), sizeof(aSample->sampleI));
fOut->write(&(aSample->sampleQ), sizeof(aSample->sampleQ));
At least you can stop worrying about alignment at that point.
Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
 

Re:structure writing question

Totte Karlsson < XXXX@XXXXX.COM >writes:
Quote
hi,
I have a structure :
struct SAMPLE_BLOCK
{
INT8U channelID; // Channel (band) ID for this blocks I/Q data
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};

I want to write this block to file, except the channelID byte.
So, I just want to write the last four byte in a sample.

How can one do that? I have tried the following, but that don't work

SAMPLE_BLOCK* aSample .....;
fOut->write((char*) &( *(aSample + 1) ), sizeof( *(aSample)) - 1 );

any suggestions?
How about re-order the fields in your structure:
struct Sample_Block
{
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
INT8U channelID; // Channel (band) ID for this blocks I/Q data
};
Then you can write out the beginning of the block by writing out from
the base address:
#include <cstddef>
FOut->write(reinterpret_cast<char*>(aSample),
offsetof(Sample_Block, channelID);
Of course, the offsetof macro requires that your type be POD, but
since your example is, I would expect it represents your real data.
Another way to accomplish this is to introducde a helper structure.
struct Sample_Block
{
struct Streamable
{
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};
Streamable streamable_data;
INT8U channelID; // Channel (band) ID for this blocks I/Q data
};
Then you can just write out streamable_data in its entirety. Of
course, this changes the way you access its members, so maybe that's
unattractive. You can also use inheritance:
struct Sample_Block_Base
{
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};
struct Sample_Block : Sample_Block_Base
{
INT8U channelID; // Channel (band) ID for this blocks I/Q data
};
Then you can just write out Sample_Block_Base, but otherwise pass
around the derived type Sample_Block.
Just some ideas.
--
Chris (TeamB);
 

Re:structure writing question

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >writes:
Quote
How about re-order the fields in your structure:

struct Sample_Block
{
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
INT8U channelID; // Channel (band) ID for this blocks I/Q data
};

Then you can write out the beginning of the block by writing out from
the base address:

#include <cstddef>

FOut->write(reinterpret_cast<char*>(aSample),
offsetof(Sample_Block, channelID);
I forgot to mention that this may write a little "extra" data at the
end, if there is some padding before channelID. To avoid that we can
do this:
FOut->write(reinterpret_cast<char*>(aSample),
offsetof(Sample_Block, sampleQ) + sizeof(aSample.sampleQ));
Then you still have to hope nobody inserts anything into your
structure in the wrong place, or it will either be written
inappropiately, or accidentally skipped. There is also the concern of
someone re-ordering the members, and then this approach is broken.
Probably the safest way is to do as Alan suggested and just write out
the memebers you want, seperately and sequentially.
--
Chris (TeamB);
 

Re:structure writing question

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote:
Quote
Probably the safest way is to do as Alan suggested and just write out
the memebers you want, seperately and sequentially.
If there's ever the possibility of wanting to reload onto a different
machine architecture, it's worth doing that in conjunction with the
htonXX and ntohXX functions.
(And using UTF-8 for string data.)
Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced
 

Re:structure writing question

Alan Bellingham wrote:
Quote
Bob Gonder wrote:

>Or the sizes of the 2 fields actually being written.
>Both 1 and sizeof(firstfield) could be incorrect with alignment>1
>
>sizeof( *aSample ) - ( &aSample->sampleI - aSample )

Is it going to be appreciably slower to write the two elements
separately?
"Appreciably" depends on how many you are writing,
the quality of the write cache, the speed of the disk,
and if writethrough was specified.
I would assume the majority of the code is within
WriteFile(), which you are executing double vs doubling
the size of the data written. The extra code might
be masked by efficient cache noted above.
After all, there is a reason we don't copy files by byte.
 

Re:structure writing question

Totte Karlsson wrote:
Quote
hi,
I have a structure :
struct SAMPLE_BLOCK
{
INT8U channelID; // Channel (band) ID for this blocks
I/Q data
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};

I want to write this block to file, except the channelID byte.
So, I just want to write the last four byte in a sample.

How can one do that? I have tried the following, but that don't work

SAMPLE_BLOCK* aSample .....;
fOut->write((char*) &( *(aSample + 1) ), sizeof( *(aSample)) - 1 );

any suggestions?
fOut->write( (char*)&(aSample->sampleI), sizeof(INT16S) );
fOut->write( (char*)&(aSample->sampleQ), sizeof(INT16S) );
Cheers,
Serge
 

Re:structure writing question

Bob Gonder < XXXX@XXXXX.COM >wrote:
Quote
After all, there is a reason we don't copy files by byte.
Yep - them floppies are slow.
Seriously - a few years ago I threw away code that actually stashed a
binary copy of my nice ascii files. The speed advantage to my strategy -
devised in the day of slow disks - had actually totally disappeared.
Admittedly, even as ASCII, the file size was rarely above a few KB. The
whole thing would arrive in a single sector read, and since I never
enabled write-through, it'd arrive back on disc as a single write.
So, I'd expect the measurable difference between trying to write 32 bits
at a time as opposed to 16 to be immeasurable.
(FILE* being buffered by default.)
Alan Bellingham
--
Team Browns
<url:www.borland.com/newsgroups/>Borland newsgroup descriptions
<url:www.borland.com/newsgroups/netiquette.html>netiquette
 

Re:structure writing question

I like the expressions to be simple for things like a call which may appear
many times in the code. I do that by putting the complicated expressions in
inline functions or by creating constants which are the value computed with
those complicated expressions. The complicated part then only appears once
in the program so there is only one chance to mess it up with a typo.
I also like to pack structures that I will be saving to disk on one byte
boundaries so that the data is then easily accessable by different programs
and languages. It also saves space.
Try this:
#pragma pack(push, 1) // pack on 1-byte boundaries
struct SAMPLE_BLOCK
{
INT8U channelID; // Channel (band) ID for this blocks I/Q
data
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};
#pragma pack(pop) // end the effect of the pack pragma
inline char *SampIOAddr(const SAMPLE_BLOCK & sb)
{
return reinterpret_cast<char *>(&sb) + offsetof(sb.sampleI);
}
const size_t SampIOSize = sizeof(SAMPLE_BLOCK) - sizeof(INT8U);
fOut->write(SampIOAddr(aSample), SampIOSize);
. Ed
Quote
Totte Karlsson wrote in message
news:4818aabf$ XXXX@XXXXX.COM ...

I have a structure :
struct SAMPLE_BLOCK
{
INT8U channelID; // Channel (band) ID for this blocks I/Q
data
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};

I want to write this block to file, except the channelID byte.
So, I just want to write the last four byte in a sample.

How can one do that? I have tried the following, but that don't work

SAMPLE_BLOCK* aSample .....;
fOut->write((char*) &( *(aSample + 1) ), sizeof( *(aSample)) - 1 );

any suggestions?
 

Re:structure writing question

I see, that will do it.
It kind of look as I'm only writing sampleI though.. got to have good comments.
-tk
Remy Lebeau (TeamB) wrote:
Quote
"Totte Karlsson" < XXXX@XXXXX.COM >wrote in message
news:4818aabf$ XXXX@XXXXX.COM ...

>I want to write this block to file, except the channelID byte.
>So, I just want to write the last four byte in a sample.
>
>How can one do that?

Like this:

SAMPLE_BLOCK* aSample .....;
fOut->write(&(aSample->sampleI), sizeof(*aSample)-1);


Gambit


 

Re:structure writing question

Thanks for the ideas!
But I can't change the order. Its predefined and out of my control.
-totte
Chris Uzdavinis (TeamB) wrote:
Quote
Totte Karlsson < XXXX@XXXXX.COM >writes:

>hi,
>I have a structure :
>struct SAMPLE_BLOCK
>{
>INT8U channelID; // Channel (band) ID for this blocks I/Q data
>INT16S sampleI; // In Phase Sample
>INT16S sampleQ; // Quadrature Phase Sample
>};
>
>I want to write this block to file, except the channelID byte.
>So, I just want to write the last four byte in a sample.
>
>How can one do that? I have tried the following, but that don't work
>
>SAMPLE_BLOCK* aSample .....;
>fOut->write((char*) &( *(aSample + 1) ), sizeof( *(aSample)) - 1 );
>
>any suggestions?

How about re-order the fields in your structure:

struct Sample_Block
{
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
INT8U channelID; // Channel (band) ID for this blocks I/Q data
};

Then you can write out the beginning of the block by writing out from
the base address:

#include <cstddef>

FOut->write(reinterpret_cast<char*>(aSample),
offsetof(Sample_Block, channelID);

Of course, the offsetof macro requires that your type be POD, but
since your example is, I would expect it represents your real data.

Another way to accomplish this is to introducde a helper structure.


struct Sample_Block
{
struct Streamable
{
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};

Streamable streamable_data;
INT8U channelID; // Channel (band) ID for this blocks I/Q data
};


Then you can just write out streamable_data in its entirety. Of
course, this changes the way you access its members, so maybe that's
unattractive. You can also use inheritance:

struct Sample_Block_Base
{
INT16S sampleI; // In Phase Sample
INT16S sampleQ; // Quadrature Phase Sample
};

struct Sample_Block : Sample_Block_Base
{
INT8U channelID; // Channel (band) ID for this blocks I/Q data
};

Then you can just write out Sample_Block_Base, but otherwise pass
around the derived type Sample_Block.

Just some ideas.

 

Re:structure writing question

I'm writing literally billions of these so I guess it will be slower.
I'm planning on setting up a memory mapped file later on.
In any case, fewer calls should make things faster, I guess?
-totte
Alan Bellingham wrote:
Quote
Bob Gonder < XXXX@XXXXX.COM >wrote:

>Alex Bakaev [TeamB] wrote:
>>Remy Lebeau (TeamB) wrote:
>>
>>>fOut->write(&(aSample->sampleI), sizeof(*aSample)-1);
>>I wouldn't use the explicit -1, but rather sizeof of the first member.
>Or the sizes of the 2 fields actually being written.
>Both 1 and sizeof(firstfield) could be incorrect with alignment>1
>
>sizeof( *aSample ) - ( &aSample->sampleI - aSample )

Is it going to be appreciably slower to write the two elements
separately?

fOut->write(&(aSample->sampleI), sizeof(aSample->sampleI));
fOut->write(&(aSample->sampleQ), sizeof(aSample->sampleQ));

At least you can stop worrying about alignment at that point.

Alan Bellingham