|
|
@ -29,18 +29,62 @@ SER::SER() {
|
|
|
|
header.DateTime = 0;
|
|
|
|
header.DateTime = 0;
|
|
|
|
header.DateTimeUTC = 0;
|
|
|
|
header.DateTimeUTC = 0;
|
|
|
|
|
|
|
|
|
|
|
|
fd = NULL;
|
|
|
|
FileDesc = NULL;
|
|
|
|
Frame = NULL;
|
|
|
|
Frame = NULL;
|
|
|
|
|
|
|
|
FramePointer = 0;
|
|
|
|
|
|
|
|
Reading = 1;
|
|
|
|
|
|
|
|
NumberOfTimeStamps = 0;
|
|
|
|
|
|
|
|
TimeStamps = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Class destructor. Free resources.
|
|
|
|
Class destructor. Free resources.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
SER::~SER() {
|
|
|
|
SER::~SER() {
|
|
|
|
/* Close file if necessary */
|
|
|
|
|
|
|
|
if(fd) {
|
|
|
|
if(FileDesc) {
|
|
|
|
fclose(fd);
|
|
|
|
|
|
|
|
|
|
|
|
/* Update header if necessary */
|
|
|
|
|
|
|
|
if(!Reading) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
long offset = (long)&header.FrameCount - (long)&header;
|
|
|
|
|
|
|
|
header.FrameCount = FramePointer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* goto file beginning */
|
|
|
|
|
|
|
|
if((err = fseek(FileDesc, offset, SEEK_SET)) == -1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed seek SER file FrameCount (%d, %s)\n", err, strerror(errno));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
/* write framecount in header data */
|
|
|
|
|
|
|
|
if((err = fwrite(&header.FrameCount, sizeof(header.FrameCount), 1, FileDesc)) != 1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed writing SER file FrameCount (%d, %s)\n",
|
|
|
|
|
|
|
|
err, strerror(errno));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* goto file end */
|
|
|
|
|
|
|
|
if((err = fseek(FileDesc, 0, SEEK_END)) == -1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed seek SER file end (%d, %s)\n", err, strerror(errno));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
/* write timestamp data */
|
|
|
|
|
|
|
|
if((err = fwrite(TimeStamps, sizeof(header.DateTime), FramePointer, FileDesc)) != FramePointer) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed writing SER file TimeStamps (%d, %s)\n",
|
|
|
|
|
|
|
|
err, strerror(errno));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Close file if necessary */
|
|
|
|
|
|
|
|
fclose(FileDesc);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Free timestamps */
|
|
|
|
|
|
|
|
if(TimeStamps) {
|
|
|
|
|
|
|
|
free(TimeStamps);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Free frame memory if necessary */
|
|
|
|
/* Free frame memory if necessary */
|
|
|
|
if(Frame) {
|
|
|
|
if(Frame) {
|
|
|
|
free(Frame);
|
|
|
|
free(Frame);
|
|
|
@ -79,6 +123,7 @@ int SER::setTelescope(char *name) {
|
|
|
|
for reading, otherwise we try to create the file.
|
|
|
|
for reading, otherwise we try to create the file.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int SER::setFile(char *name) {
|
|
|
|
int SER::setFile(char *name) {
|
|
|
|
|
|
|
|
|
|
|
|
FILE *file;
|
|
|
|
FILE *file;
|
|
|
|
|
|
|
|
|
|
|
|
/* try opening file for reading */
|
|
|
|
/* try opening file for reading */
|
|
|
@ -93,13 +138,15 @@ int SER::setFile(char *name) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
fprintf(stdout, "Debug: created file '%s' for writing SER file\n", name);
|
|
|
|
fprintf(stdout, "Debug: created file '%s' for writing SER file\n", name);
|
|
|
|
fd = file;
|
|
|
|
FileDesc = file;
|
|
|
|
|
|
|
|
Reading = 0;
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fprintf(stdout, "Debug: opened file '%s' for reading SER file\n", name);
|
|
|
|
fprintf(stdout, "Debug: opened file '%s' for reading SER file\n", name);
|
|
|
|
fd = file;
|
|
|
|
FileDesc = file;
|
|
|
|
|
|
|
|
Reading = 1;
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -113,22 +160,64 @@ int SER::writeHeader(void) {
|
|
|
|
/* adjust time stamps for header */
|
|
|
|
/* adjust time stamps for header */
|
|
|
|
setDateTime();
|
|
|
|
setDateTime();
|
|
|
|
|
|
|
|
|
|
|
|
if(fd == NULL) {
|
|
|
|
if(FileDesc == NULL) {
|
|
|
|
fprintf(stderr, "Error: writing header, SER file not yet specified\n");
|
|
|
|
fprintf(stderr, "Error: writing header, SER file not yet specified\n");
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* goto file beginning */
|
|
|
|
/* goto file beginning */
|
|
|
|
if((err = fseek(fd, 0, SEEK_SET)) == -1) {
|
|
|
|
if((err = fseek(FileDesc, 0, SEEK_SET)) == -1) {
|
|
|
|
fprintf(stderr, "Error: failed seek SER file beginning (%d, %s)\n", err, strerror(errno));
|
|
|
|
fprintf(stderr, "Error: failed seek SER file beginning (%d, %s)\n", err, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* write header data */
|
|
|
|
/* write header data */
|
|
|
|
if((err = fwrite(&header, sizeof(header), 1, fd)) != 1) {
|
|
|
|
if((err = fwrite(&header, sizeof(header), 1, FileDesc)) != 1) {
|
|
|
|
fprintf(stderr, "Error: failed writing SER header (%d, %s)\n", err, strerror(errno));
|
|
|
|
fprintf(stderr, "Error: failed writing SER header (%d, %s)\n", err, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reset space for timestamps */
|
|
|
|
|
|
|
|
NumberOfTimeStamps = 16;
|
|
|
|
|
|
|
|
if(TimeStamps) {
|
|
|
|
|
|
|
|
free(TimeStamps);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate some memory for the upcoming timestamps */
|
|
|
|
|
|
|
|
if((TimeStamps = (int64_t *)malloc(sizeof(header.DateTime) * NumberOfTimeStamps)) == NULL) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed to allocate %d bytes for timestamps\n",
|
|
|
|
|
|
|
|
sizeof(header.DateTime) * NumberOfTimeStamps);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FramePointer = 0;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
The function reads the file header of the SER file.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int SER::readHeader(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(FileDesc == NULL) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: reading header, SER file not yet specified\n");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* goto file beginning */
|
|
|
|
|
|
|
|
if((err = fseek(FileDesc, 0, SEEK_SET)) == -1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed seek SER file beginning (%d, %s)\n", err, strerror(errno));
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* read header data */
|
|
|
|
|
|
|
|
if((err = fread(&header, sizeof(header), 1, FileDesc)) != 1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed reading SER header (%d, %s)\n", err, strerror(errno));
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FramePointer = 0;
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -138,17 +227,29 @@ int SER::writeHeader(void) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int SER::appendFrame(void *data) {
|
|
|
|
int SER::appendFrame(void *data) {
|
|
|
|
|
|
|
|
|
|
|
|
if(fd == NULL) {
|
|
|
|
if(FileDesc == NULL) {
|
|
|
|
fprintf(stderr, "Error: appending frame, SER file not yet specified\n");
|
|
|
|
fprintf(stderr, "Error: appending frame, SER file not yet specified\n");
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* write frame data */
|
|
|
|
/* write frame data */
|
|
|
|
if(fwrite(data, FrameSize, 1, fd) != 1) {
|
|
|
|
if(fwrite(data, FrameSize, 1, FileDesc) != 1) {
|
|
|
|
fprintf(stderr, "Error: failed write SER frame (%s)\n", strerror(errno));
|
|
|
|
fprintf(stderr, "Error: failed write SER frame (%s)\n", strerror(errno));
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ensure we have enough memory allocated for timestamps */
|
|
|
|
|
|
|
|
if(FramePointer >= NumberOfTimeStamps) {
|
|
|
|
|
|
|
|
NumberOfTimeStamps *= 2;
|
|
|
|
|
|
|
|
if((TimeStamps = (int64_t *)realloc(TimeStamps, sizeof(header.DateTime) * NumberOfTimeStamps)) == NULL) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed to re-allocate %d bytes for timestamps\n",
|
|
|
|
|
|
|
|
sizeof(header.DateTime) * NumberOfTimeStamps);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* save timestamp for this frame */
|
|
|
|
|
|
|
|
TimeStamps[FramePointer++] = currentDateTime();
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -254,15 +355,59 @@ void * SER::allocFrame(void) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int SER::readFrame(void *data) {
|
|
|
|
int SER::readFrame(void *data) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
|
|
/* read frame data */
|
|
|
|
/* read frame data */
|
|
|
|
if(fread(data, FrameSize, 1, fd) != FrameSize) {
|
|
|
|
if((err = fread(data, FrameSize, 1, FileDesc)) != 1) {
|
|
|
|
fprintf(stderr, "Error: failed reading SER frame (%s)\n", strerror(errno));
|
|
|
|
fprintf(stderr, "Error: failed reading SER frame (%d, %s)\n", err, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* goto next frame */
|
|
|
|
|
|
|
|
FramePointer++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reached end of file? */
|
|
|
|
|
|
|
|
if(FramePointer >= getNumberOfFrames()) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* goto first frame beginning */
|
|
|
|
|
|
|
|
if((err = fseek(FileDesc, sizeof(header), SEEK_SET)) == -1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed seeking SER file frame #%d (%d, %s)\n",
|
|
|
|
|
|
|
|
0, err, strerror(errno));
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* start over at beginning */
|
|
|
|
|
|
|
|
FramePointer = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
The function reads a single frame at the given file position.
|
|
|
|
|
|
|
|
Frame size is determined by internal header data.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int SER::readFrame(void *data, int frame) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* goto frame beginning */
|
|
|
|
|
|
|
|
if((err = fseek(FileDesc, sizeof(header) + frame * FrameSize, SEEK_SET)) == -1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed seeking SER file frame #%d (%d, %s)\n",
|
|
|
|
|
|
|
|
frame, err, strerror(errno));
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* read frame data */
|
|
|
|
|
|
|
|
if((err = fread(data, FrameSize, 1, FileDesc)) != 1) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Error: failed reading SER frame (%d, %s)\n", err, strerror(errno));
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FramePointer = frame + 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Sets the number of frames in the header.
|
|
|
|
Sets the number of frames in the header.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -277,6 +422,18 @@ int32_t SER::getNumberOfFrames(void) {
|
|
|
|
return header.FrameCount;
|
|
|
|
return header.FrameCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Sets the current timestamps in the header.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int64_t SER::setDateTime(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int64_t hundred_nano_seconds = currentDateTime();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
header.DateTime = hundred_nano_seconds;
|
|
|
|
|
|
|
|
header.DateTimeUTC = hundred_nano_seconds + differenceLocalUTC();
|
|
|
|
|
|
|
|
return header.DateTime;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
Timestamps in SER
|
|
|
|
Timestamps in SER
|
|
|
|
-----------------
|
|
|
|
-----------------
|
|
|
@ -288,18 +445,17 @@ int32_t SER::getNumberOfFrames(void) {
|
|
|
|
maximum value represents 100 nanoseconds before the beginning of
|
|
|
|
maximum value represents 100 nanoseconds before the beginning of
|
|
|
|
January 1 of the year 10000.
|
|
|
|
January 1 of the year 10000.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int64_t SER::setDateTime() {
|
|
|
|
int64_t SER::currentDateTime(void) {
|
|
|
|
|
|
|
|
|
|
|
|
int64_t hundred_nano_seconds;
|
|
|
|
int64_t hundred_nano_seconds;
|
|
|
|
struct timeval current_time;
|
|
|
|
struct timeval current_time;
|
|
|
|
|
|
|
|
struct timezone current_zone;
|
|
|
|
|
|
|
|
|
|
|
|
/* get time since 01.01.1970 00:00 */
|
|
|
|
/* get time since 01.01.1970 00:00 */
|
|
|
|
gettimeofday(¤t_time, NULL);
|
|
|
|
gettimeofday (¤t_time, ¤t_zone);
|
|
|
|
hundred_nano_seconds = (62135769600L + current_time.tv_sec) * 10000000L +
|
|
|
|
hundred_nano_seconds = (62135596800L + current_time.tv_sec) * 10000000L +
|
|
|
|
current_time.tv_usec * 10L;
|
|
|
|
current_time.tv_usec * 10L;
|
|
|
|
header.DateTime = hundred_nano_seconds;
|
|
|
|
return hundred_nano_seconds;
|
|
|
|
header.DateTimeUTC = hundred_nano_seconds + differenceLocalUTC();
|
|
|
|
|
|
|
|
return header.DateTime;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
@ -307,16 +463,16 @@ int64_t SER::setDateTime() {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
int64_t SER::differenceLocalUTC(void) {
|
|
|
|
int64_t SER::differenceLocalUTC(void) {
|
|
|
|
|
|
|
|
|
|
|
|
time_t abs_ts,loc_ts,gmt_ts;
|
|
|
|
time_t abs_ts, loc_ts, gmt_ts;
|
|
|
|
struct tm loc_time_info,gmt_time_info;
|
|
|
|
struct tm loc_time_info, gmt_time_info;
|
|
|
|
|
|
|
|
|
|
|
|
/* Absolute time stamp.*/
|
|
|
|
/* Absolute time stamp.*/
|
|
|
|
time (&abs_ts);
|
|
|
|
time (&abs_ts);
|
|
|
|
|
|
|
|
|
|
|
|
/* Now get once the local time for this time stamp,
|
|
|
|
/* Now get once the local time for this time stamp,
|
|
|
|
and once the GMT (UTC without summer time) time stamp.*/
|
|
|
|
and once the GMT (UTC without summer time) time stamp.*/
|
|
|
|
localtime_r (&abs_ts,&loc_time_info);
|
|
|
|
localtime_r (&abs_ts, &loc_time_info);
|
|
|
|
gmtime_r (&abs_ts,&gmt_time_info);
|
|
|
|
gmtime_r (&abs_ts, &gmt_time_info);
|
|
|
|
|
|
|
|
|
|
|
|
/* Convert them back.*/
|
|
|
|
/* Convert them back.*/
|
|
|
|
loc_ts = mktime (&loc_time_info);
|
|
|
|
loc_ts = mktime (&loc_time_info);
|
|
|
@ -325,5 +481,7 @@ int64_t SER::differenceLocalUTC(void) {
|
|
|
|
/* Unfortunately, GMT still has summer time. Get rid of it:*/
|
|
|
|
/* Unfortunately, GMT still has summer time. Get rid of it:*/
|
|
|
|
if (gmt_time_info.tm_isdst == 1) gmt_ts -= 3600;
|
|
|
|
if (gmt_time_info.tm_isdst == 1) gmt_ts -= 3600;
|
|
|
|
|
|
|
|
|
|
|
|
return (loc_ts-gmt_ts) * 10000000L;
|
|
|
|
fprintf(stdout, "Debug: difference between local time and UTC is %ld hours\n",
|
|
|
|
|
|
|
|
(loc_ts - gmt_ts) / 3600);
|
|
|
|
|
|
|
|
return ((int64_t)gmt_ts - (int64_t)loc_ts) * 10000000L;
|
|
|
|
}
|
|
|
|
}
|
|
|
|