aboutsummaryrefslogtreecommitdiffstats
path: root/epan/ftypes/ftype-double.c
blob: 146794a597c2a6e6469793a32fa31d70611a79fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <ftypes-int.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>

static void
ftype_from_tvbuff(field_info *fi, tvbuff_t *tvb, int start, int length,
	gboolean little_endian)
{
	/* XXX */
	g_assert_not_reached();
}


static void
double_fvalue_new(fvalue_t *fv)
{
	fv->value.floating = 0.0;
}

static void
double_fvalue_set_floating(fvalue_t *fv, gdouble value)
{
	fv->value.floating = value;
}

static double
value_get_floating(fvalue_t *fv)
{
	return fv->value.floating;
}

static gboolean
val_from_string(fvalue_t *fv, char *s, LogFunc log)
{
	char    *endptr = NULL;

	fv->value.floating = strtod(s, &endptr);

	if (endptr == s || *endptr != '\0') {
		/* This isn't a valid number. */
		log("\"%s\" is not a valid number.", s);
		return FALSE;
	}
	if (errno == ERANGE) {
		if (fv->value.floating == 0) {
			log("\"%s\" causes floating-point underflow.", s);
		}
		else if (fv->value.floating == HUGE_VAL) {
			log("\"%s\" causes floating-point overflow.", s);
		}
		else {
			log("\"%s\" is not a valid floating-point number.", s);
		}
		return FALSE;
	}

	return TRUE;
}


static gboolean
cmp_eq(fvalue_t *a, fvalue_t *b)
{
	return a->value.floating == b->value.floating;
}

static gboolean
cmp_ne(fvalue_t *a, fvalue_t *b)
{
	return a->value.floating != b->value.floating;
}

static gboolean
cmp_gt(fvalue_t *a, fvalue_t *b)
{
	return a->value.floating > b->value.floating;
}

static gboolean
cmp_ge(fvalue_t *a, fvalue_t *b)
{
	return a->value.floating >= b->value.floating;
}

static gboolean
cmp_lt(fvalue_t *a, fvalue_t *b)
{
	return a->value.floating < b->value.floating;
}

static gboolean
cmp_le(fvalue_t *a, fvalue_t *b)
{
	return a->value.floating <= b->value.floating;
}

void
ftype_register_double(void)
{

	static ftype_t double_type = {
		"FT_DOUBLE",
		"floating point",
		0,
		double_fvalue_new,
		NULL,
		ftype_from_tvbuff,
		val_from_string,

		NULL,
		NULL,
		double_fvalue_set_floating,

		NULL,
		NULL,
		value_get_floating,

		cmp_eq,
		cmp_ne,
		cmp_gt,
		cmp_ge,
		cmp_lt,
		cmp_le,
	};

	ftype_register(FT_DOUBLE, &double_type);
}