Main Page   Data Structures   File List   Data Fields   Globals  

parsetime.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006 by André Lindhjem <belgarat@sdf.lonestar.org>,     *
00003  *                         Kjetil Holien <kjetil.holien@gmail.com>,        *
00004  *                         Terje Risa <terje.risa@gmail.com> &             *
00005  *                         Øyvind Nerbråten <oyvind@nerbraten.com>         *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************
00022  *
00023  * \file parsetime.c
00024  * \author André Lindhjem, Kjetil Holien, Terje Risa & Øyvind Nerbråten
00025  * \date 15.02.2006
00026  * 
00027  * This library parses valid DAISY time formats and constructs mad_timer_t
00028  * You should probably read section 7.7 "Media Clipping and Clock Values"
00029  * in ANSI/NISO Z39.86.2005 to get an understanding of the formats we're
00030  * dealing with.
00031  */
00032 
00033 
00037 #include <mad.h>    
00038 #include <string.h>
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <stdbool.h>
00042 #include <assert.h>
00043 
00044 #include "common.h"     
00045 #include "parsetime.h"
00046 #include "report.h"     
00047 #include "common.h"
00048 #include "snprintf/snprintf.h"
00049 
00050 
00051 
00052 /* ************************************************ *
00053  *          Static function declarations            *
00054  * ************************************************ */
00055 
00056 static
00057 bool isletter (char c);
00058 
00059 static
00060 void parse_timecount (int *h, int *min, int *s, int *ms, const char *expr);
00061 
00062 static
00063 void parse_partial_clock (int *h, int *min, int *s, int *ms, const char *expr);
00064 
00065 static
00066 void parse_full_clock (int *h, int *min, int *s, int *ms, const char *expr);
00067 
00068 static
00069 mad_timer_t convert_mad_timer_t (int *h, int *min, int *s, int *ms);
00070 
00071 static
00072 unsigned long int convert_milliseconds_from_time (int *h, int *min, int *s, int *ms);
00073 
00074 static
00075 enum pt_type type (const char* expr);
00076 
00077 
00078 
00079 /* ************************************************ *
00080  *          Static function definitions             *
00081  * ************************************************ */
00082 
00088 static
00089 bool isletter (char c)
00090 {
00091     if ((c > 65) && (c < 90))   
00092         return true;
00093     if ((c > 97) && (c < 122))  
00094         return true;
00095     return false;
00096 }
00097 
00106 static
00107 void parse_timecount (int *h, int *min, int *s, int *ms, const char *expr)
00108 {
00109     int unit = PT_SECONDS;  
00110     int num1 = 0, num2 = 0;
00111     char *n1, *n2;
00112     char *tmp_expr; /* temporary expression to do strtok on (strtok changes the value) */
00113     int i = strlen(expr); i--;
00114     
00115     if (DEBUG_PARSETIME) report("parse_timecount starting", REP_DEBUG);
00116     
00118     if (isletter(expr[i]))
00119     {
00121         switch (expr[i])
00122         {
00123             case 's':
00124                 if (expr[i-1] == 'm') 
00125                 {   
00126                     i--;
00127                     unit = PT_MILLISECONDS;
00128                 }
00129                 else
00130                     unit = PT_SECONDS;  
00131             break;
00132 
00133             case 'n':               
00134                 unit = PT_MINUTES;
00135                 i -= 2;
00136             break;
00137 
00138             case 'h':               
00139                 unit = PT_HOURS;
00140             break;
00141         }
00142     }
00143 
00144     tmp_expr = (char *) malloc (sizeof(char) * strlen(expr)+1); /* expr can't be changed, so we make a temp copy that can be changed */
00145     strcpy (tmp_expr, expr);    /* copies values from expr to temp_expr variable */
00146 
00148     n1 = strtok (tmp_expr, ".");
00149     n2 = strtok (NULL, "\0");
00150 
00151     num1 = atoi (n1);
00152     if (n2 != NULL)
00153     {
00154         num2 = atoi (n2);
00155     }
00156 
00157     free (tmp_expr);    /* frees memory when we're done with it */
00158 
00161     switch (unit)
00162     {
00163         case PT_MILLISECONDS:
00164             *ms = num1;
00165             break;
00166         case PT_SECONDS:
00167             *s = num1;      *ms = num2;
00168             break;
00169         case PT_MINUTES:
00170             *min = num1;    *s = num2;
00171             break;
00172         case PT_HOURS:
00173             *h = num1;      *min = num2;
00174             break;
00175         default:
00176             break;
00177     }
00178     
00179     if (DEBUG_PARSETIME)
00180     {
00181         char debug[STRLEN];
00182         sprintf (debug, "parse_timecount: %dh %dm %ds %dms", *h, *min, *s, *ms);
00183         report(debug, REP_DEBUG);
00184     }
00185 }
00186 
00195 static
00196 void parse_partial_clock (int *h, int *min, int *s, int *ms, const char *expr)
00197 {
00198     char *ptr;
00199     char *tmp_expr; /* temporary expression to do strtok on (strtok changes the value) */
00200 
00205     tmp_expr = (char *) malloc (sizeof(char) * strlen(expr)+1); /* expr can't be changed, so we make a temp copy that can be changed */
00206     strcpy (tmp_expr, expr);    /* copies values from expr to temp_expr variable */
00207 
00208     ptr = strtok (tmp_expr, ":");   
00209     *min = atoi (ptr);
00210     
00211     ptr = strtok (NULL, ".");
00212     *s = atoi (ptr);
00213     
00214     if ((ptr = strtok (NULL, "."))) 
00215         *ms = atoi (ptr);
00216     
00217     free (tmp_expr);    /* frees memory when we're done with it */
00218     
00219     if (DEBUG_PARSETIME)
00220     {
00221         char debug[STRLEN];
00222         sprintf (debug, "%d h, %dm, %ds, %df", *h, *min, *s, *ms);
00223         report(debug, REP_DEBUG);
00224     }
00225 }
00226 
00235 static
00236 void parse_full_clock (int *h, int *min, int *s, int *ms, const char *expr)
00237 {
00238     char *ptr;
00239     char *tmp_expr; /* temporary expression to do strtok on (strtok changes the value) */
00240     
00245     tmp_expr = (char *) malloc (sizeof(char) * strlen(expr));   /* expr can't be changed, so we make a temp copy that can be changed */
00246     strcpy (tmp_expr, expr);    /* copies values from expr to temp_expr variable */
00247 
00248     ptr = strtok (tmp_expr, ":");   
00249     *h = atoi (ptr);
00250 
00251 
00252     ptr = strtok (NULL, ":");   
00253     *min = atoi (ptr);
00254 
00255     ptr = strtok (NULL, ":.");  
00256     *s = atoi (ptr);
00257     
00258     if ((ptr = strtok (NULL, "."))) 
00259         *ms = atoi (ptr);
00260 
00261     free (tmp_expr);    /* frees memory when we're done with it */
00262 
00263     if (DEBUG_PARSETIME)
00264     {
00265         char debug[STRLEN]; 
00266         sprintf (debug, "parse_full_clock: %dh, %dm, %ds, %dms", *h, *min, *s, *ms);
00267         report(debug, REP_DEBUG);
00268     }
00269 }
00270 
00279 static
00280 mad_timer_t convert_mad_timer_t (int *h, int *min, int *s, int *ms)
00281 {
00282     mad_timer_t ret;
00283     ret.fraction = 0;   
00284     ret.seconds = 0;
00285 
00286     if (*h) 
00287         ret.seconds += (long) (*h * 60 * 60);   
00288     if (*min)
00289         ret.seconds += (long) (*min * 60);      
00290     if (*s)
00291         ret.seconds += (long) (*s);             
00292     if (*ms)
00294         ret.fraction += (unsigned long) (*ms * MAD_TIMER_RESOLUTION / 1000);
00295 
00297     if (ret.fraction > MAD_TIMER_RESOLUTION)
00298     {
00299         ret.seconds  += ret.fraction / MAD_TIMER_RESOLUTION;
00300         ret.fraction %= MAD_TIMER_RESOLUTION;
00301     }
00302     
00303     if (DEBUG_PARSETIME)
00304     {
00305         char debug[STRLEN];
00306         sprintf (debug, "convert: %d, %d, %d, %d", *h, *min, *s, *ms);
00307         report(debug, REP_DEBUG);
00308     }
00309     return ret;
00310 }
00311 
00320 static
00321 unsigned long int convert_milliseconds_from_time (int *h, int *min, int *s, int *ms)
00322 {
00323     unsigned long int msec = 0;
00324 
00325     if (*h) 
00326         msec += (unsigned long) (*h * 3600000.0);   
00327     if (*min)
00328         msec += (unsigned long) (*min * 60000.0);   
00329     if (*s)
00330         msec += (unsigned long) (*s * 1000.0);      
00331     if (*ms)
00332         msec += (unsigned long) (*ms);
00333     
00334     if (DEBUG_PARSETIME)
00335     {
00336         char debug[STRLEN];
00337         sprintf (debug, "convert: %d, %d, %d, %d", *h, *min, *s, *ms);
00338         report(debug, REP_DEBUG);
00339     }
00340     return msec;
00341 }
00342 
00343 
00349 static
00350 enum pt_type type (const char* expr)
00351 {
00352     char *ptr;
00353     int occurences = 0;
00354     ptr = strpbrk (expr, ":");
00355     while (ptr != NULL && occurences < 100)
00356     {
00357         occurences++;
00358         ptr = strpbrk (ptr+1, ":");
00359     }
00360     switch (occurences) {
00361         case 2  :       
00362             return PT_FULL_CLOCK;
00363         case 1  :       
00364             return PT_PARTIAL_CLOCK;
00365         case 0  :       
00366             return PT_TIMECOUNT;
00367         default : {     
00368             char error[STRLEN]; 
00369             snprintf (error, sizeof (error), "parsetime tried to evaluate an invalid time-format. (%s)", expr);
00370             report (error, REP_ERROR);
00371             return PT_INVALID_FORMAT;
00372         }
00373     }
00374 }
00375 
00376 
00377 
00378 /* ************************************************** *
00379  *          Global function definitions               *
00380  * ************************************************** */
00381 
00388 mad_timer_t parse_time_mad_time_t (const char *expr)
00389 {
00390     int h = 0, min = 0, s = 0, ms = 0;
00391     
00392     if (DEBUG_PARSETIME) report ("parse_time starting", REP_DEBUG);
00393     
00394     switch (type (expr))
00395     {
00396         case PT_FULL_CLOCK:
00398             parse_full_clock (&h, &min, &s, &ms, expr);
00399             break;
00400         case PT_PARTIAL_CLOCK:
00402             parse_partial_clock (&h, &min, &s, &ms, expr);
00403             break;
00404         case PT_TIMECOUNT:
00406             parse_timecount (&h, &min, &s, &ms, expr);
00407             break;
00408         case PT_INVALID_FORMAT:
00409             break;
00410     }
00411     
00412     if (DEBUG_PARSETIME)
00413     {
00414         char debug[STRLEN];
00415         sprintf (debug, "parse_time: %d, %d, %d, %d", h, min, s, ms);
00416         report(debug, REP_DEBUG);
00417     }
00419     return convert_mad_timer_t (&h, &min, &s, &ms);
00420 }
00421 
00428 unsigned
00429 long
00430 int parse_time_milliseconds (const char *expr)
00431 {
00432     int h = 0, min = 0, s = 0, ms = 0;
00433     
00434     if (DEBUG_PARSETIME) report ("parse_time starting", REP_DEBUG);
00435     
00436     switch (type (expr))
00437     {
00438         case PT_FULL_CLOCK:
00440             parse_full_clock (&h, &min, &s, &ms, expr);
00441             break;
00442         case PT_PARTIAL_CLOCK:
00444             parse_partial_clock (&h, &min, &s, &ms, expr);
00445             break;
00446         case PT_TIMECOUNT:
00448             parse_timecount (&h, &min, &s, &ms, expr);
00449             break;
00450         case PT_INVALID_FORMAT:
00451             break;
00452     }
00453     
00454     if (DEBUG_PARSETIME)
00455     {
00456         char debug[STRLEN];
00457         sprintf (debug, "parse_time: %d, %d, %d, %d", h, min, s, ms);
00458         report(debug, REP_DEBUG);
00459     }
00461     return convert_milliseconds_from_time(&h, &min, &s, &ms);
00462 }
00463 
00470 unsigned
00471 long
00472 int parse_time_get_dur (const char *start, const char *stop)
00473 {
00474     unsigned long int start_ms, stop_ms;
00475 
00476     start_ms = parse_time_milliseconds(start);  /* parses time expressions into milliseconds */
00477     stop_ms = parse_time_milliseconds(stop);
00478     
00479     return (stop_ms - start_ms);
00480 }

Generated on Tue Sep 5 12:14:08 2006 for libdaisy by doxygen1.2.15