/src/bloaty/third_party/abseil-cpp/absl/crc/crc32c.cc
Line | Count | Source |
1 | | // Copyright 2022 The Abseil Authors |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include "absl/crc/crc32c.h" |
16 | | |
17 | | #include <cstdint> |
18 | | |
19 | | #include "absl/crc/internal/crc.h" |
20 | | #include "absl/crc/internal/crc32c.h" |
21 | | #include "absl/crc/internal/crc_memcpy.h" |
22 | | #include "absl/strings/string_view.h" |
23 | | |
24 | | namespace absl { |
25 | | ABSL_NAMESPACE_BEGIN |
26 | | |
27 | | namespace { |
28 | | |
29 | 0 | const crc_internal::CRC* CrcEngine() { |
30 | 0 | static const crc_internal::CRC* engine = crc_internal::CRC::Crc32c(); |
31 | 0 | return engine; |
32 | 0 | } |
33 | | |
34 | | constexpr uint32_t kCRC32Xor = 0xffffffffU; |
35 | | |
36 | | } // namespace |
37 | | |
38 | | namespace crc_internal { |
39 | | |
40 | 0 | crc32c_t UnextendCrc32cByZeroes(crc32c_t initial_crc, size_t length) { |
41 | 0 | uint32_t crc = static_cast<uint32_t>(initial_crc) ^ kCRC32Xor; |
42 | 0 | CrcEngine()->UnextendByZeroes(&crc, length); |
43 | 0 | return static_cast<crc32c_t>(crc ^ kCRC32Xor); |
44 | 0 | } |
45 | | |
46 | | // Called by `absl::ExtendCrc32c()` on strings with size > 64 or when hardware |
47 | | // CRC32C support is missing. |
48 | | crc32c_t ExtendCrc32cInternal(crc32c_t initial_crc, |
49 | 0 | absl::string_view buf_to_add) { |
50 | 0 | uint32_t crc = static_cast<uint32_t>(initial_crc) ^ kCRC32Xor; |
51 | 0 | CrcEngine()->Extend(&crc, buf_to_add.data(), buf_to_add.size()); |
52 | 0 | return static_cast<crc32c_t>(crc ^ kCRC32Xor); |
53 | 0 | } |
54 | | |
55 | | } // namespace crc_internal |
56 | | |
57 | 0 | crc32c_t ExtendCrc32cByZeroes(crc32c_t initial_crc, size_t length) { |
58 | 0 | uint32_t crc = static_cast<uint32_t>(initial_crc) ^ kCRC32Xor; |
59 | 0 | CrcEngine()->ExtendByZeroes(&crc, length); |
60 | 0 | return static_cast<crc32c_t>(crc ^ kCRC32Xor); |
61 | 0 | } |
62 | | |
63 | 0 | crc32c_t ConcatCrc32c(crc32c_t lhs_crc, crc32c_t rhs_crc, size_t rhs_len) { |
64 | 0 | uint32_t result = static_cast<uint32_t>(lhs_crc); |
65 | 0 | CrcEngine()->ExtendByZeroes(&result, rhs_len); |
66 | 0 | return crc32c_t{result ^ static_cast<uint32_t>(rhs_crc)}; |
67 | 0 | } |
68 | | |
69 | 0 | crc32c_t RemoveCrc32cPrefix(crc32c_t crc_a, crc32c_t crc_ab, size_t length_b) { |
70 | 0 | return ConcatCrc32c(crc_a, crc_ab, length_b); |
71 | 0 | } |
72 | | |
73 | | crc32c_t MemcpyCrc32c(void* dest, const void* src, size_t count, |
74 | 0 | crc32c_t initial_crc) { |
75 | 0 | return static_cast<crc32c_t>( |
76 | 0 | crc_internal::Crc32CAndCopy(dest, src, count, initial_crc, false)); |
77 | 0 | } |
78 | | |
79 | | // Remove a Suffix of given size from a buffer |
80 | | // |
81 | | // Given a CRC32C of an existing buffer, `full_string_crc`; the CRC32C of a |
82 | | // suffix of that buffer to remove, `suffix_crc`; and suffix buffer's length, |
83 | | // `suffix_len` return the CRC32C of the buffer with suffix removed |
84 | | // |
85 | | // This operation has a runtime cost of O(log(`suffix_len`)) |
86 | | crc32c_t RemoveCrc32cSuffix(crc32c_t full_string_crc, crc32c_t suffix_crc, |
87 | 0 | size_t suffix_len) { |
88 | 0 | uint32_t result = static_cast<uint32_t>(full_string_crc) ^ |
89 | 0 | static_cast<uint32_t>(suffix_crc); |
90 | 0 | CrcEngine()->UnextendByZeroes(&result, suffix_len); |
91 | 0 | return crc32c_t{result}; |
92 | 0 | } |
93 | | |
94 | | ABSL_NAMESPACE_END |
95 | | } // namespace absl |