BinexData.hpp

Go to the documentation of this file.
00001 #pragma ident "$Id: BinexData.hpp 1895 2009-05-12 19:34:29Z afarris $"
00002 
00003 //============================================================================
00004 //
00005 //  This file is part of GPSTk, the GPS Toolkit.
00006 //
00007 //  The GPSTk is free software; you can redistribute it and/or modify
00008 //  it under the terms of the GNU Lesser General Public License as published
00009 //  by the Free Software Foundation; either version 2.1 of the License, or
00010 //  any later version.
00011 //
00012 //  The GPSTk is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU Lesser General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU Lesser General Public
00018 //  License along with GPSTk; if not, write to the Free Software Foundation,
00019 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 //  Copyright 2008, The University of Texas at Austin
00022 //
00023 //============================================================================
00024 
00030 #ifndef GPSTK_BINEXDATA_HPP
00031 #define GPSTK_BINEXDATA_HPP
00032 
00033 #include "gpstkplatform.h"
00034 
00035 #include "BinUtils.hpp"
00036 #include "FFData.hpp"
00037 #include "FFStream.hpp"
00038 
00039 namespace gpstk
00040 {
00044 
00052    class BinexData : public FFData
00053    {
00054    public:
00055 
00056       // Establish the endianness of the native platform
00057    #if BYTE_ORDER == LITTLE_ENDIAN
00058       static const bool nativeLittleEndian = true;
00059    #else
00060       static const bool nativeLittleEndian = false;
00061    #endif
00062 
00063       static const unsigned long INVALID_RECORD_ID    = 0xFFFFFFFF;
00064 
00065       static const unsigned char DEFAULT_RECORD_FLAGS = 0x20;
00066       static const unsigned char VALID_RECORD_FLAGS   = 0x38;
00067 
00068          // Flags indicating whether a record is reversed, whether a record
00069          // is big endian, and whether a record contains an enhanced CRC.
00070          // Combining these flags (via bitwise-or) helps create the
00071          // synchronization byte(s) for a BINEX record.
00072       enum recordFlagsEnum
00073       {
00074          eReverseReadable = 0x10,
00075          eBigEndian       = 0x20,
00076          eEnhancedCRC     = 0x08
00077       };
00078 
00080 
00081 
00087       class UBNXI
00088       {
00089       public:
00090 
00091          static const unsigned long  MIN_VALUE = 0;
00092          static const unsigned long  MAX_VALUE = 536870911;
00093          static const unsigned char  MAX_BYTES = 4;
00094 
00098          UBNXI();
00099 
00103          UBNXI(const UBNXI& other)
00104          {
00105             *this = other;
00106          };
00107 
00111          UBNXI(unsigned long ul)
00112             throw(FFStreamError);
00113 
00117          inline UBNXI&
00118          operator=(const UBNXI& right)
00119          {
00120             value = right.value;
00121             size  = right.size;
00122             return *this;
00123          };
00124 
00128          inline bool
00129          operator==(const UBNXI& other) const
00130          {
00131             return (value == other.value);
00132          };
00133 
00137          inline bool
00138          operator!=(const UBNXI& other) const
00139          {
00140             return (value != other.value);
00141          };
00142 
00146          inline bool
00147          operator<(const UBNXI& other) const
00148          {
00149             return (value < other.value);
00150          };
00151 
00155          inline bool
00156          operator<=(const UBNXI& other) const
00157          {
00158             return (value <= other.value);
00159          };
00160 
00164          inline bool
00165          operator>(const UBNXI& other) const
00166          {
00167             return (value > other.value);
00168          };
00169 
00173          inline bool
00174          operator>=(const UBNXI& other) const
00175          {
00176             return (value >= other.value);
00177          };
00178 
00182          inline
00183          operator unsigned long() const
00184          {
00185             return value;
00186          };
00187 
00192          inline size_t
00193          getSize() const
00194          {
00195             return size;
00196          };
00197 
00207          size_t
00208          decode(const std::string& inBuffer,
00209                 size_t             offset       = 0,
00210                 bool               littleEndian = false)
00211              throw(FFStreamError);
00212 
00223          size_t
00224          encode(std::string& outBuffer,
00225                 size_t       offset       = 0,
00226                 bool         littleEndian = false) const;
00227 
00242          size_t
00243          read(std::istream& strm,
00244               std::string   *outBuffer   = NULL,
00245               size_t        offset       = 0,
00246               bool          reverseBytes = false,
00247               bool          littleEndian = false)
00248             throw(FFStreamError);
00249 
00263          size_t
00264          write(std::ostream& strm,
00265                std::string   *outBuffer   = NULL,
00266                size_t        offset       = 0,
00267                bool          reverseBytes = false,
00268                bool          littleEndian = false) const
00269             throw(FFStreamError);
00270 
00271       protected:
00272 
00273          unsigned long value;
00274          size_t        size;
00275       };
00276 
00284       class MGFZI
00285       {
00286       public:
00287 
00288          static const long long      MIN_VALUE = -1157442765409226759LL;
00289          static const long long      MAX_VALUE =  1157442765409226759LL;
00290          static const unsigned char  MAX_BYTES =  8;
00291 
00295          MGFZI();
00296 
00300          MGFZI(const MGFZI& other)
00301          {
00302             *this = other;
00303          };
00304 
00308          MGFZI(long long ll)
00309             throw(FFStreamError);
00310 
00314          inline MGFZI&
00315          operator=(const MGFZI& right)
00316          {
00317             value = right.value;
00318             size  = right.size;
00319             return *this;
00320          };
00321 
00325          inline bool
00326          operator==(const MGFZI& other) const
00327          {
00328             return (value == other.value);
00329          };
00330 
00334          inline bool
00335          operator!=(const MGFZI& other) const
00336          {
00337             return (value != other.value);
00338          };
00339 
00343          inline bool
00344          operator<(const MGFZI& other) const
00345          {
00346             return (value < other.value);
00347          };
00348 
00352          inline bool
00353          operator<=(const MGFZI& other) const
00354          {
00355             return (value <= other.value);
00356          };
00357 
00361          inline bool
00362          operator>(const MGFZI& other) const
00363          {
00364             return (value > other.value);
00365          };
00366 
00370          inline bool
00371          operator>=(const MGFZI& other) const
00372          {
00373             return (value >= other.value);
00374          };
00375 
00379          inline
00380          operator long long() const
00381          {
00382             return value;
00383          };
00384 
00389          inline size_t
00390          getSize() const
00391          {
00392             return size;
00393          };
00394 
00404          size_t
00405          decode(const std::string& inBuffer,
00406                 size_t             offset       = 0,
00407                 bool               littleEndian = false)
00408             throw(FFStreamError);
00409 
00419          size_t
00420          encode(std::string& outBuffer,
00421                 size_t       offset       = 0,
00422                 bool         littleEndian = false) const;
00423 
00436          size_t
00437          read(std::istream& strm,
00438               std::string *outBuffer   = NULL,
00439               size_t      offset       = 0,
00440               bool        reverseBytes = false,
00441               bool        littleEndian = false)
00442             throw(FFStreamError);
00443 
00455          size_t
00456          write(std::ostream& strm,
00457                std::string *outBuffer   = NULL,
00458                size_t      offset       = 0,
00459                bool        reverseBytes = false,
00460                bool        littleEndian = false) const
00461             throw(FFStreamError);
00462 
00463       protected:
00464 
00465          long long value;
00466          size_t    size;
00467       };
00468 
00470 
00471 
00475       BinexData();
00476 
00480       BinexData(const BinexData& other);
00481 
00485       BinexData(unsigned long recordID,
00486                 unsigned char recordFlags = DEFAULT_RECORD_FLAGS)
00487          throw();
00488 
00492       BinexData&
00493       operator=(const BinexData& right);
00494 
00498       virtual
00499       ~BinexData() {};
00500 
00504       virtual bool
00505       isData(void) const
00506       {
00507          return true;
00508       }
00509 
00513       virtual void
00514       dump(std::ostream& s) const;
00515       
00521       bool
00522       operator==(const BinexData& b) const;
00523 
00529       inline unsigned char
00530       getRecordFlags() const
00531       {
00532             // Return only essential, valid flag bits listed in recordFlagMask
00533          return syncByte & VALID_RECORD_FLAGS;
00534       };
00535 
00548       BinexData&
00549       setRecordFlags(unsigned char flags = DEFAULT_RECORD_FLAGS);
00550 
00554       inline unsigned long
00555       getRecordID() const
00556       {
00557          return recID;         
00558       };
00559 
00563       BinexData&
00564       setRecordID(unsigned long id)
00565          throw(FFStreamError);
00566 
00571       size_t
00572       getRecordSize() const;
00573 
00577       BinexData&
00578       clearMessage();
00579 
00587       BinexData&
00588       ensureMessageCapacity(size_t cap)
00589          throw(FFStreamError);
00590 
00597       inline size_t
00598       getMessageLength() const
00599       {
00600          return msg.size();
00601       };
00602 
00609       inline size_t
00610       getMessageCapacity() const
00611       {
00612          return msg.capacity();
00613       };
00614 
00620       //inline const char*
00621       inline const std::string&
00622       getMessageData() const
00623       {
00624          //return msg.data();
00625          return msg;
00626       };
00627 
00639       BinexData&
00640       updateMessageData(
00641          size_t&      offset,
00642          const UBNXI& data)
00643             throw(FFStreamError, InvalidParameter);
00644 
00656       BinexData&
00657       updateMessageData(
00658          size_t&      offset,
00659          const MGFZI& data)
00660             throw(FFStreamError, InvalidParameter);
00661 
00674       BinexData&
00675       updateMessageData(
00676          size_t&            offset,
00677          const std::string& data,
00678          size_t             size)
00679             throw(FFStreamError, InvalidParameter);
00680 
00693       BinexData&
00694       updateMessageData(
00695          size_t&     offset,
00696          const char  *data,
00697          size_t      size)
00698             throw(FFStreamError, InvalidParameter);
00699 
00714       template<class T>
00715       BinexData&
00716       updateMessageData(
00717          size_t&      offset,
00718          const T&     data,
00719          size_t       size)
00720             throw(FFStreamError, InvalidParameter)
00721       {
00722          if (size > sizeof(T) )
00723          {
00724             std::ostringstream errStrm;
00725             errStrm << "Invalid data size: " << size;
00726             InvalidParameter ip(errStrm.str() );
00727             GPSTK_THROW(ip);
00728          }
00729          bool   littleEndian  = ( (syncByte & eBigEndian) == 0) ? true : false;
00730          if (littleEndian == nativeLittleEndian)
00731          {
00732             msg.replace(offset, size, reinterpret_cast<const char*>(&data), size);
00733          }
00734          else
00735          {
00736             T tmpData(data);
00737             BinUtils::twiddle(tmpData);
00738             msg.replace(offset, size, reinterpret_cast<const char*>(&tmpData), size);
00739          }
00740          offset += size;
00741          return *this;
00742 
00743       } // BinexData::updateMessageData()
00744 
00755       void
00756       extractMessageData(
00757          size_t& offset,
00758          UBNXI&  data)
00759             throw(FFStreamError, InvalidParameter);
00760 
00771       void
00772       extractMessageData(
00773          size_t& offset,
00774          MGFZI&  data)
00775             throw(FFStreamError, InvalidParameter);
00776 
00790       void
00791       extractMessageData(
00792          size_t&      offset,
00793          std::string& data,
00794          size_t       size) const
00795             throw(InvalidParameter);
00796 
00811       template<class T>
00812       void
00813       extractMessageData(
00814          size_t&      offset,
00815          T&           data,
00816          size_t       size) const
00817             throw(FFStreamError, InvalidParameter)
00818       {
00819          if (size > sizeof(T) )
00820          {
00821             std::ostringstream errStrm;
00822             errStrm << "Data size invalid: " << size;
00823             InvalidParameter ip(errStrm.str() );
00824             GPSTK_THROW(ip);
00825          }  
00826          if (offset + size > msg.size() )
00827          {
00828             std::ostringstream errStrm;
00829             errStrm << "Message buffer offset invalid: " << offset;
00830             InvalidParameter ip(errStrm.str() );
00831             GPSTK_THROW(ip);
00832          }  
00833          bool littleEndian  = ( (syncByte & eBigEndian) == 0) ? true : false;
00834          msg.copy(reinterpret_cast<char*>(&data), size, offset);
00835          if (littleEndian != nativeLittleEndian)
00836          {
00837             BinUtils::twiddle(data);
00838          }
00839          offset += size;
00840 
00841       } // BinexData::extractMessageData()
00842 
00843 
00844    protected:
00845 
00849       virtual void
00850       reallyPutRecord(FFStream& s) const
00851          throw(std::exception, FFStreamError, 
00852                StringUtils::StringException);     
00853 
00863       virtual void
00864       reallyGetRecord(FFStream& s) 
00865          throw(std::exception, FFStreamError,
00866                StringUtils::StringException);
00867 
00874       void getCRC(const std::string& head,
00875                   const std::string& message,
00876                   std::string&       crc) const;
00877 
00882       size_t
00883       getCRCLength(size_t crcDataLen) const;
00884 
00889       bool
00890       isHeadSyncByteValid(unsigned char  headSync,
00891                           unsigned char& expectedTailSync) const;
00892 
00897       bool
00898       isTailSyncByteValid(unsigned char  tailSync,
00899                           unsigned char& expectedHeadSync) const;
00908       static unsigned long long
00909       parseBuffer(const std::string&  buffer,
00910                   size_t              offset,
00911                   size_t              size)
00912          throw(FFStreamError);
00913 
00921       static void
00922       reverseBuffer(unsigned char *buffer,
00923                     size_t        bufferLength);
00924 
00933       static void
00934       reverseBuffer(std::string& buffer,
00935                     size_t       offset = 0,
00936                     size_t       n      = std::string::npos);
00937 
00941       unsigned char  syncByte;  
00942       unsigned long  recID;     
00943       std::string    msg;       
00944 
00945 
00946    private:
00947 
00948    };  // class BinexData
00949 
00951 
00952 } // namespace gpstk
00953 
00954 
00955 #endif // GPSTK_BINEXDATA_HPP

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