Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members
MP7Time.cpp
00001 /*********************************************************************** 00002 * * 00003 * MuViNo - ViTooKi Video Annotation Tool * 00004 * * 00005 * title: MP7Time.cpp * 00006 * * 00007 * $Id: MP7Time.cpp,v 1.5 2005/08/04 13:04:42 klschoef Exp $ 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 #include <stdlib.h> 00037 #include <string.h> 00038 #ifndef WINCE 00039 #include <errno.h> 00040 #endif 00041 00042 #include <debug.hpp> 00043 #include "MP7Time.hpp" 00044 00045 #ifdef WINCE 00046 int errno = 0; 00047 #endif 00048 00049 #define SECS_PER_DAY (24 * 3600) 00050 #define MP7TIME_TPOINT_BUFSIZE (MP7TIME_DATE_LEN + MP7TIME_TZ_LEN + 30) 00051 #define MP7TIME_DURATION_BUFSIZE (MP7TIME_TZ_LEN + 50) 00052 00053 MP7Time::MP7Time() 00054 { 00055 reset(); 00056 } 00057 00058 void MP7Time::resetTimePoint() 00059 { 00060 tpoint.date[0] = '\0'; 00061 tpoint.hasTime = false; 00062 tpoint.sec = 0; 00063 tpoint.num = 0; 00064 tpoint.denom = 1; 00065 tpoint.tz[0] = '\0'; 00066 } 00067 00068 void MP7Time::resetDuration() 00069 { 00070 duration.sign = 1; 00071 duration.days = 0; 00072 duration.sec = 0; 00073 duration.num = 0; 00074 duration.denom = 1; 00075 duration.tz[0] = '\0'; 00076 duration.units = 0; 00077 } 00078 00079 void MP7Time::reset() 00080 { 00081 resetTimePoint(); 00082 resetDuration(); 00083 } 00084 00085 bool MP7Time::setTimePoint(uint value, uint ticksPerSecond) 00086 { 00087 resetTimePoint(); 00088 if (ticksPerSecond == 0) { 00089 dprintf_err("MP7Time::setTimePoint(value = %u, ticksPerSecond = %u) invalid ticksPerSecond value!\n", 00090 value, ticksPerSecond); 00091 return false; 00092 } 00093 tpoint.sec = value / ticksPerSecond; 00094 tpoint.num = value % ticksPerSecond; 00095 tpoint.denom = ticksPerSecond; 00096 tpoint.hasTime = true; 00097 return true; 00098 } 00099 00100 bool MP7Time::setTimePoint(const char *mp7Value) 00101 { 00102 resetTimePoint(); 00103 uint val; 00104 char *pos = strchr(mp7Value, 'T'); 00105 /* date part */ 00106 if (!pos) 00107 pos = strchr(mp7Value, '\0'); 00108 if (pos > mp7Value) { 00109 int len = pos - mp7Value; 00110 if (len > MP7TIME_DATE_LEN) 00111 return false; 00112 memcpy(tpoint.date, mp7Value, len); 00113 tpoint.date[len] = '\0'; 00114 } 00115 if (*pos == '\0') 00116 return true; 00117 pos++; // advance to character after 'T' 00118 /* time zone */ 00119 char *postz = strchr(pos, '+'); 00120 if (!postz) 00121 postz = strchr(pos, '-'); 00122 if (postz) { 00123 if (strlen(postz) > MP7TIME_TZ_LEN) { 00124 resetTimePoint(); 00125 return false; 00126 } 00127 strcpy(tpoint.tz, postz); 00128 } else 00129 postz = strchr(pos, '\0'); 00130 if (pos == postz) 00131 return true; 00132 /* parse time part */ 00133 int unit = 3600; // time unit (in seconds) of next field 00134 char *num = pos; 00135 for (; pos <= postz; pos++) { 00136 if (*pos == ':' || *pos == 'F' || *pos == '+' 00137 || *pos == '-' || *pos == '\0') { 00138 char *tail; 00139 errno = 0; 00140 val = (uint) strtoul(num, &tail, 10); 00141 if (errno || tail != pos) { 00142 dprintf_err("MP7Time::setTimePoint(mp7value = %s) integer conversion FAILED!\n", 00143 mp7Value); 00144 resetTimePoint(); 00145 return false; 00146 } 00147 num = pos + 1; 00148 switch (*pos) { 00149 case ':': // fall through 00150 case '+': // fall through 00151 case '-': // fall through 00152 case '\0': 00153 if (unit) { 00154 tpoint.sec += val * unit; 00155 unit /= 60; 00156 } else { 00157 if (!val) { 00158 dprintf_err("MP7Time::setTimePoint(mp7value = %s) 0 denominator!\n", 00159 mp7Value); 00160 resetTimePoint(); 00161 return false; 00162 } 00163 tpoint.denom = val; 00164 } 00165 break; 00166 case 'F': 00167 tpoint.num = val; 00168 unit = 0; 00169 break; 00170 } // switch 00171 } // if 00172 } 00173 tpoint.hasTime = true; 00174 return true; 00175 } 00176 00177 bool MP7Time::setTimePoint(const MP7Time &otherTime) 00178 { 00179 tpoint = otherTime.tpoint; 00180 return true; 00181 } 00182 00183 bool MP7Time::moveTimePoint(int value, uint ticksPerSecond) 00184 { 00185 bool rval = true; 00186 uint denom = commonMultiple(tpoint.denom, ticksPerSecond); 00187 tpoint.num *= denom / tpoint.denom; 00188 value *= (int) (denom / ticksPerSecond); 00189 tpoint.denom = denom; 00190 if (value < 0) { 00191 int sec = (int) tpoint.sec; 00192 value = -value; 00193 tpoint.num += denom; 00194 tpoint.num -= value % denom; 00195 if (tpoint.num >= denom) 00196 tpoint.num -= denom; 00197 else 00198 sec--; 00199 sec -= value / denom; 00200 if (sec < 0) { 00201 rval = false; 00202 resetTimePoint(); 00203 } else 00204 tpoint.sec = (uint) sec; 00205 } else { 00206 tpoint.num += value % denom; 00207 if (tpoint.num >= denom) { 00208 tpoint.sec++; 00209 tpoint.num -= denom; 00210 } 00211 tpoint.sec += value / denom; 00212 } 00213 tpoint.hasTime = true; 00214 return rval; 00215 } 00216 00217 bool MP7Time::setDuration(uint value, uint ticks) 00218 { 00219 resetDuration(); 00220 if (ticks == 0) { 00221 dprintf_err("MP7Time::setDuration(value = %u, ticks = %u) invalid ticks value!\n", 00222 value, ticks); 00223 return false; 00224 } 00225 duration.sec = value / ticks; 00226 duration.num = value % ticks; 00227 duration.denom = ticks; 00228 return true; 00229 } 00230 00231 bool MP7Time::setDuration(const char *mp7Value) 00232 { 00233 resetDuration(); 00234 const char *pos = mp7Value; 00235 /* duration sign */ 00236 if (*pos == '-') { 00237 duration.sign = -1; 00238 pos++; 00239 } 00240 if (*pos != 'P') { 00241 dprintf_err("MP7Time::setDuration(mp7Value = %s) invalid MPEG-7 duration!\n", 00242 mp7Value); 00243 resetDuration(); 00244 return false; 00245 } 00246 pos++; 00247 /* parse duration and time zone */ 00248 const char *start = pos; 00249 uint val; 00250 for (; *pos; pos++) { 00251 /* duration */ 00252 if (*pos == 'T') { 00253 start = pos + 1; 00254 } else if (*pos == 'D' || *pos == 'H' || *pos == 'M' || *pos == 'S' 00255 || *pos == 'N' || *pos == 'F') { 00256 char *tail; 00257 errno = 0; 00258 val = (uint) strtoul(start, &tail, 10); 00259 if (errno || tail != pos) { 00260 dprintf_err("MP7Time::setDuration(mp7Value = %s) integer conversion FAILED!\n", 00261 mp7Value); 00262 resetDuration(); 00263 return false; 00264 } 00265 start = pos + 1; 00266 switch (*pos) { 00267 case 'D': 00268 duration.days = val; 00269 break; 00270 case 'H': 00271 duration.sec += val * 3600; 00272 break; 00273 case 'M': 00274 duration.sec += val * 60; 00275 break; 00276 case 'S': 00277 duration.sec += val; 00278 break; 00279 case 'N': 00280 duration.num = val; 00281 break; 00282 case 'F': 00283 if (val > 0) 00284 duration.denom = val; 00285 else { 00286 dprintf_err("MP7Time::setDuration(mp7Value = %s) invalid fraction!\n", 00287 mp7Value); 00288 resetDuration(); 00289 return false; 00290 } 00291 } //switch 00292 } else if (*pos == 'Z') { // time zone difference 00293 int len = pos - start; // don't copy the 'Z' character 00294 if (len > MP7TIME_TZ_LEN) { 00295 dprintf_err("MP7Time::setDuration(mp7Value = %s) time zone string too long!\n", 00296 mp7Value); 00297 resetDuration(); 00298 return false; 00299 } 00300 memcpy(duration.tz, start, len); 00301 duration.tz[len] = '\0'; 00302 } 00303 } // for 00304 return true; 00305 } 00306 00307 bool MP7Time::setDuration(const MP7Time &duration) 00308 { 00309 this->duration = duration.duration; 00310 return true; 00311 } 00312 00313 bool MP7Time::setDurationFromEnd(const MP7Time &end) 00314 { 00315 if (!tpoint.hasTime || !end.tpoint.hasTime) 00316 return false; 00317 resetDuration(); 00318 uint denom = commonMultiple(tpoint.denom, end.tpoint.denom); 00319 duration.denom = denom; 00320 if (compareTimePoint(end) <= 0) { 00321 duration.sign = 1; 00322 duration.num = end.tpoint.num * (denom / end.tpoint.denom); 00323 duration.sec = end.tpoint.sec; 00324 uint thisnum = tpoint.num * (denom / tpoint.denom); 00325 if (thisnum > duration.num) { 00326 duration.num += denom; 00327 duration.sec--; 00328 } 00329 duration.num -= thisnum; 00330 duration.sec -= tpoint.sec; 00331 } else { 00332 MP7Time end2(end); 00333 if (!end2.setDurationFromEnd(*this)) 00334 return false; 00335 duration = end2.duration; 00336 duration.sign = -1; 00337 } 00338 if (duration.sec >= SECS_PER_DAY) { 00339 duration.days = duration.sec / SECS_PER_DAY; 00340 duration.sec %= SECS_PER_DAY; 00341 } 00342 return true; 00343 } 00344 00345 bool MP7Time::addDuration(const MP7Time &otherTime) 00346 { 00347 if (duration.sign < 0 || otherTime.duration.sign < 0) 00348 return false; 00349 if (otherTime.duration.num > 0) { 00350 uint newDenom = commonMultiple(duration.denom, otherTime.duration.denom); 00351 duration.num *= newDenom / duration.denom; 00352 duration.denom = newDenom; 00353 duration.num += otherTime.duration.num * newDenom / otherTime.duration.denom; 00354 if (duration.num >= duration.denom) { 00355 duration.sec++; 00356 duration.num -= duration.denom; 00357 } 00358 } 00359 duration.sec += otherTime.duration.sec; 00360 if (duration.sec >= SECS_PER_DAY) { 00361 duration.days++; 00362 duration.sec -= SECS_PER_DAY; 00363 } 00364 duration.days += otherTime.duration.days; 00365 return true; 00366 } 00367 00368 const char *MP7Time::timePointPretty(bool forceSubSec) const 00369 { 00370 static char buf[MP7TIME_TPOINT_BUFSIZE]; 00371 int len = strlen(tpoint.date); 00372 char *pos = buf; 00373 if (len > 0) { 00374 memcpy(pos, tpoint.date, len); 00375 pos += len; 00376 if (tpoint.hasTime && *(pos-1) != '-') 00377 *pos++ = ' '; 00378 } 00379 /* avoid returning a null string for "empty" time point */ 00380 if (tpoint.hasTime || !len) { 00381 pos += sprintf(pos, "%02u:%02u:%02u", tpoint.sec / 3600, (tpoint.sec % 3600) / 60, 00382 tpoint.sec % 60); 00383 if (tpoint.num || forceSubSec) { 00384 *pos++ = '.'; 00385 pos += sprintf(pos, "%02u", tpoint.num * 100 / tpoint.denom); 00386 } 00387 } 00388 len = strlen(tpoint.tz); 00389 if (len > 0) { 00390 memcpy(pos, tpoint.tz, len); 00391 pos += len; 00392 } 00393 *pos = '\0'; 00394 return buf; 00395 } 00396 00397 const char *MP7Time::durationPretty() const 00398 { 00399 static char buf[MP7TIME_DURATION_BUFSIZE]; 00400 char *pos = buf; 00401 int size = MP7TIME_DURATION_BUFSIZE; 00402 int n; 00403 bool hasTime = (duration.sec != 0 || duration.num != 0); 00404 if (duration.units) { 00405 n = snprintf(pos, size, "%d * [", duration.units); 00406 if (n+1 >= size) { // count also '-' added below 00407 dprintf_err("MP7Time::durationPretty() static buffer too small, buf = %s\n", 00408 buf); 00409 return buf; 00410 } 00411 pos += n; 00412 size -= n; 00413 } 00414 if (duration.sign < 0) { 00415 *pos++ = '-'; 00416 size--; 00417 } 00418 if (duration.days) { 00419 n = snprintf(pos, size, "%u days", duration.days); 00420 if (n+1 >= size) { 00421 dprintf_err("MP7Time::durationPretty() static buffer too small, buf = %s\n", 00422 buf); 00423 return buf; 00424 } 00425 pos += n; 00426 size -= n; 00427 if (hasTime || *duration.tz) { 00428 *pos++ = ' '; 00429 *pos = '\0'; 00430 size--; 00431 } 00432 } 00433 if (hasTime) { 00434 n = snprintf(pos, size, "%02u:%02u:%02u", duration.sec / 3600, 00435 (duration.sec % 3600) / 60, duration.sec % 60); 00436 if (n+3 >= size) { 00437 dprintf_err("MP7Time::durationPretty() static buffer too small, buf = %s\n", 00438 buf); 00439 return buf; 00440 } 00441 pos += n; 00442 size -= n; 00443 if (duration.num) { 00444 n = snprintf(pos, size, ".%02u", duration.num * 100 / duration.denom); 00445 pos += n; 00446 size -= n; 00447 } 00448 } 00449 if (*duration.tz) { 00450 int len = strlen(duration.tz); 00451 if (len >= size) { 00452 dprintf_err("MP7Time::durationPretty() static buffer too small, buf = %s\n", 00453 buf); 00454 return buf; 00455 } 00456 strcpy(pos, duration.tz); 00457 pos += len; 00458 size -= len; 00459 } 00460 if (duration.units) { 00461 if (size < 2) { 00462 dprintf_err("MP7Time::durationPretty() static buffer too small, buf = %s\n", 00463 buf); 00464 return buf; 00465 } 00466 *pos++ = ']'; 00467 } 00468 *pos = '\0'; 00469 return buf; 00470 } 00471 00472 MP7Time MP7Time::endTimePoint() const 00473 { 00474 MP7Time end; 00475 end.tpoint.hasTime = tpoint.hasTime; 00476 end.tpoint.sec = tpoint.sec; 00477 end.tpoint.num = tpoint.num; 00478 end.tpoint.denom = tpoint.denom; 00479 if (duration.num > 0) { 00480 end.tpoint.denom = commonMultiple(tpoint.denom, duration.denom); 00481 if (end.tpoint.denom != tpoint.denom) 00482 end.tpoint.num *= end.tpoint.denom / tpoint.denom; 00483 } 00484 int i = 1; 00485 int sign = duration.sign; 00486 if (duration.units > 0) { 00487 i = duration.units; 00488 } else if (duration.units < 0) { 00489 i = -duration.units; 00490 sign = -sign; 00491 } 00492 if (sign > 0) { 00493 if (duration.days) 00494 end.tpoint.sec += duration.days * SECS_PER_DAY; 00495 end.tpoint.sec += duration.sec; 00496 if (duration.num > 0) { 00497 end.tpoint.num += duration.num * end.tpoint.denom / duration.denom; 00498 end.tpoint.sec += end.tpoint.num / end.tpoint.denom; 00499 end.tpoint.num %= end.tpoint.denom; 00500 } 00501 } else { 00502 if (duration.days) 00503 end.tpoint.sec -= duration.days * SECS_PER_DAY; 00504 end.tpoint.sec -= duration.sec; 00505 if (duration.num > 0) { 00506 uint diff = duration.num * end.tpoint.denom / duration.denom; 00507 end.tpoint.sec -= diff / end.tpoint.denom; 00508 diff %= end.tpoint.denom; 00509 if (diff > end.tpoint.num) { 00510 end.tpoint.sec--; 00511 diff -= end.tpoint.denom; 00512 } 00513 end.tpoint.num -= diff; 00514 } 00515 } 00516 return end; 00517 } 00518 00519 const char *MP7Time::endTimePointPretty(bool forceSubSec) const 00520 { 00521 return endTimePoint().timePointPretty(forceSubSec); 00522 } 00523 00524 const char *MP7Time::toString() const 00525 { 00526 static char buf[MP7TIME_TPOINT_BUFSIZE + MP7TIME_DURATION_BUFSIZE + 3]; 00527 const char *tp = timePointPretty(); 00528 const char *dur = durationPretty(); 00529 int len1 = strlen(tp); 00530 int len2 = strlen(dur); 00531 char *pos = buf; 00532 if (len1 > 0) { 00533 memcpy(pos, tp, len1); 00534 pos += len1; 00535 if (len2 > 0) { 00536 *pos++ = ' '; 00537 *pos++ = '['; 00538 } 00539 } 00540 if (len2 > 0) { 00541 memcpy(pos, dur, len2); 00542 pos += len2; 00543 if (len1 > 0) 00544 *pos++ = ']'; 00545 } 00546 *pos = '\0'; 00547 return buf; 00548 } 00549 00550 const char *MP7Time::timePointMP7() const 00551 { 00552 static char buf[MP7TIME_TPOINT_BUFSIZE]; 00553 char *pos = buf; 00554 int size = MP7TIME_TPOINT_BUFSIZE; 00555 int len = strlen(tpoint.date); 00556 int n; 00557 if (len > 0) { 00558 strcpy(pos, tpoint.date); 00559 pos += len; 00560 size -= len; 00561 } 00562 if (tpoint.hasTime) { 00563 *pos++ = 'T'; 00564 size--; 00565 n = snprintf(pos, size, "%02u:%02u:%02u", tpoint.sec / 3600, 00566 (tpoint.sec % 3600) / 60, tpoint.sec % 60); 00567 if (n >= size) { 00568 dprintf_err("MP7Time::timePointMP7() static buffer too small, buf = %s\n", 00569 buf); 00570 return buf; 00571 } 00572 pos += n; 00573 size -= n; 00574 if (tpoint.num) { 00575 n = snprintf(pos, size, ":%uF%u", tpoint.num, tpoint.denom); 00576 if (n >= size) { 00577 dprintf_err("MP7Time::timePointMP7() static buffer too small, buf = %s\n", 00578 buf); 00579 return buf; 00580 } 00581 pos += n; 00582 size -= n; 00583 } 00584 } 00585 len = strlen(tpoint.tz); 00586 if (len > 0) { 00587 if (len >= size) { 00588 dprintf_err("MP7Time::timePointMP7() static buffer too small, buf = %s\n", 00589 buf); 00590 return buf; 00591 } 00592 strcpy(pos, tpoint.tz); 00593 } 00594 return buf; 00595 } 00596 00597 const char *MP7Time::durationMP7() const 00598 { 00599 static char buf[MP7TIME_DURATION_BUFSIZE]; 00600 char *pos = buf; 00601 int size = MP7TIME_DURATION_BUFSIZE; 00602 int len = strlen(duration.tz); 00603 int n; 00604 const char *err_format = "MP7Time::durationMP7() static buffer too small, buf = %s\n"; 00605 bool hasTime = (duration.sec != 0 || duration.num != 0); 00606 if (duration.sign < 0) { 00607 *pos++ = '-'; 00608 size--; 00609 } 00610 *pos++ = 'P'; 00611 size--; 00612 if (duration.days) { 00613 n = snprintf(pos, size, "%uD", duration.days); 00614 if (n >= size) { 00615 dprintf_err(err_format, buf); 00616 return buf; 00617 } 00618 pos += n; 00619 size -= n; 00620 } 00621 if (hasTime) { 00622 if (size >= 2) { 00623 *pos++ = 'T'; 00624 *pos = '\0'; 00625 size--; 00626 } 00627 uint val = duration.sec / 3600; 00628 if (val) { 00629 n = snprintf(pos, size, "%uH", val); 00630 if (n >= size) { 00631 dprintf_err(err_format, buf); 00632 return buf; 00633 } 00634 pos += n; 00635 size -= n; 00636 } 00637 val = (duration.sec % 3600) / 60; 00638 if (val) { 00639 n = snprintf(pos, size, "%uM", val); 00640 if (n >= size) { 00641 dprintf_err(err_format, buf); 00642 return buf; 00643 } 00644 pos += n; 00645 size -= n; 00646 } 00647 val = duration.sec % 60; 00648 if (val) { 00649 n = snprintf(pos, size, "%uS", val); 00650 if (n >= size) { 00651 dprintf_err(err_format, buf); 00652 return buf; 00653 } 00654 pos += n; 00655 size -= n; 00656 } 00657 if (duration.num) { 00658 n = snprintf(pos, size, "%uN%uF", duration.num, duration.denom); 00659 if (n >= size) { 00660 dprintf_err(err_format, buf); 00661 return buf; 00662 } 00663 pos += n; 00664 size -= n; 00665 } 00666 } 00667 if (len > 0) { 00668 if (len+1 >= size) { 00669 dprintf_err(err_format, buf); 00670 return buf; 00671 } 00672 memcpy(pos, duration.tz, len); 00673 pos += len; 00674 *pos++ = 'Z'; 00675 } 00676 *pos = '\0'; 00677 return buf; 00678 } 00679 00680 double MP7Time::timeToSec() const 00681 { 00682 if (!tpoint.hasTime) 00683 return 0.0; 00684 double sec = (double) tpoint.sec; 00685 if (tpoint.num) 00686 sec += (double) tpoint.num / (double) tpoint.denom; 00687 return sec; 00688 } 00689 00690 int MP7Time::timeToMSec() const 00691 { 00692 if (!tpoint.hasTime) 00693 return 0; 00694 int msec = (int) tpoint.sec * 1000; 00695 if (tpoint.num) 00696 msec += (int) (tpoint.num * 1000 / tpoint.denom); 00697 return msec; 00698 } 00699 00700 int MP7Time::durationToMSec() const 00701 { 00702 int msec = (int) duration.sec * 1000; 00703 if (duration.days) 00704 msec += (int) duration.days * SECS_PER_DAY; 00705 if (duration.num) 00706 msec += (int) (duration.num * 1000 / duration.denom); 00707 if (duration.units) 00708 msec *= duration.units; 00709 return msec; 00710 } 00711 00712 double MP7Time::durationToSec() const 00713 { 00714 double sec = (double) duration.sec; 00715 if (duration.days) 00716 sec += (double) (duration.days * SECS_PER_DAY); 00717 if (duration.num) 00718 sec += (double) duration.num / (double) duration.denom; 00719 if (duration.units) 00720 sec *= (double) duration.units; 00721 return sec; 00722 } 00723 00724 bool MP7Time::timePointIsValid() const 00725 { 00726 return *tpoint.date || tpoint.hasTime; 00727 } 00728 00729 bool MP7Time::durationIsNull() const 00730 { 00731 return !duration.days && !duration.sec && !duration.num; 00732 } 00733 00734 int MP7Time::compareTimePoint(const MP7Time &other) const 00735 { 00736 if (!tpoint.hasTime && !other.tpoint.hasTime) 00737 return 0; 00738 if (!tpoint.hasTime) 00739 return -1; 00740 if (!other.tpoint.hasTime) 00741 return 1; 00742 if (tpoint.sec < other.tpoint.sec) 00743 return -1; 00744 if (tpoint.sec > other.tpoint.sec) 00745 return 1; 00746 uint denom = commonMultiple(tpoint.denom, other.tpoint.denom); 00747 uint thisnum = tpoint.num * (denom / tpoint.denom); 00748 uint othernum = other.tpoint.num * (denom / other.tpoint.denom); 00749 if (thisnum < othernum) 00750 return -1; 00751 if (thisnum > othernum) 00752 return 1; 00753 return 0; 00754 } 00755 00756 bool MP7Time::contains(const MP7Time &time) const 00757 { 00758 int cmpStart = compareTimePoint(time); 00759 int cmpEnd = endTimePoint().compareTimePoint(time); 00760 if (duration.sign < 0) { 00761 return cmpStart >= 0 && cmpEnd <= 0; 00762 } 00763 return cmpStart <= 0 && cmpEnd >= 0; 00764 } 00765 00766 uint MP7Time::commonMultiple(uint op1, uint op2) 00767 { 00768 if (op1 % op2 == 0) 00769 return op1; 00770 if (op2 % op1 == 0) 00771 return op2; 00772 return op1 * op2; 00773 }