1 //============================================================================== 2 // 3 // This file is part of GPSTk, the GPS Toolkit. 4 // 5 // The GPSTk is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published 7 // by the Free Software Foundation; either version 3.0 of the License, or 8 // any later version. 9 // 10 // The GPSTk is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with GPSTk; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 18 // 19 // This software was developed by Applied Research Laboratories at the 20 // University of Texas at Austin. 21 // Copyright 2004-2020, The Board of Regents of The University of Texas System 22 // 23 //============================================================================== 24 25 //============================================================================== 26 // 27 // This software was developed by Applied Research Laboratories at the 28 // University of Texas at Austin, under contract to an agency or agencies 29 // within the U.S. Department of Defense. The U.S. Government retains all 30 // rights to use, duplicate, distribute, disclose, or release this software. 31 // 32 // Pursuant to DoD Directive 523024 33 // 34 // DISTRIBUTION STATEMENT A: This software has been approved for public 35 // release, distribution is unlimited. 36 // 37 //============================================================================== 38 39 /** 40 * @file SinexBlock.hpp 41 * Encapsulate SINEX block data, including I/O 42 */ 43 44 #ifndef GPSTK_SINEXBLOCK_HPP 45 #define GPSTK_SINEXBLOCK_HPP 46 47 #include <vector> 48 #include <map> 49 #include "SinexBase.hpp" 50 #include "SinexTypes.hpp" 51 52 namespace gpstk 53 { 54 namespace Sinex 55 { 56 /// @ingroup FileHandling 57 //@{ 58 59 /** Base class for all SINEX blocks; the common base allows blocks 60 * of varying types to be stored in a vector. Specific block types 61 * are realized by the derived Block class defined below. 62 */ 63 class BlockBase 64 { 65 /* Sinex:Data calls the protected putBlock() and 66 * getBlock() methods. */ 67 friend class Data; 68 69 public: 70 ~BlockBase()71 virtual ~BlockBase() {} 72 73 /// Comments that apply to an entire block 74 std::string comment; 75 76 /**Returns the block title 77 */ 78 virtual std::string getTitle() const = 0; 79 80 /** Returns the number of lines in the block 81 */ 82 virtual size_t getSize() const = 0; 83 84 protected: 85 86 /** 87 * Writes the formatted block to the SinexStream. 88 * @param s Stream to which to write 89 * @returns Number of lines written 90 * @throw std::exception 91 * @throw FFStreamError 92 * @throw StringUtils::StringException 93 */ 94 virtual size_t putBlock(Sinex::Stream& s) const = 0; 95 96 /** 97 * Reads a record from the given SinexStream; if an error 98 * is encountered in retrieving the record, the stream is reset 99 * to its original position and its fail-bit is set. 100 * @param s Stream from which to read 101 * @returns Number of lines read 102 * @throw std::exception 103 * @throw StringException when a StringUtils function fails 104 * @throw FFStreamError when exceptions(failbit) is set and 105 * a read or formatting error occurs. This also resets the 106 * stream to its pre-read position. 107 */ 108 virtual size_t getBlock(Sinex::Stream& s) = 0; 109 110 }; // class BlockBase 111 112 113 /** SINEX block parameterized by the type of data it contains. 114 * Each element in the block is a data line of the specified type. 115 */ 116 template<class T> 117 class Block : public BlockBase 118 { 119 public: 120 ~Block()121 virtual ~Block() {} 122 create()123 static BlockBase* create() { return new Block<T>; } 124 getTitle() const125 std::string getTitle() const { return T::BLOCK_TITLE; } 126 127 /** Returns the number of data items in the block 128 */ getSize() const129 size_t getSize() const { return dataVec.size(); } 130 131 /** Appends data to the block 132 */ push_back(const T & x)133 void push_back(const T& x) { dataVec.push_back(x); } 134 getData()135 std::vector<T>& getData() { return dataVec; } 136 137 protected: 138 139 std::vector<T> dataVec; // Data storage 140 141 /** Writes all data in the block to the specified stream 142 * @throw std::exception 143 * @throw FFStreamError 144 */ putBlock(Sinex::Stream & s) const145 virtual size_t putBlock(Sinex::Stream& s) const 146 { 147 size_t lineNum = 0; 148 typename std::vector<T>::const_iterator i = dataVec.begin(); 149 for ( ; i != dataVec.end(); ++i, ++lineNum) 150 { 151 try 152 { 153 const Sinex::DataType& d = *i; 154 s << (std::string)d << std::endl; 155 } 156 catch (Exception& exc) 157 { 158 FFStreamError err(exc); 159 GPSTK_THROW(err); 160 } 161 } 162 return lineNum; 163 }; 164 165 /** Reads all data in a block from the specified stream 166 * @throw std::exception 167 * @throw FFStreamError 168 * @throw StringUtils::StringException 169 */ getBlock(Sinex::Stream & s)170 virtual size_t getBlock(Sinex::Stream& s) 171 { 172 size_t lineNum = 0; 173 char c; 174 while (s.good() ) 175 { 176 c = s.get(); 177 if (s.good() ) 178 { 179 if (c == DATA_START) 180 { 181 /// More data 182 std::string line; 183 s.formattedGetLine(line); 184 try 185 { 186 dataVec.push_back( 187 T(line.insert( (size_t)0, (size_t)1, c), 188 lineNum) ); 189 } 190 catch (Exception& exc) 191 { 192 FFStreamError err(exc); 193 GPSTK_THROW(err); 194 } 195 ++lineNum; 196 } 197 else 198 { 199 /// End of data 200 s.putback(c); 201 break; 202 } 203 } 204 } 205 return lineNum; 206 }; 207 208 }; // class Block<T> 209 210 211 /// Block storage type 212 typedef std::vector<const BlockBase*> Blocks; 213 214 /// Block iterator 215 typedef Blocks::iterator BlockIter; 216 217 /// Function pointer for invoking create methods for blocks 218 typedef BlockBase* (*BlockCreateFunc)(); 219 220 /// Mapping from block titles to block create functions 221 typedef std::map<std::string, BlockCreateFunc> BlockFactory; 222 223 //@} 224 225 } // namespace Sinex 226 227 } // namespace gpstk 228 229 #endif // GPSTK_SINEXBLOCK_HPP 230