HyperFile chunks

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 28/11/2006 at 05:45, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   9.6 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
Hello,

I'm trying to store and retrieve my plugin information into a c4d file. I need to use chunks (I know we're discouraged, but I'm afraid its a must).

My problem lies in the chunk IDs, I think I'm saving them properly with:

LONG id = ...
m_pHyperFile->WriteChunkStart(id, 0);
m_pHyperFile->WriteChunkEnd();

but when my plugin is being loaded, I'm not able to retrieve those chunk IDs:

LONG chunkID, level;
Bool res = m_pHyperFile->ReadChunkStart(&chunkID;, &level;);
if (res == TRUE && level == 0)
{
    my chunk ID is weird here!, for instance, if I was supposed to retrieve a ID = 512, I get chunkID = 16777218 (0x1000002 hex)
}

Then I keep on searching (closing the chunk with SkipToEndChunk and ReadChunkEnd), but none of my chunks shows up.

Any idea or any obviousness I'm missing? this is quite frustrating 😞

Thanks in advance!

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 28/11/2006 at 10:20, xxxxxxxx wrote:

Well seems i've got a hint on what's going on:

the problem lies in the 'endianness' of the values! in fact, i've got to convert both chunk id and level to big endian (i'm working on an windows/intel platform) before saving them in the hyperfile:

HyperFile* hf;
LONG c_ = ReverseEndianness(c);
LONG l_ = ReverseEndianness(l);
hf->WriteChunkStart(c_, l_);

And then, to retrieve them back, the values look like:

hf->ReadChunkStart(&id;, &level;)
(extract from a heavy chunk/level loop dump)
CHUNK_ID (14) --> I read id = 0x010e00
LEVEL (4) --> I read id = 0x00040000

So they seem to be in reversed endian order again, and we need to discard the last 2 bytes, which are 01 for the chunk id and 00 for the level. This lies in:

LONG recovered_id = (ReverseEndianness(id) & 0xFFFFFF00) >> 8;
LONG recovered_level = (ReverseEndianness(level) & 0XFFFFFF00) >> 8;

(Wow), this looks like a rather manual and low-level way of working, I wonder if the file format will always remain the same... or this won't work! 😄

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 28/11/2006 at 11:50, xxxxxxxx wrote:

Aagh, however it isn't loading ANYTHING from inside a chunk!, no matter what ReadXXXX call I use...

It is working when the data isn't inside a chunk...

What's wrong with chunks? 😞

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 29/11/2006 at 10:59, xxxxxxxx wrote:

Well, I finally figured out how to make chunks work

All of the following are my guesses based on some trial-and-error happy hours 🙂 I'm just posting it here in the hope of saving this exciting process to someone!

It seems the chunk id's i was reading are actually made of 2 fields: the first 2 bytes are the 'header', and the following 6 are the value itself. So the following code (which is on the sdk) retrieves the id and level correctly:

  
UCHAR h;  
Bool res;  
LONG chunkID, level;  
m_pHyperFile->ReadValueHeader(&h;); // this erases the first 2 bytes, making the >> 8 bit shifting unnecessary  
if (h == HFILE_START) res = m_pHyperFile->ReadChunkStart(&chunkID;, &level;);       
lSwap(&chunkID;); // reverse the endianness (working on   
lSwap(&level;);   // an Intel/PC)  

so strange conversions are no longer needed 🙂

however, this code only applies to chunk headers, since I haven't managed to check for another types, say a LONG, for instance.

  
UCHAR h;  
m_pHyperFile->ReadValueHeader(&h;);   
if (h == HFILE_LONG)  
{  
   LONG l;  
   Bool res = m_pHyperFile->ReadLong(&l;); // will return false despite l is supposed to be a long!  
}  

my second problem was I wasn't able to load anything from inside a chunk, no mattered what kind of data it was. Well, it was due to the combination of not reading the chunk header and the way I was closing the chunks:

  
<wrong code>  
Bool res = m_pHyperFile->SkipToEndChunk();  
res &= m_pHyperFile->ReadChunkEnd();  

And it started to work when i *removed* the second line, ReadChunkEnd(), closing a chunk by just Skipping to its end.

The important thing is it is working now 🙂
Cheers