/usr/share/doc/libcrcutil-doc/examples/interface.h is in libcrcutil-doc 1.0-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | // Copyright 2010 Google Inc. All rights reserved.
//
// 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.
// Example how to use CRC implementation via the interface which
// hides details of implementation.
//
// The raw implementation is not indended to be used in a project
// directly because:
// - Implementation lives in the header files because that is the
// only way to use templates efficiently.
// - Header files are quite "dirty" -- they define and use a
// lot of macros. Bringing these macros to all files in
// a project is not particularly good idea.
// - The code takes forever to compile with GCC (e.g. GCC
// 4.4.3 and 4.5.0 compile the unittest for about 30 seconds).
//
// Solution:
// - Create your own, clean interface.
// - Do not expose interface internals in a header file.
// - Proxy all calls to your interface to CRC implementation.
// - Keep only one copy of actual implementation.
#ifndef CRCUTIL_INTERFACE_H_
#define CRCUTIL_INTERFACE_H_
#include "std_headers.h" // size_t
namespace crcutil_interface {
// Many projects define their own uint64. Do it here.
typedef unsigned long long UINT64;
class CRC {
public:
// Creates new instance of CRC class.
// If arguments are illegal (e.g. provided generating polynomial
// has more bits than provided degree), returns NULL.
//
// poly_* - generating polynomial (reversed bit format).
// degree - degree of generating polynomial.
// canonical - if true, input CRC value will be XOR'ed with
// (inverted) before and after CRC computation.
// roll_start_value - starting value of rolling CRC.
// roll_window_bytes - length of rolling CRC window in bytes.
// If roll_length is 0, roll_start_value
// shall be 0.
// use_sse4_2 - if true, use SSE4.2 crc32 instruction to compute
// CRC when generating polynomial is CRC32C (Castagnoli)
// allocated_memory - optional (may be NULL) address of a variable
// to store the address of actually allocated memory.
static CRC *Create(UINT64 poly_lo,
UINT64 poly_hi,
size_t degree,
bool canonical,
UINT64 roll_start_value_lo,
UINT64 roll_start_value_hi,
size_t roll_window_bytes,
bool use_sse4_2,
const void **allocated_memory);
// Deletes the instance of CRC class.
virtual void Delete() = 0;
// Returns true if SSE4.2 is available.
static bool IsSSE42Available();
// Returns generating polynomial.
virtual void GeneratingPolynomial(/* OUT */ UINT64 *lo,
/* OUT */ UINT64 *hi = NULL) const = 0;
// Returns degree of generating polynomial.
virtual size_t Degree() const = 0;
// Returns canonization constant used to XOR crc value
// before and after CRC computation.
virtual void CanonizeValue(/* OUT */ UINT64 *lo,
/* OUT */ UINT64 *hi = NULL) const = 0;
// Returns rolling CRC starting value.
virtual void RollStartValue(/* OUT */ UINT64 *lo,
/* OUT */ UINT64 *hi = NULL) const = 0;
// Returns length of rolling CRC window.
virtual size_t RollWindowBytes() const = 0;
// Returns CRC of CRC tables to enable verification
// of integrity of CRC function itself by comparing
// the result with pre-computed value.
virtual void SelfCheckValue(/* OUT */ UINT64 *lo,
/* OUT */ UINT64 *hi = NULL) const = 0;
// Given CRC value of previous chunk of data,
// extends it to new chunk, retuning the result in-place.
//
// If degree of CRC polynomial is 64 or less,
// (*hi) will not be touched.
virtual void Compute(const void *data,
size_t bytes,
/* INOUT */ UINT64 *lo,
/* INOUT */ UINT64 *hi = NULL) const = 0;
// Starts rolling CRC by computing CRC of first
// "roll_length" bytes of "data", using "roll_start_value"
// as starting value (see Create()).
// Should not be called if the value of "roll_value" was 0.
virtual void RollStart(const void *data,
/* OUT */ UINT64 *lo,
/* OUT */ UINT64 *hi = NULL) const = 0;
// Rolls CRC by 1 byte, given the bytes leaving and
// entering the window of "roll_length" bytes.
// RollStart() should be called before "Roll".
// Should not be called if the value of "roll_value" was 0.
virtual void Roll(size_t byte_out,
size_t byte_in,
/* INOUT */ UINT64 *lo,
/* INOUT */ UINT64 *hi = NULL) const = 0;
// Computes CRC of sequence of zeroes -- without touching the data.
virtual void CrcOfZeroes(UINT64 bytes,
/* INOUT */ UINT64 *lo,
/* INOUT */ UINT64 *hi = NULL) const = 0;
// Computes value of CRC(A, bytes, start_new) given known
// crc=CRC(A, bytes, start_old) -- without touching the data.
virtual void ChangeStartValue(
UINT64 start_old_lo, UINT64 start_old_hi,
UINT64 start_new_lo, UINT64 start_new_hi,
UINT64 bytes,
/* INOUT */ UINT64 *lo,
/* INOUT */ UINT64 *hi = NULL) const = 0;
// Returns CRC of concatenation of blocks A and B when CRCs
// of blocks A and B are known -- without touching the data.
//
// To be precise, given CRC(A, |A|, startA) and CRC(B, |B|, 0),
// returns CRC(AB, |AB|, startA).
virtual void Concatenate(UINT64 crcB_lo, UINT64 crcB_hi,
UINT64 bytes_B,
/* INOUT */ UINT64* crcA_lo,
/* INOUT */ UINT64* crcA_hi = NULL) const = 0;
// Given CRC of a message, stores extra (degree + 7)/8 bytes after
// the message so that CRC(message+extra, start) = result.
// Does not change CRC start value (use ChangeStartValue for that).
// Returns number of stored bytes.
virtual size_t StoreComplementaryCrc(
void *dst,
UINT64 message_crc_lo, UINT64 message_crc_hi,
UINT64 result_crc_lo, UINT64 result_crc_hi = 0) const = 0;
// Stores given CRC of a message as (degree + 7)/8 bytes filled
// with 0s to the right. Returns number of stored bytes.
// CRC of the message and stored CRC is a constant value returned
// by CrcOfCrc() -- it does not depend on contents of the message.
virtual size_t StoreCrc(/* OUT */ void *dst,
UINT64 lo,
UINT64 hi = 0) const = 0;
// Computes expected CRC value of CRC(Message,CRC(Message))
// when CRC is stored after the message. This value is fixed
// and does not depend on the message or CRC start value.
virtual void CrcOfCrc(/* OUT */ UINT64 *lo,
/* OUT */ UINT64 *hi = NULL) const = 0;
protected:
// CRC instance should be created only once (most of the time):
// - Creation and initializion is relatively expensive.
// - CRC is fully defined by its generating polynomials
// (well, and few more parameters).
// - CRC instances are pure constants. There is no
// reason to have 2 instances of the same CRC.
// - There are not too many generating polynomials that are
// used on practice. It is hard to imagine a project
// which uses 50 different generating polynomials.
// Thus, a handful of CRC instances is sufficient
// to cover the needs of even very large project.
// - Finally and most importantly, CRC tables should be
// aligned properly. No, the instances of CRC class
// are not created by blind "new" -- they use placement
// "new" and, in absense of placement "delete",
// should be deleted by calling explicit Delete() method.
virtual ~CRC();
// Cannot instantiate the class -- instances may be created
// by CRC::Create() only.
CRC();
};
} // namespace crcutil_interface
#endif // CRCUTIL_INTERFACE_H_
|