35 #include <lal/XLALError.h>
45 #define POLY64 0xd800000000000000ULL
47 #define BLOCKSIZE 65536
50 unsigned long long crc64(
const unsigned char *
data,
unsigned int length,
unsigned long long crc );
51 static void swap2(
char *location );
52 static void swap4(
char *location );
53 static void swap8(
char *location );
61 unsigned long long crc64(
const unsigned char *
data,
63 unsigned long long crc )
66 unsigned long long CRCTable[
TABLELEN];
70 if ( !length || !
data ) {
80 unsigned long long part =
i;
81 for (
j = 0;
j < 8;
j++ ) {
83 part = ( part >> 1 ) ^
POLY64;
92 for (
i = 0;
i < length;
i++ ) {
93 unsigned long long temp1 = crc >> 8;
94 unsigned long long temp2 = CRCTable[( crc ^ (
unsigned long long )
data[
i] ) & 0xff];
104 char tmp = *location;
105 *location = *( location + 1 );
106 *( location + 1 ) = tmp;
112 char tmp = *location;
113 *location = *( location + 3 );
114 *( location + 3 ) = tmp;
115 swap2( location + 1 );
121 char tmp = *location;
122 *location = *( location + 7 );
123 *( location + 7 ) = tmp;
124 tmp = *( location + 1 );
125 *( location + 1 ) = *( location + 6 );
126 *( location + 6 ) = tmp;
127 swap4( location + 2 );
137 sizeof(
char ) != 1 ||
138 sizeof(
int ) != 4 ||
139 sizeof(
long long ) != 8 ||
165 switch ( errorcode ) {
169 return "SFT file pointer is NULL";
171 return "SFT fseek() failed in stream";
173 return "SFT fread() failed in stream";
175 return "SFT version in header is unknown";
177 return "SFT header GPS nsec not in range 0 to 10^9-1";
179 return "SFT comment length not a multiple of 8";
181 return "SFT fgetpos() failed: unable to save position of stream";
183 return "SFT corrupted: CRC checksum in header does not match data";
185 return "SFT fsetpos() failed: unable to restore stream position";
187 return "SFT calloc() failed: unable to allocate memory";
189 return "SFT sizeof() objects does not match assumptions";
191 return "SFT fwrite() failed";
193 return "SFT library routine passed a null data pointer";
195 return "SFT file empty (zero length)";
197 return "SFT comment contains data AFTER null character";
199 return "SFT comment field is not null-terminated";
201 return "SFT GPS times not increasing between SFT blocks";
203 return "SFT time base changes between SFT blocks";
205 return "SFT first frequency index changes between SFT blocks";
207 return "SFT number of data samples changes between SFT blocks";
209 return "SFT window specification changes between SFT blocks";
211 return "SFT instrument changes between SFT blocks";
213 return "SFT version changes between SFT blocks";
215 return "SFT time base is not positive";
217 return "SFT first frequency index is negative";
219 return "SFT number of data samples is not positive";
221 return "SFT detector not one of A1 B1 E1 G1 H1 H2 K1 L1 N1 O1 P1 T1 V1 V2 X1";
223 return "SFT data requested lies before available data";
225 return "SFT data requested lies after available data";
227 return "SFT data contains a non-FINITE (+/- Inf, NaN) value";
229 return "SFT Error Code not recognized";
242 unsigned short windowspec,
262 if ( gps_nsec < 0 || gps_nsec > 999999999 ) {
267 if (
tbase <= 0.0 ) {
297 for (
i = 0;
i < inc;
i++ ) {
331 if ( 1 != fwrite( (
const void * )&
header,
sizeof(
header ), 1,
fp ) ) {
341 if ( inc != (
int )fwrite( (
const void * )
pad, 1, inc,
fp ) ) {
364 int what, retval = 0;
365 fpos_t streamposition;
366 char *mycomment = NULL;
378 if ( !
info || !swapendian ) {
383 if ( fgetpos(
fp, &streamposition ) ) {
390 if ( !what && feof(
fp ) ) {
399 header_unswapped =
header;
421 if (
header.comment_length % 8 ) {
429 if (
header.nsamples <= 0 ) {
438 unsigned long long crc;
439 unsigned long long crc64save =
header.crc64;
440 int total_length =
header.comment_length + 2 *
sizeof( float ) *
header.nsamples;
442 fpos_t streamposition2;
443 int i, tocheck, foundhidden = 0, comment_left =
header.comment_length, foundnull = !comment_left;
446 if ( fgetpos(
fp, &streamposition2 ) ) {
452 header_unswapped.
crc64 = 0ULL;;
453 crc =
crc64( (
unsigned char * )&header_unswapped,
sizeof( header_unswapped ), ~( 0ULL ) );
456 while ( total_length > 0 ) {
459 if ( toread != (
int )fread( block, 1, toread,
fp ) ) {
463 total_length -= toread;
464 crc =
crc64( (
unsigned char * )block, toread, crc );
468 tocheck = ( comment_left < toread ) ? comment_left : toread;
469 for (
i = 0;
i < tocheck;
i++ ) {
473 if ( foundnull && block[
i] ) {
477 comment_left -= tocheck;
481 if ( crc != crc64save ) {
501 if ( fsetpos(
fp, &streamposition2 ) ) {
508 if (
header.gps_nsec < 0 ||
header.gps_nsec > 999999999 ) {
514 if (
header.tbase <= 0.0 ) {
520 if (
header.firstfreqindex < 0 ) {
535 if ( !( mycomment = calloc(
header.comment_length, 1 ) ) ) {
541 if (
header.comment_length != (
int )fread( mycomment, 1,
header.comment_length,
fp ) ) {
551 for (
i = 0;
i <
header.comment_length;
i++ ) {
552 if ( !mycomment[
i] ) {
555 if ( !retval && mycomment[
i] ) {
569 if ( fsetpos(
fp, &streamposition ) ) {
602 fpos_t streamposition;
603 int retval = 0, swapendian;
617 if ( fgetpos(
fp, &streamposition ) ) {
644 if ( fseek(
fp, seekforward, SEEK_CUR ) ) {
672 if ( fsetpos(
fp, &streamposition ) ) {
677 if (
info && !retval ) {
691 if ( !headerone || !headertwo ) {
741 const char *knownDetectors[] = {
764 for (
i = 0; knownDetectors[
i];
i++ ) {
797 if ( !(
fp = fopen( fname,
"r" ) ) ) {
808 memset( &lastinfo, 0,
sizeof( lastinfo ) );
811 int swapendian, move,
j;
840 data = (
float * )realloc( (
void * )
data,
info.nsamples * 4 * 2 );
859 for (
j = 0;
j <
info.nsamples;
j++ ) {
860 if ( !isfinite(
data[2 *
j] ) || !isfinite(
data[2 *
j + 1] ) ) {
872 fseek(
fp, move, SEEK_CUR );
#define __func__
log an I/O error, i.e.
static int validate_sizes(void)
static void swap2(char *location)
static void swap4(char *location)
unsigned long long crc64(const unsigned char *data, unsigned int length, unsigned long long crc)
static int validate_version(double version)
static void swap8(char *location)
Internal SFT types and functions.
#define SFTERESTORESTREAMPOS
#define SFTEVERSIONCHANGES
const char * SFTErrorMessage(int errorcode)
int CheckSFTHeaderConsistency(struct headertag2 *headerone, struct headertag2 *headertwo)
#define SFTEHIDDENCOMMENT
int unknownDetector(const char *detector)
#define SFTENSAMPLESCHANGES
#define SFTEFIRSTINDEXCHANGES
#define SFTEWINDOWSPECCHANGES
int ReadSFTHeader(FILE *fp, struct headertag2 *info, char **comment, int *swapendian, int validate)
int ValidateSFTFile(const char *fname)
Verify that the contents of a SFT file are valid.
#define SFTENONULLINCOMMENT
#define SFTEINSTRUMENTUNKNOWN
#define SFTEGPSNOTINCREASING
int WriteSFT(FILE *fp, int gps_sec, int gps_nsec, double tbase, int firstfreqindex, int nsamples, const char *detector, unsigned short windowspec, const char *comment, float *data)
#define SFTENSAMPLESNOTPOS
int ReadSFTData(FILE *fp, float *data, int firstbin, int nsamples, char **comment, struct headertag2 *info)
#define SFTEINSTRUMENTCHANGES
#define SFTEFIRSTINDEXNEG
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1