// bdlde_crc32c.h -*-C++-*- #ifndef INCLUDED_BDLDE_CRC32C #define INCLUDED_BDLDE_CRC32C #include <bsls_ident.h> BSLS_IDENT("$Id$") //@PURPOSE: Provide utilities to calculate the CRC32-C checksum of a dataset. // //@CLASSES: // bdlde::Crc32c : calculates CRC32-C checksum // bdlde::Crc32c_Impl: calculates CRC32-C checksum with alternative impl. // //@SEE_ALSO: bdlde_crc32 // //@DESCRIPTION: This component defines a struct, 'bdlde::Crc32c' that // dramatically accelerates (as opposite to the 'bdlde::Crc32' component) // calculation of a CRC32-C checksum (a cyclic redundancy check, comprised of // 32 bits, that uses the Castagnoli polynomial), using a hardware-accelerated // implementation if supported or a software implementation otherwise. It // additionally defines the struct 'bdlde::Crc32c_Impl' to expose alternative // implementations that should not be used other than to test and benchmark. // Note that a CRC32-C checksum is a strong and fast technique for determining // whether or not a message was received without errors. Also note that a // CRC-32 checksum does not aid in error correction and is not naively useful // in any sort of cryptography application. // ///Thread Safety ///------------- // Thread safe. // ///Support for Hardware Acceleration ///--------------------------------- // Hardware-accelerated implementation is enabled at compile time when building // on a supported architecture with a compatible compiler. In addition, // runtime checks are performed to detect whether the running platform has the // required hardware support: //: o x86: SSE4.2 instructions are required //: o sparc: runtime check is detected by the 'is_sparc_crc32c_avail' system //: call // ///Performance ///----------- // See the test driver for this component in the '.t.cpp' to compare // performance of the hardware-accelerated and software implementations against // various alternative implementations that compute a 32-bit CRC checksum. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Computing and updating a checksum /// - - - - - - - - - - - - - - - - - - - - - - // The following code illustrates how to calculate and update a CRC32-C // checksum for a message over the course of building the full message. // // First, prepare a message. //.. // bsl::string message = "This is a test message."; //.. // Now, generate a checksum for 'message'. //.. // unsigned int checksum = bdlde::Crc32c::calculate(message.c_str(), // message.size()); //.. // Finally, if we learn that our message has grown by another chunk and we want // to compute the checksum of the original message plus the new chunk, let's // update the checksum by using it as a starting point. //.. // // New chunk // bsl::string newChunk = "This is a chunk appended to original message"; // message += newChunk; // // // Update checksum using previous value as starting point // checksum = bdlde::Crc32c::calculate(newChunk.c_str(), // newChunk.size(), // checksum); //.. #include <bdlscm_version.h> #include <bsl_cstddef.h> namespace BloombergLP { namespace bdlde { // ============= // struct Crc32c // ============= struct Crc32c { // This class provides runtime-efficient utilities to calculate a CRC32-C // checksum. public: // CLASS DATA static const unsigned int k_NULL_CRC32C = 0U; // CRC32-C value for a 0 length input. Note that a buffer with this // CRC32-C value need not be a 0 length input. // CLASS METHODS static unsigned int calculate(const void *data, bsl::size_t length, unsigned int crc = k_NULL_CRC32C); // Return the CRC32-C value calculated for the specified 'data' over // the specified 'length' number of bytes, using the optionally // specified 'crc' value as the starting point for the calculation. // Note that if 'data' is 0, then 'length' also must be 0. }; // ================== // struct Crc32c_Impl // ================== struct Crc32c_Impl { // This class provides alternative implementations of utilities to // calculate a CRC32-C checksum. public: // CLASS METHODS static unsigned int calculateSoftware(const void *data, bsl::size_t length, unsigned int crc = Crc32c::k_NULL_CRC32C); // Return the CRC32-C value calculated for the specified 'data' over // the specified 'length' number of bytes, using the optionally // specified 'crc' value as the starting point for the calculation. // This utilizes a portable software-based implementation to perform // the calculation. Note that if 'data' is 0, then 'length' must also // be 0. static unsigned int calculateHardwareSerial( const void *data, bsl::size_t length, unsigned int crc = Crc32c::k_NULL_CRC32C); // Return the CRC32-C value calculated for the specified 'data' over // the specified 'length' number of bytes, using the optionally // specified 'crc' value as the starting point for the calculation. // This utilizes a hardware-based implementation that does not leverage // instruction level parallelism to perform the calculation (hence it // calculates the crc32c in "serial"). Note that this function will // fall back to the software version when running on unsupported // platforms. Also note that if 'data' is 0, then 'length' must also // be 0. }; } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2018 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------