blib.c File Reference

Simplified Hierarchical Binary Library. More...

#include "ctl/ctldef.h"
#include "ctl/blib.h"

Include dependency graph for blib.c:

Go to the source code of this file.

Functions

uint32 BLIB_Size (const BLIB *lib)
 Return the size of a Library (measured in bytes).
uint32 BLIB_Count (const BLIB *lib)
 Return the (non-recursive) count of members in a Library.
uint32 BLIB_User (const BLIB *lib)
 Return the user identifier for a Library.
bool BLIB_Valid (const BLIB *lib, uint32 libSize)
 Validate this library's integrity.
uint32 BLIB_ElementSize (const BLIB *lib, int index)
 Return the size of an element in a library.
const void * BLIB_ElementPointer (const BLIB *lib, int index)
 Return a pointer to an element in a library.
uint32 BLIB_ElementCopyData (const BLIB *lib, int index, void *data, uint32 dataSize)
 Copy an element into a provided buffer.
BLIB * BLIB_Create (uint32 userID)
 Make a new Library.
BLIB * BLIB_Copy (const BLIB *lib)
 Make a copy of a library, such as a non-mutable library.
void BLIB_Destroy (BLIB **lib)
 Destroy a Library created by BLIB_Create or BLIB_Copy.
bool BLIB_ElementAdd (BLIB **lib, const void *data, uint32 dataSize)
 Add a library element to the end of the library.
bool BLIB_ElementReplace (BLIB **lib, int index, const void *data, uint32 dataSize)
 Change a library element DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy.
bool BLIB_ElementInsert (BLIB **lib, int index, const void *data, uint32 dataSize)
 Insert an element into the library at index DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy.
bool BLIB_ElementDelete (BLIB **lib, int index)
 Remove an element of the library DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy.


Detailed Description

Simplified Hierarchical Binary Library.

Author:
David Mace
BLIB gives some basic structure hierarchical binary data. It's up to the surrounding code to give the contents of BLIB meaning. This provides a simple mechanism for concatenating together lots of similar or dissimilar data and retrieving it again.

The BLIB format is not particularly portable. Unless all the same assumptions about word size and byte order and probably structure alignment are the same, the data will be invalid. This is intended for internal data files that are part of an application, rather than for data that will be exchanged. An example of such data might be user interface components, or binary resources for a file to configure and load at runtime.

BLIB elements may be of variable size BLIB data may be modified within library BLIB elements may contain additional BLIBs NOTE: If you are going to change a BLIB member of a BLIB, copy it, change it, then edit it back to its parent. BLIB does not presume to care what it's storing, so beware. BLIBs should only be edited if they are meant to be edited. BLIBs will load & save without any sort of pointer thunk. If you store data that also doesn't need a pointer thunk, then mapping data data into RAM/ROM will be the only step you need.

Definition in file blib.c.


Function Documentation

BLIB* BLIB_Copy ( const BLIB *  lib  ) 

Make a copy of a library, such as a non-mutable library.

Parameters:
lib Library to copy
Returns:
Clone of lib

Definition at line 187 of file blib.c.

References assert, BLIB_SIZE, and BLIB_VALID.

00188 {
00189     uint32 size;
00190     BLIB *pRet;
00191     assert( BLIB_VALID( lib ) );
00192     size = BLIB_SIZE( lib );
00193     pRet = (BLIB *)malloc(size);
00194     if( pRet )
00195         memcpy( pRet, lib, size );
00196     return pRet;
00197 }

uint32 BLIB_Count ( const BLIB *  lib  ) 

Return the (non-recursive) count of members in a Library.

Parameters:
lib Instance of lib
Returns:
count of lib members

Definition at line 55 of file blib.c.

References assert, BLIB_COUNT, and BLIB_VALID.

Referenced by GUI_BlibNeeds().

00056 {
00057     assert( BLIB_VALID( lib ) );
00058     return BLIB_COUNT( lib );
00059 }

