ACEware Level1 Library: c utilities


Contents

Time Conversions
getDateFromDay19964/22/1998
getDateFromSecondsSince19964/22/1998
getDay1996FromDate4/22/1998
getDay1996FromSecondsSince19964/22/1998
getSecondsSince1996FromDate4/23/1998
getSecondsSince1996FromDay19964/23/1998
General Archive Information
getFirstDateOfArchivedData4/22/1998
getLastDateOfArchivedData4/22/1998
getTimeStampsOfDaysStructs4/22/1998
Event Processing Tools
getRequestTimesForDaysEvtCycles4/22/1998
Low Level Time Stamp Routines
getTimeStamp4/22/1998
getStopTimeStamp4/22/1998
Low Level Archive Information Tools
getArchiveFilesTimeStamps4/22/1998
generateDataFilePath4/22/1998
getDataFileSuffixFromStructName4/22/1998
getDataTypePeriodFromStructName4/22/1998
getInstrumentIDFromStructName4/22/1998
getFilesStructCount4/22/1998
getStructSizeFromName4/22/1998
validateDataFileSuffix4/22/1998
validateInstrumentID4/22/1998
Low Level Data Retrieval Routines
getStructs4/22/1998
getStruct4/22/1998
getDaysStructs4/22/1998
Low Level File I/O and System Utilities
fileExists4/22/1998
directoryExists4/22/1998
createDirectory4/22/1998
openOrCreateFileToReadWrite4/22/1998
readFromFile4/22/1998
writeToFile4/22/1998
Low Level Data Archival Routines
createInitializedFile4/22/1998
createInitializedFileWithIntervalN4/22/1998
determineDataFilePathAndCreateDirsAsNeeded4/22/1998
sortTrackers4/21/1998
writeDataStructToFile4/22/1998
writeHeader4/22/1998

Time Conversions

End-user routines for easy conversions between dates, seconds-since-1996, and day-of-1996.

Get a date (struct tm format) from the day-of-1996
struct tm* getDateFromDay1996(int day1996);

This routine returns a structure which corresponds to the zeroth second of the day day1996. Be aware that day1996 = 1 is defined as 1/1/96.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get a date (struct tm format) from seconds since start of 1996
struct tm* getDateFromSecondsSince1996(time_t secondsSince1996);

getDateFromSecondsSince1996 returns the struct tm (see time.h) which corresponds to the number of seconds since Jan 1, 1996, 00:00:00.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the day-of-1996 from the date (date in struct tm format)
int getDay1996FromDate(struct tm* date);

getDay1996FromDate returns the day-of-1996 corresponding to the date given in a struct tm format (as defined in ).

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the day-of1996 in which secondsSince1996 occurs
int getDay1996FromSecondsSince1996(uint32 secondsSince1996);

getDay1996FromSecondsSince1996 returns the day of 1996 (a count of days since Jan 1, 1996 where day1996 = 1 on Jan 1, 1996) in which the second secondsSince1996 occurs.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the number of seconds-since-1996 from a date (date in struct tm format)
uint32 getSecondsSince1996FromDate(struct tm *pTimeStruct);

getSecondsSince1996FromDate returns the seconds-since-1996 corresponding to the date given in a struct tm format (as defined in ).

Input:

Output:
Last Modified: 4/23/1998 Return to Contents

Get the number of seconds since 1996 from the day-of-1996
uint32 getSecondsSince1996FromDay1996(int day1996);

getSecondsSince1996FromDay1996 returns the seconds since 1996 corresponding to the zeroth second of the day day1996. Be aware that day1996 = 1 is defined as 1/1/96.

Input:

Output:
Last Modified: 4/23/1998 Return to Contents

General Archive Information

End-user routines to get general information about the archive and archive files.

Determine the date of the first data archived for an instrument and data type
void getFirstDateOfArchivedData(char* structName, struct tm *pTimeStruct);

getFirstDateOfArchivedData is used to determine what the first day of a particular type of data is in the archive for a particular instrument (CRIS or SIS).

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Determine the date of the last data archived for an instrument and data type
void getLastDateOfArchivedData(char* structName, struct tm *pTimeStruct);

