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! :D



  • 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


Log in to reply