00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 #include <stdlib.h>
00103 #include <string.h>
00104 #include <math.h>
00105 #include <sys/param.h>
00106 #include <sys/types.h>
00107 #include <sys/stat.h>
00108 #include <unistd.h>
00109
00110
00111 #ifdef __GLIBC__
00112 #ifdef __restrict_arr
00113 #undef __restrict_arr
00114 #endif
00115 #define __restrict_arr
00116 #endif
00117
00118 #include <regex.h>
00119 #include <glob.h>
00120
00121 #include <lal/LALStdio.h>
00122 #include <lal/LALStdlib.h>
00123 #include <lal/FrameCache.h>
00124
00125 NRCSID( FRAMECACHEC, "$Id: FrameCache.c,v 1.14 2007/06/08 14:41:46 bema Exp $" );
00126
00127 #define TMPSTRLEN 15
00128 #define XSTR( x ) #x
00129 #define STR( x ) XSTR( x )
00130
00131 static int FrStatCompare( const void *p1, const void *p2 );
00132
00133 FrCache * XLALFrImportCache( const char *fname )
00134 {
00135 static const char *func = "XLALFrImportCache";
00136 UINT4 numLines = 0;
00137 CHAR line[1024];
00138 FILE *fp;
00139 FrCache *cache;
00140
00141 fp = LALFopen( fname, "r" );
00142 if ( ! fp )
00143 {
00144 XLALPrintError( "XLAL Error - %s: couldn't open file %s for input\n",
00145 func, fname );
00146 XLAL_ERROR_NULL( func, XLAL_EIO );
00147 }
00148 numLines = 0;
00149 while ( fgets( line, sizeof( line ), fp ) )
00150 {
00151 if ( strlen( line ) > sizeof( line ) - 2 )
00152 {
00153 XLALPrintError( "XLAL Error - %s: line too long in %s (max length: %d)\n",
00154 func, fname, (int)sizeof( line ) - 2 );
00155 XLAL_ERROR_NULL( func, XLAL_EBADLEN );
00156 }
00157 ++numLines;
00158 }
00159 if ( ! numLines )
00160 {
00161 XLALPrintError( "XLAL Error - %s: empty file %s\n", func, fname );
00162 XLAL_ERROR_NULL( func, XLAL_EIO );
00163 }
00164
00165 cache = LALCalloc( 1, sizeof( *cache ) );
00166 if ( ! cache )
00167 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00168 cache->numFrameFiles = numLines;
00169 cache->frameFiles = LALCalloc( numLines, sizeof( *cache->frameFiles ) );
00170 if ( ! cache->frameFiles )
00171 {
00172 LALFree( cache );
00173 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00174 }
00175
00176 rewind( fp );
00177 numLines = 0;
00178 while ( fgets( line, sizeof( line ), fp ) )
00179 {
00180 FrStat *file = cache->frameFiles + numLines++;
00181 char t0[TMPSTRLEN + 1];
00182 char dt[TMPSTRLEN + 1];
00183 int src0, src1;
00184 int dsc0, dsc1;
00185 int url0, url1;
00186 int c;
00187 sscanf( line, "%n%*[a-zA-Z0-9_+#-]%n %n%*[a-zA-Z0-9_+#-]%n %*"
00188 STR( TMPSTRLEN ) "s %*" STR( TMPSTRLEN ) "s %n%*s%n",
00189 &src0, &src1, &dsc0, &dsc1, &url0, &url1 );
00190 file->source = LALMalloc( src1 - src0 + 1 );
00191 file->description = LALMalloc( dsc1 - dsc0 + 1 );
00192 file->url = LALMalloc( url1 - url0 + 1 );
00193 if ( ! file->source || ! file->description || ! file->url )
00194 {
00195 XLALFrDestroyCache( cache );
00196 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00197 }
00198 c = sscanf( line, "%[a-zA-Z0-9_+#-] %[a-zA-Z0-9_+#-] %" STR( TMPSTRLEN )
00199 "s %" STR( TMPSTRLEN ) "s %s", file->source, file->description,
00200 t0, dt, file->url );
00201 if ( strchr( file->source, '-' ) )
00202 {
00203 LALFree( file->source );
00204 file->source = NULL;
00205 }
00206 if ( strchr( file->description, '-' ) )
00207 {
00208 LALFree( file->description );
00209 file->description = NULL;
00210 }
00211 if ( *file->url == '-' )
00212 {
00213 LALFree( file->url );
00214 file->url = NULL;
00215 }
00216 if ( strchr( t0, '-' ) || 0 == ( file->startTime = atoi( t0 ) ) )
00217 {
00218 file->startTime = 0;
00219 }
00220 if ( strchr( dt, '-' ) || 0 == ( file->duration = atoi( dt ) ) )
00221 {
00222 file->duration = 0;
00223 }
00224 }
00225 LALFclose( fp );
00226 return cache;
00227 }
00228
00229
00230 FrCache * XLALFrSieveCache( FrCache *input, FrCacheSieve *params )
00231 {
00232 static const char *func = "XLALFrSieveCache";
00233 FrCache *cache;
00234
00235 regex_t srcReg;
00236 regex_t dscReg;
00237 regex_t urlReg;
00238
00239 UINT4 n;
00240 UINT4 i;
00241
00242 if ( params->srcRegEx )
00243 regcomp( &srcReg, params->srcRegEx, REG_NOSUB );
00244 if ( params->dscRegEx )
00245 regcomp( &dscReg, params->dscRegEx, REG_NOSUB );
00246 if ( params->urlRegEx )
00247 regcomp( &urlReg, params->urlRegEx, REG_NOSUB );
00248
00249 n = 0;
00250 for ( i = 0; i < input->numFrameFiles; ++i )
00251 {
00252 FrStat *file = input->frameFiles + i;
00253 if ( params->earliestTime > 0 )
00254 if ( params->earliestTime > file->startTime + file->duration )
00255 continue;
00256 if ( params->latestTime > 0 )
00257 if ( file->startTime <= 0 || params->latestTime < file->startTime )
00258 continue;
00259 if ( params->srcRegEx )
00260 if ( ! file->source || regexec( &srcReg, file->source, 0, NULL, 0 ) )
00261 continue;
00262 if ( params->dscRegEx )
00263 if ( ! file->description
00264 || regexec( &dscReg, file->description, 0, NULL, 0 ) )
00265 continue;
00266 if ( params->urlRegEx )
00267 if ( ! file->source || regexec( &urlReg, file->url, 0, NULL, 0 ) )
00268 continue;
00269 ++n;
00270 }
00271
00272 cache = LALCalloc( 1, sizeof( *cache ) );
00273 if ( ! cache )
00274 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00275
00276 cache->numFrameFiles = n;
00277 if ( ! cache->numFrameFiles )
00278 cache->frameFiles = NULL;
00279 else
00280 {
00281 cache->frameFiles = LALCalloc( n, sizeof( *cache->frameFiles ) );
00282 if ( ! cache->frameFiles )
00283 {
00284 LALFree( cache );
00285 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00286 }
00287
00288 n = 0;
00289 for ( i = 0; i < input->numFrameFiles; ++i )
00290 {
00291 FrStat *file = input->frameFiles + i;
00292 if ( params->earliestTime > 0 )
00293 if ( params->earliestTime > file->startTime + file->duration )
00294 continue;
00295 if ( params->latestTime > 0 )
00296 if ( file->startTime <= 0 || params->latestTime < file->startTime )
00297 continue;
00298 if ( params->srcRegEx )
00299 if ( ! file->source || regexec( &srcReg, file->source, 0, NULL, 0 ) )
00300 continue;
00301 if ( params->dscRegEx )
00302 if ( ! file->description
00303 || regexec( &dscReg, file->description, 0, NULL, 0 ) )
00304 continue;
00305 if ( params->urlRegEx )
00306 if ( ! file->source || regexec( &urlReg, file->url, 0, NULL, 0 ) )
00307 continue;
00308
00309
00310 cache->frameFiles[n] = *file;
00311 if ( file->source )
00312 {
00313 size_t size = strlen( file->source ) + 1;
00314 cache->frameFiles[n].source = LALMalloc( size );
00315 if ( ! cache->frameFiles[n].source )
00316 {
00317 XLALFrDestroyCache( cache );
00318 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00319 }
00320 memcpy( cache->frameFiles[n].source, file->source, size );
00321 }
00322 if ( file->description )
00323 {
00324 size_t size = strlen( file->description ) + 1;
00325 cache->frameFiles[n].description = LALMalloc( size );
00326 if ( ! cache->frameFiles[n].description )
00327 {
00328 XLALFrDestroyCache( cache );
00329 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00330 }
00331 memcpy( cache->frameFiles[n].description, file->description, size );
00332 }
00333 if ( file->url )
00334 {
00335 size_t size = strlen( file->url ) + 1;
00336 cache->frameFiles[n].url = LALMalloc( size );
00337 if ( ! cache->frameFiles[n].url )
00338 {
00339 XLALFrDestroyCache( cache );
00340 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00341 }
00342 memcpy( cache->frameFiles[n].url, file->url, size );
00343 }
00344 ++n;
00345 }
00346
00347 qsort( cache->frameFiles, cache->numFrameFiles,
00348 sizeof( *cache->frameFiles ), FrStatCompare );
00349 }
00350
00351 if ( params->srcRegEx ) regfree( &srcReg );
00352 if ( params->dscRegEx ) regfree( &dscReg );
00353 if ( params->urlRegEx ) regfree( &urlReg );
00354
00355 return cache;
00356 }
00357
00358
00359 FrCache * XLALFrGenerateCache( const CHAR *dirstr, const CHAR *fnptrn )
00360 {
00361 static const char *func = "XLALFrGenerateCache";
00362 FrCache *cache;
00363 glob_t g;
00364 int globflags = 0;
00365 int i;
00366
00367 fnptrn = fnptrn ? fnptrn : "*.gwf";
00368 dirstr = dirstr ? dirstr : ".";
00369
00370 if ( fnptrn[0] &&
00371 ( fnptrn[0] == '/'
00372 || ( fnptrn[0] == '.' && fnptrn[1] &&
00373 ( fnptrn[1] == '/' || ( fnptrn[1] == '.' && fnptrn[2] == '/' ) ) )
00374 )
00375 )
00376 glob( fnptrn, globflags, NULL, &g );
00377 else
00378 {
00379 CHAR path[MAXPATHLEN];
00380 CHAR dirname[MAXPATHLEN];
00381 CHAR *nextdir;
00382 strncpy( dirname, dirstr, sizeof( dirname ) - 1 );
00383 do
00384 {
00385 nextdir = strchr( dirname, ':' );
00386 if ( nextdir )
00387 *nextdir++ = 0;
00388 LALSnprintf( path, sizeof( path ) - 1, "%s/%s",
00389 *dirname ? dirname : ".", fnptrn );
00390 glob( path, globflags, NULL, &g );
00391 fnptrn = path;
00392 globflags |= GLOB_APPEND;
00393 }
00394 while ( nextdir );
00395 }
00396
00397 if ( ! g.gl_pathc )
00398 {
00399 XLALPrintError( "XLAL Error - %s: no frame files found in %s",
00400 func, fnptrn );
00401 XLAL_ERROR_NULL( func, XLAL_EIO );
00402 }
00403
00404 cache = LALCalloc( 1, sizeof( *cache ) );
00405 if ( ! cache )
00406 {
00407 globfree( &g );
00408 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00409 }
00410 cache->numFrameFiles = g.gl_pathc;
00411 cache->frameFiles = LALCalloc( g.gl_pathc, sizeof( *cache->frameFiles ) );
00412 if ( ! cache->frameFiles )
00413 {
00414 globfree( &g );
00415 LALFree( cache );
00416 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00417 }
00418
00419
00420 for ( i = 0; i < g.gl_pathc; ++i )
00421 {
00422 FrStat *file = cache->frameFiles + i;
00423 char src[MAXPATHLEN];
00424 char dsc[MAXPATHLEN];
00425 int t0 = 0;
00426 int dt = 0;
00427 char *path = g.gl_pathv[i];
00428 char *base = strrchr( path, '/' );
00429 int c;
00430 if ( ! base )
00431 base = path;
00432 else
00433 ++base;
00434 if ( *path == '/' )
00435 {
00436 size_t urlsz = strlen( path ) + sizeof( "file://localhost" );
00437 file->url = LALMalloc( urlsz );
00438 if ( ! file->url )
00439 {
00440 globfree( &g );
00441 XLALFrDestroyCache( cache );
00442 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00443 }
00444 LALSnprintf( file->url, urlsz, "file://localhost%s", path );
00445 }
00446 else
00447 {
00448 size_t urlsz = strlen( path ) + sizeof( "file://localhost" );
00449 CHAR cwd[MAXPATHLEN];
00450 getcwd( cwd, MAXPATHLEN - 1 );
00451 urlsz += strlen( cwd ) + 1;
00452 file->url = LALMalloc( urlsz );
00453 if ( ! file->url )
00454 {
00455 globfree( &g );
00456 XLALFrDestroyCache( cache );
00457 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00458 }
00459 LALSnprintf( file->url, urlsz, "file://localhost%s/%s", cwd, path );
00460 }
00461
00462
00463 c = sscanf( base ? base : path, "%[a-zA-Z0-9_+#]-%[a-zA-Z0-9_+#]-%d-%d",
00464 src, dsc, &t0, &dt );
00465 if ( c == 4 )
00466 {
00467 file->source = LALMalloc( strlen( src ) + 1 );
00468 if ( ! file->source )
00469 {
00470 globfree( &g );
00471 XLALFrDestroyCache( cache );
00472 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00473 }
00474 strcpy( file->source, src );
00475 file->description = LALMalloc( strlen( dsc ) + 1 );
00476 if ( ! file->description )
00477 {
00478 globfree( &g );
00479 XLALFrDestroyCache( cache );
00480 XLAL_ERROR_NULL( func, XLAL_ENOMEM );
00481 }
00482 strcpy( file->description, dsc );
00483 file->startTime = t0;
00484 file->duration = dt;
00485 }
00486 }
00487
00488 globfree( &g );
00489
00490 qsort( cache->frameFiles, cache->numFrameFiles, sizeof( *cache->frameFiles ),
00491 FrStatCompare );
00492
00493 return cache;
00494 }
00495
00496
00497 int XLALFrExportCache( FrCache *cache, const CHAR *fname )
00498 {
00499 static const char *func = "XLALFrExportCache";
00500 UINT4 i;
00501 FILE *fp;
00502
00503 if ( ! cache || ! fname )
00504 XLAL_ERROR( func, XLAL_EFAULT );
00505
00506 fp = LALFopen( fname, "w" );
00507 if ( ! fp )
00508 {
00509 XLALPrintError( "XLAL Error - %s: could not open file %s for output\n",
00510 func, fname );
00511 XLAL_ERROR( func, XLAL_EIO );
00512 }
00513
00514 for ( i = 0; i < cache->numFrameFiles; ++i )
00515 {
00516 FrStat *file = cache->frameFiles + i;
00517 char t0[TMPSTRLEN + 1];
00518 char dt[TMPSTRLEN + 1];
00519 int c;
00520 if ( file->startTime > 0 )
00521 LALSnprintf( t0, sizeof( t0 ), "%d", file->startTime );
00522 else
00523 strncpy( t0, "-", sizeof( t0 ) );
00524 if ( file->duration > 0 )
00525 LALSnprintf( dt, sizeof( dt ), "%d", file->duration );
00526 else
00527 LALSnprintf( dt, sizeof( dt ), "-" );
00528
00529 c = fprintf( fp, "%s %s %s %s %s\n", file->source ? file->source : "-",
00530 file->description ? file->description : "-", t0, dt,
00531 file->url ? file->url : "-" );
00532 if ( c < 1 )
00533 {
00534 XLALPrintError( "XLAL Error - %s: could not output to file %s\n",
00535 func, fname );
00536 XLAL_ERROR( func, XLAL_EIO );
00537 }
00538 }
00539 LALFclose( fp );
00540 return 0;
00541 }
00542
00543
00544 void XLALFrDestroyCache( FrCache *cache )
00545 {
00546 if ( cache )
00547 {
00548 UINT4 i;
00549 for ( i = 0; i < cache->numFrameFiles; ++i )
00550 {
00551 FrStat *file = cache->frameFiles + i;
00552 if ( file->source )
00553 LALFree( file->source );
00554 if ( file->description )
00555 LALFree( file->description );
00556 if ( file->url )
00557 LALFree( file->url );
00558 }
00559 if ( cache->frameFiles )
00560 LALFree( cache->frameFiles );
00561 LALFree( cache );
00562 }
00563 return;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 void LALFrCacheImport(
00577 LALStatus *status,
00578 FrCache **output,
00579 const CHAR *fname
00580 )
00581 {
00582 INITSTATUS( status, "LALFrCacheImport", FRAMECACHEC );
00583 ASSERT( output, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00584 ASSERT( ! *output, status, FRAMECACHEH_ENNUL, FRAMECACHEH_MSGENNUL );
00585 ASSERT( fname, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00586
00587 *output = XLALFrImportCache( fname );
00588 if ( ! *output )
00589 {
00590 int errnum = xlalErrno;
00591 XLALClearErrno();
00592 switch ( errnum )
00593 {
00594 case XLAL_EIO:
00595 ABORT( status, FRAMECACHEH_EIEIO, FRAMECACHEH_MSGEIEIO );
00596 case XLAL_EBADLEN:
00597 ABORT( status, FRAMECACHEH_ELINE, FRAMECACHEH_MSGELINE );
00598 case XLAL_ENOMEM:
00599 ABORT( status, FRAMECACHEH_EALOC, FRAMECACHEH_MSGEALOC );
00600 default:
00601 ABORTXLAL( status );
00602 }
00603 }
00604
00605 RETURN( status );
00606 }
00607
00608
00609
00610 void LALFrCacheExport(
00611 LALStatus *status,
00612 FrCache *cache,
00613 const CHAR *fname
00614 )
00615 {
00616 INITSTATUS( status, "LALFrCacheExport", FRAMECACHEC );
00617 ASSERT( cache, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00618 ASSERT( fname, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00619
00620 if ( XLALFrExportCache( cache, fname ) < 0 )
00621 {
00622 XLALClearErrno();
00623 ABORT( status, FRAMECACHEH_EIEIO, FRAMECACHEH_MSGEIEIO );
00624 }
00625
00626 RETURN( status );
00627 }
00628
00629
00630
00631 void
00632 LALDestroyFrCache(
00633 LALStatus *status,
00634 FrCache **cache
00635 )
00636 {
00637 INITSTATUS( status, "LALDestroyFrCache", FRAMECACHEC );
00638 ASSERT( cache, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00639 ASSERT( *cache, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00640
00641 XLALFrDestroyCache( *cache );
00642 *cache = NULL;
00643
00644 RETURN( status );
00645 }
00646
00647
00648
00649 void
00650 LALFrCacheSieve(
00651 LALStatus *status,
00652 FrCache **output,
00653 FrCache *input,
00654 FrCacheSieve *params
00655 )
00656 {
00657 INITSTATUS( status, "LALFrCacheSieve", FRAMECACHEC );
00658 ASSERT( output, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00659 ASSERT( ! *output, status, FRAMECACHEH_ENNUL, FRAMECACHEH_MSGENNUL );
00660 ASSERT( input, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00661 ASSERT( params, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00662
00663 *output = XLALFrSieveCache( input, params );
00664 if ( ! *output )
00665 {
00666 XLALClearErrno();
00667 ABORT( status, FRAMECACHEH_EALOC, FRAMECACHEH_MSGEALOC );
00668 }
00669
00670 RETURN( status );
00671 }
00672
00673
00674
00675 void
00676 LALFrCacheGenerate(
00677 LALStatus *status,
00678 FrCache **output,
00679 const CHAR *dirstr,
00680 const CHAR *fnptrn
00681 )
00682 {
00683 INITSTATUS( status, "LALFrCacheGenerate", FRAMECACHEC );
00684 ASSERT( output, status, FRAMECACHEH_ENULL, FRAMECACHEH_MSGENULL );
00685 ASSERT( ! *output, status, FRAMECACHEH_ENNUL, FRAMECACHEH_MSGENNUL );
00686
00687 *output = XLALFrGenerateCache( dirstr, fnptrn );
00688 if ( ! *output )
00689 {
00690 int errnum = xlalErrno;
00691 XLALClearErrno();
00692 switch ( errnum )
00693 {
00694 case XLAL_EIO:
00695 ABORT( status, FRAMECACHEH_EPATH, FRAMECACHEH_MSGEPATH );
00696 case XLAL_ENOMEM:
00697 ABORT( status, FRAMECACHEH_EALOC, FRAMECACHEH_MSGEALOC );
00698 default:
00699 ABORTXLAL( status );
00700 }
00701 }
00702
00703 RETURN( status );
00704 }
00705
00706
00707 static int FrStatCompare( const void *p1, const void *p2 )
00708 {
00709 const FrStat *file1 = p1;
00710 const FrStat *file2 = p2;
00711 int ans = 0;
00712
00713
00714 if ( ! file1->source || ! file1->description
00715 || ! file2->source || ! file2->description )
00716 {
00717 if ( file1->source && ! file2->source )
00718 return -1;
00719 if ( file2->source && ! file1->source )
00720 return 1;
00721 if ( file1->description && ! file2->description )
00722 return -1;
00723 if ( file2->description && ! file1->description )
00724 return 1;
00725 }
00726
00727
00728 if ( file1->source && file2->source
00729 && ( ans = strcmp( file1->source, file2->source ) ) )
00730 return ans;
00731 else if ( file1->description && file2->description
00732 && ( ans = strcmp( file1->description, file2->description ) ) )
00733 return ans;
00734
00735
00736 if ( file1->startTime < file2->startTime )
00737 ans = -1;
00738 else if ( file1->startTime > file2->startTime )
00739 ans = 1;
00740 else
00741 if ( file1->url )
00742 if ( file2->url )
00743 ans = strcmp( file1->url, file2->url );
00744 else
00745 ans = -1;
00746 else if ( file2->url )
00747 ans = 1;
00748 else
00749 ans = 0;
00750
00751 return ans;
00752 }