getLastDateOfArchivedData is used to determine what the first last of a particular type of data is in the archive for a particular instrument (CRIS or SIS).

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get a list of the time stamps of a particular data type for a given day
uint32 *getTimeStampsOfDaysStructs(int day1996, char *structName);

Get a list of the time stamps of a particular data type for a given day. The time stamps returned are those starting at the data valid at second zero of the day and ending just before the data which is valid at second zero of the next day. Any intervals of missing data for the day return values of -1 for their time stamps. Beware that both start and stop time stamps are returned. For periodic data types, this means all of the stop time stamps will be set to -1 (because they have no stop time stamps.)

You need to free the memory allocated to the time stamp list when you are finished using it.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Event Processing Tools

End-user routines specific to the processing of event data.

Get a list of times which can be used to iteratively retrieve a day's worth of event data
uint32 *getRequestTimesForDaysEvtCycles(int day1996, char instrumentID);

Get a list of times which can be used to iteratively retrieve a day's worth of event data with no possibility of getting overlapping data when using this routine to retrieve data over many days. These times *are not* data time stamps because actually getting the time stamps would be just as time consuming as a full read of the data.

You need to free the memory allocated to this list when you are finished using it.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Low Level Time Stamp Routines

Low level routines for time stamp determination.

Get the start time stamp of a data struct
uint32 getTimeStamp(void *pStruct, char *structName);

getTimeStamp merely returns the start time stamp of a data struct of type structName.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get a struct's stop time stamp (if it has one)
uint32 getStopTimeStamp(void *pStruct, char *structName);

getStopTimeStamp extracts the stop time stamp from the struct of type structName. If there is no stop time stamp field in the struct, a zero is returned.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Low Level Archive Information Tools

Low level archive data retrieval utilities.

Get the time stamps of the data in one archive file (WARNING: See below.)
uint32 *getArchiveFilesTimeStamps(int day1996, char *structName);

getArchiveFilesTimeStamps creates a list of the time stamps of a particular type of data in one daily archive file. WARNING: This routine *does not* return what is referred to elsewhere as a day's set of data. This routine should be used to check what time stamps are on data in an archive file for debugging purposes only. Do not process data using this routine.

You must free the memory associated with the time stamp list when you are finished using it.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Construct the path to a data archive file
void generateDataFilePath(char *pathBuffer, struct tm *timeStruct,
				char instrumentID, const char *dataFileSuffix);

generateDataFilePath constructs the path to a particular archive data file.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the suffix which marks a data type in the archive files
void getDataFileSuffixFromStructName(char *suffixBuffer, char *structName);

The data files in the CRIS/SIS archive have suffixes associated with them, such as "hp" (high priority rates), "evt" (event cycles), etc. getDataFileSuffixFromStructName looks at the name of the structure we are dealing with and determines the suffix string associated with it.

This routine is useful in generating data file paths to the desired archive files.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the data type's validity period per data struct
int getDataTypePeriodFromStructName(char *structName);

Most of the data types in the CRIS/SIS archive are periodic in the time interval they cover. getDataTypePeriodFromStructName takes the name of a data type and returns this period.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the data type's instrument ID ('c' for CRIS, 's' for SIS)
char getInstrumentIDFromStructName(char *structName);

Get an ID for the instrument associated with the data type given by structName.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the number of structs in a particular archive file
int getFilesStructCount(char *dataFilePath, int structSize, int hasHeader);

getFilesStructCount is used to determine the number of data structs of size structSize in the file pointed at by dataFilePath. It does this merely by looking at the size of the file, subtracting out the number of bytes in the standard CRIS/SIS data archive header if the flag hasHeader is set (it usually will be), and then dividing by structSize. If the divide does not return an integral number, getFilesStructCount will exit with an error message.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get the size (in bytes) of a type of data struct
int getStructSizeFromName(char *structName);

