00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <assert.h>
00031 #include <stdio.h>
00032
00033 #include "TKEvents.h"
00034 #include "TKArray.h"
00035 #include "ErrorLog.h"
00036 #include "ram.h"
00037 #include "string.h"
00038
00039 typedef struct
00040 {
00041 geTKEvents_TimeType EventTime;
00042 uint32 DataOffset;
00043 } EventType;
00044
00045 typedef struct geTKEventsIterator
00046 {
00047 geTKEvents_TimeType EndTime;
00048 int CurrentIndex;
00049 } geTKEventsIterator;
00050
00051 typedef struct geTKEvents
00052 {
00053 geTKArray* pTimeKeys;
00054 uint32 DataSize;
00055 char* pEventData;
00056
00057 geTKEventsIterator Iterator;
00058 } geTKEvents;
00059
00060
00061
00062
00063
00064 #ifdef _DEBUG
00065
00066 #define TKE_ASSERT_VALID(E) geTKEvents_Asserts(E)
00067
00068
00069 static void GENESISCC geTKEvents_Asserts(const geTKEvents* E)
00070 {
00071 assert( (E) != NULL );
00072 assert( (E)->pTimeKeys != NULL );
00073 if(geTKArray_NumElements((E)->pTimeKeys) == 0)
00074 {
00075 assert( (E)->pEventData == NULL );
00076 }
00077 else
00078 {
00079 assert( (E)->pEventData != NULL );
00080 }
00081 }
00082
00083 #else // !_DEBUG
00084
00085 #define TKE_ASSERT_VALID(E) ((void)0)
00086
00087 #endif // _DEBUG
00088
00089 geTKEvents* GENESISCC geTKEvents_Create(void)
00090
00091 {
00092 geTKEvents* pEvents;
00093
00094 pEvents = GE_RAM_ALLOCATE_STRUCT(geTKEvents);
00095 if(!pEvents)
00096 {
00097 geErrorLog_Add(ERR_TKEVENTS_CREATE_ENOMEM, NULL);
00098 return NULL;
00099 }
00100
00101 pEvents->pTimeKeys = geTKArray_Create(sizeof(EventType));
00102 if(!pEvents->pTimeKeys)
00103 {
00104 geErrorLog_Add(ERR_TKEVENTS_CREATE_ENOMEM, NULL);
00105 geRam_Free(pEvents);
00106 return NULL;
00107 }
00108
00109 pEvents->DataSize = 0;
00110 pEvents->pEventData = NULL;
00111
00112 pEvents->Iterator.CurrentIndex = 0;
00113 pEvents->Iterator.EndTime = -99e33f;
00114
00115 return pEvents;
00116 }
00117
00118
00119 void GENESISCC geTKEvents_Destroy(geTKEvents** ppEvents)
00120
00121 {
00122 geTKEvents* pE;
00123
00124 assert(ppEvents);
00125 pE = *ppEvents;
00126 assert(pE);
00127
00128 if( pE->pEventData != NULL )
00129 {
00130 geRam_Free(pE->pEventData);
00131 }
00132
00133 if (pE->pTimeKeys != NULL)
00134 {
00135 geTKArray_Destroy(&pE->pTimeKeys);
00136 }
00137 geRam_Free(*ppEvents);
00138 *ppEvents = NULL;
00139 }
00140
00141
00142 geBoolean GENESISCC geTKEvents_Insert(geTKEvents* pEvents, geTKEvents_TimeType tKey, const char* pEventData)
00143 {
00144 int nIndex;
00145 uint32 DataLength;
00146 uint32 InitialOffset;
00147 int nNumElements;
00148 EventType* pKeyInfo;
00149 char* pNewData;
00150
00151 TKE_ASSERT_VALID(pEvents);
00152
00153 if( geTKArray_Insert(&pEvents->pTimeKeys, tKey, &nIndex) != GE_TRUE )
00154 {
00155 geErrorLog_Add(ERR_TKEVENTS_INSERT, NULL);
00156 return GE_FALSE;
00157 }
00158 pKeyInfo = geTKArray_Element(pEvents->pTimeKeys, nIndex);
00159 assert( pKeyInfo != NULL );
00160
00161 DataLength = strlen(pEventData) + 1;
00162
00163
00164 pNewData = geRam_Realloc(pEvents->pEventData, pEvents->DataSize + DataLength);
00165 if(!pNewData)
00166 {
00167 geErrorLog_Add(ERR_TKEVENTS_INSERT_ENOMEM, NULL);
00168 if( geTKArray_DeleteElement(&pEvents->pTimeKeys, nIndex) == GE_FALSE)
00169 {
00170
00171 assert(0);
00172 }
00173
00174 pEvents->Iterator.EndTime = -99e33f;
00175 return GE_FALSE;
00176 }
00177 pEvents->pEventData = pNewData;
00178
00179
00180 nNumElements = geTKArray_NumElements(pEvents->pTimeKeys);
00181 assert(nIndex < nNumElements);
00182 if(nIndex == nNumElements - 1)
00183 {
00184
00185 InitialOffset = pEvents->DataSize;
00186 }
00187 else
00188 {
00189 EventType* pNextKeyInfo = geTKArray_Element(pEvents->pTimeKeys, nIndex + 1);
00190 assert( pNextKeyInfo != NULL );
00191
00192 InitialOffset = pNextKeyInfo->DataOffset;
00193 }
00194 pKeyInfo->DataOffset = InitialOffset;
00195
00196
00197 if(InitialOffset < pEvents->DataSize)
00198 {
00199 memmove(pEvents->pEventData + InitialOffset + DataLength,
00200 pEvents->pEventData + InitialOffset,
00201 pEvents->DataSize - InitialOffset);
00202 }
00203 memcpy( pEvents->pEventData + InitialOffset,
00204 pEventData,
00205 DataLength);
00206
00207 pEvents->DataSize += DataLength;
00208
00209
00210 nIndex++;
00211 while(nIndex < nNumElements)
00212 {
00213 pKeyInfo = geTKArray_Element(pEvents->pTimeKeys, nIndex);
00214 assert( pKeyInfo != NULL );
00215 pKeyInfo->DataOffset += DataLength;
00216
00217 nIndex++;
00218 }
00219
00220
00221 pEvents->Iterator.EndTime = -99e33f;
00222
00223 return GE_TRUE;
00224 }
00225
00226
00227 geBoolean GENESISCC geTKEvents_Delete(geTKEvents* pEvents, geTKEvents_TimeType tKey)
00228 {
00229 int nIndex, Count;
00230 geTKEvents_TimeType tFound;
00231 EventType* pKeyInfo;
00232 int DataOffset, DataSize;
00233 char *pNewData;
00234
00235 TKE_ASSERT_VALID(pEvents);
00236
00237 nIndex = geTKArray_BSearch(pEvents->pTimeKeys, tKey);
00238
00239 if( nIndex < 0 )
00240 {
00241 geErrorLog_Add(ERR_TKEVENTS_DELETE_NOT_FOUND, NULL);
00242 return GE_FALSE;
00243 }
00244
00245 tFound = geTKArray_ElementTime(pEvents->pTimeKeys, nIndex);
00246 if(tFound < tKey - GE_TKA_TIME_TOLERANCE)
00247 {
00248
00249 geErrorLog_Add(ERR_TKEVENTS_DELETE_NOT_FOUND, NULL);
00250 return GE_FALSE;
00251 }
00252
00253 pKeyInfo = geTKArray_Element(pEvents->pTimeKeys, nIndex);
00254 DataOffset = pKeyInfo->DataOffset;
00255 if(nIndex < geTKArray_NumElements(pEvents->pTimeKeys) - 1)
00256 {
00257
00258 pKeyInfo = geTKArray_Element(pEvents->pTimeKeys, nIndex + 1);
00259 DataSize = pKeyInfo->DataOffset - DataOffset;
00260
00261 memmove(pEvents->pEventData + DataOffset,
00262 pEvents->pEventData + DataOffset + DataSize,
00263 pEvents->DataSize - DataOffset - DataSize);
00264 }
00265 else
00266 {
00267
00268 DataSize = pEvents->DataSize - DataOffset;
00269 }
00270
00271
00272 pEvents->DataSize -= DataSize;
00273 if (pEvents->DataSize == 0)
00274 {
00275 geRam_Free (pEvents->pEventData);
00276 pEvents->pEventData = NULL;
00277 }
00278 else
00279 {
00280 pNewData = geRam_Realloc(pEvents->pEventData, pEvents->DataSize);
00281
00282
00283 if(pNewData)
00284 {
00285 pEvents->pEventData = pNewData;
00286 }
00287 }
00288
00289
00290 geTKArray_DeleteElement(&pEvents->pTimeKeys, nIndex);
00291
00292
00293 Count = geTKArray_NumElements(pEvents->pTimeKeys);
00294 while(nIndex < Count)
00295 {
00296 pKeyInfo = geTKArray_Element(pEvents->pTimeKeys, nIndex);
00297 assert( pKeyInfo != NULL );
00298 pKeyInfo->DataOffset -= DataSize;
00299 nIndex++;
00300 }
00301
00302
00303 pEvents->Iterator.EndTime = -99e33f;
00304
00305 return GE_TRUE;
00306 }
00307
00308
00309 #define TKEVENTS_ASCII_FILE_TYPE 0x56454B54 // 'TKEV'
00310 #define TKEVENTS_FILE_VERSION 0x00F0 // Restrict to 16 bits
00311
00312 #define TKEVENTS_BIN_FILE_TYPE 0x42454B54 // 'TKEB'
00313 #define TKEVENTS_TIMEKEYS_ID "TimeKeys"
00314 #define TKEVENTS_DATASIZE_ID "DataSize"
00315
00316
00317 geTKEvents* GENESISCC geTKEvents_CreateFromFile(
00318 geVFile* pFile)
00319
00320 {
00321 uint32 u;
00322 geTKEvents* pEvents;
00323
00324 assert( pFile != NULL );
00325
00326
00327 if(geVFile_Read(pFile, &u, sizeof(u)) == GE_FALSE)
00328 {
00329 geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL);
00330 return NULL;
00331 }
00332
00333 pEvents = GE_RAM_ALLOCATE_STRUCT(geTKEvents);
00334 if(!pEvents)
00335 {
00336 geErrorLog_Add(ERR_TKEVENTS_CREATE_ENOMEM, NULL);
00337 return NULL;
00338 }
00339 pEvents->pEventData = NULL;
00340 pEvents->pTimeKeys = NULL;
00341
00342 if(u == TKEVENTS_ASCII_FILE_TYPE)
00343 {
00344 int i;
00345 uint32 v;
00346 char VersionString[32];
00347 #define LINE_LENGTH 256
00348 char line[LINE_LENGTH];
00349 char* pTextLine = NULL;
00350 EventType* pEInfo;
00351 geTKEvents_TimeType Time;
00352
00353 #define ABORT_READ_AND_FREE { geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL); geTKEvents_Destroy(&pEvents); return NULL; }
00354 #define ABORT_READ_AND_FREE_ALL \
00355 { \
00356 geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL); \
00357 geTKEvents_Destroy(&pEvents); \
00358 if(pTextLine != NULL) \
00359 geRam_Free(pTextLine); \
00360 return NULL; \
00361 }
00362
00363
00364 if (geVFile_GetS(pFile, VersionString, sizeof(VersionString)) == GE_FALSE)
00365 {
00366 geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL);
00367 return NULL;
00368 }
00369 sscanf(VersionString, "%X.%X\n", &u, &v);
00370 v |= (u << 8);
00371
00372 if(v != TKEVENTS_FILE_VERSION)
00373 ABORT_READ_AND_FREE;
00374
00375 if(geVFile_GetS(pFile, line, LINE_LENGTH) == GE_FALSE)
00376 ABORT_READ_AND_FREE;
00377
00378 if(strnicmp(line, TKEVENTS_DATASIZE_ID, sizeof(TKEVENTS_DATASIZE_ID)-1) != 0)
00379 ABORT_READ_AND_FREE;
00380
00381 if(sscanf(line + sizeof(TKEVENTS_DATASIZE_ID)-1, "%d", &pEvents->DataSize) != 1)
00382 ABORT_READ_AND_FREE;
00383 if (pEvents->DataSize +1> LINE_LENGTH)
00384 ABORT_READ_AND_FREE;
00385
00386 if(geVFile_GetS(pFile, line, LINE_LENGTH) == GE_FALSE)
00387 ABORT_READ_AND_FREE;
00388
00389 if(strnicmp(line, TKEVENTS_TIMEKEYS_ID, sizeof(TKEVENTS_TIMEKEYS_ID)-1) != 0)
00390 ABORT_READ_AND_FREE;
00391
00392 if(sscanf(line + sizeof(TKEVENTS_TIMEKEYS_ID)-1, "%d", &i) != 1)
00393 ABORT_READ_AND_FREE;
00394
00395 pEvents->pTimeKeys = geTKArray_Create(sizeof(EventType));
00396 if(!pEvents->pTimeKeys)
00397 ABORT_READ_AND_FREE;
00398
00399 pEvents->pEventData = geRam_Allocate(pEvents->DataSize);
00400 if(!pEvents->pEventData)
00401 ABORT_READ_AND_FREE_ALL;
00402
00403
00404
00405 pTextLine = geRam_Allocate(pEvents->DataSize + 1);
00406 if(pTextLine == NULL)
00407 ABORT_READ_AND_FREE_ALL;
00408
00409 while(i > 0)
00410 {
00411 char TimeString[64];
00412 if (geVFile_GetS(pFile, TimeString, sizeof(TimeString)) == GE_FALSE)
00413 ABORT_READ_AND_FREE_ALL;
00414 if(sscanf(TimeString, "%f %d\n", &Time, &v) != 2)
00415 ABORT_READ_AND_FREE_ALL;
00416 if(!geTKArray_Insert(&pEvents->pTimeKeys, Time, (int*)&u))
00417 ABORT_READ_AND_FREE_ALL;
00418 pEInfo = geTKArray_Element(pEvents->pTimeKeys, u);
00419 pEInfo->DataOffset = v;
00420
00421 if(geVFile_GetS(pFile, pTextLine, pEvents->DataSize + 1) == GE_FALSE)
00422 ABORT_READ_AND_FREE_ALL;
00423
00424 pTextLine[strlen(pTextLine) - 1] = 0;
00425 {
00426 int len = strlen(pTextLine)-1;
00427 if (pTextLine[len] == 13)
00428 {
00429 pTextLine[len] = 0;
00430 }
00431 }
00432 strcpy(pEvents->pEventData + v, pTextLine);
00433
00434 i--;
00435 }
00436
00437 if(pTextLine != NULL)
00438 geRam_Free(pTextLine);
00439 }
00440 else
00441 {
00442 if(u == TKEVENTS_BIN_FILE_TYPE)
00443 {
00444 if(geVFile_Read(pFile, &u, sizeof(u)) == GE_FALSE)
00445 {
00446 geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL);
00447 geTKEvents_Destroy(&pEvents);
00448 return GE_FALSE;
00449 }
00450 if (u != TKEVENTS_FILE_VERSION)
00451 {
00452 geErrorLog_AddString(-1,"Failure to recognize TKEvents file version", NULL);
00453 geTKEvents_Destroy(&pEvents);
00454 return GE_FALSE;
00455 }
00456
00457 if(geVFile_Read(pFile, &(pEvents->DataSize), sizeof(pEvents->DataSize)) == GE_FALSE)
00458 {
00459 geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL);
00460 geTKEvents_Destroy(&pEvents);
00461 return NULL;
00462 }
00463
00464 pEvents->pEventData = geRam_Allocate(pEvents->DataSize);
00465 if(!pEvents->pEventData)
00466 {
00467 geErrorLog_Add(ERR_TKEVENTS_CREATE_ENOMEM, NULL);
00468 geTKEvents_Destroy(&pEvents);
00469 return NULL;
00470 }
00471
00472 if(geVFile_Read(pFile, pEvents->pEventData, pEvents->DataSize) == GE_FALSE)
00473 {
00474 geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL);
00475 geTKEvents_Destroy(&pEvents);
00476 return NULL;
00477 }
00478 pEvents->pTimeKeys = geTKArray_CreateFromBinaryFile(pFile);
00479 if(!pEvents->pTimeKeys)
00480 {
00481 geErrorLog_Add(ERR_TKEVENTS_FILE_READ, NULL);
00482 geTKEvents_Destroy(&pEvents);
00483 return NULL;
00484 }
00485 }
00486 }
00487
00488 return pEvents;
00489 }
00490
00491
00492 #define CHECK_FOR_WRITE(uu) if(uu <= 0) { geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL); return GE_FALSE; }
00493
00494 geBoolean GENESISCC geTKEvents_WriteToFile(
00495 const geTKEvents* pEvents,
00496 geVFile* pFile)
00497
00498 {
00499 uint32 u;
00500 int NumElements;
00501 int i;
00502 EventType* pEInfo;
00503
00504 assert( pEvents != NULL );
00505 assert( pFile != NULL );
00506
00507 u = TKEVENTS_ASCII_FILE_TYPE;
00508 if(geVFile_Write(pFile, &u, sizeof(u)) == GE_FALSE)
00509 {
00510 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00511 return GE_FALSE;
00512 }
00513
00514
00515 if (geVFile_Printf(pFile,
00516 " %X.%.2X\n",
00517 (TKEVENTS_FILE_VERSION & 0xFF00) >> 8,
00518 TKEVENTS_FILE_VERSION & 0x00FF) == GE_FALSE)
00519 {
00520 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00521 return GE_FALSE;
00522 }
00523
00524
00525
00526 if (geVFile_Printf(pFile, "%s %d\n", TKEVENTS_DATASIZE_ID, pEvents->DataSize) == GE_FALSE)
00527 {
00528 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00529 return GE_FALSE;
00530 }
00531
00532
00533 NumElements = geTKArray_NumElements(pEvents->pTimeKeys);
00534 if (geVFile_Printf(pFile, "%s %d\n", TKEVENTS_TIMEKEYS_ID, NumElements) == GE_FALSE)
00535 {
00536 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00537 return GE_FALSE;
00538 }
00539
00540 for(i=0;i<NumElements;i++)
00541 {
00542 pEInfo = geTKArray_Element(pEvents->pTimeKeys, i);
00543 if (geVFile_Printf(pFile, "%f %d\n", pEInfo->EventTime, pEInfo->DataOffset) == GE_FALSE)
00544 {
00545 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00546 return GE_FALSE;
00547 }
00548 if (geVFile_Printf(pFile, "%s\n", pEvents->pEventData + pEInfo->DataOffset) == GE_FALSE)
00549 {
00550 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00551 return GE_FALSE;
00552 }
00553 }
00554 return GE_TRUE;
00555 }
00556
00557
00558
00559 geBoolean GENESISCC geTKEvents_WriteToBinaryFile(
00560 const geTKEvents* pEvents,
00561 geVFile* pFile)
00562
00563 {
00564 uint32 u;
00565 assert( pEvents != NULL );
00566 assert( pFile != NULL );
00567
00568 u = TKEVENTS_BIN_FILE_TYPE;
00569 if(geVFile_Write(pFile, &u, sizeof(u)) == GE_FALSE)
00570 {
00571 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00572 return GE_FALSE;
00573 }
00574 u = TKEVENTS_FILE_VERSION;
00575
00576 if(geVFile_Write(pFile, &u, sizeof(u)) == GE_FALSE)
00577 {
00578 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00579 return GE_FALSE;
00580 }
00581
00582 if(geVFile_Write(pFile, &pEvents->DataSize, sizeof(pEvents->DataSize)) == GE_FALSE)
00583 {
00584 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00585 return GE_FALSE;
00586 }
00587
00588 if(geVFile_Write(pFile, pEvents->pEventData, pEvents->DataSize) == GE_FALSE)
00589 {
00590 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00591 return GE_FALSE;
00592 }
00593
00594 if (geTKArray_WriteToBinaryFile(pEvents->pTimeKeys, pFile)==GE_FALSE)
00595 {
00596 geErrorLog_Add(ERR_TKEVENTS_FILE_WRITE, NULL);
00597 return GE_FALSE;
00598 }
00599 return GE_TRUE;
00600 }
00601
00602 GENESISAPI geBoolean GENESISCC geTKEvents_GetExtents(geTKEvents *Events,
00603 geTKEvents_TimeType *FirstEventTime,
00604 geTKEvents_TimeType *LastEventTime)
00605 {
00606 int Count;
00607 assert( Events != NULL );
00608
00609 Count = geTKArray_NumElements(Events->pTimeKeys);
00610 if (Count<0)
00611 {
00612 return GE_FALSE;
00613 }
00614
00615 *FirstEventTime = geTKArray_ElementTime(Events->pTimeKeys, 0);
00616 *LastEventTime = geTKArray_ElementTime(Events->pTimeKeys, Count-1);
00617 return GE_TRUE;
00618 }
00619
00620 void GENESISCC geTKEvents_SetupIterator(
00621 geTKEvents* pEvents,
00622 geTKEvents_TimeType StartTime,
00623 geTKEvents_TimeType EndTime)
00624
00625
00626
00627 {
00628 geTKEventsIterator* pTKEI;
00629
00630 assert( pEvents != NULL );
00631
00632 pTKEI = &pEvents->Iterator;
00633
00634 pTKEI->EndTime = EndTime;
00635
00636
00637 pTKEI->CurrentIndex = geTKArray_BSearch(pEvents->pTimeKeys, StartTime - GE_TKA_TIME_TOLERANCE);
00638 while( (pTKEI->CurrentIndex > -1) &&
00639 (geTKArray_ElementTime(pEvents->pTimeKeys, pTKEI->CurrentIndex) >= StartTime - GE_TKA_TIME_TOLERANCE) )
00640 {
00641 pTKEI->CurrentIndex--;
00642 }
00643 }
00644
00645
00646 geBoolean GENESISCC geTKEvents_GetNextEvent(
00647 geTKEvents* pEvents,
00648 geTKEvents_TimeType *pTime,
00649 const char **ppEventString)
00650
00651
00652
00653
00654
00655
00656 {
00657 geTKEventsIterator* pTKEI;
00658 geTKArray* pTimeKeys;
00659 EventType* pKeyInfo;
00660 int Index;
00661
00662 assert(pEvents);
00663 assert(pTime);
00664 assert(ppEventString);
00665
00666 pTKEI = &pEvents->Iterator;
00667
00668 pTimeKeys = pEvents->pTimeKeys;
00669
00670 pTKEI->CurrentIndex++;
00671 Index = pTKEI->CurrentIndex;
00672 if(Index < geTKArray_NumElements(pTimeKeys))
00673 {
00674 *pTime = geTKArray_ElementTime(pTimeKeys, Index);
00675 if(*pTime + GE_TKA_TIME_TOLERANCE < pTKEI->EndTime)
00676 {
00677
00678 pKeyInfo = geTKArray_Element(pTimeKeys, Index);
00679 *ppEventString = pEvents->pEventData + pKeyInfo->DataOffset;
00680 return GE_TRUE;
00681 }
00682 }
00683
00684
00685 *pTime = 0.0f;
00686 *ppEventString = NULL;
00687 return GE_FALSE;
00688 }