00001 /* 00002 * WOscLib, an object oriented OSC library. 00003 * Copyright (C) 2005 Uli Clemens Franke, Weiss Engineering LTD, Switzerland. 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 * 00019 * For details see lgpl.txt 00020 * 00021 * Weiss Engineering LTD. 00022 * Florastrass 42 00023 * 8610 Uster 00024 * Switzerland 00025 * 00026 * uli.franke@weiss.ch 00027 */ 00028 00029 /** WOscTimeTag source file. 00030 * \file 00031 * 00032 * $Author: cls-nebadje $ ( \ref _UcfWOscLib ) 00033 * $Date: 2006-08-13 16:38:01 $ 00034 * $Revision: 1.4 $ 00035 * 00036 * Copyright (c) Weiss Engineering Ltd 00037 * 00038 */ 00039 #include "WOscTimeTag.h" 00040 #include "WOscUtil.h" 00041 #include "limits.h" 00042 00043 /* ----------------------------------------------------------------------- */ 00044 /* WOscSystemTime */ 00045 /* ----------------------------------------------------------------------- */ 00046 00047 #if WOSC_HAS_STD_TIME_LIB 00048 # include <time.h> 00049 /* 17 leap years, stolen from OSC-kit, no guarantee for correctness... */ 00050 # if defined( _MSC_VER ) 00051 # define SECONDS_FROM_1900_TO_1970 2208988800 00052 # elif defined(__GNUC__) 00053 # define SECONDS_FROM_1900_TO_1970 2208988800ULL 00054 # endif 00055 #endif 00056 00057 /** Returns the system time. 00058 * When not overridden in a derived class, it returns largest time tag possible. 00059 * 00060 * \returns 00061 * Time representing the current system time. 00062 * 00063 * \remarks 00064 * Time tags are represented by a 64 bit fixed point number. The first 32 bits specify 00065 * the number of seconds since midnight on January 1, 1900, and the last 32 bits specify 00066 * fractional parts of a second to a precision of about 200 picoseconds. This is the rep- 00067 * resentation used by Internet NTP timestamps. The time tag value consisting of 63 zero 00068 * bits followed by a one in the least signifigant bit is a special case meaning "immediately." 00069 */ 00070 WOscTimeTag 00071 WOscSystemTime::GetSystemTime() const 00072 { 00073 #if WOSC_HAS_STD_TIME_LIB 00074 /* The time.h lib states: 00075 * "" time_t time ( time_t * timer ); "" 00076 * Get the number of seconds elapsed since 00:00 hours, 00077 * Jan 1, 1970 UTC from the system clock. 00078 */ 00079 WOscTimeTag systemTime; 00080 systemTime.m_timeTag = (uint64_t)time(NULL) + SECONDS_FROM_1900_TO_1970; 00081 return systemTime; 00082 #else 00083 return WOscTimeTag::GetLargestTimeTag(); 00084 #endif 00085 } 00086 00087 00088 /* ----------------------------------------------------------------------- */ 00089 /* WOscTimeTag */ 00090 /* ----------------------------------------------------------------------- */ 00091 00092 /** Constructor 00093 * Initializes the time-tag to immediate time. 00094 * 00095 */ 00096 WOscTimeTag::WOscTimeTag() 00097 { 00098 m_timeTag = 1; 00099 } 00100 00101 /** Construct an OSC-time tag from a raw OSC (network) byte- 00102 * stream (buffer). 00103 * The OSC (network) buffer has to be big-endian 00104 * 00105 * \param rawTimeTag 00106 * Buffer containing the raw time-tag 00107 * 00108 * \remarks 00109 * The argument buffer has to have a minimum length of 00110 * WOscTimeTag::Constants::TIME_TAG_SIZE. Smaller lengths 00111 * may produce runtime errors. 00112 */ 00113 WOscTimeTag::WOscTimeTag(const char* rawTimeTag) 00114 { 00115 InitFromCharArray(rawTimeTag); 00116 } 00117 00118 /** Copy constructor. 00119 * Initializes the current time-tag with the data from the referenced. 00120 * 00121 * \param rhs 00122 * Reference of time-tag to be copied. 00123 */ 00124 WOscTimeTag::WOscTimeTag(const WOscTimeTag& rhs) 00125 { 00126 m_timeTag = rhs.m_timeTag; 00127 } 00128 00129 /** Returns the current system time. 00130 * A optional system-time object can be passed, which implements 00131 * the system specific system-time-query. 00132 * 00133 * \param systemTime 00134 * Pointer to system time object (optional). If not specified, 00135 * The system time gets initialized with the library default 00136 * system time. 00137 * 00138 * \returns 00139 * Time-tag representing the current system time. 00140 */ 00141 WOscTimeTag WOscTimeTag::GetCurrentTime(const WOscSystemTime* systemTime /* = NULL*/){ 00142 if ( systemTime == NULL ){ 00143 /* get library default */ 00144 WOscSystemTime time; 00145 return time.GetSystemTime(); 00146 }else 00147 return systemTime->GetSystemTime(); 00148 } 00149 00150 /** Returns the "immediate" time-tag. 00151 * Immediate implies the LSB set to one. 00152 * 00153 * \returns 00154 * Immediate time-tag. 00155 */ 00156 WOscTimeTag 00157 WOscTimeTag::GetImmediateTime() 00158 { 00159 WOscTimeTag retTag; 00160 retTag.m_timeTag = 1; 00161 return retTag; 00162 } 00163 00164 /** Returns the largest possible time-tag. 00165 * I.e. all bits set to one. 00166 * 00167 * \returns 00168 * Largest possible time-tag. 00169 */ 00170 WOscTimeTag 00171 WOscTimeTag::GetLargestTimeTag() 00172 { 00173 WOscTimeTag retTag; 00174 retTag.m_timeTag = ULONG_LONG_MAX; 00175 return retTag; 00176 } 00177 00178 /** Returns the "immediate" time-tag. 00179 * Immediate implies the LSB set to one. 00180 * 00181 * \returns 00182 * Immediate time-tag. 00183 */ 00184 WOscTimeTag 00185 WOscTimeTag::GetSmallestTimeTag() 00186 { 00187 return GetImmediateTime(); 00188 } 00189 00190 /** Sets this time-tag to the current system time. 00191 * A optional system-time object can be passed, which implements 00192 * the system specific system-time-query. 00193 * 00194 * \param systemTime 00195 * Pointer to system time object (optional). If not specified, 00196 * The system time gets initialized with the library default 00197 * system time. 00198 * 00199 * \see 00200 * WOscTimeTag::getCurrentTime(const WOscSystemTime* systemTime) 00201 */ 00202 void 00203 WOscTimeTag::SetToCurrentTime(const WOscSystemTime* systemTime /*= NULL*/) 00204 { 00205 *this = systemTime->GetSystemTime(); 00206 } 00207 00208 /** Sets this time tag to immediate time. 00209 * 00210 * \see 00211 * WOscTimeTag::getImmediateTime() 00212 */ 00213 void 00214 WOscTimeTag::SetToImmediateTime() 00215 { 00216 *this = GetImmediateTime(); 00217 } 00218 00219 /** Sets this time tag to the biggest time-tag possible. 00220 * 00221 * \see 00222 * WOscTimeTag::getLargestTimeTag() 00223 */ 00224 void 00225 WOscTimeTag::SetToLargestTimeTag() 00226 { 00227 *this = GetLargestTimeTag(); 00228 } 00229 00230 /** Sets this time tag to the smallest time-tag possible. 00231 * 00232 * \see 00233 * WOscTimeTag::getSmallestTimeTag() 00234 */ 00235 void 00236 WOscTimeTag::SetToSmallestTimeTag() 00237 { 00238 *this = GetSmallestTimeTag(); 00239 } 00240 00241 /** Add operator. 00242 * Adds the right-hand time-tag to the left-hand time-tag 00243 * and returns the result without modifying the left-hand time-tag. 00244 * 00245 * \param rhs 00246 * Right-hand time-tag reference to be added to the left one. 00247 * 00248 * \returns 00249 * Left-hand time-tag plus right-hand time-tag. 00250 */ 00251 WOscTimeTag 00252 WOscTimeTag::operator+ (const WOscTimeTag& rhs) const 00253 { 00254 WOscTimeTag retTag; 00255 retTag.m_timeTag = m_timeTag + rhs.m_timeTag; 00256 return retTag; 00257 } 00258 00259 /** Assignment operator. 00260 * Assigns the right-hand time-tag to the left-hand time-tag 00261 * and returns it. 00262 * 00263 * \param rhs 00264 * Right-hand time-tag reference to be assigned to the left one. 00265 * 00266 * \returns 00267 * Left-hand time-tag value which equals now the right-hand time-tag. 00268 */ 00269 WOscTimeTag 00270 WOscTimeTag::operator= (const WOscTimeTag& rhs) 00271 { 00272 m_timeTag = rhs.m_timeTag; 00273 return *this; 00274 } 00275 00276 /** Add and assign operator. 00277 * Adds the right-hand time-tag to the left-hand time-tag, 00278 * stores the result in the left-hand time-tag and 00279 * returns the result. 00280 * 00281 * \param rhs 00282 * Right-hand time-tag reference to be added to the left one. 00283 * 00284 * \returns 00285 * Left-hand time-tag plus right-hand time-tag. 00286 */ 00287 WOscTimeTag 00288 WOscTimeTag::operator+= (const WOscTimeTag& rhs) 00289 { 00290 m_timeTag =+ rhs.m_timeTag; 00291 return *this; 00292 } 00293 00294 /** Subtract operator. 00295 * Subtracts the right-hand time-tag from the left-hand time-tag 00296 * and returns the result without modifying the left-hand time-tag. 00297 * 00298 * \param rhs 00299 * Right-hand time-tag reference to be subtracted from the left one. 00300 * 00301 * \returns 00302 * Left-hand time-tag minus right-hand time-tag. 00303 */ 00304 WOscTimeTag 00305 WOscTimeTag::operator- (const WOscTimeTag& rhs) const 00306 { 00307 WOscTimeTag retTag; 00308 retTag.m_timeTag = m_timeTag - rhs.m_timeTag; 00309 return retTag; 00310 } 00311 00312 /** Subtract and assign operator. 00313 * Subtracts the right-hand time-tag from the left-hand time-tag, 00314 * stores the result in the left-hand time-tag and 00315 * returns the result. 00316 * 00317 * \param rhs 00318 * Right-hand time-tag reference to be subtracted from the left one. 00319 * 00320 * \returns 00321 * Left-hand time-tag minus right-hand time-tag. 00322 */ 00323 WOscTimeTag 00324 WOscTimeTag::operator-= (const WOscTimeTag& rhs) 00325 { 00326 m_timeTag -= rhs.m_timeTag; 00327 return *this; 00328 } 00329 00330 /** Smaller or equal comparison operator. 00331 * Returns true if the left time-tag is smaller (older) 00332 * than the right. 00333 * 00334 * \param rhs 00335 * Right-hand side. 00336 * 00337 * \returns 00338 * True if the left time-tag is smaller (older) 00339 * than the right. False else. 00340 */ 00341 bool 00342 WOscTimeTag::operator< (const WOscTimeTag& rhs) const 00343 { 00344 return (m_timeTag < rhs.m_timeTag); 00345 } 00346 00347 /** Smaller or equal comparison operator. 00348 * Returns true if the left time-tag is smaller (older) 00349 * or equal (same time) than the right. 00350 * 00351 * \param rhs 00352 * Right-hand side. 00353 * 00354 * \returns 00355 * True if the left time-tag is smaller (older) 00356 * or equal (same time) than the right. False else. 00357 */ 00358 bool 00359 WOscTimeTag::operator<= (const WOscTimeTag& rhs) const 00360 { 00361 return (m_timeTag <= rhs.m_timeTag); 00362 } 00363 00364 /** Is equal operator. 00365 * Returns true if the right time-tag is equal to the left. 00366 * 00367 * \param rhs 00368 * Right-hand side. 00369 * 00370 * \returns 00371 * True if the right time-tag is equal to the left. 00372 * False else. 00373 */ 00374 bool 00375 WOscTimeTag::operator== (const WOscTimeTag& rhs) const 00376 { 00377 return (m_timeTag == rhs.m_timeTag); 00378 } 00379 00380 /** Is not equal operator. 00381 * Returns true if the right time-tag is different from the left. 00382 * 00383 * \param rhs 00384 * Right-hand side. 00385 * 00386 * \returns 00387 * True if the right time-tag is different from the left. 00388 * False else. 00389 */ 00390 bool 00391 WOscTimeTag::operator!= (const WOscTimeTag& rhs) const 00392 { 00393 return (m_timeTag != rhs.m_timeTag); 00394 } 00395 00396 /** Bigger comparison operator. 00397 * Returns true if the right time-tag is smaller (older) 00398 * than the left. 00399 * 00400 * \param rhs 00401 * Right-hand side. 00402 * 00403 * \returns 00404 * True if the right time-tag is smaller (older) 00405 * than the left. False else. 00406 */ 00407 bool 00408 WOscTimeTag::operator> (const WOscTimeTag& rhs) const 00409 { 00410 return (m_timeTag > rhs.m_timeTag); 00411 } 00412 00413 /** Bigger or equal comparison operator. 00414 * Returns true if the right time-tag is smaller (older) 00415 * or equal (same time) than the left. 00416 * 00417 * \param rhs 00418 * Right-hand side. 00419 * 00420 * \returns 00421 * True if the right time-tag is smaller (older) 00422 * or equal (same time) than the left. False else. 00423 */ 00424 bool 00425 WOscTimeTag::operator>= (const WOscTimeTag& rhs) const 00426 { 00427 return (m_timeTag >= rhs.m_timeTag); 00428 } 00429 00430 /** Returns a new char array of size TIME_TAG_SIZE filled with the 00431 * network aligned (big endian) timetag. 00432 * 00433 * The caller has to free the allocated memory. 00434 * 00435 * \returns 00436 * The allocated char array filled with the 00437 * network aligned (big endian) timetag. 00438 * 00439 * \remarks 00440 * The caller has to free the allocated memory. 00441 * 00442 */ 00443 const char* 00444 WOscTimeTag::ToCharArray() const 00445 { 00446 char* buffer = new char[sizeof(uint64_t)]; 00447 WOscUtil::FillBufferWith(buffer, m_timeTag); 00448 return buffer; 00449 } 00450 00451 /** Fill the given buffer with the network char array 00452 * representation of an OSC time tag. 00453 * 00454 * \param buffer 00455 * Caller supplied buffer with a minimum size of TIME_TAG_SIZE. 00456 * 00457 * \remarks 00458 * The byte stream buffer has to have a minimum length of 00459 * TIME_TAG_SIZE. 00460 */ 00461 void WOscTimeTag::WriteToCharArray(char* buffer) const 00462 { 00463 WOscUtil::FillBufferWith(buffer, m_timeTag); 00464 } 00465 00466 /** Initializes an OSC time tag from a byte stream (big endian 00467 * ordered). 00468 * The byte stream buffer has to have a minimum length of 00469 * TIME_TAG_SIZE. 00470 * 00471 * \param buffer 00472 * Pointer to buffer with initialization data. 00473 * 00474 * \remarks 00475 * The byte stream buffer has to have a minimum length of 00476 * TIME_TAG_SIZE. 00477 */ 00478 void 00479 WOscTimeTag::InitFromCharArray(const char* buffer) 00480 { 00481 m_timeTag = WOscUtil::BufferTo<uint64_t>(buffer); 00482 }