Board index » cppbuilder » Using TStream and Structures

Using TStream and Structures


2007-04-04 05:12:01 AM
cppbuilder97
Hello, could someone help me in reading data from a TStream into a
structure. The following code is what I am trying to do.
I have the following structure ( which represents a record type within an
emf file )
typedef struct tagSPLHEADER {
DWORD SIGNATURE;
DWORD nSize; // record size INCLUDING header
DWORD offDocumentName; // offset of Job Title from start
DWORD offPort; // offset of portname from start
BYTE HeaderData[];
} SPL_HEADER, *PSPL_HEADER;
#define MAX_BUFFER 5000 // 5K of data at a time
BYTE stbuffer[MAX_BUFFER];
So I am trying to read data from the file into this structure. The following
gets my data into a buffer but now I do not know how to get the data into
the structure.
TFileStream *Filestrm = new TFileStream( "InputFile.spl",
fmOpenRead | fmShareExclusive ) ;
size = Filestrm->Read( stbuffer, sizeof ( SPL_HEADER ) ) ;
So if I check stBuffer it has 16 bytes of data, but I would like to have
this data in the structure defined above.
Thank you for any help which may be provided.
Mike
 
 

Re:Using TStream and Structures

mike wrote:
Quote
So if I check stBuffer it has 16 bytes of data, but I would like to have
this data in the structure defined above.
Until now you still have no structure. Only a typedef. So first make
a structure:
SPL_HEADER spl_header = {0};
Then you could as well directly read from file in that structure:
size = Filestrm->Read( &spl_header, sizeof ( SPL_HEADER ) ) ;
Quote
typedef struct tagSPLHEADER {
DWORD SIGNATURE;
DWORD nSize; // record size INCLUDING header
DWORD offDocumentName; // offset of Job Title from start
DWORD offPort; // offset of portname from start
BYTE HeaderData[];
} SPL_HEADER, *PSPL_HEADER;

Now about how you did define your structure.
What should BYTE HeaderData[]; be?
That does not declare any space as the whole structure is 16 bytes for
four DWORD's.
Hans.
 

Re:Using TStream and Structures

Hans,
Thank you for replying. Yes I should have known about the definition of the
structure. To many long days and little sleep.
This is a structure that is defined for emf files. The BYTE HeaderData[];
is a variable length and its starting position is defined in the DWORD
offDocumentName. The overall length of the header record id defined in the
DWORD nSize;. So to find the size of the HeaderData a calculation must be
made.
So based upon that is there a way to better define the structure.
Thanks
Mike
"Hans Galema" < XXXX@XXXXX.COM >wrote in message
Quote
mike wrote:

>So if I check stBuffer it has 16 bytes of data, but I would like to have
>this data in the structure defined above.

Until now you still have no structure. Only a typedef. So first make
a structure:

SPL_HEADER spl_header = {0};

Then you could as well directly read from file in that structure:

size = Filestrm->Read( &spl_header, sizeof ( SPL_HEADER ) ) ;

>typedef struct tagSPLHEADER {
>DWORD SIGNATURE;
>DWORD nSize; // record size INCLUDING header
>DWORD offDocumentName; // offset of Job Title from start
>DWORD offPort; // offset of portname from start
>BYTE HeaderData[];
>} SPL_HEADER, *PSPL_HEADER;
>

Now about how you did define your structure.

What should BYTE HeaderData[]; be?

That does not declare any space as the whole structure is 16 bytes for
four DWORD's.

Hans.
 

{smallsort}

Re:Using TStream and Structures

"mike" < XXXX@XXXXX.COM >wrote in message
Quote
Hello, could someone help me in reading data from a
TStream into a structure.
TFileStream *Filestrm = new TFileStream("InputFile.spl",
fmOpenRead | fmShareDenyWrite);
DWORD signature;
if( Filestrm->Read(&signature, sizeof(DWORD)) ==
sizeof(signature) )
{
if( signature == ... )
{
DWORD size;
if( Filestrm->Read(&size, sizeof(DWORD)) ==
sizeof(DWORD) )
{
BYTE *buffer = new BYTE[size];
PSPL_HEADER pHdr = (PSPL_HEADER) buffer;
pHdr->SIGNATURE = signature;
pHdr->nSize = size;
size -= 8;
if( Filestrm->Read(&buffer[8], size) == size )
{
// use pHdr as needed...
}
delete[] buffer;
}
else
// unable to read record size ...
}
else
// not a valid spl file ...
}
else
// unable to read signature ...
Alternatively, you can do away with the TFileStream altogether and
access the file data directly instead:
HANDLE hFile = CreateFile("InputFile.spl", GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if( hFile != INVALID_HANDLE_VALUE )
{
DWORD dwSize = GetFileSize(hFile, NULL);
if( (dwSize != 0xFFFFFFFF) && (dwSize>= 16) )
{
HANDLE hMapping = CreateFileMapping(hFile, NULL,
PAGE_READONLY, 0, dwSize, NULL);
if( hMapping != NULL )
{
PSPL_HEADER pHdr = (PSPL_HEADER)
MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, dwSize);
if( pHdr )
{
if( pHdr->SIGNATURE == ... )
{
if( pHdr->nSize <= dwSize )
{
// use pHdr as needed ...
}
else
// invalid record size ...
}
else
// not a valid spl file ...
UnmapViewOfFile(pHdr);
}
CloseHandle(hMapping);
}
}
CloseHandle(hFile);
}
Gambit
 

Re:Using TStream and Structures

mike wrote:
Quote
So based upon that is there a way to better define the structure.
Please trim your reply's.
You did not reply on Remy's proposal so it is only guessing if
you still need help.
I would do away with the HeaderData member.
Just write the structure to file and then after it the data.
When reading from file first read the structure, determine size
and then read size bytes of data that you place somewhere.
Hans.