1 | #ifndef AWS_COMMON_MATH_FALLBACK_INL |
2 | #define AWS_COMMON_MATH_FALLBACK_INL |
3 | |
4 | /* |
5 | * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"). |
8 | * You may not use this file except in compliance with the License. |
9 | * A copy of the License is located at |
10 | * |
11 | * http://aws.amazon.com/apache2.0 |
12 | * |
13 | * or in the "license" file accompanying this file. This file is distributed |
14 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
15 | * express or implied. See the License for the specific language governing |
16 | * permissions and limitations under the License. |
17 | */ |
18 | |
19 | /* |
20 | * This header is already included, but include it again to make editor |
21 | * highlighting happier. |
22 | */ |
23 | #include <aws/common/common.h> |
24 | #include <aws/common/math.h> |
25 | |
26 | AWS_EXTERN_C_BEGIN |
27 | /** |
28 | * Multiplies a * b. If the result overflows, returns 2^64 - 1. |
29 | */ |
30 | AWS_STATIC_IMPL uint64_t aws_mul_u64_saturating(uint64_t a, uint64_t b) { |
31 | if (a > 0 && b > 0 && a > (UINT64_MAX / b)) |
32 | return UINT64_MAX; |
33 | return a * b; |
34 | } |
35 | |
36 | /** |
37 | * If a * b overflows, returns AWS_OP_ERR; otherwise multiplies |
38 | * a * b, returns the result in *r, and returns AWS_OP_SUCCESS. |
39 | */ |
40 | AWS_STATIC_IMPL int aws_mul_u64_checked(uint64_t a, uint64_t b, uint64_t *r) { |
41 | if (a > 0 && b > 0 && a > (UINT64_MAX / b)) |
42 | return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); |
43 | *r = a * b; |
44 | return AWS_OP_SUCCESS; |
45 | } |
46 | |
47 | /** |
48 | * Multiplies a * b. If the result overflows, returns 2^32 - 1. |
49 | */ |
50 | AWS_STATIC_IMPL uint32_t aws_mul_u32_saturating(uint32_t a, uint32_t b) { |
51 | if (a > 0 && b > 0 && a > (UINT32_MAX / b)) |
52 | return UINT32_MAX; |
53 | return a * b; |
54 | } |
55 | |
56 | /** |
57 | * If a * b overflows, returns AWS_OP_ERR; otherwise multiplies |
58 | * a * b, returns the result in *r, and returns AWS_OP_SUCCESS. |
59 | */ |
60 | AWS_STATIC_IMPL int aws_mul_u32_checked(uint32_t a, uint32_t b, uint32_t *r) { |
61 | if (a > 0 && b > 0 && a > (UINT32_MAX / b)) |
62 | return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); |
63 | *r = a * b; |
64 | return AWS_OP_SUCCESS; |
65 | } |
66 | |
67 | /** |
68 | * Adds a + b. If the result overflows returns 2^64 - 1. |
69 | */ |
70 | AWS_STATIC_IMPL uint64_t aws_add_u64_saturating(uint64_t a, uint64_t b) { |
71 | if ((b > 0) && (a > (UINT64_MAX - b))) |
72 | return UINT64_MAX; |
73 | return a + b; |
74 | } |
75 | |
76 | /** |
77 | * If a + b overflows, returns AWS_OP_ERR; otherwise adds |
78 | * a + b, returns the result in *r, and returns AWS_OP_SUCCESS. |
79 | */ |
80 | AWS_STATIC_IMPL int aws_add_u64_checked(uint64_t a, uint64_t b, uint64_t *r) { |
81 | if ((b > 0) && (a > (UINT64_MAX - b))) |
82 | return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); |
83 | *r = a + b; |
84 | return AWS_OP_SUCCESS; |
85 | } |
86 | |
87 | /** |
88 | * Adds a + b. If the result overflows returns 2^32 - 1. |
89 | */ |
90 | AWS_STATIC_IMPL uint32_t aws_add_u32_saturating(uint32_t a, uint32_t b) { |
91 | if ((b > 0) && (a > (UINT32_MAX - b))) |
92 | return UINT32_MAX; |
93 | return a + b; |
94 | } |
95 | |
96 | /** |
97 | * If a + b overflows, returns AWS_OP_ERR; otherwise adds |
98 | * a + b, returns the result in *r, and returns AWS_OP_SUCCESS. |
99 | */ |
100 | AWS_STATIC_IMPL int aws_add_u32_checked(uint32_t a, uint32_t b, uint32_t *r) { |
101 | if ((b > 0) && (a > (UINT32_MAX - b))) |
102 | return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); |
103 | *r = a + b; |
104 | return AWS_OP_SUCCESS; |
105 | } |
106 | |
107 | AWS_EXTERN_C_END |
108 | |
109 | #endif /* AWS_COMMON_MATH_FALLBACK_INL */ |
110 | |