Move a couple of time-related modules into wsutil.
[metze/wireshark/wip.git] / wsutil / nstime.c
1 /* nstime.c
2  * Routines for manipulating nstime_t structures
3  *
4  * Copyright (c) 2005 MX Telecom Ltd. <richardv@mxtelecom.com>
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  *
26  */
27
28 #include <glib.h>
29 #include "nstime.h"
30
31 /* this is #defined so that we can clearly see that we have the right number of
32    zeros, rather than as a guard against the number of nanoseconds in a second
33    changing ;) */
34 #define NS_PER_S 1000000000
35
36 /* set the given nstime_t to zero */
37 void nstime_set_zero(nstime_t *nstime)
38 {
39     nstime->secs  = 0;
40     nstime->nsecs = 0;
41 }
42
43 /* is the given nstime_t currently zero? */
44 gboolean nstime_is_zero(nstime_t *nstime)
45 {
46     if(nstime->secs == 0 && nstime->nsecs == 0) {
47         return TRUE;
48     } else {
49         return FALSE;
50     }
51 }
52
53 /* set the given nstime_t to (0,maxint) to mark it as "unset"
54  * That way we can find the first frame even when a timestamp
55  * is zero (fix for bug 1056)
56  */
57 void nstime_set_unset(nstime_t *nstime)
58 {
59     nstime->secs  = 0;
60     nstime->nsecs = G_MAXINT;
61 }
62
63 /* is the given nstime_t currently (0,maxint)? */
64 gboolean nstime_is_unset(nstime_t *nstime)
65 {
66     if(nstime->secs == 0 && nstime->nsecs == G_MAXINT) {
67         return TRUE;
68     } else {
69         return FALSE;
70     }
71 }
72
73
74 /** funcion: nstime_copy
75  *
76  * a = b
77  */
78 void nstime_copy(nstime_t *a, const nstime_t *b)
79 {
80     a->secs = b->secs;
81     a->nsecs = b->nsecs;
82 }
83
84 /*
85  * function: nstime_delta
86  * delta = b - a
87  */
88
89 void nstime_delta(nstime_t *delta, const nstime_t *b, const nstime_t *a )
90 {
91     if (b->secs == a->secs) {
92         /* The seconds part of b is the same as the seconds part of a, so if
93            the nanoseconds part of the first time is less than the nanoseconds
94            part of a, b is before a.  The nanoseconds part of the delta should
95            just be the difference between the nanoseconds part of b and the
96            nanoseconds part of a; don't adjust the seconds part of the delta,
97            as it's OK if the nanoseconds part is negative, and an overflow
98            can never result. */
99         delta->secs = 0;
100         delta->nsecs = b->nsecs - a->nsecs;
101     } else if (b->secs <= a->secs) {
102         /* The seconds part of b is less than the seconds part of a, so b is
103            before a.
104
105            Both the "seconds" and "nanoseconds" value of the delta
106            should have the same sign, so if the difference between the
107            nanoseconds values would be *positive*, subtract 1,000,000,000
108            from it, and add one to the seconds value. */
109         delta->secs = b->secs - a->secs;
110         delta->nsecs = b->nsecs - a->nsecs;
111         if(delta->nsecs > 0) {
112             delta->nsecs -= NS_PER_S;
113             delta->secs ++;
114         }
115     } else {
116         delta->secs = b->secs - a->secs;
117         delta->nsecs = b->nsecs - a->nsecs;
118         if(delta->nsecs < 0) {
119             delta->nsecs += NS_PER_S;
120             delta->secs --;
121         }
122     }
123 }
124
125 /*
126  * function: nstime_sum
127  * sum = a + b
128  */
129
130 void nstime_sum(nstime_t *sum, const nstime_t *a, const nstime_t *b)
131 {
132     sum->secs = a->secs + b->secs;
133     sum->nsecs = a->nsecs + b->nsecs;
134     if(sum->nsecs>=NS_PER_S || (sum->nsecs>0 && sum->secs<0)){
135         sum->nsecs-=NS_PER_S;
136         sum->secs++;
137     } else if(sum->nsecs<=-NS_PER_S || (sum->nsecs<0 && sum->secs>0)) {
138         sum->nsecs+=NS_PER_S;
139         sum->secs--;
140     }
141 }
142
143 /*
144  * function: nstime_cmp
145  *
146  * a > b : > 0
147  * a = b : 0
148  * a < b : < 0
149  */
150
151 int nstime_cmp (const nstime_t *a, const nstime_t *b )
152 {
153     if (a->secs == b->secs) {
154         return a->nsecs - b->nsecs;
155     } else {
156         return (int) (a->secs - b->secs);
157     }
158 }
159
160 /*
161  * function: nstime_to_msec
162  * converts nstime to double, time base is milli seconds
163  */
164
165 double nstime_to_msec(const nstime_t *nstime)
166 {
167     return ((double)nstime->secs*1000 + (double)nstime->nsecs/1000000);
168 }
169
170 /*
171  * function: nstime_to_sec
172  * converts nstime to double, time base is seconds
173  */
174
175 double nstime_to_sec(const nstime_t *nstime)
176 {
177     return ((double)nstime->secs + (double)nstime->nsecs/1000000000);
178 }
179
180 /*
181  * function: wtap_nstime_to_sec
182  * converts wtap_nstime to double, time base is seconds
183  */
184
185 double wtap_nstime_to_sec(const struct wtap_nstime *nstime)
186 {
187     return ((double)nstime->secs + (double)nstime->nsecs/1000000000);
188 }
189
190 /*
191  * Editor modelines
192  *
193  * Local Variables:
194  * c-basic-offset: 4
195  * tab-width: 8
196  * indent-tabs-mode: nil
197  * End:
198  *
199  * ex: set shiftwidth=4 tabstop=8 expandtab:
200  * :indentSize=4:tabSize=8:noTabs=true:
201  */
202