BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlde_crc64.h
Go to the documentation of this file.
1/// @file bdlde_crc64.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlde_crc64.h -*-C++-*-
8#ifndef INCLUDED_BDLDE_CRC64
9#define INCLUDED_BDLDE_CRC64
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlde_crc64 bdlde_crc64
15/// @brief Provide a mechanism for computing the CRC-64 checksum of a dataset.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlde
19/// @{
20/// @addtogroup bdlde_crc64
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlde_crc64-purpose"> Purpose</a>
25/// * <a href="#bdlde_crc64-classes"> Classes </a>
26/// * <a href="#bdlde_crc64-description"> Description </a>
27/// * <a href="#bdlde_crc64-usage"> Usage </a>
28/// * <a href="#bdlde_crc64-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#bdlde_crc64-purpose}
31/// Provide a mechanism for computing the CRC-64 checksum of a dataset.
32///
33/// # Classes {#bdlde_crc64-classes}
34///
35/// - bdlde::Crc64: stores and updates a CRC-64 checksum
36///
37/// @see
38///
39/// # Description {#bdlde_crc64-description}
40/// `bdlde::Crc64` implements a mechanism for computing, updating,
41/// and streaming a CRC-64 checksum (a cyclic redundancy check comprising 64
42/// bits). This checksum is a strong and fast technique for determining whether
43/// a message was received without errors. Note that a CRC-64 checksum does not
44/// aid in error correction and is not naively useful in any sort of
45/// cryptographic application. Compared to other methods such as MD5 and
46/// SHA-256, it is relatively easy to find alternate texts with identical
47/// checksum.
48///
49/// ## Usage {#bdlde_crc64-usage}
50///
51///
52/// This section illustrates intended use of this component.
53///
54/// ### Example 1: Basic Usage {#bdlde_crc64-example-1-basic-usage}
55///
56///
57/// The following snippets of code illustrate a typical use of the
58/// `bdlde::Crc64` class. Each function would typically execute in separate
59/// processes or potentially on separate machines. The `senderExample` function
60/// below demonstrates how a message sender can write a message and its CRC-64
61/// checksum to a `bdex` output stream. Note that `Out` may be a `typedef` of
62/// any class that implements the `bslx::OutStream` protocol:
63/// @code
64/// /// Write a message and its CRC-64 checksum to the specified `output`
65/// /// stream.
66/// void senderExample(Out& output)
67/// {
68/// // prepare a message
69/// bsl::string message = "This is a test message.";
70///
71/// // generate a checksum for `message`
72/// bdlde::Crc64 crc(message.data(), message.length());
73///
74/// // write the message to `output`
75/// output << message;
76///
77/// // write the checksum to `output`
78/// const int VERSION = 1;
79/// crc.bdexStreamOut(output, VERSION);
80/// }
81/// @endcode
82/// The `receiverExample` function below illustrates how a message receiver can
83/// read a message and its CRC-64 checksum from a `bdex` input stream, then
84/// perform a local CRC-64 computation to verify that the message was received
85/// intact. Note that `In` may be a `typedef` of any class that implements the
86/// `bslx::InStream` protocol:
87/// @code
88/// /// Read a message and its CRC-64 checksum from the specified `input`
89/// /// stream, and verify the integrity of the message.
90/// void receiverExample(In& input)
91/// {
92/// // read the message from `input`
93/// bsl::string message;
94/// input >> message;
95///
96/// // read the checksum from `input`
97/// bdlde::Crc64 crc;
98/// const int VERSION = 1;
99/// crc.bdexStreamIn(input, VERSION);
100///
101/// // locally compute the checksum of the received `message`
102/// bdlde::Crc64 crcLocal;
103/// crcLocal.update(message.data(), message.length());
104///
105/// // verify that the received and locally-computed checksums match
106/// assert(crcLocal == crc);
107/// }
108/// @endcode
109/// @}
110/** @} */
111/** @} */
112
113/** @addtogroup bdl
114 * @{
115 */
116/** @addtogroup bdlde
117 * @{
118 */
119/** @addtogroup bdlde_crc64
120 * @{
121 */
122
123#include <bdlscm_version.h>
124
125#include <bsls_assert.h>
126#include <bsls_types.h>
127
128#include <bsl_cstddef.h>
129#include <bsl_iosfwd.h>
130
131
132namespace bdlde {
133
134 // ===========
135 // class Crc64
136 // ===========
137
138/// This class represents a CRC-64 checksum value that can be updated as
139/// data is provided.
140///
141/// More generally, this class supports a complete set of *value*
142/// *semantic* operations, including copy construction, assignment,
143/// equality comparison, `ostream` printing, and `bdex` serialization.
144/// (A precise operational definition of when two objects have the same
145/// value can be found in the description of `operator==` for the class.)
146/// This class is *exception* *neutral* with no guarantee of rollback: if an
147/// exception is thrown during the invocation of a method on a pre-existing
148/// object, the class is left in a valid state, but its value is undefined.
149/// In no event is memory leaked. Finally, *aliasing* (e.g., using all or
150/// part of an object as both source and destination) is supported in all
151/// cases.
152///
153/// See @ref bdlde_crc64
154class Crc64 {
155
156 // DATA
157 bsls::Types::Uint64 d_crc; // bitwise inverse of the current checksum
158
159 // FRIENDS
160 friend bool operator==(const Crc64&, const Crc64&);
161
162 public:
163 // CLASS METHODS
164
165 /// Return the maximum valid BDEX format version, as indicated by the
166 /// specified `versionSelector`, to be passed to the `bdexStreamOut` method.
167 ///
168 /// \note Note that the `versionSelector` is expected to be formatted
169 /// as `yyyymmdd`, a date representation. See the `bslx` package-level
170 /// documentation for more information on BDEX streaming of
171 /// value-semantic types and containers.
172 static int maxSupportedBdexVersion(int versionSelector);
173
174 // CREATORS
175
176 /// Construct a checksum having the value corresponding to no data
177 /// having been provided (i.e., having the value 0).
178 Crc64();
179
180 /// Construct a checksum corresponding to the specified `data` having the specified `length` (in bytes).
181 ///
182 /// \note Note that if `data` is 0, then
183 /// `length` also must be 0.
184 Crc64(const void *data, bsl::size_t length);
185
186 /// Construct a checksum having the value of the specified `original`
187 /// checksum.
188 Crc64(const Crc64& original);
189
190 /// Destroy this checksum.
191 /// \note Note that this trivial destructor is
192 /// generated by the compiler.
193 ~Crc64() = default;
194
195 // MANIPULATORS
196
197 /// Assign to this checksum the value of the specified `rhs` checksum,
198 /// and return a reference to this modifiable checksum.
199 Crc64& operator=(const Crc64& rhs);
200
201 /// Assign to this object the value read from the specified input
202 /// `stream` using the specified `version` format, and return a
203 /// reference to `stream`. If `stream` is initially invalid, this
204 /// operation has no effect. If `version` is not supported, this object
205 /// is unaltered and `stream` is invalidated but otherwise unmodified.
206 /// If `version` is supported but `stream` becomes invalid during this
207 /// operation, this object has an undefined, but valid, state.
208 ///
209 /// \note Note that no version is read from `stream`. See the `bslx` package-level
210 /// documentation for more information on BDEX streaming of
211 /// value-semantic types and containers.
212 template <class STREAM>
213 STREAM& bdexStreamIn(STREAM& stream, int version);
214
215 /// Return the current value of this checksum and set the value of this
216 /// checksum to the value the default constructor provides.
218
219 /// Reset the value of this checksum to the value the default
220 /// constructor provides.
221 void reset();
222
223 /// Update the value of this checksum to incorporate the specified
224 /// `data` having the specified `length`. If the current state is the
225 /// default state, the resultant value of this checksum is the
226 /// application of the CRC-64 algorithm upon the currently given `data`
227 /// of the given `length`. If this checksum has been previously
228 /// provided data and has not been subsequently reset, the current state
229 /// is not the default state and the resultant value is equivalent to
230 /// applying the CRC-64 algorithm upon the concatenation of all the provided data.
231 ///
232 /// \note Note that if `data` is 0, then `length` also must be
233 /// 0.
234 void update(const void *data, bsl::size_t length);
235
236 // ACCESSORS
237
238 /// Write this value to the specified output `stream` using the
239 /// specified `version` format, and return a reference to `stream`. If
240 /// `stream` is initially invalid, this operation has no effect. If
241 /// `version` is not supported, `stream` is invalidated but otherwise unmodified.
242 ///
243 /// \note Note that `version` is not written to `stream`. See
244 /// the `bslx` package-level documentation for more information on BDEX
245 /// streaming of value-semantic types and containers.
246 template <class STREAM>
247 STREAM& bdexStreamOut(STREAM& stream, int version) const;
248
249 /// Return the current value of this checksum.
251
252 /// Format this object to the specified output `stream` at the (absolute
253 /// value of) the optionally specified indentation `level` and return a
254 /// reference to `stream`. If `level` is specified, optionally specify
255 /// `spacesPerLevel`, the number of spaces per indentation level for
256 /// this and all of its nested objects. If `level` is negative,
257 /// suppress indentation of the first line. If `spacesPerLevel` is
258 /// negative, format the entire output on one line, suppressing all but
259 /// the initial indentation (as governed by `level`). If `stream` is
260 /// not valid on entry, this operation has no effect.
261 bsl::ostream& print(bsl::ostream& stream) const;
262};
263
264// FREE OPERATORS
265
266/// Return `true` if the specified `lhs` and `rhs` checksums have the same
267/// value, and `false` otherwise. Two checksums have the same value if the
268/// values obtained from their `checksum` methods are identical.
269bool operator==(const Crc64& lhs, const Crc64& rhs);
270
271/// Return `true` if the specified `lhs` and `rhs` checksums do not have the
272/// same value, and `false` otherwise. Two checksums do not have the same
273/// value if the values obtained from their `checksum` methods differ.
274bool operator!=(const Crc64& lhs, const Crc64& rhs);
275
276/// Write to the specified output `stream` the specified `checksum` value
277/// and return a reference to the modifiable `stream`.
278bsl::ostream& operator<<(bsl::ostream& stream, const Crc64& checksum);
279
280// ============================================================================
281// INLINE DEFINITIONS
282// ============================================================================
283
284 // -----------
285 // class Crc64
286 // -----------
287
288// CLASS METHODS
289inline
291{
292 return 1;
293}
294
295// CREATORS
296inline
298: d_crc(~bsls::Types::Uint64())
299{
300}
301
302inline
303Crc64::Crc64(const void *data, bsl::size_t length)
304: d_crc(~bsls::Types::Uint64())
305{
306 update(data, length);
307}
308
309inline
310Crc64::Crc64(const Crc64& original)
311: d_crc(original.d_crc)
312{
313}
314
315// MANIPULATORS
316inline
318{
319 d_crc = rhs.d_crc;
320 return *this;
321}
322
323template <class STREAM>
324STREAM& Crc64::bdexStreamIn(STREAM& stream, int version)
325{
326 if (stream) {
327 switch (version) {
328 case 1: {
330 stream.getUint64(crc);
331 if (!stream) {
332 return stream; // RETURN
333 }
334 d_crc = ~crc;
335 } break;
336 default: {
337 stream.invalidate();
338 } break;
339 }
340 }
341 return stream;
342}
343
344inline
346{
347 const bsls::Types::Uint64 crc = ~d_crc;
348 d_crc = ~bsls::Types::Uint64();
349 return crc;
350}
351
352inline
354{
355 d_crc = ~bsls::Types::Uint64();
356}
357
358// ACCESSORS
359template <class STREAM>
360STREAM& Crc64::bdexStreamOut(STREAM& stream, int version) const
361{
362 switch (version) {
363 case 1: {
364 stream.putUint64(~d_crc);
365 } break;
366 default: {
367 stream.invalidate();
368 } break;
369 }
370 return stream;
371}
372
373inline
375{
376 return ~d_crc;
377}
378
379} // close package namespace
380
381// FREE OPERATORS
382inline
383bool bdlde::operator==(const Crc64& lhs, const Crc64& rhs)
384{
385 return lhs.d_crc == rhs.d_crc;
386}
387
388inline
389bool bdlde::operator!=(const Crc64& lhs, const Crc64& rhs)
390{
391 return !(lhs == rhs);
392}
393
394inline
395bsl::ostream& bdlde::operator<<(bsl::ostream& stream, const Crc64& checksum)
396{
397 return checksum.print(stream);
398}
399
400
401
402#endif
403
404// ----------------------------------------------------------------------------
405// Copyright 2018 Bloomberg Finance L.P.
406//
407// Licensed under the Apache License, Version 2.0 (the "License");
408// you may not use this file except in compliance with the License.
409// You may obtain a copy of the License at
410//
411// http://www.apache.org/licenses/LICENSE-2.0
412//
413// Unless required by applicable law or agreed to in writing, software
414// distributed under the License is distributed on an "AS IS" BASIS,
415// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
416// See the License for the specific language governing permissions and
417// limitations under the License.
418// ----------------------------- END-OF-FILE ----------------------------------
419
420/** @} */
421/** @} */
422/** @} */
Definition bdlde_crc64.h:154
friend bool operator==(const Crc64 &, const Crc64 &)
~Crc64()=default
bsls::Types::Uint64 checksumAndReset()
Definition bdlde_crc64.h:345
bsl::ostream & print(bsl::ostream &stream) const
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlde_crc64.h:324
void update(const void *data, bsl::size_t length)
static int maxSupportedBdexVersion(int versionSelector)
Definition bdlde_crc64.h:290
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlde_crc64.h:360
void reset()
Definition bdlde_crc64.h:353
Crc64()
Definition bdlde_crc64.h:297
bsls::Types::Uint64 checksum() const
Return the current value of this checksum.
Definition bdlde_crc64.h:374
Crc64 & operator=(const Crc64 &rhs)
Definition bdlde_crc64.h:317
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlde_base64alphabet.h:118
bool operator!=(const Base64DecoderOptions &lhs, const Base64DecoderOptions &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, Base64Alphabet::Enum value)
bool operator==(const Base64DecoderOptions &lhs, const Base64DecoderOptions &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition bdlt_iso8601util.h:707
unsigned long long Uint64
Definition bsls_types.h:139