there is both way i saw.
1. stream is pretty easily and (!) flexible.
i like flexible structures.
format this:
1. block id: 4 byte
2. block size 4 byte;
3. blockdata. (exactly blocksize)
so if you read this file and encounter unknown block just read size and jump on next block.
in my sharemem files i made first block-header where is stored filesize and blockscount (for users who like for...next structure

)
but fixed structure is also can be done. with some advantages. and this also can be flexible
just open sharefile as version 1, then check version and then reopen as version 2. all is easilly.
take a look this example for RivaTuner:
// v1.0 header
- Code: Select All Code
type PRTHM_SHARED_MEMORY_HEADER_V_1_0=^TRTHM_SHARED_MEMORY_HEADER_V_1_0;
TRTHM_SHARED_MEMORY_HEADER_V_1_0=record
Signature:TSignature;//array [0..3] of char ; //dword
//signature allows applications to verify status of shared memory
//The signature can be set to:
//'RTHM' - hardware monitoring memory is initialized and contains
// valid data
//0xDEAD - hardware monitoring memory is marked for deallocation and
// no longer contain valid data
//otherwise the memory is not initialized
Version:DWORD ;
//header version ((major<<16) + minor)
//must be set to 0x00010000 for v1.0 header
ItemsCount:DWORD ;
//number of subsequent RTHM_SHARED_MEMORY_ENTRY_V_1_0 entries
time:dword;//time_t ;
//last polling time
end;
type PRTHM_SHARED_MEMORY_HEADER=^TRTHM_SHARED_MEMORY_HEADER;
TRTHM_SHARED_MEMORY_HEADER= record
Signature:TSignature;//array [0..3] of char ; //dword
//signature allows applications to verify status of shared memory
//The signature can be set to:
//'RTHM' - hardware monitoring memory is initialized and contains
// valid data
//0xDEAD - hardware monitoring memory is marked for deallocation and
// no longer contain valid data
//otherwise the memory is not initialized
Version:DWORD ;
//header version ((major<<16) + minor)
//must be set to 0x00010001 or greater to use this structure
ItemsCount:DWORD ;
//number of subsequent RTHM_SHARED_MEMORY_ENTRY entries
time:dword;//time_t ;
//last polling time
ItemSize:dword;
//size of entries in subsequent RTHM_SHARED_MEMORY_ENTRY entries array
end;
in this sharemem file all data except header placed in block of same size. just read Itemsie and parse whole file by for-next. (for first version it was 40 bytes fixed)
----------------
i used both way at one time.
block structure with blockID and blockSize. but some blocks just raw data which must be read byte to byte, and some others blocks is fixed structure.
this is causing dificulties when some block make longer than it was before. so only one application can write block of variable size. well... or place flag in header "now writing"
in my sharemem when my applet writing this block of unknown size if make its header as "end of file block" and after write completed change it ID to right and continue writing next block.
very easy way for you is this:
1. sighature: 4 byte = XION
2. version of sharedata: 4 byte = 1; (00 00 00 01)
3. full time of cur song: 4 byte (milliseconds)
4. played time of cur song: 4 byte (milliseconds)
5. zeroterminated ansi string
no ending block needed, just #0.
when you decide to change sharemem structure just change block 2 to "2" (00 00 00 02)
this will mean that following data is placed in other order.
i know, after first implementation there will be request for more and more features, so changing inner structure is possible. may i will request by muself to place into this file spectrum to visualization.
as far as i tested there is no bugs issued with very fast sharemem acces. (but i use only reading from)
my applet create sharemem file for read-write. so you player can take direct acces to my applet and draw visualization on background without any my attention.
