00001 #pragma ident "$Id: GPSZcount.cpp 500 2007-04-27 12:02:53Z ocibu $"
00002
00003
00004
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <limits>
00033
00034 #include "GPSZcount.hpp"
00035 #include "StringUtils.hpp"
00036
00037 using namespace std;
00038 using gpstk::StringUtils::asString;
00039
00040 namespace gpstk
00041 {
00042 const long GPSZcount::ZCOUNT_MINUTE = 40;
00043 const long GPSZcount::ZCOUNT_HOUR = 2400;
00044 const long GPSZcount::ZCOUNT_DAY = 57600;
00045 const long GPSZcount::ZCOUNT_WEEK = 403200;
00046
00047 GPSZcount::GPSZcount(short inWeek,
00048 long inZcount)
00049 throw(gpstk::InvalidParameter)
00050 {
00051 try
00052 {
00053 setWeek(inWeek);
00054 setZcount(inZcount);
00055 }
00056 catch(gpstk::InvalidParameter& ip)
00057 {
00058 GPSTK_RETHROW(ip);
00059 }
00060 }
00061
00062 GPSZcount::GPSZcount(long inFullZcount)
00063 throw(gpstk::InvalidParameter)
00064 {
00065 try
00066 {
00067 setFullZcount(inFullZcount);
00068 }
00069 catch(gpstk::InvalidParameter& ip)
00070 {
00071 GPSTK_RETHROW(ip);
00072 }
00073 }
00074
00075 GPSZcount::GPSZcount(const GPSZcount& right)
00076 throw()
00077 {
00078 operator=(right) ;
00079 }
00080
00081 GPSZcount& GPSZcount::setWeek(short inWeek)
00082 throw(gpstk::InvalidParameter)
00083 {
00084 if( inWeek < 0 )
00085 {
00086 gpstk::InvalidParameter ip("GPS Week invalid: " +
00087 asString<short>(inWeek)) ;
00088 GPSTK_THROW(ip) ;
00089 }
00090 week = inWeek;
00091 return *this;
00092 }
00093
00094 GPSZcount& GPSZcount::setZcount(long inZcount)
00095 throw(gpstk::InvalidParameter)
00096 {
00097 if(validZcount(inZcount) != 0)
00098 {
00099 gpstk::InvalidParameter ip("GPS Z-count invalid: " +
00100 asString<long>(inZcount)) ;
00101 GPSTK_THROW(ip) ;
00102 }
00103 zcount = inZcount ;
00104 return *this ;
00105 }
00106
00107 GPSZcount& GPSZcount::setFullZcount(long inZcount)
00108 throw(gpstk::InvalidParameter)
00109 {
00110 try
00111 {
00112 setZcount(inZcount & 0x7FFFFL) ;
00113
00114
00115
00116 setWeek((inZcount >> 19) & 0x3FFL) ;
00117
00118 }
00119 catch(gpstk::InvalidParameter& ip)
00120 {
00121 ip.addText("GPS Full Z-count invalid: " + asString<long>(inZcount)) ;
00122 GPSTK_RETHROW(ip) ;
00123 }
00124 return *this ;
00125 }
00126
00127 GPSZcount& GPSZcount::addWeeks(short inWeeks)
00128 throw(gpstk::InvalidRequest)
00129 {
00130 if (inWeeks == 0)
00131 {
00132 return *this ;
00133 }
00134
00135 try
00136 {
00137 return setWeek(week + inWeeks) ;
00138 }
00139 catch(gpstk::InvalidParameter& ip)
00140 {
00141 gpstk::InvalidRequest ir(ip) ;
00142 ir.addText("Addition of " + asString(inWeeks) +
00143 " weeks renders this object invalid.") ;
00144 GPSTK_THROW(ir) ;
00145 }
00146 }
00147
00148 GPSZcount& GPSZcount::addZcounts(long inZcounts)
00149 throw(gpstk::InvalidRequest)
00150 {
00151 if (inZcounts == 0)
00152 {
00153 return *this ;
00154 }
00155
00156 short originalWeek(week) ;
00157 long originalZcount(zcount) ;
00158
00159 try
00160 {
00161
00162 addWeeks(inZcounts / ZCOUNT_WEEK) ;
00163
00164
00165 long tmp = zcount + (inZcounts % ZCOUNT_WEEK) ;
00166
00167 if (tmp < 0)
00168 {
00169 addWeeks(-1);
00170 tmp += ZCOUNT_WEEK ;
00171 }
00172 else if (tmp >= ZCOUNT_WEEK)
00173 {
00174 addWeeks(1);
00175 tmp -= ZCOUNT_WEEK ;
00176 }
00177
00178 setZcount(tmp) ;
00179 return *this ;
00180
00181 }
00182 catch(gpstk::InvalidRequest& ir)
00183 {
00184 setWeek(originalWeek) ;
00185 setZcount(originalZcount) ;
00186 ir.addText("Did not add " + asString(inZcounts) + " Z-counts.") ;
00187 GPSTK_RETHROW(ir) ;
00188
00189 }
00190 catch(gpstk::InvalidParameter& ip)
00191 {
00192 setWeek(originalWeek) ;
00193 setZcount(originalZcount) ;
00194 gpstk::InvalidRequest ir(ip) ;
00195 ir.addText("Did not add " + asString(inZcounts) + " Z-counts.") ;
00196 GPSTK_THROW(ir) ;
00197 }
00198 }
00199
00200 GPSZcount GPSZcount::operator++(int)
00201 throw(gpstk::InvalidRequest)
00202 {
00203 GPSZcount temp = *this ;
00204 ++(*this) ;
00205 return temp ;
00206 }
00207
00208 GPSZcount& GPSZcount::operator++()
00209 throw(gpstk::InvalidRequest)
00210 {
00211 return addZcounts(1);
00212 }
00213
00214 GPSZcount GPSZcount::operator--(int)
00215 throw(gpstk::InvalidRequest)
00216 {
00217 GPSZcount temp = *this ;
00218 --(*this) ;
00219 return temp ;
00220 }
00221
00222 GPSZcount& GPSZcount::operator--()
00223 throw(gpstk::InvalidRequest)
00224 {
00225 return addZcounts(-1);
00226 }
00227
00228 GPSZcount GPSZcount::operator+(long inZcounts) const
00229 throw(gpstk::InvalidRequest)
00230 {
00231 return GPSZcount(*this).addZcounts(inZcounts);
00232 }
00233
00234 GPSZcount GPSZcount::operator-(long inZcounts) const
00235 throw(gpstk::InvalidRequest)
00236 {
00237 return operator+(-inZcounts);
00238 }
00239
00240 double GPSZcount::operator-(const GPSZcount& right) const
00241 throw()
00242 {
00243 return (double(week) - right.week) * ZCOUNT_WEEK
00244 + (zcount - right.zcount) ;
00245 }
00246
00247 long GPSZcount::operator%(const long right) const
00248 throw()
00249 {
00250 return zcount % right;
00251 }
00252
00253 GPSZcount& GPSZcount::operator+=(long inZcounts)
00254 throw(gpstk::InvalidRequest)
00255 {
00256 return addZcounts(inZcounts);
00257 }
00258
00259 GPSZcount& GPSZcount::operator-=(long inZcounts)
00260 throw(gpstk::InvalidRequest)
00261 {
00262 return addZcounts(-inZcounts);
00263 }
00264
00265 GPSZcount& GPSZcount::operator=(const GPSZcount& right)
00266 throw()
00267 {
00268 week = right.week;
00269 zcount = right.zcount;
00270 return *this;
00271 }
00272
00273 bool GPSZcount::operator<(const GPSZcount& right) const
00274 throw()
00275 {
00276 if (week < right.week)
00277 {
00278 return true;
00279 }
00280 if (week == right.week &&
00281 zcount < right.zcount)
00282 {
00283 return true;
00284 }
00285 return false;
00286 }
00287
00288 bool GPSZcount::operator>(const GPSZcount& right) const
00289 throw()
00290 {
00291 if (week > right.week)
00292 {
00293 return true;
00294 }
00295 if (week == right.week &&
00296 zcount > right.zcount)
00297 {
00298 return true;
00299 }
00300 return false;
00301 }
00302
00303 bool GPSZcount::operator==(const GPSZcount& right) const
00304 throw()
00305 {
00306 if (week == right.week &&
00307 zcount == right.zcount)
00308 {
00309 return true;
00310 }
00311 return false;
00312 }
00313
00314 bool GPSZcount::operator!=(const GPSZcount& right) const
00315 throw()
00316 {
00317 return (! operator==(right));
00318 }
00319
00320 bool GPSZcount::operator<=(const GPSZcount& right) const
00321 throw()
00322 {
00323 return (! operator>(right));
00324 }
00325
00326 bool GPSZcount::operator>=(const GPSZcount& right) const
00327 throw()
00328 {
00329 return (! operator<(right));
00330 }
00331
00332 GPSZcount::operator std::string() const
00333 throw()
00334 {
00335 return asString<short>(week) + "w" + asString<long>(zcount) + "z";
00336 }
00337
00338 bool GPSZcount::inSameTimeBlock(const GPSZcount& other,
00339 unsigned long inZcountBlock,
00340 unsigned long inZcountOffset)
00341 throw()
00342 {
00343 if (inZcountBlock < ZCOUNT_WEEK)
00344 {
00345
00346
00347 if ( (getWeek() == other.getWeek()) &&
00348 (((getZcount() - inZcountOffset) / inZcountBlock) ==
00349 ((other.getZcount() - inZcountOffset) / inZcountBlock)) )
00350 {
00351 return true ;
00352 }
00353 }
00354 else
00355 {
00356
00357 if (long((getTotalZcounts() - inZcountOffset) / inZcountBlock) ==
00358 long((other.getTotalZcounts() - inZcountOffset) / inZcountBlock))
00359 {
00360 return true ;
00361 }
00362 }
00363
00364 return false ;
00365 }
00366
00367 void GPSZcount::dump(std::ostream& out,
00368 short level) const
00369 throw()
00370 {
00371 switch(level)
00372 {
00373 case 0:
00374 out << week << "w" << zcount << "z" << flush;
00375 break;
00376 case 1:
00377 default:
00378 out << "GPS Full Week: " << setw(6) << week << endl
00379 << "GPS Z-count: " << setw(6) << zcount << endl;
00380 break;
00381 }
00382 }
00383
00384 long GPSZcount::validZcount(long z)
00385 throw()
00386 {
00387 if (z < 0)
00388 {
00389 return z;
00390 }
00391 if (z >= GPSZcount::ZCOUNT_WEEK)
00392 {
00393 return (z - (GPSZcount::ZCOUNT_WEEK - 1));
00394 }
00395 return 0;
00396 }
00397
00398 std::ostream& operator<<(std::ostream& s,
00399 const gpstk::GPSZcount& z)
00400 {
00401 z.dump(s, 0) ;
00402 return s;
00403 }
00404
00405 }