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