00001 #pragma ident "$Id: BinexData.hpp 1895 2009-05-12 19:34:29Z afarris $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00069
00070
00071
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
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
00621 inline const std::string&
00622 getMessageData() const
00623 {
00624
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 }
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 }
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 };
00949
00951
00952 }
00953
00954
00955 #endif // GPSTK_BINEXDATA_HPP