1 | /* |
2 | * Copyright 2015 Canonical Limited |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * See the included COPYING file for more information. |
10 | * |
11 | * Author: Allison Ryan Lortie <desrt@desrt.ca> |
12 | */ |
13 | |
14 | #include <glib.h> |
15 | |
16 | typedef struct |
17 | { |
18 | gboolean success; |
19 | guint64 c, a, b; |
20 | } Case; |
21 | |
22 | static void |
23 | test_checked_guint_add (void) |
24 | { |
25 | static const Case cases[] = { |
26 | /* success c = a + b */ |
27 | { TRUE, 0, 0, 0 }, |
28 | { TRUE, G_MAXINT, G_MAXINT, 0 }, |
29 | { TRUE, G_MAXINT, 0, G_MAXINT }, |
30 | { TRUE, G_MAXUINT, G_MAXUINT, 0 }, |
31 | { TRUE, G_MAXUINT, 0, G_MAXUINT }, |
32 | { TRUE, G_MAXUINT - 1, G_MAXINT, G_MAXINT }, |
33 | { FALSE, 0, G_MAXUINT, 1 }, |
34 | { FALSE, 0, 1, G_MAXUINT }, |
35 | { FALSE, 0, G_MAXUINT, G_MAXUINT } |
36 | }; |
37 | guint i; |
38 | |
39 | for (i = 0; i < G_N_ELEMENTS (cases); i++) |
40 | { |
41 | guint result; |
42 | |
43 | g_assert_cmpuint (cases[i].success, ==, g_uint_checked_add (&result, cases[i].a, cases[i].b)); |
44 | if (cases[i].success) |
45 | g_assert_cmpuint (cases[i].c, ==, result); |
46 | } |
47 | } |
48 | |
49 | static void |
50 | test_checked_guint_mul (void) |
51 | { |
52 | static const Case cases[] = { |
53 | /* success c = a * b */ |
54 | { TRUE, 0, 0, 0 }, |
55 | { TRUE, 0, G_MAXINT, 0 }, |
56 | { TRUE, G_MAXINT, G_MAXINT, 1 }, |
57 | { TRUE, 0, G_MAXUINT, 0 }, |
58 | { TRUE, G_MAXUINT, G_MAXUINT, 1 }, |
59 | { TRUE, 2 * (guint) G_MAXINT, 2, G_MAXINT }, |
60 | { TRUE, 2 * (guint) G_MAXINT, G_MAXINT, 2 }, |
61 | { FALSE, 0, 3, G_MAXINT }, |
62 | { FALSE, 0, G_MAXINT, 3 } |
63 | }; |
64 | guint i; |
65 | |
66 | for (i = 0; i < G_N_ELEMENTS (cases); i++) |
67 | { |
68 | guint result; |
69 | |
70 | g_assert_cmpuint (cases[i].success, ==, g_uint_checked_mul (&result, cases[i].a, cases[i].b)); |
71 | if (cases[i].success) |
72 | g_assert_cmpuint (cases[i].c, ==, result); |
73 | } |
74 | } |
75 | |
76 | |
77 | static void |
78 | test_checked_guint64_add (void) |
79 | { |
80 | static const Case cases[] = { |
81 | /* success c = a + b */ |
82 | { TRUE, 0, 0, 0 }, |
83 | { TRUE, G_MAXINT64, G_MAXINT64, 0 }, |
84 | { TRUE, G_MAXINT64, 0, G_MAXINT64 }, |
85 | { TRUE, G_MAXUINT64, G_MAXUINT64, 0 }, |
86 | { TRUE, G_MAXUINT64, 0, G_MAXUINT64 }, |
87 | { TRUE, G_MAXUINT64 - 1, G_MAXINT64, G_MAXINT64 }, |
88 | { FALSE, 0, G_MAXUINT64, 1 }, |
89 | { FALSE, 0, 1, G_MAXUINT64 }, |
90 | { FALSE, 0, G_MAXUINT64, G_MAXUINT64 } |
91 | }; |
92 | guint i; |
93 | |
94 | for (i = 0; i < G_N_ELEMENTS (cases); i++) |
95 | { |
96 | guint64 result; |
97 | |
98 | g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_add (&result, cases[i].a, cases[i].b)); |
99 | if (cases[i].success) |
100 | g_assert_cmpuint (cases[i].c, ==, result); |
101 | } |
102 | } |
103 | |
104 | static void |
105 | test_checked_guint64_mul (void) |
106 | { |
107 | static const Case cases[] = { |
108 | /* success c = a * b */ |
109 | { TRUE, 0, 0, 0 }, |
110 | { TRUE, 0, G_MAXINT64, 0 }, |
111 | { TRUE, G_MAXINT64, G_MAXINT64, 1 }, |
112 | { TRUE, 0, G_MAXUINT64, 0 }, |
113 | { TRUE, G_MAXUINT64, G_MAXUINT64, 1 }, |
114 | { TRUE, 2 * (guint64) G_MAXINT64, 2, G_MAXINT64 }, |
115 | { TRUE, 2 * (guint64) G_MAXINT64, G_MAXINT64, 2 }, |
116 | { FALSE, 0, 3, G_MAXINT64 }, |
117 | { FALSE, 0, G_MAXINT64, 3 } |
118 | }; |
119 | guint i; |
120 | |
121 | for (i = 0; i < G_N_ELEMENTS (cases); i++) |
122 | { |
123 | guint64 result; |
124 | |
125 | g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_mul (&result, cases[i].a, cases[i].b)); |
126 | if (cases[i].success) |
127 | g_assert_cmpuint (cases[i].c, ==, result); |
128 | } |
129 | } |
130 | |
131 | |
132 | static void |
133 | test_checked_gsize_add (void) |
134 | { |
135 | static const Case cases[] = { |
136 | /* success c = a + b */ |
137 | { TRUE, 0, 0, 0 }, |
138 | { TRUE, G_MAXSSIZE, G_MAXSSIZE, 0 }, |
139 | { TRUE, G_MAXSSIZE, 0, G_MAXSSIZE }, |
140 | { TRUE, G_MAXSIZE, G_MAXSIZE, 0 }, |
141 | { TRUE, G_MAXSIZE, 0, G_MAXSIZE }, |
142 | { TRUE, G_MAXSIZE - 1, G_MAXSSIZE, G_MAXSSIZE }, |
143 | { FALSE, 0, G_MAXSIZE, 1 }, |
144 | { FALSE, 0, 1, G_MAXSIZE }, |
145 | { FALSE, 0, G_MAXSIZE, G_MAXSIZE } |
146 | }; |
147 | guint i; |
148 | |
149 | for (i = 0; i < G_N_ELEMENTS (cases); i++) |
150 | { |
151 | gsize result; |
152 | |
153 | g_assert_cmpuint (cases[i].success, ==, g_size_checked_add (&result, cases[i].a, cases[i].b)); |
154 | if (cases[i].success) |
155 | g_assert_cmpuint (cases[i].c, ==, result); |
156 | } |
157 | } |
158 | |
159 | static void |
160 | test_checked_gsize_mul (void) |
161 | { |
162 | static const Case cases[] = { |
163 | /* success c = a * b */ |
164 | { TRUE, 0, 0, 0 }, |
165 | { TRUE, 0, G_MAXSSIZE, 0 }, |
166 | { TRUE, G_MAXSSIZE, G_MAXSSIZE, 1 }, |
167 | { TRUE, 0, G_MAXSIZE, 0 }, |
168 | { TRUE, G_MAXSIZE, G_MAXSIZE, 1 }, |
169 | { TRUE, 2 * (gsize) G_MAXSSIZE, 2, G_MAXSSIZE }, |
170 | { TRUE, 2 * (gsize) G_MAXSSIZE, G_MAXSSIZE, 2 }, |
171 | { FALSE, 0, 3, G_MAXSSIZE }, |
172 | { FALSE, 0, G_MAXSSIZE, 3 } |
173 | }; |
174 | guint i; |
175 | |
176 | for (i = 0; i < G_N_ELEMENTS (cases); i++) |
177 | { |
178 | gsize result; |
179 | |
180 | g_assert_cmpuint (cases[i].success, ==, g_size_checked_mul (&result, cases[i].a, cases[i].b)); |
181 | if (cases[i].success) |
182 | g_assert_cmpuint (cases[i].c, ==, result); |
183 | } |
184 | } |
185 | |
186 | int |
187 | main (int argc, char **argv) |
188 | { |
189 | g_test_init (argc: &argc, argv: &argv, NULL); |
190 | |
191 | g_test_add_func (testpath: "/glib/checked-math/guint-add" , test_func: test_checked_guint_add); |
192 | g_test_add_func (testpath: "/glib/checked-math/guint-mul" , test_func: test_checked_guint_mul); |
193 | g_test_add_func (testpath: "/glib/checked-math/guint64-add" , test_func: test_checked_guint64_add); |
194 | g_test_add_func (testpath: "/glib/checked-math/guint64-mul" , test_func: test_checked_guint64_mul); |
195 | g_test_add_func (testpath: "/glib/checked-math/gsize-add" , test_func: test_checked_gsize_add); |
196 | g_test_add_func (testpath: "/glib/checked-math/gsize-mul" , test_func: test_checked_gsize_mul); |
197 | |
198 | return g_test_run (); |
199 | } |
200 | |