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