getStructSizeFromName merely returns the size (in bytes) of the data struct structName.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Check that a data type archive file suffix is valid
char *validateDataFileSuffix(char *suffix);

Check that a data type archive file suffix is valid. If it is not valid, but is recognizable, the suffix is fixed to the valid version. If it is not recognizable, the process exits.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Check that an instrument ID is valid
char validateInstrumentID(char id);

Check that an instrument ID is valid. If it is not valid, but is recognizable, the ID is fixed to the valid version. If it is not recognizable, the process exits.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Low Level Data Retrieval Routines

Low level archive data retrieval engines and low level wrappers.

Get a set of data structs between a start and a stop time
void *getStructs(uint32 secondsSince1996Start,
                        uint32 secondsSince1996Stop, char *structName);

getStructs retrieves any data structures of type structName from the archives which was valid between the start time, secondsSince1996Start, and the stop time, secondsSince1996Stop (But see the note below for an important clarification of exactly what this means.) A pointer (void *) to an array of structs of type structName is returned. This array is always terminated by a zeroed struct of type structName.

The start and stop times used in getStructs can be across an arbitrary time interval. This may cause problems if users abuse it. In other words, getStructs can be called on to allocate an arbitrary amount of memory for the struct array it will be creating. Users should be warned about this (though they will likely be accessing getStructs via a more user friendly wrapper like getGroupHiRates_s or the like.)

Memory has been allocated in the call to getStructs for the array of structures returned, and this memory needs to be freed by the caller at some point.

Note: A structure which is valid at the time secondsSince1996Start will always be returned by this call, but the structure valid at secondsSince1996Stop will not be returned unless it is the same structure which is valid at secondsSince1996Start. Any and all structures valid at times between secondsSince1996Start and secondsSince1996Stop will be returned (which seems too obvious to state.) The reason that the last structure (the one valid at secondsSince1996Stop) is not returned by this call is to prevent seemingly contiguous calls to getStructs from returning overlapping data. For this reason, any series of calls to getStructs for contiguous data must use the prior secondsSince1996Stop as the secondsSince1996Start for the new call. Otherwise there will be a 1 second gap in each call's time intervals.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Get a data struct valid at a particular second-since-1996
void *getStruct(uint32 secondsSince1996, char *structName);

getStruct retrieves any data structure of type structName from the archives which was valid at time secondsSince1996. Beware that despite the singular nature of the name, a pointer to an array of structs of type structName is always returned. This array is always terminated by a zeroed struct of type structName. The reason for this is that, due to some anomoly with the clock perhaps, more than 1 data struct may be stamped as valid during a particular interval, so there is a small chance of getting more than a single "valid" data struct back. There is a much better chance of the array only containing the terminal zeroed struct. In such a case, either no data exists during the interval or it has not yet been archived. - getStruct is really just a special case of getStructs, where both secondsSince1996Start and secondsSince1996Stop are set to the same value, secondsSince1996. - Memory has been allocated inside the call to getStruct for the array of structures returned, and this memory needs to be freed by the caller.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

A get a day's worth of data structs
void *getDaysStructs(int day1996, char *structName);

A get a day's worth of structs, starting with the data struct which is valid at second zero of the day (which is usually archived in the file of the previous day), and ending just prior to the data struct which is valid at second zero of the next day (which is usually the last struct in this day's archive file.)

getDaysStructs determines the memory needed to store the days worth of data, allocates it, reads the non-zero structs from the file into memory, terminates the array of structs with a zeroed struct, chops the memory allocation down to size (since any zeroed structs in the file were not copied into the array), and returns a pointer (void *) to the caller. The caller must handle deallocation of this memory when it is through with it.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Low Level File I/O and System Utilities

Low level file I/O routines.

Check on the existence of a file
int fileExists(char *path);

fileExists is used primarily by the put data routines to check if an archive data file exists already or needs to be created and initialized. Returns 1 (true) if the file does exist, and 0 (false) if not. If the file is actually a directory, 0 is returned.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Check on the existence of a directory
int directoryExists(char *path);

