BDE 4.14.0 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`
167 /// method. Note that the `versionSelector` is expected to be formatted
168 /// as `yyyymmdd`, a date representation. See the `bslx` package-level
169 /// documentation for more information on BDEX streaming of
170 /// value-semantic types and containers.
171 static int maxSupportedBdexVersion(int versionSelector);
172
173 // CREATORS
174
175 /// Construct a checksum having the value corresponding to no data
176 /// having been provided (i.e., having the value 0).
177 Crc64();
178
179 /// Construct a checksum corresponding to the specified `data` having
180 /// the specified `length` (in bytes). Note that if `data` is 0, then
181 /// `length` also must be 0.
182 Crc64(const void *data, bsl::size_t length);
183
184 /// Construct a checksum having the value of the specified `original`
185 /// checksum.
186 Crc64(const Crc64& original);
187
188 /// Destroy this checksum. Note that this trivial destructor is
189 /// generated by the compiler.
190 ~Crc64() = default;
191
192 // MANIPULATORS
193
194 /// Assign to this checksum the value of the specified `rhs` checksum,
195 /// and return a reference to this modifiable checksum.
196 Crc64& operator=(const Crc64& rhs);
197
198 /// Assign to this object the value read from the specified input
199 /// `stream` using the specified `version` format, and return a
200 /// reference to `stream`. If `stream` is initially invalid, this
201 /// operation has no effect. If `version` is not supported, this object
202 /// is unaltered and `stream` is invalidated but otherwise unmodified.
203 /// If `version` is supported but `stream` becomes invalid during this
204 /// operation, this object has an undefined, but valid, state. Note
205 /// that no version is read from `stream`. See the `bslx` package-level
206 /// documentation for more information on BDEX streaming of
207 /// value-semantic types and containers.
208 template <class STREAM>
209 STREAM& bdexStreamIn(STREAM& stream, int version);
210
211 /// Return the current value of this checksum and set the value of this
212 /// checksum to the value the default constructor provides.
214
215 /// Reset the value of this checksum to the value the default
216 /// constructor provides.
217 void reset();
218
219 /// Update the value of this checksum to incorporate the specified
220 /// `data` having the specified `length`. If the current state is the
221 /// default state, the resultant value of this checksum is the
222 /// application of the CRC-64 algorithm upon the currently given `data`
223 /// of the given `length`. If this checksum has been previously
224 /// provided data and has not been subsequently reset, the current state
225 /// is not the default state and the resultant value is equivalent to
226 /// applying the CRC-64 algorithm upon the concatenation of all the
227 /// provided data. Note that if `data` is 0, then `length` also must be
228 /// 0.
229 void update(const void *data, bsl::size_t length);
230
231 // ACCESSORS
232
233 /// Write this value to the specified output `stream` using the
234 /// specified `version` format, and return a reference to `stream`. If
235 /// `stream` is initially invalid, this operation has no effect. If
236 /// `version` is not supported, `stream` is invalidated but otherwise
237 /// unmodified. Note that `version` is not written to `stream`. See
238 /// the `bslx` package-level documentation for more information on BDEX
239 /// streaming of value-semantic types and containers.
240 template <class STREAM>
241 STREAM& bdexStreamOut(STREAM& stream, int version) const;
242
243 /// Return the current value of this checksum.
245
246 /// Format this object to the specified output `stream` at the (absolute
247 /// value of) the optionally specified indentation `level` and return a
248 /// reference to `stream`. If `level` is specified, optionally specify
249 /// `spacesPerLevel`, the number of spaces per indentation level for
250 /// this and all of its nested objects. If `level` is negative,
251 /// suppress indentation of the first line. If `spacesPerLevel` is
252 /// negative, format the entire output on one line, suppressing all but
253 /// the initial indentation (as governed by `level`). If `stream` is
254 /// not valid on entry, this operation has no effect.
255 bsl::ostream& print(bsl::ostream& stream) const;
256};
257
258// FREE OPERATORS
259
260/// Return `true` if the specified `lhs` and `rhs` checksums have the same
261/// value, and `false` otherwise. Two checksums have the same value if the
262/// values obtained from their `checksum` methods are identical.
263bool operator==(const Crc64& lhs, const Crc64& rhs);
264
265/// Return `true` if the specified `lhs` and `rhs` checksums do not have the
266/// same value, and `false` otherwise. Two checksums do not have the same
267/// value if the values obtained from their `checksum` methods differ.
268bool operator!=(const Crc64& lhs, const Crc64& rhs);
269
270/// Write to the specified output `stream` the specified `checksum` value
271/// and return a reference to the modifiable `stream`.
272bsl::ostream& operator<<(bsl::ostream& stream, const Crc64& checksum);
273
274// ============================================================================
275// INLINE DEFINITIONS
276// ============================================================================
277
278 // -----------
279 // class Crc64
280 // -----------
281
282// CLASS METHODS
283inline
285{
286 return 1;
287}
288
289// CREATORS
290inline
292: d_crc(~bsls::Types::Uint64())
293{
294}
295
296inline
297Crc64::Crc64(const void *data, bsl::size_t length)
298: d_crc(~bsls::Types::Uint64())
299{
300 update(data, length);
301}
302
303inline
304Crc64::Crc64(const Crc64& original)
305: d_crc(original.d_crc)
306{
307}
308
309// MANIPULATORS
310inline
312{
313 d_crc = rhs.d_crc;
314 return *this;
315}
316
317template <class STREAM>
318STREAM& Crc64::bdexStreamIn(STREAM& stream, int version)
319{
320 if (stream) {
321 switch (version) {
322 case 1: {
324 stream.getUint64(crc);
325 if (!stream) {
326 return stream; // RETURN
327 }
328 d_crc = ~crc;
329 } break;
330 default: {
331 stream.invalidate();
332 } break;
333 }
334 }
335 return stream;
336}
337
338inline
340{
341 const bsls::Types::Uint64 crc = ~d_crc;
342 d_crc = ~bsls::Types::Uint64();
343 return crc;
344}
345
346inline
348{
349 d_crc = ~bsls::Types::Uint64();
350}
351
352// ACCESSORS
353template <class STREAM>
354STREAM& Crc64::bdexStreamOut(STREAM& stream, int version) const
355{
356 switch (version) {
357 case 1: {
358 stream.putUint64(~d_crc);
359 } break;
360 default: {
361 stream.invalidate();
362 } break;
363 }
364 return stream;
365}
366
367inline
369{
370 return ~d_crc;
371}
372
373} // close package namespace
374
375// FREE OPERATORS
376inline
377bool bdlde::operator==(const Crc64& lhs, const Crc64& rhs)
378{
379 return lhs.d_crc == rhs.d_crc;
380}
381
382inline
383bool bdlde::operator!=(const Crc64& lhs, const Crc64& rhs)
384{
385 return !(lhs == rhs);
386}
387
388inline
389bsl::ostream& bdlde::operator<<(bsl::ostream& stream, const Crc64& checksum)
390{
391 return checksum.print(stream);
392}
393
394
395
396#endif
397
398// ----------------------------------------------------------------------------
399// Copyright 2018 Bloomberg Finance L.P.
400//
401// Licensed under the Apache License, Version 2.0 (the "License");
402// you may not use this file except in compliance with the License.
403// You may obtain a copy of the License at
404//
405// http://www.apache.org/licenses/LICENSE-2.0
406//
407// Unless required by applicable law or agreed to in writing, software
408// distributed under the License is distributed on an "AS IS" BASIS,
409// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
410// See the License for the specific language governing permissions and
411// limitations under the License.
412// ----------------------------- END-OF-FILE ----------------------------------
413
414/** @} */
415/** @} */
416/** @} */
Definition bdlde_crc64.h:154
friend bool operator==(const Crc64 &, const Crc64 &)
~Crc64()=default
bsls::Types::Uint64 checksumAndReset()
Definition bdlde_crc64.h:339
bsl::ostream & print(bsl::ostream &stream) const
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlde_crc64.h:318
void update(const void *data, bsl::size_t length)
static int maxSupportedBdexVersion(int versionSelector)
Definition bdlde_crc64.h:284
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlde_crc64.h:354
void reset()
Definition bdlde_crc64.h:347
Crc64()
Definition bdlde_crc64.h:291
bsls::Types::Uint64 checksum() const
Return the current value of this checksum.
Definition bdlde_crc64.h:368
Crc64 & operator=(const Crc64 &rhs)
Definition bdlde_crc64.h:311
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
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)
Definition bdlt_iso8601util.h:691
unsigned long long Uint64
Definition bsls_types.h:137