BLIB* BLIB_Create ( uint32  userID  ) 

Make a new Library.

Parameters:
userID A 32 bit application defined identifier for this library's contents
Returns:
Pointer to an empty, new library

Definition at line 168 of file blib.c.

References BLIB_MAGIC.

00169 {
00170     /*  */
00171     BLIB *libRet = malloc( sizeof(BLIB) );
00172     if( libRet )
00173     {
00174         (*((uint32 *)(libRet->magic)) = *((uint32 *)BLIB_MAGIC));
00175         libRet->userID        = userID;
00176         libRet->count  = 0;
00177         libRet->offsets[0]     = sizeof(BLIB);
00178     }
00179     return libRet;
00180 }

void BLIB_Destroy ( BLIB **  lib  ) 

Destroy a Library created by BLIB_Create or BLIB_Copy.

Parameters:
lib Instance of lib DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy

Definition at line 204 of file blib.c.

References assert, and BLIB_VALID.

Referenced by BLIB_ElementDelete(), BLIB_ElementInsert(), and BLIB_ElementReplace().

00205 {
00206     assert( lib );
00207     if( BLIB_VALID( *lib ) )
00208     {
00209         free( *lib );
00210         *lib = NULL;
00211     }
00212 }

bool BLIB_ElementAdd ( BLIB **  lib,
const void *  data,
uint32  dataSize 
)

Add a library element to the end of the library.

Parameters:
lib Instance of lib
data data to add
dataSize size of data
Returns:
true on success DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy

Definition at line 222 of file blib.c.

References assert, assertconst, BLIB_COUNT, BLIB_ElementInsert(), and BLIB_VALID.

00223 {
00224     assert( lib );
00225     assert( BLIB_VALID( *lib ) );
00226     assert( data );
00227     assertconst( data, dataSize );
00228     return BLIB_ElementInsert( lib, BLIB_COUNT( *lib ), data, dataSize );
00229 }

Here is the call graph for this function:

uint32 BLIB_ElementCopyData ( const BLIB *  lib,
int  index,
void *  data,
uint32  dataSize 
)

Copy an element into a provided buffer.

Parameters:
lib Instance of lib
index Element index to get data from
data Pointer to buffer to receive the data
dataSize Size of data buffer
Returns:
Count of bytes copied.

Definition at line 145 of file blib.c.

References assert, assertconst, BLIB_ELEMENT_PTR, BLIB_ELEMENT_SIZE, BLIB_INDEX_VALID, and BLIB_VALID.

00146 {
00147     uint32 dwSize;
00148     const void *pElement;
00149     assert( BLIB_VALID( lib ) );
00150     assert( BLIB_INDEX_VALID( lib, index ) );
00151     assert( dataSize );
00152     assertconst( data, dataSize );
00153     dwSize = min( BLIB_ELEMENT_SIZE( lib, index ), dataSize );
00154     pElement = BLIB_ELEMENT_PTR( lib, index );
00155     memcpy( data, pElement, dwSize );
00156     return dwSize;
00157 }

bool BLIB_ElementDelete ( BLIB **  lib,
int  index 
)

Remove an element of the library DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy.

Parameters:
lib Pointer to library's pointer you wish to change; returns changed pointer here
index Index of member we're removing
Returns:
true on success

Definition at line 375 of file blib.c.

References assert, BLIB_Destroy(), BLIB_ELEMENT_PTR, BLIB_ELEMENT_SIZE, BLIB_INDEX_VALID, BLIB_SIZE, and BLIB_VALID.