directoryExists is used primarily by the put data routines to check if an archive directory already exists (before createDirectory is called). Returns 1 (true) if the directory does exist, and 0 (false) if not.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Create a new directory
int createDirectory(char *path);

createDirectory is used primarily by the put data routines to create new locations for archiving the data. If createDirectory fails to create the directory, the program will exit.1

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Open a file (or create it if it doesn't exist) with read/write capability
int openOrCreateFileToReadWrite(char *path);

openOrCreateFileToReadWrite is a low level routine used internally in the CRIS/SIS routines. It is used mostly by the put routines to write data to an archive file. If the file does not exist, it is created, initialized, and re-opened with read and write capability. openOrCreateFileToReadWrite also does some error checking and exits if the file cannot be created or opened as expected.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Read from a file
int readFromFile(int fd, char *buffer, int bytesToRead);

readFromFile is a low level routine used internally in the CRIS/SIS routines. Primarily it just adds a little error checking to the usual read calls. If the routine does not read the expected number of bytes into the buffer, it will exit.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Write to a file
int writeToFile(int fd, char *buffer, int bytesToWrite);

writeToFile is a low level routine used internally in the CRIS/SIS routines. Primarily it just adds a little error checking to the usual write calls. If writeToFile does not write the expected number of bytes from the buffer into the file, it will exit.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Low Level Data Archival Routines

Low level data archival routines. Available for C only.

Initialize a day's data file for a particular data type
void createInitializedFile(int fd, char dataBuffer[], int bufferSize,
                                                        int dataTypeID);

createInitializedFile initializes a day's data file for a particular data type. It writes the 32 byte header and zeros the rest of the file. The file is made large enough on initialization to contain all of the given type of data for the full day. createInitializedFile assumes that the data type has a periodicity of 256 seconds per data struct. Data types with different periododicities use the routine createInitializedFileWithIntervalN. Non-periodic data types use neither.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Initialize aday's data file for a data type with a period other than 256 secs
void createInitializedFileWithIntervalN(int fd, char dataBuffer[],
                        int bufferSize, int dataTypeID, int timeInterval);

See notes for routine createInitializedFile.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Generate a data file path and create directories as needed for storage
void determineDataFilePathAndCreateDirsAsNeeded(uint32 secondsSince1996,
                                const char *dataFileSuffix, char *path,
                                int *pIntervalNumber, char instrumentID);

determineDataFilePathAndCreateDirsAsNeeded determines the path to the archive file of a particular data type from a particular day. If parts of this path do not exist yet, this routine attempts to create them before handing back the file's (or file-to-be's) path.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Reorder data structs in a file
int sortTrackers(const void *pVoid1, const void *pVoid2);

sortTrackers is called by qsort in a few routines to reorder data structs in their files. This routine is used only for the reordering of non-periodic data types (i.e., those with start and stop time stamps) in their files when a struct needs to be written to an archive file somewhere before the end of the file in order to preserve a chronological ordering of the structs in the file.

Input:

Output:
Last Modified: 4/21/1998 Return to Contents

Write a data struct into the proper position in its archive file
int writeDataStructToFile(int fd, int intervalNumber, char dataBuffer[],
                                int bufferSize, char *pDataStruct, char *path);

writeDataStructToFile is used to write a data struct into the proper position in its archive file.

First this routine checks what has been written into the data file at the interval where the passed data struct is to be written. If the interval is all zeros (done at file initialization), the struct is written and a status of 0 is returned.

If the interval is found to contain data already, both the passed struct and the one already in the file are written out to an auxiliary file (same file name with ".overlap" suffix appended), the interval is filled with char -1s, and a status of 1 is returned.

If the interval is filled with char -1s, then the passed struct is written to the auxiliary file and a status of 2 is returned.

Finally, if the passed data struct is identical to the data already in the interval, nothing is written, and a status of 3 is returned.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents

Write data archive file's header
void writeHeader(int fd, int dataTypeID);

writeHeader is used for writing the 32 byte header present at the beginning of every data file in the archive. See header description.

Input:

Output:
Last Modified: 4/22/1998 Return to Contents