RTFileFrame.hpp

Go to the documentation of this file.
00001 #pragma ident "$Id: RTFileFrame.hpp 70 2006-08-01 18:36:21Z ehagen $"
00002 
00003 
00004 
00010 #ifndef GPSTK_RTFILEFRAME_HPP
00011 #define GPSTK_RTFILEFRAME_HPP
00012 
00013 //============================================================================
00014 //
00015 //  This file is part of GPSTk, the GPS Toolkit.
00016 //
00017 //  The GPSTk is free software; you can redistribute it and/or modify
00018 //  it under the terms of the GNU Lesser General Public License as published
00019 //  by the Free Software Foundation; either version 2.1 of the License, or
00020 //  any later version.
00021 //
00022 //  The GPSTk is distributed in the hope that it will be useful,
00023 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025 //  GNU Lesser General Public License for more details.
00026 //
00027 //  You should have received a copy of the GNU Lesser General Public
00028 //  License along with GPSTk; if not, write to the Free Software Foundation,
00029 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00030 //  
00031 //  Copyright 2004, The University of Texas at Austin
00032 //
00033 //============================================================================
00034 
00035 //============================================================================
00036 //
00037 //This software developed by Applied Research Laboratories at the University of
00038 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00039 //Department of Defense. The U.S. Government retains all rights to use,
00040 //duplicate, distribute, disclose, or release this software. 
00041 //
00042 //Pursuant to DoD Directive 523024 
00043 //
00044 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00045 //                           release, distribution is unlimited.
00046 //
00047 //=============================================================================
00048 
00049 
00050 
00051 
00052 
00053 
00054 #include <sys/types.h>
00055 #include <sys/stat.h>
00056 #include <iterator>
00057 #include "FileSpec.hpp"
00058 #include "FileFilter.hpp"
00059 
00060 namespace gpstk
00061 {
00064 
00067    class RTFileFrameHelper
00068    {
00069    public:
00070       enum GetRecordMode
00071       {
00072          Dumb  = 0, 
00073          Smart = 1  
00074       };
00075       
00080       enum FileReadingMode
00081       {
00082          AppendedData = 0,     
00083          FromTheBeginning = 1  
00084       };
00085    };
00086 
00087       // forward declaration of the RTFileFrame class
00088    template <class FileStream, class FileData>
00089    class RTFileFrame;
00090 
00095    template <class FileStream, class FileData>
00096    class RTFileFrameIterator
00097    {
00098    public:
00100       RTFileFrameIterator() 
00101             : rtff(NULL)
00102          {}
00103 
00105       RTFileFrameIterator(const RTFileFrameIterator& right)
00106             : rtff(right.rtff)
00107          {}
00108 
00110       virtual ~RTFileFrameIterator() {}
00111 
00113       RTFileFrameIterator& operator=(const RTFileFrameIterator& r)
00114          { 
00115             rtff = r.rtff; 
00116             return *this; 
00117          }
00118 
00120       RTFileFrameIterator operator++()
00121          {
00122             rtff->getRecord();
00123             return *this;
00124          }
00125 
00127       RTFileFrameIterator operator++(int)
00128          {
00129             RTFileFrameIterator<FileStream, FileData> temp = *this;
00130             read();
00131             return temp;
00132          }
00133 
00135       const FileData& operator*() const
00136          {
00137             return rtff->lastData;
00138          }
00139 
00141       const FileData* operator->() const
00142          {
00143             return &(rtff->lastData);
00144          }
00145       
00147       bool operator==(const RTFileFrameIterator& right) const
00148          {
00149             if (rtff == right.rtff)
00150             {
00151                if (rtff == NULL)
00152                   return true;
00153                
00154                if ((rtff->isOK == right.rtff->isOK) ||
00155                    (!rtff->isOK && (right.rtff->fileStream == rtff->fileStream)))
00156                   return true;
00157                return false;
00158             }
00159             else if ((rtff == NULL) && (right.rtff))
00160                return !right.rtff->isOK;
00161             else if ((right.rtff == NULL) && (rtff))
00162                return !rtff->isOK;
00163             else
00164                return false;
00165          }
00166 
00168       bool operator!=(const RTFileFrameIterator& right) const
00169          { return !(*this == right);}
00170 
00172       friend class RTFileFrame<FileStream, FileData>;
00173       
00174    protected:
00176       void read() 
00177          { rtff->getRecord(); }
00178 
00179    private:
00181       RTFileFrameIterator(gpstk::RTFileFrame<FileStream, FileData>& r)
00182             : rtff(&r)
00183          { rtff->getRecord(); }
00184 
00186       gpstk::RTFileFrame<FileStream, FileData>* rtff;
00187    };
00188 
00235    template <class FileStream, class FileData>
00236    class RTFileFrame : public RTFileFrameHelper
00237    {
00238    public:
00248       RTFileFrame(const gpstk::FileSpec& fnFormat,
00249                   const gpstk::DayTime& beginning = gpstk::DayTime(),
00250                   const gpstk::DayTime& ending = gpstk::DayTime::END_OF_TIME, 
00251                   const FileReadingMode frm = AppendedData,
00252                   const GetRecordMode grm = Dumb)
00253          throw(gpstk::Exception);
00254       
00256       ~RTFileFrame();
00257       
00259       RTFileFrame& setFileReadingMode(const FileReadingMode f);
00260 
00262       RTFileFrame& setGetRecordMode(const GetRecordMode g);
00263 
00269       void waitForData(unsigned wait = 0);
00270 
00273       bool hasFileChanged();
00274       
00276       bool endOfDataSet();
00277 
00279       RTFileFrameIterator<FileStream, FileData> end();
00280 
00286       RTFileFrameIterator<FileStream, FileData> begin();
00287 
00290       bool getRecord();
00291 
00293       void openNextDay();
00294       
00296       const FileData& data() const { return lastData;}
00297 
00302       std::list<FileData> getList() const;
00303 
00308       FileFilter<FileData> getFileFilter() const;
00309 
00311       std::string getCurrentFile() const {return currentFileName;}
00312 
00314       gpstk::DayTime getCurrentTime() const {return currentTime;}
00315 
00317       friend class RTFileFrameIterator<FileStream, FileData>;
00318 
00320       bool openCurrentFile();
00321 
00323       void closeCurrentFile();
00324 
00325    protected:
00327       FileStream* fileStream;
00328 
00329       FileData lastData;
00331       std::streampos lastPosition;
00333       std::string currentFileName;
00335       gpstk::FileSpec fs;
00336       
00337       gpstk::DayTime startTime, 
00338          currentTime,            
00339          endTime;                
00340 
00341       FileReadingMode readMode;
00343       GetRecordMode getMode;
00345       struct stat fileInfo;
00349       bool isOK;
00350    };
00351 
00353 
00354    template <class FileStream, class FileData>
00355    RTFileFrame<FileStream, FileData>::
00356    RTFileFrame<FileStream, FileData>(const gpstk::FileSpec& fnFormat,
00357                                      const gpstk::DayTime& beginning,
00358                                      const gpstk::DayTime& ending, 
00359                                      const RTFileFrameHelper::FileReadingMode frm,
00360                                      const RTFileFrameHelper::GetRecordMode grm)
00361       throw(gpstk::Exception)
00362          : fileStream(NULL), fs(fnFormat), startTime(beginning), 
00363            currentTime(beginning), endTime(ending), readMode(frm), getMode(grm)
00364    {
00365          // zero out seconds
00366       startTime.setMJDdate(floor(startTime.MJDdate()));
00367       endTime.setMJDdate(floor(endTime.MJDdate()));
00368       currentTime.setMJDdate(floor(currentTime.MJDdate()));
00369 
00370          // set up the stream
00371       openCurrentFile();
00372    }
00373 
00374    template <class FileStream, class FileData>
00375    RTFileFrame<FileStream, FileData>::~RTFileFrame()
00376    {
00377       if (fileStream)
00378       {
00379          fileStream->close();
00380          delete fileStream;
00381       }
00382    }
00383 
00384    template <class FileStream, class FileData>
00385    RTFileFrame<FileStream, FileData>& 
00386    RTFileFrame<FileStream, FileData> :: 
00387    setFileReadingMode(const RTFileFrameHelper::FileReadingMode f)
00388    { 
00389      readMode = f; 
00390      return *this; 
00391    }
00392 
00394    template <class FileStream, class FileData>
00395    RTFileFrame<FileStream, FileData>& 
00396    RTFileFrame<FileStream, FileData> :: 
00397    setGetRecordMode(const RTFileFrameHelper::GetRecordMode g)
00398    { 
00399       getMode = g; 
00400       return *this;
00401    }
00402 
00403    template <class FileStream, class FileData>
00404    void
00405    RTFileFrame<FileStream, FileData>::waitForData(unsigned wait)
00406    {
00407       sleep(wait);
00408       if(readMode == AppendedData)
00409       {  
00410             // reopen the file and skip to where we left off - openCurrentFile
00411             // will overwrite lastPosition...
00412          std::streampos cachedPos = lastPosition;
00413          if(openCurrentFile())
00414             fileStream->seekg(cachedPos);
00415          lastPosition = cachedPos;
00416       }
00417       else
00418       {
00419             // start from the beginning
00420          openCurrentFile();
00421       }
00422    }
00423 
00424    template <class FileStream, class FileData>
00425    bool
00426    RTFileFrame<FileStream, FileData>::hasFileChanged()
00427    {
00428       struct stat tempStat;
00429       if (stat(currentFileName.c_str(), &tempStat))
00430          return false;
00431       if (tempStat.st_mtime != fileInfo.st_mtime)
00432          return true;
00433       else 
00434          return false;
00435    }
00436 
00437    template <class FileStream, class FileData>
00438    bool
00439    RTFileFrame<FileStream, FileData>::endOfDataSet()
00440    {
00441       if (currentTime > endTime)
00442          return true;
00443       else
00444          return false;
00445    }
00446 
00447    template <class FileStream, class FileData>
00448    RTFileFrameIterator<FileStream, FileData>
00449    RTFileFrame<FileStream, FileData>::end()
00450    {
00451       return RTFileFrameIterator<FileStream, FileData>();
00452    }
00453 
00454    template <class FileStream, class FileData>
00455    RTFileFrameIterator<FileStream, FileData> 
00456    RTFileFrame<FileStream, FileData>::begin()
00457    {
00458       if (readMode == AppendedData)
00459       {
00460          ;
00461       }
00462       else // if (readMode == FromTheBeginning)
00463       {
00464          openCurrentFile();
00465       }
00466          // this constructor does not read in the first record, so force it
00467          // to do so before returning
00468       RTFileFrameIterator<FileStream, FileData> toReturn(*this);
00469       return toReturn;
00470    }
00471 
00472    template <class FileStream, class FileData>
00473    bool
00474    RTFileFrame<FileStream, FileData>::getRecord()
00475    {
00476       if (!isOK)
00477          return false;
00478 
00479          // is the stream still good to read?
00480       if (*fileStream >> lastData)
00481       {
00482          lastPosition = fileStream->tellg();
00483          return true;
00484       }
00485          // the last read failed - try opening the next file until
00486          // today's file is reched or else return false
00487       else
00488       {
00489             // read the next file or not?
00490          if (getMode == Smart)
00491          {
00492             if (!endOfDataSet())
00493             {
00494                   // still before today?
00495                gpstk::DayTime today;
00496                today.setYDoySod(today.year(), today.DOY(), 0);
00497                
00498                if (currentTime < today)
00499                {
00500                   openNextDay();
00501                   return getRecord();
00502                }
00503                   // we've read through today, so just wait until tomorrow's
00504                   // data comes in - the user needs to call waitForData()
00505                   // to continue
00506                else
00507                   isOK = false;
00508             }
00509             else
00510             {
00511                isOK = false;
00512             }
00513          } // if (getmode == smart)
00514 
00515             // in dumb mode, the user needs to call openNextDay or
00516             // openCurrentFile to continue.
00517          else
00518          {
00519             isOK = false;
00520          }
00521       } // if (isOK)
00522       return isOK;
00523    }
00524 
00525    template <class FileStream, class FileData>
00526    void
00527    RTFileFrame<FileStream, FileData>::openNextDay()
00528    {
00529          // open a new file for another day, if any.
00530       currentTime += gpstk::DayTime::SEC_DAY;
00531       if (!endOfDataSet())
00532          openCurrentFile();
00533    }
00534    
00535    template <class FileStream, class FileData>
00536    std::list<FileData>
00537    RTFileFrame<FileStream, FileData>::getList() const
00538    {
00539       RTFileFrameIterator<FileStream, FileData> inputStream;
00540       std::list<FileData> toReturn;
00541       inputStream = begin();
00542       while (inputStream != end())
00543       {
00544          toReturn.push_back(data());
00545       }
00546       return toReturn;
00547    }
00548 
00549    template <class FileStream, class FileData>
00550    FileFilter<FileData>
00551    RTFileFrame<FileStream, FileData>::getFileFilter() const
00552    {
00553       RTFileFrameIterator<FileStream, FileData> inputStream;
00554       FileFilter<FileData> toReturn;
00555       inputStream = begin();
00556       while (inputStream != end())
00557       {
00558          toReturn.addData(data());
00559       }
00560       return toReturn;
00561    }
00562 
00563    template <class FileStream, class FileData>
00564    bool
00565    RTFileFrame<FileStream, FileData>::openCurrentFile()
00566    {
00567       isOK = false;
00568       currentFileName = fs.toString(currentTime);
00569       stat(currentFileName.c_str(), &fileInfo);
00570       lastPosition = 0;
00571 
00572       if(fileStream)
00573       {
00574          fileStream->close();
00575          delete fileStream;
00576          fileStream = NULL;
00577       }
00578 
00579       fileStream = new FileStream;
00580       fileStream->open(currentFileName.c_str(), std::ios::in);
00581       if (!fileStream->fail())
00582          isOK = true;
00583       return isOK;
00584    }
00585 
00586    template <class FileStream, class FileData>
00587    void
00588    RTFileFrame<FileStream, FileData>::closeCurrentFile()
00589    {
00590       if(fileStream)
00591       {
00592          fileStream->close();
00593          delete fileStream;
00594          fileStream = NULL;
00595       }
00596       isOK = false;
00597    }
00598 
00599 } // namespace gpstk
00600 
00601 #endif  // GPSTK_RTFILEFRAME_HPP

Generated on Wed Feb 8 03:31:02 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1