00376 {
00377     /* Remove an element from the library */
00378     assert( BLIB_VALID( *lib ) );
00379     assert( BLIB_INDEX_VALID( *lib, index ) );
00380     assert( (*lib)->count );
00381 
00382     {
00383         int curr;
00384         uint32 dwSizeIn  = BLIB_SIZE(*lib);
00385         BLIB *libIn      = *lib;
00386         uint32 dwSizeOut = dwSizeIn - (BLIB_ELEMENT_SIZE( libIn, index ) + sizeof(uint32));
00387         BLIB *libOut     = malloc( dwSizeOut );
00388         if( !libOut )
00389             return false;
00390 
00391         /* Copy original data */
00392         *libOut = *libIn;
00393         libOut->count--;
00394         dwSizeOut = sizeof( BLIB ) + (libOut->count * sizeof(uint32) );
00395 
00396         /* Copy over any unaffected items */
00397         for( curr = 0; curr < index; ++curr )
00398         {
00399             libOut->offsets[curr] = dwSizeOut;
00400             dwSizeOut += BLIB_ELEMENT_SIZE(libIn, curr);
00401             memcpy( BLIB_ELEMENT_PTR(libOut, curr), BLIB_ELEMENT_PTR(libIn, curr), BLIB_ELEMENT_SIZE(libIn, curr) );
00402         }
00403         
00404         /* Copy over any unaffected items */
00405         for( curr = index + 1; curr < (int)libIn->count; ++curr )
00406         {
00407             libOut->offsets[curr-1] = dwSizeOut;
00408             dwSizeOut += BLIB_ELEMENT_SIZE(libIn, curr);
00409             memcpy( BLIB_ELEMENT_PTR(libOut, curr-1), BLIB_ELEMENT_PTR(libIn, curr), BLIB_ELEMENT_SIZE(libIn, curr) );
00410         }
00411         libOut->offsets[curr-1] = dwSizeOut;
00412 
00413         /* Destroy the input library */
00414         BLIB_Destroy( &libIn );
00415 
00416         /* Return the output library */
00417         *lib = libOut;
00418     }
00419     return true;
00420 }

Here is the call graph for this function:

bool BLIB_ElementInsert ( BLIB **  lib,
int  index,
const void *  data,
uint32  dataSize 
)

Insert an element into the library at index DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy.

Parameters:
lib Pointer to library's pointer you wish to change; returns changed pointer here
index Index of member we're inserting before
data Data to insert
dataSize Size of new data
Returns:
true on success

Definition at line 315 of file blib.c.

References assert, assertconst, BLIB_COUNT, BLIB_Destroy(), BLIB_ELEMENT_PTR, BLIB_ELEMENT_SIZE, BLIB_SIZE, and BLIB_VALID.

Referenced by BLIB_ElementAdd().

00316 {
00317     assert( lib );
00318     assert( BLIB_VALID( *lib ) );
00319     assert( index >= 0 && index <= (int)BLIB_COUNT( *lib ) );
00320     assert( data );
00321     assertconst( data, dataSize );
00322 
00323     {
00324         int curr;
00325         uint32 dwSizeIn  = BLIB_SIZE(*lib);
00326         BLIB *libIn      = *lib;
00327         uint32 dwSizeOut = dwSizeIn + dataSize + sizeof(uint32);
00328         BLIB *libOut     = malloc( dwSizeOut );
00329         if( !libOut )
00330             return false;
00331 
00332         /* Copy original data */
00333         *libOut = *libIn;
00334         libOut->count++;
00335         dwSizeOut = sizeof( BLIB ) + (libOut->count * sizeof(uint32) );
00336 
00337         /* Copy over any unaffected items */
00338         for( curr = 0; curr < index; ++curr )
00339         {
00340             libOut->offsets[curr] = dwSizeOut;
00341             dwSizeOut += BLIB_ELEMENT_SIZE(libIn, curr);
00342             memcpy( BLIB_ELEMENT_PTR(libOut, curr), BLIB_ELEMENT_PTR(libIn, curr), BLIB_ELEMENT_SIZE(libIn, curr) );
00343         }
00344 
00345         /* Copy the new data */
00346         libOut->offsets[index] = dwSizeOut;
00347         dwSizeOut += dataSize;
00348         memcpy( BLIB_ELEMENT_PTR(libOut, index), data, dataSize );
00349         
00350         /* Copy over any unaffected items */
00351         for( curr = index; curr < (int)libIn->count; ++curr )
00352         {
00353             libOut->offsets[curr+1] = dwSizeOut;
00354             dwSizeOut += BLIB_ELEMENT_SIZE(libIn, curr);
00355             memcpy( BLIB_ELEMENT_PTR(libOut, curr+1), BLIB_ELEMENT_PTR(libIn, curr), BLIB_ELEMENT_SIZE(libIn, curr) );
00356         }
00357         libOut->offsets[curr+1] = dwSizeOut;
00358 
00359         /* Destroy the input library */
00360         BLIB_Destroy( &libIn );
00361 
00362         /* Return the output library */
00363         *lib = libOut;
00364     }
00365     return true;
00366 }

