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 = 0x00040000So 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