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
26AWS_EXTERN_C_BEGIN
27/**
28 * Multiplies a * b. If the result overflows, returns 2^64 - 1.
29 */
30AWS_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 */
40AWS_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 */
50AWS_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 */
60AWS_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 */
70AWS_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 */
80AWS_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 */
90AWS_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 */
100AWS_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
107AWS_EXTERN_C_END
108
109#endif /* AWS_COMMON_MATH_FALLBACK_INL */
110