#ident "@(#) mainVIDF.c 1.7 05/08/19 SwRI" #include /* for fprintf */ #include /* for free */ #include /* for MAXPATHLEN */ #include /* for strcpy, strrchr */ #include /* for access */ #include /* for threading */ #include "vidf_local.h" #include "vidf_codes.h" #include "libVIDF.h" #include "SDDAS_types.h" #include "ant.h" /* for Time_t and compare_times */ #include "libdb.h" /* for _VIDF_ and dbGetIDFSFile */ /* This file contains all the public routines */ static int whichVIDF = -1; static int numVIDFs = 0; static VIDFInfo **VIDFs = NULL; static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; /* this routine will add a new element to the end of the VIDFs array so one can use as many VIDFs as necessary and then call CloseVIDF to free them all */ void AddVIDF () { CreateCache (); numVIDFs++; VIDFs = (VIDFInfo **) realloc (VIDFs, numVIDFs * sizeof (VIDFInfo *)); VIDFs [numVIDFs - 1] = (VIDFInfo *) calloc (1, sizeof (VIDFInfo)); } void CloseVIDF () { int i; if (VIDFs != NULL) { for (i = 0; i < numVIDFs; i++) { if (VIDFs [i]->_vidf != NULL) { if (VIDFs [i]->_usingNewVIDF == sTrue) { DeleteVIDF (VIDFs [i]->_vidf); } else { free_vidf_structure (VIDFs [i]->_vidf); free (VIDFs [i]->_vidf); } } /* if */ VIDFs [i]->_vidf = NULL; free (VIDFs [i]); } /* for */ free (VIDFs); numVIDFs = 0; VIDFs = NULL; ClearCache (); } } /* reads from VIDF pointed to by whichVIDF which must be set prior to this call - InitializeVIDFFromFile will set it. */ int ReadFromCurrentVIDF (void *var, VIDF_DEFS what, SDDAS_SHORT num, SDDAS_LONG start, SDDAS_SHORT len) { int ret_val; /* read from either the old or the new */ if (VIDFs [whichVIDF]->_usingNewVIDF == sTrue) ret_val = ReadNewVIDF (VIDFs [whichVIDF]->_vidf, var, what, num, start, len); else ret_val = (int) ReadOldVIDF (VIDFs [whichVIDF]->_vidf, 0, var, (SDDAS_SHORT) what, num, start, len); return (ret_val); } int FillTimes () { /* ASSUMPTION - the VIDF is open and ready to go and whichVIDF is pointing to the correct one */ int ret_val = ALL_OKAY; SDDAS_SHORT short_var; if ((ret_val = ReadFromCurrentVIDF (&short_var, _DS_YEAR, 0, 0, -1)) != ALL_OKAY) return ret_val; else VIDFs [whichVIDF]->_BTime.yr = (SDDAS_LONG) short_var; if ((ret_val = ReadFromCurrentVIDF (&short_var, _DS_DAY, 0, 0, -1)) != ALL_OKAY) return ret_val; else VIDFs [whichVIDF]->_BTime.day = (SDDAS_LONG) short_var; if ((ret_val = ReadFromCurrentVIDF (&VIDFs [whichVIDF]->_BTime.msec, _DS_MSEC, 0, 0, -1)) != ALL_OKAY) return ret_val; if ((ret_val = ReadFromCurrentVIDF (&short_var, _DE_YEAR, 0, 0, -1)) != ALL_OKAY) return ret_val; else VIDFs [whichVIDF]->_ETime.yr = (SDDAS_LONG) short_var; if ((ret_val = ReadFromCurrentVIDF (&short_var, _DE_DAY, 0, 0, -1)) != ALL_OKAY) return ret_val; else VIDFs [whichVIDF]->_ETime.day = (SDDAS_LONG) short_var; ret_val = ReadFromCurrentVIDF (&VIDFs [whichVIDF]->_ETime.msec, _DE_MSEC, 0, 0, -1); return ret_val; } int InitializeVIDFFromFile (char *vidf_filename) { int ret_val; for (whichVIDF = 0; whichVIDF < numVIDFs; whichVIDF++) { if (strcmp (VIDFs [whichVIDF]->_FileName, vidf_filename) == 0) { return (ALL_OKAY); } } /* First we must make room for the new VIDF */ /* whichVIDF is where it needs to be */ AddVIDF (); /* Check to see if we are reading a new VIDF or an old VIDF, read accordingly */ if (strstr (vidf_filename, "V.v3") != NULL) { ret_val = ParseNewVIDF (&VIDFs [whichVIDF]->_vidf, vidf_filename); VIDFs [whichVIDF]->_usingNewVIDF = sTrue; } else { create_vidf_structure (&VIDFs [whichVIDF]->_vidf); ret_val = ParseOldVIDF (VIDFs [whichVIDF]->_vidf, vidf_filename); VIDFs [whichVIDF]->_usingNewVIDF = sFalse; } strcpy (VIDFs [whichVIDF]->_FileName, vidf_filename); VIDFs [whichVIDF]->_DataKey = 0; if (ret_val == ALL_OKAY) ret_val = FillTimes (); return (ret_val); } int InitializeVIDF (SDDAS_ULONG data_key, SDDAS_SHORT btime_yr, SDDAS_SHORT btime_day, SDDAS_LONG btime_sec, SDDAS_LONG btime_nsec, SDDAS_SHORT etime_yr, SDDAS_SHORT etime_day, SDDAS_LONG etime_sec, SDDAS_LONG etime_nsec) { char filename [MAXPATHLEN]; char new_filename [MAXPATHLEN]; int ret_val = ALL_OKAY; Time_t btime, etime; /* Initialize our btime and etime structure */ btime.yr = btime_yr; btime.day = btime_day; btime.msec = (btime_sec * 1000) + (btime_nsec / 1000000); etime.yr = etime_yr; etime.day = etime_day; etime.msec = (etime_sec * 1000) + (btime_nsec / 1000000); pthread_mutex_lock (&_mutex); /* locks the VIDFs */ for (whichVIDF = 0; whichVIDF < numVIDFs; whichVIDF++) { if (VIDFs [whichVIDF]->_DataKey == data_key) { /* is the requested beginning time > our VIDF's end time? */ /* is the requested beginning time < our VIDF's beginning time? */ /* is the requested ending time > our VIDF's beginning time? */ /* we do not check if the ending time < our VIDF's end time? */ /* since we could ask for a range bigger than a VIDF handles */ if ((btime_yr == -1) || ((compare_times (btime, VIDFs [whichVIDF]->_ETime) <= 0) && (compare_times (btime, VIDFs [whichVIDF]->_BTime) >= 0) && (compare_times (etime, VIDFs [whichVIDF]->_BTime) >= 0))) { /* no, the the requested time is within our current VIDF */ pthread_mutex_unlock (&_mutex); /* unlocks the VIDF */ return (ALL_OKAY); } } } /* If we are at this point, we have either requested a new VIDF or the times were not okay, and we need a new one. */ /* First we must make room for the new VIDF */ /* whichVIDF is already pointing to the right place */ AddVIDF (); /* Second thing to do is check the database and get a good name. */ ret_val = dbIDFSGetFile (data_key, btime_yr, btime_day, btime.msec, etime_yr, etime_day, etime.msec, _VIDF_, "", filename, NULL); if (ret_val != ALL_OKAY) { pthread_mutex_unlock (&_mutex); /* unlocks the VIDF */ return (ret_val); } /* If we got a filename, let's replace the I with a V.v3 and see if the new type VIDF exists. */ strcpy (new_filename, filename); strcpy (strrchr (new_filename, 'I'), "V.v3"); if (access (new_filename, R_OK) == 0) { /* New style VIDF exists */ ret_val = ParseNewVIDF (&VIDFs [whichVIDF]->_vidf, new_filename); strcpy (VIDFs [whichVIDF]->_FileName, new_filename); VIDFs [whichVIDF]->_usingNewVIDF = sTrue; } else { /* Old school VIDF */ if (access (filename, R_OK) == 0) { create_vidf_structure (&VIDFs [whichVIDF]->_vidf); ret_val = ParseOldVIDF (VIDFs [whichVIDF]->_vidf, filename); strcpy (VIDFs [whichVIDF]->_FileName, filename); VIDFs [whichVIDF]->_usingNewVIDF = sFalse; } else { /* VIDF file not online! */ fprintf (stderr, "WARNING - VIDF %s needs to be online! ", filename); pthread_mutex_unlock (&_mutex); /* unlocks the VIDF */ return (VIDF_NOT_READABLE); } } VIDFs [whichVIDF]->_DataKey = data_key; if (ret_val == ALL_OKAY) ret_val = FillTimes (); /* Check that the times we need are in the VIDF */ /* This is a sanity check that the database is accurate */ if ((btime_yr == -1) || ((compare_times (btime, VIDFs [whichVIDF]->_ETime) <= 0) && (compare_times (btime, VIDFs [whichVIDF]->_BTime) >= 0) && (compare_times (etime, VIDFs [whichVIDF]->_BTime) >= 0))) { /* VIDF is good, do nothing! */ } else { fprintf (stderr, "ERROR - VIDF database is out of date! "\ "The file, %s, is reporting a different time "\ "than the database reports. You must "\ "repromote the meta data!\n", VIDFs [whichVIDF]->_FileName); ret_val = VIDF_DATABASE_CORRUPT; } pthread_mutex_unlock (&_mutex); /* unlocks the VIDF */ return (ret_val); } SDDAS_LONG read_idf (SDDAS_ULONG data_key, const char *exten, SDDAS_USHORT vnum, void *var, SDDAS_SHORT quan, SDDAS_SHORT num, SDDAS_LONG start, SDDAS_SHORT len) { /* exten and vnum are ignored! */ /* this call ignore what time you are asking for and reads from the first VIDF file matching the data key - very dangerous if you are have multiple VIDFs. */ /* find out which VIDF we need to read from */ whichVIDF = 0; while ((whichVIDF < numVIDFs) && (data_key != VIDFs [whichVIDF]->_DataKey)) whichVIDF++; if (whichVIDF > numVIDFs) { fprintf (stderr, "ERROR - VIDF not initialized!\n"); return (-1); } return ((SDDAS_LONG) ReadFromCurrentVIDF (var, (VIDF_DEFS) quan, num, start, len)); } int ReadVIDF (SDDAS_ULONG data_key, SDDAS_SHORT btime_yr, SDDAS_SHORT btime_day, SDDAS_LONG btime_sec, SDDAS_LONG btime_nsec, SDDAS_SHORT etime_yr, SDDAS_SHORT etime_day, SDDAS_LONG etime_sec, SDDAS_LONG etime_nsec, void *var, VIDF_DEFS what, SDDAS_SHORT num, SDDAS_LONG start, SDDAS_SHORT len) { int ret_val = ALL_OKAY; /* find out which VIDF we need to read from */ /* this will initialize whichVIDF */ /* if we are being passed a data_key of 0, assume we already have a VIDF initialized */ if (data_key != 0) { ret_val = InitializeVIDF (data_key, btime_yr, btime_day, btime_sec, btime_nsec, etime_yr, etime_day, etime_sec, etime_nsec); } /* read from either the old or the new */ if (ret_val == ALL_OKAY) ret_val = ReadFromCurrentVIDF (var, what, num, start, len); return (ret_val); }