Here is the call graph for this function:

const void* BLIB_ElementPointer ( const BLIB *  lib,
int  index 
)

Return a pointer to an element in a library.

Parameters:
lib Instance of lib
index Element index to get pointer to
Returns:
pointer to element

Definition at line 129 of file blib.c.

References assert, BLIB_ELEMENT_PTR, BLIB_INDEX_VALID, and BLIB_VALID.

00130 {
00131     /* Return a pointer to an element in a library */
00132     assert( BLIB_VALID( lib ) );
00133     assert( BLIB_INDEX_VALID( lib, index ) );
00134     return BLIB_ELEMENT_PTR( lib, index );
00135 }

bool BLIB_ElementReplace ( BLIB **  lib,
int  index,
const void *  data,
uint32  dataSize 
)

Change a library element DO NOT use on any library which was not created by BLIB_Create or BLIB_Copy.

Parameters:
lib Pointer to library's pointer you wish to change; returns changed pointer here
index Index of member to change
data Data to replace existing content
dataSize Size of new replacement data
Returns:
true on success

Definition at line 240 of file blib.c.

References assert, assertconst, BLIB_Destroy(), BLIB_ELEMENT_PTR, BLIB_ELEMENT_SIZE, BLIB_INDEX_VALID, BLIB_SIZE, and BLIB_VALID.

00241 {
00242     assert( lib );
00243     assert( BLIB_VALID( *lib ) );
00244     assert( BLIB_INDEX_VALID( *lib, index ) );
00245     assert( data );
00246     assert( dataSize > 0 );
00247     assertconst( data, dataSize );
00248 
00249     {
00250         int32 lDiff      = dataSize - BLIB_ELEMENT_SIZE( *lib, index );
00251         /* Though it's tempting not to reallocate the return if it's smaller, that could allow memory to slowly  */
00252         /* bleed as Libraries change items. */
00253         if( lDiff )
00254         {
00255             /* Size of output will change */
00256             int curr;
00257             uint32 dwSizeIn  = BLIB_SIZE(*lib);
00258             BLIB *libIn      = *lib;
00259             uint32 dwSizeOut = dwSizeIn + lDiff;
00260             BLIB *libOut     = lDiff ? malloc( dwSizeOut ) : libIn;
00261             if( !libOut )
00262                 return false;
00263             /* Copy original data */
00264             *libOut = *libIn;
00265             dwSizeOut = sizeof( BLIB ) + (libOut->count * sizeof(uint32) );
00266 
00267             /* Copy over any unaffected items */
00268             for( curr = 0; curr < index; ++curr )
00269             {
00270                 libOut->offsets[curr] = dwSizeOut;
00271                 dwSizeOut += BLIB_ELEMENT_SIZE(libIn, curr);
00272                 memcpy( BLIB_ELEMENT_PTR(libOut, curr), BLIB_ELEMENT_PTR(libIn, curr), BLIB_ELEMENT_SIZE(libIn, curr) );
00273             }
00274 
00275             /* Copy the new data */
00276             libOut->offsets[index] = dwSizeOut;
00277             dwSizeOut += dataSize;
00278             memcpy( BLIB_ELEMENT_PTR(libOut, index), data, dataSize );
00279 
00280             /* Copy over any unaffected items */
00281             for( curr = index + 1; curr < (int)libIn->count; ++curr )
00282             {
00283                 libOut->offsets[curr] = dwSizeOut;
00284                 dwSizeOut += BLIB_ELEMENT_SIZE(libIn, curr);
00285                 memcpy( BLIB_ELEMENT_PTR(libOut, curr), BLIB_ELEMENT_PTR(libIn, curr), BLIB_ELEMENT_SIZE(libIn, curr) );
00286             }
00287             libOut->offsets[curr] = dwSizeOut;
00288 
00289             /* Destroy the input library */
00290             BLIB_Destroy( &libIn );
00291 
00292             /* Return the output library */
00293             *lib = libOut;
00294         }
00295         else
00296         {
00297             /* Size unchanged, just copy the data */
00298             memcpy( BLIB_ELEMENT_PTR(*lib,index), data, dataSize );
00299         }
00300     }
00301 
00302     /* Success */
00303     return true;
00304 }

