/*------------------------------------------------------------------------------ FILE : Register.c CREATED : 98/05/19 AUTHOR : Catalin Cocos CONTENTS: callback registering structures & functions ------------------------------------------------------------------------------*/ #include "StdInc.h" #include "Register.h" #include "Interface.h" #include "Error.h" #include "Refs.h" /* Globals -------------*/ extern int g_nInitialized; LDT_tdst_DSArray g_ArSectionCallbacks; /* the section callbacks */ LDT_tdst_DSArray g_ArFileCallbacks; /* the file callbacks */ LDT_tdst_DSArray g_ArPaths; /* the paths */ LDT_tdst_DSArray g_ArPathStrings; /* the path strings */ LDT_tdst_DSArray g_ArBaseDirectories; /* the base paths */ LDT_tdst_CallbackEntry Default_Type = { ".*", LDT_Default_NULL_Create, LDT_Default_Load}; /* Functions -------------*/ /*------------------------------------------------------------------------------ DESC. : compares two callback registration entries CREATED : 98/05/12 AUTHOR : Catalin Cocos ------------------------------------------------------------------------------*/ int LDT_Compare_CallbackEntries(const void** _pA, const void** _pB) { int Result = stricmp(((LDT_tdst_CallbackEntry*) *_pA)->szType, ((LDT_tdst_CallbackEntry*) *_pB)->szType ); if(Result < 0) return -1; return Result; } /*------------------------------------------------------------------------------ DESC. : registers a type INPUT : the type; the pointer to the create callback; pointer to the load callback; Registering mode: LDT_REG_SECTION - registers section callbacks LDT_REG_FILE - registers file callbacks OUTPUT : non-zero if successful, 0 if the type is already registered or if the paramters are invalid CREATED : 98/05/12 AUTHOR : Catalin Cocos ------------------------------------------------------------------------------*/ int LDT_RegisterType(char* szType, int (*_Create) ( LDT_tdst_Link* ), int (*_Load) ( LDT_tdst_Link* ), int Mode) { // char *sz; LDT_tdst_DSArray* pAr; LDT_tdst_CallbackEntry* pNewEntry, *pOldEntry; int position; if( !g_nInitialized ) return 0; /* table not initialized */ if( !szType || !_Create || !_Load ) return 0; /* invalid parameters */ pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks; /* select the array*/ /* convert to lower case */ // sz=szType; // for( ; *sz; sz++ ) // if( ( *sz>='A') && ( *sz<='Z' ) ) // *sz+='a'-'A'; /* create the new entry */ pNewEntry = malloc( sizeof(LDT_tdst_CallbackEntry)); pNewEntry->szType = szType; pNewEntry->Create = _Create; pNewEntry->Load = _Load; if( LDT_DSAr_SAdd( pAr, pNewEntry, 0, &position) < 0 ) { /* insertion failed */ #if defined(LDT_ERROR_TREATMENT) pOldEntry = LDT_DSAr_GetAt( pAr, position ); if( (pOldEntry->Create != _Create) || (pOldEntry->Load != _Load) ) ERRoR(0, NULL, 0, "Type already registered. Registration failed."); #endif free( pNewEntry ); return 0; } strcpy( pNewEntry->szType = malloc( strlen(szType) + 1 ), szType ); /* copy the type string*/ return 1; } /*------------------------------------------------------------------------------ DESC. : returns a pointer to the type or NULL if the type is not registered; the parameters have the same signification as in the above function CREATED : 98/05/12 AUTHOR : Catalin Cocos ------------------------------------------------------------------------------*/ LDT_tdst_CallbackEntry* LDT_IsTypeRegistered( char* szType, int Mode) { LDT_tdst_DSArray* pAr; /* convert to lower case */ // char *sz; // sz=szType; // for( ; *sz; sz++ ) // if( ( *sz>='A') && ( *sz<='Z' ) ) // *sz+='a'-'A'; if( !g_nInitialized ) return NULL; /* table not initialized */ if( !szType) return NULL; /* invalid parameter */ pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks; return LDT_DSAr_GetAt(pAr, LDT_DSAr_Index( pAr, (LDT_tdst_CallbackEntry*)&szType, NULL )); } /*------------------------------------------------------------------------------ DESC. : returns a pointer to the type or the default type if the type is not registered; the parameters have the same signification as in the above function CREATED : 98/05/12 NOTE : the input string MUST BE LOWERCASE AUTHOR : Catalin Cocos ------------------------------------------------------------------------------*/ LDT_tdst_CallbackEntry* GetType( char* szType, int Mode) { LDT_tdst_DSArray* pAr; LDT_tdst_CallbackEntry* pType; if(!g_nInitialized || !szType) return &Default_Type; pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks; pType = LDT_DSAr_GetAt(pAr, LDT_DSAr_Index( pAr, (LDT_tdst_CallbackEntry*)&szType, NULL )); if( !pType ) { #if defined(LDT_ERROR_TREATMENT) && ( LDT_WARNING_LEVEL >= 3 || LDT_ERROR_LEVEL >= 3) char buffer [300]; sprintf(buffer, "The type \"%s\" (%s) is not registered. The default callback will be used.", szType, (Mode == LDT_REG_SECTION)?"SECTION":"FILE"); ERRoR((Mode == LDT_REG_SECTION)?3:4, NULL, 0, buffer ); #endif return &Default_Type; } return pType; } /*------------------------------------------------------------------------------ DESC. : unregisters an existing type OUTPUT : non-zero if successful, 0 on error CREATED : 98/05/12 AUTHOR : Catalin Cocos ------------------------------------------------------------------------------*/ int LDT_UnregisterType( char* szType, int Mode) { // char *sz; int idx; LDT_tdst_DSArray* pAr; LDT_tdst_CallbackEntry TestEntry, *pDelEntry; if( !g_nInitialized || !szType ) return 1; /* no opened session or invalid type */ /* convert to lower case */ // sz=szType; // for( ; *sz; sz++ ) // if( ( *sz>='A') && ( *sz<='Z' ) ) // *sz+='a'-'A'; TestEntry.szType = szType; pAr = (Mode == LDT_REG_SECTION)? &g_ArSectionCallbacks: &g_ArFileCallbacks; /* select the array*/ idx = LDT_DSAr_Index( pAr, &TestEntry, NULL ); if( idx < 0) return 1; /* not found */ /* solve all references before proceeding */ if(!LDT_Flush()) return 0; /* if the flush failed, return */ /* remove & delete the entry */ pDelEntry = LDT_DSAr_RemoveAt( pAr, idx ); free( pDelEntry->szType ); free( pDelEntry ); return 1; } /*------------------------------------------------------------------------------ DESC. : registers a Base Directory - if present the base directories will always prefix the paths INPUT : the base directory OUTPUT : 0 if successful, !0 on error CREATED : 98/09/24 AUTHOR : Catalin Cocos ------------------------------------------------------------------------------*/ int LDT_AddBaseDirectory( char* szPath ) { // char *sz; char path[_MAX_PATH]; int i; if( !g_nInitialized || !szPath ) return 1; /* no opened session or invalid parameters */ /* Get the path */ while (*szPath == ' ') szPath ++; strcpy( path, szPath ); for( i = strlen(path)-1; i>=0 && path[i] == ' '; i--) path[i] = 0; if(path[strlen(path)-1] != '\\') strcat( path, "\\"); /* convert file path string to lower case */ // sz=path; // for( ; *sz; sz++ ) // if( ( *sz>='A') && ( *sz<='Z' ) ) // *sz+='a'-'A'; /* add the file path to the base directories list */ LDT_DSAr_Add( &g_ArBaseDirectories, strcpy( malloc( strlen(path) +1 ), path)); return 0; } /*------------------------------------------------------------------------------ DESC. : registers a Path INPUT : the path, the file types extensions(without the leading'.'), separated by spaces OUTPUT : 0 if successful, !0 on error CREATED : 98/05/12 AUTHOR : Catalin Cocos ------------------------------------------------------------------------------*/ int LDT_RegisterPath( char* szPath, char* szFileTypes ) { char *sz, * szNewPath; char buffer[_MAX_EXT]; char path[_MAX_PATH]; int i, idx, iidx; LDT_tdst_TypePaths Dummy; Dummy.szExtension = buffer; if( !g_nInitialized || !szPath || !szFileTypes ) return 1; /* no opened session or invalid parameters */ /* Get the path */ while (*szPath == ' ') szPath ++; strcpy( path, szPath ); for( i = strlen(path)-1; i>=0 && path[i] == ' '; i--) path[i] = 0; if(path[strlen(path)-1] != '\\') strcat( path, "\\"); /* convert file path string to lower case */ // sz=path; // for( ; *sz; sz++ ) // if( ( *sz>='A') && ( *sz<='Z' ) ) // *sz+='a'-'A'; /* add the file path to the path collection */ idx = LDT_DSAr_Index( &g_ArPathStrings, path, &iidx); if( idx<0 ) /* insert the new path */ LDT_DSAr_InsertAt(&g_ArPathStrings, iidx, strcpy( szNewPath = malloc( strlen(path) +1), path)); else /* we already have it */ szNewPath = g_ArPathStrings.pData[idx]; /* convert file type string to lower case */ // sz=szFileTypes; // for( ; *sz; sz++ ) // if( ( *sz>='A') && ( *sz<='Z' ) ) // *sz+='a'-'A'; sz=szFileTypes; while ( *sz ) { int cnt = 0; while (*sz == ' ') sz++; for(; *sz!=' ' && *sz ; sz++, cnt++ ) buffer[cnt] = *sz; buffer[cnt] = 0; if(*buffer) { /* we have a valid file type */ int idx,iidx; idx = LDT_DSAr_Index( &g_ArPaths, &Dummy, &iidx ); if(idx<0) { /* type not registered before */ LDT_tdst_TypePaths* pPath = malloc( sizeof(LDT_tdst_TypePaths)); strcpy( pPath->szExtension = malloc( strlen(buffer) + 1 ), buffer); LDT_DSAr_Init(&pPath->arPaths); LDT_DSAr_SetGranularity(&pPath->arPaths, 10); LDT_DSAr_Add(&pPath->arPaths, szNewPath); LDT_DSAr_InsertAt( &g_ArPaths, iidx, pPath ); } else /* type already present */ LDT_DSAr_Add(&((LDT_tdst_TypePaths*)g_ArPaths.pData[idx])->arPaths, szNewPath); } } return 0; } #ifdef LDT_LOG_STATISTICS /* Log/stat stuff -------------------*/ unsigned TimerStartCount = 0; unsigned TimerStopCount = 0; LONGLONG Frequency; LONGLONG TimingOverhead = 0; LONGLONG StartOverhead = 0; LONGLONG StopOverhead = 0; void InitializeTimingEnvironment() { LARGE_INTEGER li; LONGLONG tmpli; int i; TimerStruct time, dummy; QueryPerformanceFrequency( &li ); Frequency = li.QuadPart; /* the clock frequency */ InitTimer( &time ); for( i = 0; i<32768; i++) /* 2^15 */ { StartTimer( &time ); StopTimer( &time ); } TimingOverhead = Int64ShraMod32(time.TimeCounter, 15); /* the timing overhead */ InitTimer( &time ); for( i = 0; i<32768; i++) /* 2^15 */ { StartTimer( &time ); StartTimer( &dummy ); StopTimer( &time ); } tmpli = time.TimeCounter; InitTimer( &time ); InitTimer( &dummy ); for( i = 0; i<32768; i++) /* 2^15 */ { StartTimer( &time ); StartTimer( &dummy ); StopTimer( &dummy ); StopTimer( &time ); } StartOverhead = Int64ShraMod32(tmpli , 15); /* the stoptiming overhead */ StopOverhead = Int64ShraMod32(time.TimeCounter - tmpli , 15); /* the stoptiming overhead */ InitTimer( &time ); InitTimer( &dummy ); StartTimer( &time ); StartTimer( &dummy ); StopTimer( &dummy ); StopTimer( &time ); } void InitTimer(TimerStruct* time) { time->TimeCounter = 0; } void StartTimer(TimerStruct* time) { time->LastStartCount = ++TimerStartCount; time->LastStopCount = TimerStopCount; QueryPerformanceCounter((LARGE_INTEGER*)&time->LastValue); } void StopTimer(TimerStruct* time) { LARGE_INTEGER li; QueryPerformanceCounter(&li); time->TimeCounter += li.QuadPart - time->LastValue - TimingOverhead - (TimerStartCount-time->LastStartCount)*StartOverhead - (TimerStopCount-time->LastStopCount)*StopOverhead; TimerStopCount++; } double ReadTimer(TimerStruct* time) { return ((double)time->TimeCounter)/Frequency; } #endif