LCOV - code coverage report
Current view: top level - nrao/VLA - VLADiskInput.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 19 129 14.7 %
Date: 2024-12-11 20:54:31 Functions: 4 11 36.4 %

          Line data    Source code
       1             : //# VLADiskInput.cc: This class reads VLA archive files from a Disk
       2             : //# Copyright (C) 1999,2000,2001,2002,2003
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id: VLADiskInput.cc,v 19.2.20.3 2006/10/09 20:08:34 wyoung Exp $
      27             : 
      28             : #include <nrao/VLA/VLADiskInput.h>
      29             : #include <nrao/VLA/nreal.h>
      30             : #include <casacore/casa/Utilities/Assert.h>
      31             : #include <casacore/casa/Exceptions/Error.h>
      32             : #include <casacore/casa/IO/MemoryIO.h>
      33             : #include <casacore/casa/IO/ByteIO.h>
      34             : #include <casacore/casa/OS/RegularFile.h>
      35             : #include <iostream>
      36             : #include <arpa/inet.h>
      37             : #include <cstdlib>
      38             : #include <unistd.h>
      39             : 
      40             : #ifndef MAX_LOGICAL_RECORD_SIZE
      41             : #define MAX_LOGICAL_RECORD_SIZE 850000u
      42             : #endif
      43             : 
      44             : // this is an expediant, we should get it from the IERS table
      45             : #define LEAP_SECONDS 33
      46             : 
      47           0 : String VLADiskInput::getTodaysFile(int relDay){
      48           0 :   int LeapSeconds = LEAP_SECONDS;
      49             :   time_t curTime, holdTime;          /* time vars */
      50             :   struct tm *tmTime;                 /* time structure */
      51           0 :   ostringstream  aDate;
      52           0 :   curTime = time(&holdTime) + LeapSeconds + relDay*86400;
      53           0 :   tmTime = gmtime(&curTime);
      54           0 :   oldDay = tmTime->tm_yday;
      55             : 
      56             : // Format up the online vla file
      57             : 
      58           0 :   aDate << visDir << "/vla";
      59           0 :   aDate.width(4);
      60           0 :   aDate.fill('0');
      61           0 :   aDate << tmTime->tm_year+1900 << "-";
      62           0 :   aDate.width(2);
      63           0 :   aDate << tmTime->tm_mon+1 << "-" << tmTime->tm_mday;
      64           0 :   aDate << ".dat";
      65           0 :   return(String(aDate.str()));
      66           0 : }
      67             : 
      68             : // simple function see what today is
      69             : 
      70           0 : Int VLADiskInput::whatsToday(){
      71           0 :   time_t LeapSeconds = LEAP_SECONDS;
      72             :   time_t curTime, holdTime;          /* time vars */
      73             :   struct tm *tmTime;                 /* time structure */
      74           0 :   curTime = time(&holdTime) + LeapSeconds;
      75           0 :   tmTime = gmtime(&curTime);
      76           0 :   return tmTime->tm_yday;
      77             : }
      78             : 
      79             : // As we go over IAT midnight the VLA data repository file
      80             : // changes its name so we have to attach to the new day's file.
      81             : 
      82           0 : void VLADiskInput::reattachCurrent(){
      83             :    // OK file may not have been created yet so lets wait a bit
      84           0 :    RegularFile nrtFile(getTodaysFile(0));
      85           0 :    while(!nrtFile.exists()){
      86           0 :       sleep(5);
      87             :    }
      88             :    //std::cerr << "Attached to new file" << std::endl;
      89           0 :    itsFile = new RegularFileIO(nrtFile);
      90           0 : }
      91             : 
      92             : // Here's the online version to read data from the VLA online data repository
      93             : 
      94           0 : VLADiskInput::VLADiskInput(const String& onlineFlag)
      95           0 :   :VLAArchiveInput()
      96             : {
      97             :    // Need to check for :-x to set the relative day.
      98           0 :    if(onlineFlag == "online"){
      99           0 :       previousDay = 0;
     100           0 :       char *dataDir = getenv("VISDATADIR");
     101           0 :       if(!dataDir){
     102           0 :           dataDir = strdup("/home/vis-serv-mirror/vladata");
     103             :       }
     104           0 :       visDir = String(dataDir);
     105           0 :       Path nrtFile = Path(getTodaysFile());
     106           0 :       itsFile = new RegularFileIO(RegularFile(nrtFile));
     107           0 :       onlineFill = true;
     108           0 :       itsFile->seek(0, ByteIO::End);
     109           0 :    } else {
     110           0 :       throw(AipsError("Invalid online specifier " + onlineFlag));
     111             :    }
     112           0 : }
     113             : 
     114          16 : VLADiskInput::VLADiskInput(const Path& fileName)
     115             :   :VLAArchiveInput(),
     116          16 :    itsFile(new RegularFileIO(fileName)), onlineFill(false)
     117             : {
     118          16 :         attachFile(fileName.absoluteName().c_str());
     119          16 : }
     120             : 
     121          32 : VLADiskInput::~VLADiskInput() {
     122             :   // The RegularFileIO destructor closes the disk file.
     123          16 :   delete itsFile;
     124          16 :   detachFile();
     125          32 : }
     126             : 
     127             : /*
     128             : Bool VLADiskInput::read() {
     129             :   // Clear the internal buffers and reset the flags as we will try to read some
     130             :   // more data.
     131             :   itsMemIO.clear();
     132             :   // Find an initial record.
     133             :   Short n = 1, m;
     134             :   uInt curRecSize(0);
     135             :   Int bytesToRead(0);
     136             :   Int thisReadSize(0);
     137             :   uChar *recordPtr(0);
     138             :   if (findFirstRecord(m) == false) if(!onlineFill)return false;
     139             :   // We have the first physical record in Memory. Now decode how long this
     140             :   // logical record is.
     141             :   itsRecord.seek(0);
     142             :   Int logicalRecordSize;
     143             :   if(this->bytesRead() < this->totalBytes()){
     144             :      try {
     145             :         itsRecord >> logicalRecordSize;
     146             :         logicalRecordSize *= 2;
     147             :         curRecSize = itsMemIO.length();
     148             :         bytesToRead = logicalRecordSize - curRecSize;
     149             :   // make the buffer a bit bigger than necessary as we may need to read up to
     150             :   // VLAArchiveInput::BlockSize - 1 extra bytes (to pad out the block).
     151             :         // cerr << "Uno Setting buffer size: " << logicalRecordSize << " " << VLAArchiveInput::BlockSize << endl;
     152             :         if(logicalRecordSize > MAX_LOGICAL_RECORD_SIZE)
     153             :                 return false;
     154             :         recordPtr = itsMemIO.setBuffer(logicalRecordSize +
     155             :                                      VLAArchiveInput::BlockSize-1);
     156             :      } catch (AipsError x) {
     157             :              std::cerr << "end of file???" << std::endl;
     158             :             std::cerr << x.getMesg() << std::endl;
     159             :      }
     160             : // Sanity check here.
     161             :   }
     162             :   cerr << "A File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     163             :   while(this->bytesRead() >= this->totalBytes()){
     164             :     //std::cerr << "Waiting..." << std::endl;
     165             :     if(!onlineFill){
     166             :         cerr << "VLADiskInput::read end of file encountered." << endl;
     167             :         itsMemIO.clear();
     168             :         return false;
     169             :     }
     170             :         // I'm online so check to see if the day changed and we need
     171             :         // to move to the next day's file otherwise sleep and see if
     172             :         // we've got some more data.
     173             :     sleep(10);
     174             :     itsMemIO.clear();
     175             :     itsRecord.seek(0);
     176             :     Int curDay = whatsToday();
     177             :     if(oldDay != curDay){
     178             :         reattachCurrent();
     179             :         oldDay += 1;
     180             :     }
     181             :     //std::cerr << this->bytesRead() << " " << this->totalBytes() << std::endl;
     182             :     if(this->bytesRead() < this->totalBytes()){
     183             :        itsFile->seek(Int64(-4), ByteIO::Current);
     184             :        if(findFirstRecord(m)){
     185             :           itsRecord >> logicalRecordSize;
     186             :         // A new record has arrived, march on!
     187             :           logicalRecordSize *= 2;
     188             :           curRecSize = itsMemIO.length();
     189             :           bytesToRead = logicalRecordSize - curRecSize;
     190             :         // cerr << "Dos Setting buffer size: " << logicalRecordSize << " " << VLAArchiveInput::BlockSize << endl;
     191             :         if(logicalRecordSize > MAX_LOGICAL_RECORD_SIZE)
     192             :                 return false;
     193             :           recordPtr = itsMemIO.setBuffer(logicalRecordSize +
     194             :                                   VLAArchiveInput::BlockSize-1);
     195             :        }
     196             :     }
     197             :   }
     198             : 
     199             :   cerr << "B File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     200             :   while (bytesToRead > 0) {
     201             :     thisReadSize = VLAArchiveInput::HeaderSize;
     202             :     DebugAssert(static_cast<Int64>(curRecSize + VLAArchiveInput::HeaderSize) <=
     203             :                 itsMemIO.length(), AipsError);
     204             :     Int bytesRead =
     205             :       itsFile->read(VLAArchiveInput::HeaderSize, recordPtr+curRecSize, false);
     206             :     if (bytesRead < static_cast<Int>(VLAArchiveInput::HeaderSize)) {
     207             :       itsMemIO.clear();
     208             :       return false;
     209             :     }
     210             :     // Check the sequence numbers
     211             :     {
     212             :       itsRecord.seek(Int(curRecSize));
     213             :       Short newn, newm;
     214             :       itsRecord >> newn;
     215             :       itsRecord >> newm;
     216             :       if (newm != m || ++n != newn) {
     217             :         itsMemIO.clear();
     218             :         return false;
     219             :       }
     220             :     }
     221             :     // The sequence numbers are OK so read the rest of the data
     222             :     if (bytesToRead <
     223             :         static_cast<Int>(VLAArchiveInput::BlockSize*
     224             :                          VLAArchiveInput::MaxBlocksPerPhysicalRecord)) {
     225             :       thisReadSize = (bytesToRead-1)/VLAArchiveInput::BlockSize + 1;
     226             :       thisReadSize *= VLAArchiveInput::BlockSize;
     227             :     } else {
     228             :       thisReadSize = VLAArchiveInput::BlockSize *
     229             :         VLAArchiveInput::MaxBlocksPerPhysicalRecord;
     230             :     }
     231             :     thisReadSize -= VLAArchiveInput::HeaderSize;
     232             :     DebugAssert(static_cast<Int64>(curRecSize+thisReadSize)<=itsMemIO.length(),
     233             :                 AipsError);
     234             :     bytesRead = itsFile->read(thisReadSize, recordPtr+curRecSize, false);
     235             :     if (bytesRead < thisReadSize) {
     236             :       itsMemIO.clear();
     237             :       return false;
     238             :     }
     239             :     curRecSize += thisReadSize;
     240             :     bytesToRead -= thisReadSize;
     241             :     cerr << "File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     242             :   }
     243             :   cerr << "C File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     244             :   itsMemIO.setUsed(logicalRecordSize);
     245             :   itsRecord.seek(0);
     246             :   return true;
     247             : }
     248             : */
     249             : 
     250             : 
     251       20585 : Bool VLADiskInput::read() {
     252       20585 :    Bool rstatus(true);
     253       20585 :    itsMemIO->clear();
     254       20585 :    Long logicalRecordSize(MAX_LOGICAL_RECORD_SIZE);
     255       20585 :    Char* recordPtr = (Char *)itsMemIO->setBuffer(logicalRecordSize);
     256       20585 :    logicalRecordSize = readVLALogRec(recordPtr);
     257       20585 :    itsMemIO->setUsed(logicalRecordSize);
     258       20585 :    itsRecord.seek(0);
     259       20585 :    if(!logicalRecordSize)
     260          16 :       rstatus = false;
     261       20585 :    return rstatus;
     262             : }
     263             : 
     264             : 
     265             : // Find an initial record. An initial record MUST have the first 2-byte integer
     266             : // as 1 and the next 2-byte integer as a number greater than zero. If we have
     267             : // not found an initial record after searching 5MBytes worth of data then just
     268             : // give up.
     269             : //
     270             : //This is nuts for VLA Disk files and needs to be redone as we can calculate
     271             : //the number of physical records and avoid all this piecemeal reading of
     272             : //the file to find where the records start.
     273             : //wky 2-23-08
     274           0 : Bool VLADiskInput::findFirstRecord(Short& m) {
     275           0 :   const uInt maxBytesToSearch = 5*1024*1024;
     276           0 :   Short n = 0 ;
     277           0 :   m = 0;
     278           0 :   cerr << "AA File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     279             :   {
     280           0 :     uInt bytesSearched = 0;
     281             :     // Search for the correct sequence number or give up after a while.
     282           0 :     Bool maybe(false);
     283             :     uInt logicalRecordSize;
     284           0 :     uChar* recordPtr = itsMemIO->setBuffer(VLAArchiveInput::HeaderSize);
     285           0 :     while (!maybe && (bytesSearched <= maxBytesToSearch)) {
     286             :       //std::cerr << n << " " << m << std::endl;
     287           0 :       if (bytesSearched > 0) {
     288           0 :         if(itsFile->seek(Int64(VLAArchiveInput::BlockSize -
     289           0 :                            VLAArchiveInput::HeaderSize),
     290           0 :                      ByteIO::Current) <= 0)
     291           0 :                 return false;
     292             :       }
     293           0 :       bytesSearched += VLAArchiveInput::BlockSize;
     294             :       // std::cerr << bytesSearched << std::endl;
     295             : 
     296             :       // std::cerr << this->bytesRead() << " " << this->totalBytes() << std::endl;
     297             :       Int bytesRead =
     298           0 :         itsFile->read(VLAArchiveInput::HeaderSize, recordPtr, false);
     299           0 :       cerr << "BB File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     300           0 :       if (bytesRead < static_cast<Int>(VLAArchiveInput::HeaderSize)) {
     301           0 :         itsMemIO->clear();
     302           0 :         return false;
     303             :       }
     304             :       // Find out what the sequence numbers are.
     305           0 :       itsRecord.seek(0);
     306           0 :       itsRecord >> n;
     307           0 :       itsRecord >> m;
     308             :       // OK we need to make sure that Logical record size is OK too before accepting n and m.
     309           0 :        if(n == 1 && m > 0 && m < 40){
     310           0 :         itsFile->read(4, recordPtr, false);
     311           0 :         itsRecord.seek(0);
     312           0 :         itsRecord >> logicalRecordSize;
     313           0 :         itsFile->seek(Int64(-4), ByteIO::Current);
     314             :         // itsRecord.seek(-4);
     315             :         //`cerr << "Logical Record Size is: " << logicalRecordSize << endl;
     316           0 :         if(logicalRecordSize > MAX_LOGICAL_RECORD_SIZE)
     317           0 :                 maybe = false;
     318             :         else
     319           0 :                 maybe = true;
     320             :        }
     321             :     }
     322             :     //cerr << n << " " << m << endl;
     323           0 :     if (bytesSearched > maxBytesToSearch) {
     324           0 :       itsMemIO->clear();
     325           0 :       return false;
     326             :     }
     327             :   }
     328             :   // OK so we have found the beginning of the first physical record. Now read
     329             :   // the data into the logical record.
     330           0 :   uInt offset = 0;
     331           0 :   Int bytesToCopy =
     332           0 :     VLAArchiveInput::MaxBlocksPerPhysicalRecord * VLAArchiveInput::BlockSize -
     333           0 :     VLAArchiveInput::HeaderSize;
     334           0 :   if (m == 1) { // If m=1 we may need to copy less than the maximum number of
     335             :     // blocks per physical record. To work this out we need to read and parse
     336             :     // the first block.
     337           0 :     itsRecord.seek(0);
     338           0 :     const Int bytesToRead =
     339           0 :       VLAArchiveInput::BlockSize - VLAArchiveInput::HeaderSize;
     340           0 :     uChar* recordPtr = itsMemIO->setBuffer(bytesToRead);
     341             :     // cerr << "Bytes to read " << bytesToRead << endl;
     342           0 :     const Int bytesRead = itsFile->read(bytesToRead, recordPtr, false);
     343           0 :     cerr << "CC File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     344           0 :     if (bytesRead < bytesToRead) {
     345           0 :       itsMemIO->clear();
     346           0 :       return false;
     347             :     }
     348           0 :     itsRecord.seek(0);
     349             :     Int logicalRecordSize;
     350           0 :     itsRecord >> logicalRecordSize;
     351           0 :     logicalRecordSize *= 2;
     352           0 :     bytesToCopy =
     353           0 :       ((logicalRecordSize - bytesToRead)/VLAArchiveInput::BlockSize + 1) *
     354           0 :       VLAArchiveInput::BlockSize;
     355           0 :     offset = bytesToRead;
     356             :   }
     357           0 :   if (bytesToCopy > 0) {
     358           0 :     uChar* recordPtr = itsMemIO->setBuffer(bytesToCopy+offset);
     359             :     // cerr << "Bytes to copy " << bytesToCopy << endl;
     360           0 :     Int bytesRead = itsFile->read(bytesToCopy, recordPtr+offset, false);
     361           0 :     cerr << "DD File position is " << itsFile->seek(0, ByteIO::Current) << " " << endl;
     362           0 :     if (bytesRead < bytesToCopy) {
     363           0 :       itsMemIO->clear();
     364           0 :       return false;
     365             :     }
     366             :   }
     367           0 :   DebugAssert(n == 1, AipsError);
     368           0 :   DebugAssert(m > 0, AipsError);
     369           0 :   return true;
     370             : }
     371             : 
     372           0 : uInt VLADiskInput::bytesRead() {
     373           0 :   return itsFile->seek(0, ByteIO::Current);
     374             : }
     375             : 
     376           0 : uInt VLADiskInput::totalBytes() {
     377           0 :   return itsFile->length();
     378             : }
     379             : 
     380             : // Local Variables:
     381             : // compile-command: "gmake VLADiskInput; cd test; gmake OPTLIB=1 tVLADiskInput"
     382             : // End:

Generated by: LCOV version 1.16