00001
00030 #include "ctl/ctldef.h"
00031 #include "ctl/blib.h"
00032
00033 #ifndef CTL_UNIT
00034
00035
00036
00037
00038
00044 uint32 BLIB_Size( const BLIB *lib )
00045 {
00046 assert( BLIB_VALID( lib ) );
00047 return BLIB_SIZE( lib );
00048 }
00049
00055 uint32 BLIB_Count( const BLIB *lib )
00056 {
00057 assert( BLIB_VALID( lib ) );
00058 return BLIB_COUNT( lib );
00059 }
00060
00066 uint32 BLIB_User( const BLIB *lib )
00067 {
00068
00069 assert( BLIB_VALID( lib ) );
00070 return BLIB_USER( lib );
00071 }
00072
00079 bool BLIB_Valid( const BLIB *lib, uint32 libSize )
00080 {
00081
00082
00083 if( !BLIB_VALID( lib ) )
00084 return false;
00085
00086
00087 if( lib->offsets[0] != sizeof(BLIB) + (lib->count * sizeof(uint32)) )
00088 return false;
00089
00090 if( libSize )
00091 {
00092 uint32 curr;
00093
00094
00095 if( BLIB_SIZE( lib ) != libSize )
00096 return false;
00097
00098
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 }
00109
00116 uint32 BLIB_ElementSize( const BLIB *lib, int index )
00117 {
00118 assert( BLIB_VALID( lib ) );
00119 assert( BLIB_INDEX_VALID( lib, index ) );
00120 return BLIB_ELEMENT_SIZE( lib, index );
00121 }
00122
00129 const void *BLIB_ElementPointer( const BLIB *lib, int index )
00130 {
00131
00132 assert( BLIB_VALID( lib ) );
00133 assert( BLIB_INDEX_VALID( lib, index ) );
00134 return BLIB_ELEMENT_PTR( lib, index );
00135 }
00136
00145 uint32 BLIB_ElementCopyData( const BLIB *lib, int index, void *data, uint32 dataSize )
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 }
00158
00159
00160
00161
00162
00168 BLIB *BLIB_Create( uint32 userID )
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 }
00181
00187 BLIB *BLIB_Copy( const BLIB *lib )
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 }
00198
00204 void BLIB_Destroy( BLIB **lib )
00205 {
00206 assert( lib );
00207 if( BLIB_VALID( *lib ) )
00208 {
00209 free( *lib );
00210 *lib = NULL;
00211 }
00212 }
00213
00222 bool BLIB_ElementAdd( BLIB **lib, const void *data, uint32 dataSize )
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 }
00230
00240 bool BLIB_ElementReplace( BLIB **lib, int index, const void *data, uint32 dataSize )
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
00252
00253 if( lDiff )
00254 {
00255
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
00264 *libOut = *libIn;
00265 dwSizeOut = sizeof( BLIB ) + (libOut->count * sizeof(uint32) );
00266
00267
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
00276 libOut->offsets[index] = dwSizeOut;
00277 dwSizeOut += dataSize;
00278 memcpy( BLIB_ELEMENT_PTR(libOut, index), data, dataSize );
00279
00280
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
00290 BLIB_Destroy( &libIn );
00291
00292
00293 *lib = libOut;
00294 }
00295 else
00296 {
00297
00298 memcpy( BLIB_ELEMENT_PTR(*lib,index), data, dataSize );
00299 }
00300 }
00301
00302
00303 return true;
00304 }
00305
00315 bool BLIB_ElementInsert( BLIB **lib, int index, const void *data, uint32 dataSize )
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
00333 *libOut = *libIn;
00334 libOut->count++;
00335 dwSizeOut = sizeof( BLIB ) + (libOut->count * sizeof(uint32) );
00336
00337
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
00346 libOut->offsets[index] = dwSizeOut;
00347 dwSizeOut += dataSize;
00348 memcpy( BLIB_ELEMENT_PTR(libOut, index), data, dataSize );
00349
00350
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
00360 BLIB_Destroy( &libIn );
00361
00362
00363 *lib = libOut;
00364 }
00365 return true;
00366 }
00367
00375 bool BLIB_ElementDelete( BLIB **lib, int index )
00376 {
00377
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
00392 *libOut = *libIn;
00393 libOut->count--;
00394 dwSizeOut = sizeof( BLIB ) + (libOut->count * sizeof(uint32) );
00395
00396
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
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
00414 BLIB_Destroy( &libIn );
00415
00416
00417 *lib = libOut;
00418 }
00419 return true;
00420 }
00421
00422 #else
00423
00424 #include "unit/unit.h"
00425
00426
00427 const char *TestJunk[] = {
00428 "1SPORK",
00429 "2FOON",
00430 "3FOO",
00431 "4BAR",
00432 "5BAZ",
00433 "6NI",
00434 "76543210",
00435 NULL
00436 };
00437
00438 void Test_BLIB(void)
00439 {
00440 {
00441
00442
00443
00444 int curr, count;
00445 BLIB *lib = BLIB_Create( *((uint32 *)"SPAM") );
00446 Test_Error( BLIB_Valid( lib, BLIB_Size(lib) ) );
00447 for( curr = 0; TestJunk[curr]; ++curr )
00448 {
00449 BLIB_ElementAdd( &lib, TestJunk[curr], strlen( TestJunk[curr] ) + 1 );
00450 Test_Error( BLIB_Valid( lib, BLIB_Size(lib) ) );
00451 }
00452 Test_Error( BLIB_Count( lib ) == countof(TestJunk)-1 );
00453
00454
00455
00456 count = BLIB_Count( lib );
00457 for( curr = 0; curr < count; ++curr )
00458 {
00459 Test_Error( !strcmp(TestJunk[curr], BLIB_ElementPointer( lib, curr ) ) );
00460 }
00461
00462
00463
00464
00465 BLIB_ElementDelete( &lib, 2 );
00466 BLIB_ElementDelete( &lib, 1 );
00467 BLIB_ElementDelete( &lib, 0 );
00468 count = BLIB_Count( lib );
00469 for( curr = 0; curr < count; ++curr )
00470 {
00471 Test_Error( !strcmp(TestJunk[curr+3], BLIB_ElementPointer( lib, curr ) ) );
00472 Test_Error( BLIB_Valid( lib, BLIB_Size(lib) ) );
00473 }
00474
00475
00476
00477
00478 for( curr = 0; curr < 3; ++curr )
00479 {
00480 BLIB_ElementInsert( &lib, 0, TestJunk[curr], strlen( TestJunk[curr] ) + 1 );
00481 Test_Error( BLIB_Valid( lib, BLIB_Size(lib) ) );
00482 }
00483
00484
00485
00486
00487
00488 BLIB_ElementReplace( &lib, 2, "ZAP! ZAP!", strlen("ZAP! ZAP!") + 1 );
00489 Test_Error( BLIB_Valid( lib, BLIB_Size(lib) ) );
00490 BLIB_ElementReplace( &lib, 0, "PING! PING!", strlen("PING! PING!") + 1 );
00491 Test_Error( BLIB_Valid( lib, BLIB_Size(lib) ) );
00492 count = BLIB_Count( lib );
00493 for( curr = 0; curr < count; ++curr )
00494 {
00495 if( curr == 0 )
00496 {
00497 Test_Error( !strcmp("PING! PING!", BLIB_ElementPointer( lib, curr ) ) );
00498 }
00499 else if( curr == 2 )
00500 {
00501 Test_Error( !strcmp("ZAP! ZAP!", BLIB_ElementPointer( lib, curr ) ) );
00502 }
00503 else
00504 Test_Error( !strcmp(TestJunk[curr], BLIB_ElementPointer( lib, curr ) ) );
00505 }
00506
00507 BLIB_Destroy( &lib );
00508 }
00509 {
00510
00511
00512
00513 int curr,rcurr, count;
00514 BLIB *lib = BLIB_Create( *((uint32 *)"FOON") );
00515 for( curr = 0; TestJunk[curr]; ++curr )
00516 {
00517 BLIB_ElementInsert( &lib, 0, TestJunk[curr], strlen( TestJunk[curr] ) + 1 );
00518 Test_Error( BLIB_Valid( lib, 0 ) );
00519 }
00520 Test_Error( BLIB_Count( lib ) == countof(TestJunk)-1 );
00521
00522
00523
00524 count = BLIB_Count( lib );
00525 for( curr = 0, rcurr = countof(TestJunk)-2; curr < count; ++curr, --rcurr )
00526 {
00527 Test_Error( !strcmp(TestJunk[rcurr], BLIB_ElementPointer( lib, curr ) ) );
00528 }
00529
00530 BLIB_Destroy( &lib );
00531 }
00532
00533
00534 }
00535
00536
00537 #endif
00538