Here is the call graph for this function:

uint32 BLIB_ElementSize ( const BLIB *  lib,
int  index 
)

Return the size of an element in a library.

Parameters:
lib Instance of lib
index Element index to get size of
Returns:
size of element

Definition at line 116 of file blib.c.

References assert, BLIB_ELEMENT_SIZE, BLIB_INDEX_VALID, and BLIB_VALID.

00117 {
00118     assert( BLIB_VALID( lib ) );
00119     assert( BLIB_INDEX_VALID( lib, index ) );
00120     return BLIB_ELEMENT_SIZE( lib, index );
00121 }

uint32 BLIB_Size ( const BLIB *  lib  ) 

Return the size of a Library (measured in bytes).

Parameters:
lib Instance of lib
Returns:
size of lib

Definition at line 44 of file blib.c.

References assert, BLIB_SIZE, and BLIB_VALID.

00045 {
00046     assert( BLIB_VALID( lib ) );
00047     return BLIB_SIZE( lib );
00048 }

uint32 BLIB_User ( const BLIB *  lib  ) 

Return the user identifier for a Library.

Parameters:
lib Instance of lib
Returns:
size user ID

Definition at line 66 of file blib.c.

References assert, BLIB_USER, and BLIB_VALID.

Referenced by GUI_BlibInit(), and GUI_BlibNeeds().

00067 {
00068     /*  */
00069     assert( BLIB_VALID( lib ) );
00070     return BLIB_USER( lib );
00071 }

bool BLIB_Valid ( const BLIB *  lib,
uint32  libSize 
)

Validate this library's integrity.

Parameters:
lib Instance of lib
libSize Suspected size of library; if this is non-zero, will perform more thorough checking.
Returns:
true if valid, false if there's some problem.

Definition at line 79 of file blib.c.

References BLIB_SIZE, and BLIB_VALID.

Referenced by GUI_BlibInit(), and GUI_BlibNeeds().

00080 {
00081 
00082     /* Intended for verification of file or resource load. */
00083     if( !BLIB_VALID( lib ) )
00084         return false;
00085 
00086     /* Does first index measure out correctly according to element count? */
00087     if( lib->offsets[0] != sizeof(BLIB) + (lib->count * sizeof(uint32)) )
00088         return false;
00089     
00090     if( libSize )
00091     {
00092         uint32 curr;
00093 
00094         /* If we have a size, check it against our calculated size */
00095         if( BLIB_SIZE( lib ) != libSize )
00096             return false;
00097 
00098         /* Walk through members to see if they overlap */
00099         for( curr = lib->count; curr; --curr )
00100         {
00101             if( lib->offsets[curr] < lib->offsets[curr - 1] )
00102             {
00103                 return false;
00104             }
00105         }
00106     }
00107     return true;
00108 }


Generated on Fri Jan 2 15:28:35 2009 for Squat by  doxygen 1.5.6