name change
[obnox/wireshark/wip.git] / epan / ftypes / ftype-double.c
1 /*
2  * $Id$
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 2001 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <ftypes-int.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <errno.h>
31 #include <float.h>
32
33 #include "strutil.h"
34
35 static void
36 double_fvalue_new(fvalue_t *fv)
37 {
38         fv->value.floating = 0.0;
39 }
40
41 static void
42 double_fvalue_set_floating(fvalue_t *fv, gdouble value)
43 {
44         fv->value.floating = value;
45 }
46
47 static double
48 value_get_floating(fvalue_t *fv)
49 {
50         return fv->value.floating;
51 }
52
53 static gboolean
54 val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
55 {
56         char    *endptr = NULL;
57
58         fv->value.floating = strtod(s, &endptr);
59
60         if (endptr == s || *endptr != '\0') {
61                 /* This isn't a valid number. */
62                 logfunc("\"%s\" is not a valid number.", s);
63                 return FALSE;
64         }
65         if (errno == ERANGE) {
66                 if (fv->value.floating == 0) {
67                         logfunc("\"%s\" causes floating-point underflow.", s);
68                 }
69                 else if (fv->value.floating == HUGE_VAL) {
70                         logfunc("\"%s\" causes floating-point overflow.", s);
71                 }
72                 else {
73                         logfunc("\"%s\" is not a valid floating-point number.",
74                             s);
75                 }
76                 return FALSE;
77         }
78
79         return TRUE;
80 }
81
82 static int
83 float_val_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
84 {
85         /*
86          * 1 character for a sign.
87          * 26 characters for a Really Big Number.
88          * XXX - is that platform-dependent?
89          * XXX - smaller for float than for double?
90          * XXX - can we compute it from FLT_DIG and the like?
91          */
92         return 1 + 26;
93 }
94
95 static void
96 float_val_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
97 {
98         sprintf(buf, "%." STRINGIFY(FLT_DIG) "g", fv->value.floating);
99 }
100
101 static int
102 double_val_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
103 {
104         /*
105          * 1 character for a sign.
106          * 26 characters for a Really Big Number.
107          * XXX - is that platform-dependent?
108          * XXX - can we compute it from DBL_DIG and the like?
109          */
110         return 1 + 26;
111 }
112
113 static void
114 double_val_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
115 {
116         sprintf(buf, "%." STRINGIFY(DBL_DIG) "g", fv->value.floating);
117 }
118
119 static gboolean
120 cmp_eq(fvalue_t *a, fvalue_t *b)
121 {
122         return a->value.floating == b->value.floating;
123 }
124
125 static gboolean
126 cmp_ne(fvalue_t *a, fvalue_t *b)
127 {
128         return a->value.floating != b->value.floating;
129 }
130
131 static gboolean
132 cmp_gt(fvalue_t *a, fvalue_t *b)
133 {
134         return a->value.floating > b->value.floating;
135 }
136
137 static gboolean
138 cmp_ge(fvalue_t *a, fvalue_t *b)
139 {
140         return a->value.floating >= b->value.floating;
141 }
142
143 static gboolean
144 cmp_lt(fvalue_t *a, fvalue_t *b)
145 {
146         return a->value.floating < b->value.floating;
147 }
148
149 static gboolean
150 cmp_le(fvalue_t *a, fvalue_t *b)
151 {
152         return a->value.floating <= b->value.floating;
153 }
154
155 void
156 ftype_register_double(void)
157 {
158
159         static ftype_t float_type = {
160                 FT_FLOAT,                       /* ftype */
161                 "FT_FLOAT",                     /* name */
162                 "floating point (single-precision)", /* pretty_name */
163                 0,                              /* wire_size */
164                 double_fvalue_new,              /* new_value */
165                 NULL,                           /* free_value */
166                 val_from_unparsed,              /* val_from_unparsed */
167                 NULL,                           /* val_from_string */
168                 float_val_to_repr,              /* val_to_string_repr */
169                 float_val_repr_len,             /* len_string_repr */
170
171                 NULL,                           /* set_value */
172                 NULL,                           /* set_value_integer */
173                 NULL,                           /* set_value_integer64 */
174                 double_fvalue_set_floating,     /* set_value_floating */
175
176                 NULL,                           /* get_value */
177                 NULL,                           /* get_value_integer */
178                 NULL,                           /* get_value_integer64 */
179                 value_get_floating,             /* get_value_floating */
180
181                 cmp_eq,
182                 cmp_ne,
183                 cmp_gt,
184                 cmp_ge,
185                 cmp_lt,
186                 cmp_le,
187                 NULL,                           /* cmp_bitwise_and */
188                 NULL,                           /* cmp_contains */
189                 NULL,                           /* cmp_matches */
190
191                 NULL,
192                 NULL,
193         };
194
195         static ftype_t double_type = {
196                 FT_DOUBLE,                      /* ftype */
197                 "FT_DOUBLE",                    /* name */
198                 "floating point (double-precision)", /* pretty_name */
199                 0,                              /* wire_size */
200                 double_fvalue_new,              /* new_value */
201                 NULL,                           /* free_value */
202                 val_from_unparsed,              /* val_from_unparsed */
203                 NULL,                           /* val_from_string */
204                 double_val_to_repr,             /* val_to_string_repr */
205                 double_val_repr_len,            /* len_string_repr */
206
207                 NULL,                           /* set_value */
208                 NULL,                           /* set_value_integer */
209                 NULL,                           /* set_value_integer64 */
210                 double_fvalue_set_floating,     /* set_value_floating */
211
212                 NULL,                           /* get_value */
213                 NULL,                           /* get_value_integer */
214                 NULL,                           /* get_value_integer64 */
215                 value_get_floating,             /* get_value_floating */
216
217                 cmp_eq,
218                 cmp_ne,
219                 cmp_gt,
220                 cmp_ge,
221                 cmp_lt,
222                 cmp_le,
223                 NULL,                           /* cmp_bitwise_and */
224                 NULL,                           /* cmp_contains */
225                 NULL,                           /* cmp_matches */
226
227                 NULL,
228                 NULL,
229         };
230
231         ftype_register(FT_FLOAT, &float_type);
232         ftype_register(FT_DOUBLE, &double_type);
233 }