BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balber_berutil.h
Go to the documentation of this file.
1/// @file balber_berutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balber_berutil.h -*-C++-*-
8#ifndef INCLUDED_BALBER_BERUTIL
9#define INCLUDED_BALBER_BERUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balber_berutil balber_berutil
15/// @brief Provide functions to encode and decode simple types in BER format.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balber
19/// @{
20/// @addtogroup balber_berutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balber_berutil-purpose"> Purpose</a>
25/// * <a href="#balber_berutil-classes"> Classes </a>
26/// * <a href="#balber_berutil-description"> Description </a>
27/// * <a href="#balber_berutil-terminology"> Terminology </a>
28/// * <a href="#balber_berutil-usage"> Usage </a>
29/// * <a href="#balber_berutil-example-1-reading-and-writing-identifier-octets"> Example 1: Reading and Writing Identifier Octets </a>
30///
31/// # Purpose {#balber_berutil-purpose}
32/// Provide functions to encode and decode simple types in BER format.
33///
34/// # Classes {#balber_berutil-classes}
35///
36/// - balber::BerUtil: namespace of utility functions for BER
37///
38/// @see balber_berencoder, balber_berdecoder
39///
40/// # Description {#balber_berutil-description}
41/// This component provides utility functions for encoding and
42/// decoding of primitive BER constructs, such as tag identifier octets, length
43/// octets, fundamental C++ types. The encoding and decoding of `bsl::string`
44/// and BDE date/time types is also implemented. For `bsl::string_view` and
45/// `bslstl::StringRef` types only encoding is supported.
46///
47/// These utility functions operate on `bsl::streambuf` for buffer management.
48///
49/// More information about BER constructs can be found in the BER specification
50/// (X.690). A copy of the specification can be found at the URL:
51/// * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
52///
53/// Note that this is a low-level component that only encodes and decodes
54/// primitive constructs. Clients should use the @ref balber_berencoder and
55/// @ref balber_berdecoder components (which use this component in the
56/// implementation) to encode and decode well-formed BER messages.
57///
58/// ## Terminology {#balber_berutil-terminology}
59///
60///
61/// The documentation of this component occasionally uses the following
62/// terminology as shorthand:
63///
64/// * **date-and-time type**:
65/// > A data type provided by BDE for the representation of a date and/or time
66/// > value. The date-and-time types are: `bdlt::Date`, `bdlt::DateTz`,
67/// > `bdlt::Datetime`, `bdlt::DatetimeTz`, `bdlt::Time`, and `bdlt::TimeTz`.
68/// > Note that under this definition, the time-zone-aware types provided by
69/// > BDE, such as `baltzo::LocalDatetime`, are not date-and-time types.
70///
71/// * **date-and-time value**:
72/// > The value associated with an object of a date-and-time type.
73///
74/// ## Usage {#balber_berutil-usage}
75///
76///
77/// This section illustrates intended use of this component.
78///
79/// ### Example 1: Reading and Writing Identifier Octets {#balber_berutil-example-1-reading-and-writing-identifier-octets}
80///
81///
82/// The following snippets of code illustrate the usage of this component. Due
83/// to the low-level nature of this component, an extended usage example is not
84/// necessary.
85///
86/// Suppose we wanted to write the identifier octets for a BER tag having the
87/// following properties:
88/// @code
89/// Tag Class: Context-specific
90/// Tag Type: Primitive
91/// Tag Number: 31
92/// @endcode
93/// According to the BER specification, this should generate two octets
94/// containing the values 0x9F and 0x1F. The following function demonstrates
95/// this:
96/// @code
97/// bdlsb::MemOutStreamBuf osb;
98///
99/// balber::BerConstants::TagClass tagClass =
100/// balber::BerConstants::e_CONTEXT_SPECIFIC;
101/// balber::BerConstants::TagType tagType =
102/// balber::BerConstants::e_PRIMITIVE;
103/// int tagNumber = 31;
104///
105/// int retCode = balber::BerUtil::putIdentifierOctets(&osb,
106/// tagClass,
107/// tagType,
108/// tagNumber);
109/// assert(0 == retCode);
110/// assert(2 == osb.length());
111/// assert(0x9F == (unsigned char)osb.data()[0]);
112/// assert(0x1F == (unsigned char)osb.data()[1]);
113/// @endcode
114/// The next part of the function will read the identifier octets from the
115/// stream and verify its contents:
116/// @code
117/// bdlsb::FixedMemInStreamBuf isb(osb.data(), osb.length());
118///
119/// balber::BerConstants::TagClass tagClassIn;
120/// balber::BerConstants::TagType tagTypeIn;
121/// int tagNumberIn;
122/// int numBytesConsumed = 0;
123///
124/// retCode = balber::BerUtil::getIdentifierOctets(&isb,
125/// &tagClassIn,
126/// &tagTypeIn,
127/// &tagNumberIn,
128/// &numBytesConsumed);
129/// assert(0 == retCode);
130/// assert(2 == numBytesConsumed);
131/// assert(tagClass == tagClassIn);
132/// assert(tagType == tagTypeIn);
133/// assert(tagNumber == tagNumberIn);
134/// @endcode
135/// @}
136/** @} */
137/** @} */
138
139/** @addtogroup bal
140 * @{
141 */
142/** @addtogroup balber
143 * @{
144 */
145/** @addtogroup balber_berutil
146 * @{
147 */
148
149#include <balscm_version.h>
150
151#include <balber_berconstants.h>
154
155#include <bdldfp_decimal.h>
156
157#include <bdlt_date.h>
158#include <bdlt_datetime.h>
159#include <bdlt_datetimetz.h>
160#include <bdlt_datetz.h>
161#include <bdlt_iso8601util.h>
163#include <bdlt_time.h>
164#include <bdlt_timetz.h>
165
166#include <bdlb_float.h>
167#include <bdlb_variant.h>
168
169#include <bslmf_assert.h>
170
171#include <bsla_nodiscard.h>
172#include <bsla_unreachable.h>
173
174#include <bsls_assert.h>
175#include <bsls_platform.h>
176#include <bsls_review.h>
177
178#include <bsl_streambuf.h>
179#include <bsl_string.h>
180#include <bsl_string_view.h>
181#include <bsl_vector.h>
182
183
184namespace balber {
185
186 // ==============
187 // struct BerUtil
188 // ==============
189
190/// This utility contains functions to encode and decode primitive BER
191/// constructs and simple value semantic types. By convention, all
192/// functions return 0 on success, and a non-zero value otherwise. Also by
193/// convention, all the "get" functions take an `accumNumBytesConsumed`;
194/// each of the functions will add to this variable the number of bytes
195/// consumed within the scope of the function.
196///
197/// See @ref balber_berutil
198struct BerUtil {
199
200 enum {
201 k_INDEFINITE_LENGTH = -1 // used to indicate that the length is
202 // indefinite
203
204#ifndef BDE_OMIT_INTERNAL_DEPRECATED
208#endif // BDE_OMIT_INTERNAL_DEPRECATED
209 };
210
211 // CLASS METHODS
212
213 /// Decode the "end-of-content" octets (two consecutive zero-octets) from
214 /// the specified `streamBuf` and add the number of bytes consumed (which
215 /// is always 2) to the specified `accumNumBytesConsumed`. Return 0 on
216 /// success, and a non-zero value otherwise.
217 static int getEndOfContentOctets(bsl::streambuf *streamBuf,
218 int *accumNumBytesConsumed);
219
220 /// Decode the identifier octets from the specified `streamBuf` and load
221 /// the tag class, tag type, and tag number to the specified `tagClass`,
222 /// `tagType`, and `tagNumber` respectively. Add the number of bytes
223 /// consumed to the specified `accumNumBytesConsumed`. Return 0 on
224 /// success, and a non-zero value otherwise.
226 bsl::streambuf *streamBuf,
227 BerConstants::TagClass *tagClass,
228 BerConstants::TagType *tagType,
229 int *tagNumber,
230 int *accumNumBytesConsumed);
231
232 /// Decode the length octets from the specified `streamBuf` and load the
233 /// result to the specified `result`. If the length is indefinite (i.e.,
234 /// contents will be terminated by "end-of-content" octets) then `result`
235 /// will be set to `k_INDEFINITE_LENGTH`. Add the number of bytes consumed
236 /// to the specified `accumNumBytesConsumed`. Return 0 on success, and a
237 /// non-zero value otherwise.
238 static int getLength(bsl::streambuf *streamBuf,
239 int *result,
240 int *accumNumBytesConsumed);
241
242 /// Decode the specified `value` from the specified `streamBuf`, consuming
243 /// exactly the specified `length` bytes. Return 0 on success, and a
244 /// non-zero value otherwise. Optionally specify decoding `options` to control aspects of the decoding.
245 ///
246 /// \note Note that the value consists of the
247 /// contents bytes only (no length prefix). Also note that only
248 /// fundamental C++ types, `bsl::string`, and BDE date/time types are
249 /// supported.
250 template <typename TYPE>
251 static int getValue(
252 bsl::streambuf *streamBuf,
253 TYPE *value,
254 int length,
255 const BerDecoderOptions& options = BerDecoderOptions());
256
257 /// Decode the specified `value` from the specified `streamBuf` and add the
258 /// number of bytes consumed to the specified `accumNumBytesConsumed`.
259 /// Return 0 on success, and a non-zero value otherwise. Optionally
260 /// specify decoding `options` to control aspects of the decoding.
261 ///
262 /// \note Note that the value consists of the length and contents primitives. Also
263 /// note that only fundamental C++ types, `bsl::string`, and BDE date/time
264 /// types are supported.
265 template <typename TYPE>
266 static int getValue(
267 bsl::streambuf *streamBuf,
268 TYPE *value,
269 int *accumNumBytesConsumed,
270 const BerDecoderOptions& options = BerDecoderOptions());
271
272 /// Encode the "end-of-content" octets (two consecutive zero-octets) to the
273 /// specified `streamBuf`. The "end-of-content" octets act as the
274 /// termination bytes for objects that have indefinite length. Return 0 on
275 /// success, and a non-zero value otherwise.
276 static int putEndOfContentOctets(bsl::streambuf *streamBuf);
277
278 /// Encode the identifier octets for the specified `tagClass`, `tagType`
279 /// and `tagNumber` to the specified `streamBuf`. Return 0 on success, and
280 /// a non-zero value otherwise.
281 static int putIdentifierOctets(bsl::streambuf *streamBuf,
282 BerConstants::TagClass tagClass,
283 BerConstants::TagType tagType,
284 int tagNumber);
285
286 /// Encode the "indefinite-length" octet onto the specified `streamBuf`.
287 /// This octet signifies that the length of the contents is indefinite
288 /// (i.e., contents will be terminated by end of content octets). Return 0
289 /// on success, and a non-zero value otherwise.
290 static int putIndefiniteLengthOctet(bsl::streambuf *streamBuf);
291
292 /// Encode the specified `length` to the specified `streamBuf`. Return 0
293 /// on success, and a non-zero value otherwise.
294 ///
295 /// \pre The behavior is undefined unless `0 <= length`.
296 static int putLength(bsl::streambuf *streamBuf, int length);
297
298 /// Encode the specified `value` to the specified `streamBuf`. Return 0 on success, and a non-zero value otherwise.
299 ///
300 /// \note Note that the value consists
301 /// of the length and contents primitives. Also note that only fundamental
302 /// C++ types, `bsl::string`, `bsl::string_view`, `bslstl::StringRef`, and
303 /// BDE date/time types are supported.
304 template <typename TYPE>
305 static int putValue(bsl::streambuf *streamBuf,
306 const TYPE& value,
307 const BerEncoderOptions *options = 0);
308};
309
310// Implementation Note
311// -------------------
312// The following utility structs used in the implementation of `BerUtil` are
313// provided in reverse dependency order. This means that low-level utilities
314// appear first, and higher-level utilities later. No utility uses another
315// that appears later.
316//
317// Each utility provides type aliases for the lower-level utilities used in its
318// implementation. This set of type aliases also serves as a manifest of the
319// utility's dependencies.
320
321 // ========================
322 // struct BerUtil_Constants
323 // ========================
324
325/// This component-private utility `struct` provides a namespace for a set
326/// of constants used to calculate quantities needed by BER encoders and
327/// decoders. For example, this struct provides a named constant for the
328/// number of bits in a byte, which is used in downstream calculations.
329///
330/// See @ref balber_berutil
332
333 // TYPES
335};
336
337 // ============================
338 // struct BerUtil_StreambufUtil
339 // ============================
340
341/// This component-private utility `struct` provides a namespace for a suite
342/// of functions used by `BerUtil` to perform input and output operations on `bsl::streambuf` objects.
343///
344/// \note Note that these functions are intended to
345/// adapt the standard stream-buffer operations to a BDE-style interface.
346///
347/// See @ref balber_berutil
349
350 // CLASS METHODS
351
352 /// Read the next byte from the specified `streamBuf` without advancing the
353 /// read position and load that byte into the specified `value`. Return 0
354 /// on success, and a non-zero value otherwise. If this operation is not
355 /// successful, the value of `*value` is unchanged. This operation fails
356 /// if the input sequence of `streamBuf` is at its end.
357 static int peekChar(char *value, bsl::streambuf *streamBuf);
358
359 /// Read the specified `bufferLength` number of bytes from the input
360 /// sequence of the specified `streamBuf`, as if by a call to
361 /// `streamBuf->sgetn(buffer, bufferLength)`, and load the bytes into
362 /// successive elements of the specified `buffer`, starting at the first
363 /// element. Return 0 on success, and a non-zero value otherwise. The
364 /// operation succeeds if `length` bytes are successfully read from the
365 /// input sequence of the `streamBuf` without the read position becoming
366 /// unavailable. If less than `bufferLength` bytes are read, the number of
367 /// bytes loaded into `buffer` is not specified.
368 ///
369 /// \pre The behavior is undefined unless `0 <= bufferLength` and `buffer` is the address of a sequence of
370 /// at least `bufferLength` bytes.
371 static int getChars(char *buffer,
372 bsl::streambuf *streamBuf,
373 int bufferLength);
374
375 /// Write the first specified `bufferLength` number of bytes from the
376 /// specified `buffer` to the specified `streamBuf`, as if by a call to
377 /// `streamBuf->sputn(buffer, bufferLength)`. Return 0 on success, and
378 /// a non-zero value otherwise.
379 static int putChars(bsl::streambuf *streamBuf,
380 const char *buffer,
381 int bufferLength);
382};
383
384 // ================================
385 // struct BerUtil_IdentifierImpUtil
386 // ================================
387
388/// This component-private utility `struct` provides a namespace for a suite of
389/// functions used by `BerUtil` to implement BER identifier octet encoding and
390/// decoding.
391///
392/// See @ref balber_berutil
394
395 // TYPES
396
397 /// `Constants` is an alias to a namespace for a suite of general-purpose
398 /// constants that occur when encoding or decoding BER data.
400
401 private:
402 // PRIVATE TYPES
403 enum {
404 k_TAG_CLASS_MASK = 0xC0, // 0xC0 = 0b1100'0000
405 k_TAG_TYPE_MASK = 0x20, // 0x20 = 0b0010'0000
406 k_TAG_NUMBER_MASK = 0x1F, // 0x1F = 0b0001'1111
407 // The first octet in a sequence of one or more BER identifier
408 // octets encodes 3 quantities: the tag class, the tag type, and
409 // the leading bits of the tag number. These quantities are
410 // encoded according to the packing suggested by the above 3 masks.
411
412 k_MAX_TAG_NUMBER_IN_ONE_OCTET = 30,
413 // The last 5 bits of the first octet in a sequence of one or more
414 // BER identifier octets encodes one of 32 different values.
415 // Values 0 through 30 indicate the tag number of the contents is
416 // the corresponding value. The value 31 indicates that the next
417 // octet is the first byte in a possibly multi-byte encoding of an
418 // 8-bit VLQ.
419
420 k_NUM_VALUE_BITS_IN_TAG_OCTET = 7,
421 // BER identifier octets (after the first octet) encode an 8-bit
422 // VLQ unsigned integer value that indicates the tag number of the
423 // contents. The most significant bit of this octet indicates
424 // whether or not the octet is the last one in the VLQ sequence, or
425 // if another VLQ octet follows.
426
427 k_MAX_TAG_NUMBER_OCTETS =
428 (sizeof(int) * Constants::k_NUM_BITS_PER_OCTET) /
429 k_NUM_VALUE_BITS_IN_TAG_OCTET +
430 1,
431 // This component restricts the maximum supported number of octets
432 // used to represent the tag number to 4. This means that there
433 // are at most '4 * 7 = 28' bits used to encode such a tag number.
434
435 k_CHAR_MSB_MASK = 0x80, // 0x80 = 0b1000'0000
436 // An 8-bit mask for the most significant bit of an octet.
437
438 k_SEVEN_BITS_MASK = 0x7F // 0x7F = 0b0111'1111
439 // An 8-bit mask for all but the most significant bit of an octet.
440 };
441
442 public:
443 // CLASS METHODS
444
445 /// Decode the identifier octets from the specified `streamBuf` and load
446 /// the tag class, tag type, and tag number to the specified `tagClass`,
447 /// `tagType`, and `tagNumber`, respectively. Add the number of bytes
448 /// consumed to the specified `accumNumBytesConsumed`. Return 0 on
449 /// success, and a non-zero value otherwise.
451 BerConstants::TagClass *tagClass,
452 BerConstants::TagType *tagType,
453 int *tagNumber,
454 int *accumNumBytesConsumed,
455 bsl::streambuf *streamBuf);
456
457 /// Encode the identifier octets for the specified `tagClass`, `tagType`
458 /// and `tagNumber`, in that order, to the specified `streamBuf`.
459 /// Return 0 on success, and a non-zero value otherwise.
460 static int putIdentifierOctets(bsl::streambuf *streamBuf,
461 BerConstants::TagClass tagClass,
462 BerConstants::TagType tagType,
463 int tagNumber);
464};
465
466 // ================================
467 // struct BerUtil_RawIntegerImpUtil
468 // ================================
469
470/// This component-private utility `struct` provides a namespace for a suite
471/// of functions used by `BerUtil` to implement BER integer encoding. This
472/// `struct` is separate from `BerUtil_IntegerImpUtil` to break a dependency
473/// cycle between `BerUtil_IntegerImpUtil` and `BerUtil_LengthImpUtil`.
474///
475/// See @ref balber_berutil
477
478 // TYPES
479
480 /// `Constants` is an alias to a namespace for a suite of general-purpose
481 /// constants that occur when encoding or decoding BER data.
483
484 // CLASS METHODS
485
486 /// Encode the octets used in the BER encoding of the specified `value` of
487 /// the specified `INTEGRAL_TYPE` to the specified `streamBuf`, using
488 /// exactly the specified `length` number of octets. Return 0 on success, and a non-zero value otherwise.
489 ///
490 /// \pre The behavior is undefined unless
491 /// `INTEGRAL_TYPE` is fundamental integral type and exactly `length`
492 /// number of octets is used in the BER encoding of the specified `value`.
493 template <class INTEGRAL_TYPE>
494 static int putIntegerGivenLength(bsl::streambuf *streamBuf,
495 INTEGRAL_TYPE value,
496 int length);
497};
498
499 // ============================
500 // struct BerUtil_LengthImpUtil
501 // ============================
502
503/// This component-private utility `struct` provides a namespace for a suite of
504/// functions used by `BerUtil` to implement BER length quantity encoding and
505/// decoding.
506///
507/// See @ref balber_berutil
509
510 // TYPES
511
512 /// `Constants` is an alias to a namespace for a suite of general-purpose
513 /// constants that occur when encoding or decoding BER data.
515
516 /// `RawIntegerUtil` is an alias to a namespace for a suite of functions
517 /// used to implement integer encoding.
519
520 private:
521 // PRIVATE TYPES
522 enum {
523 k_INDEFINITE_LENGTH = -1,
524 // constant used to indicate that a calculated length quantity is
525 // indefinite
526
527 k_INDEFINITE_LENGTH_OCTET = 0x80, // 0x80 = 0b1000'0000
528 // value of the (singular) length octet used to indicate that
529 // the length of a sequence of BER octets will be determined by
530 // seeking forward until and end-of-contents pair of octets is
531 // encountered
532
533 k_LONG_FORM_LENGTH_FLAG_MASK = 0x80, // 0x80 = 0b1000'0000
534 // mask used to determine if the higher-order bit of a length
535 // octet indicates that the next octet in the sequence is part of
536 // the VLQ-encoding of the length or if the current octet is the
537 // final octet of the length octets
538
539 k_LONG_FORM_LENGTH_VALUE_MASK = 0x7F // 0x7F = 0b0111'1111
540 // mask used to retrieve the bits of a non-final length octet
541 // that contribute to the BLQ-encoding of the length
542 };
543
544 public:
545 // CLASS METHODS
546
547 // Length Decoding Functions
548
549 /// Decode the length octets from the specified `streamBuf` and load the
550 /// result to the specified `result`. If the length is indefinite
551 /// (i.e., contents will be terminated by "end-of-content" octets) then
552 /// `result` will be set to `k_INDEFINITE_LENGTH`. Add the number of
553 /// bytes consumed to the specified `accumNumBytesConsumed`. Return 0
554 /// on success, and a non-zero value otherwise.
555 static int getLength(int *result,
556 int *accumNumBytesConsumed,
557 bsl::streambuf *streamBuf);
558
559 /// Decode the "end-of-content" octets (two consecutive zero-octets) from
560 /// the specified `streamBuf` and add the number of bytes consumed (which
561 /// is always 2) to the specified `accumNumBytesConsumed`. Return 0 on
562 /// success, and a non-zero value otherwise.
563 static int getEndOfContentOctets(int *accumNumBytesConsumed,
564 bsl::streambuf *streamBuf);
565
566 // Length Encoding Functions
567
568 /// Encode the specified `length` length octets to the specified
569 /// `streamBuf`. Return 0 on success, and a non-zero value otherwise.
570 ///
571 /// \pre The behavior is undefined unless `0 <= length`.
572 static int putLength(bsl::streambuf *streamBuf, int length);
573
574 /// Encode the "indefinite-length" octet onto the specified `streamBuf`.
575 /// This octet signifies that the length of the contents is indefinite
576 /// (i.e., contents will be terminated by end of content octets). Return 0
577 /// on success, and a non-zero value otherwise.
578 static int putIndefiniteLengthOctet(bsl::streambuf *streamBuf);
579
580 /// Encode the identifier octets for the specified `tagClass`, `tagType`
581 /// and `tagNumber` to the specified `streamBuf`. Return 0 on success, and
582 /// a non-zero value otherwise.
583 static int putEndOfContentOctets(bsl::streambuf *streamBuf);
584};
585
586 // =============================
587 // struct BerUtil_BooleanImpUtil
588 // =============================
589
590/// This component-private utility `struct` provides a namespace for a suite of
591/// functions used by `BerUtil` to implement BER encoding and decoding
592/// operations for boolean values. Within the definition of this `struct`:
593///
594/// * **the specification**:
595/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690.
596///
597/// See @ref balber_berutil
599
600 // TYPES
601
602 /// `LengthUtil` is an alias to a namespace for a suite of functions used
603 /// to implement BER encoding and decoding operations for length
604 /// quantities.
606
607 // CLASS METHODS
608
609 // Decoding
610
611 /// Decode to the specified `value` from the specified `streamBuf`,
612 /// consuming exactly the specified `length` bytes. Return 0 on success,
613 /// and a non-zero value otherwise. This operations succeeds if `length`
614 /// bytes are successfully read from the `streamBuf` and they contain a
615 /// valid representation of the contents octets for a BER-encoded boolean
616 /// value according to the specification.
617 static int getBoolValue(bool *value,
618 bsl::streambuf *streamBuf,
619 int length);
620
621 // Encoding
622
623 /// Encode the specified `value` to the specified `streamBuf`. Return 0 on
624 /// success and a non-zero value otherwise. The `value` is encoded as the
625 /// sequence of contents octets for a BER-encoded boolean value according
626 /// to the specification. This operation succeeds if all of the contents
627 /// octets are successfully written to the `streamBuf`.
628 static int putBoolValue(bsl::streambuf *streamBuf, bool value);
629};
630
631 // =============================
632 // struct BerUtil_IntegerImpUtil
633 // =============================
634
635/// This component-private utility `struct` provides a namespace for a suite
636/// of functions used by `BerUtil` to implement BER encoding and decoding
637/// operations for integer values. Within the definition of this `struct`:
638///
639/// * **the specification**:
640/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690.
641///
642/// See @ref balber_berutil
644
645 // TYPES
646
647 /// `Constants` is an alias to a namespace for a suite of
648 /// general-purpose constants that occur when encoding or decoding BER
649 /// data.
651
652 /// `LengthUtil` is an alias to a namespace for a suite of functions
653 /// used to implement BER encoding and decoding operations for length
654 /// quantities.
656
657 /// `RawIntegerUtil` is an alias to a namespace for a suite of low-level
658 /// functions used to implement BER encoding operations for integer
659 /// values.
661
662 /// `StreambufUtil` is an alias to a namespace for a suite of functions
663 /// used to implement input and output operations on `bsl::streambuf`
664 /// objects.
666
667 // CLASS DATA
668
669 /// Number of octets used to encode a signed integer value in 40 bits.
670 static const int k_40_BIT_INTEGER_LENGTH = 5;
671
672 // CLASS METHODS
673
674 /// Return the number of octets required to provide a BER encoding of
675 /// the specified `value` according to the specification.
676 static int getNumOctetsToStream(short value);
677 static int getNumOctetsToStream(int value);
678 static int getNumOctetsToStream(long long value);
679
680 /// Return the number of octets required to provide a BER encoding of the
681 /// specified `value` according to the specification. The program is
682 /// ill-formed unless the specified `INTEGRAL_TYPE` is a fundamental
683 /// integral type.
684 template <class INTEGRAL_TYPE>
685 static int getNumOctetsToStream(INTEGRAL_TYPE value);
686
687 /// Read the specified `length` number of bytes from the input sequence of
688 /// the specified `streamBuf` and load to the specified `value` the
689 /// interpretation of those bytes as the contents octets of a BER-encoded
690 /// integer value according to the specification. Return 0 if successful,
691 /// and a non-zero value otherwise.
692 static int getIntegerValue(long long *value,
693 bsl::streambuf *streamBuf,
694 int length);
695
696 /// Read the specified `length` number of bytes from the input sequence of
697 /// the specified `streamBuf` and load to the specified `value` the
698 /// interpretation of those bytes as the contents octets of BER-encoded
699 /// integer value according to the specification. Return 0 if successful,
700 /// and a non-zero value otherwise. The operation succeeds if `length`
701 /// bytes are successfully read from the input sequence of the `streamBuf`
702 /// without the read position becoming unavailable, and the bytes read
703 /// contain a valid representation of the contents octets of an integer
704 /// value according to the specification. The program is ill-formed unless
705 /// the specified `INTEGRAL_TYPE` is a fundamental integral type.
706 template <class INTEGRAL_TYPE>
707 static int getIntegerValue(INTEGRAL_TYPE *value,
708 bsl::streambuf *streamBuf,
709 int length);
710
711 /// Read 5 bytes from the input sequence of the specified `streamBuf`
712 /// and load to the specified `value` the interpretation of those bytes
713 /// as a 40-bit, signed, 2's-complement, big-endian integer. Return 0
714 /// if successful, and a non-zero value otherwise. The operation
715 /// succeeds if all 5 bytes are successfully read from the input
716 /// sequence of the `streamBuf` without the read position becoming
717 /// unavailable, and the bytes read contain a valid representation of a
718 /// 40-bit, signed, 2's-complement, big-endian integer.
720 bsl::streambuf *streamBuf);
721
722 /// Write the length and contents octets of the BER encoding of the
723 /// specified integer `value` (as defined in the specification) to the
724 /// output sequence of the specified `streamBuf`. Return 0 if successful,
725 /// and a non-zero value otherwise. The operation succeeds if all bytes
726 /// corresponding to the length and contents octets are written to the
727 /// `streamBuf` without the write position becoming unavailable. The
728 /// program is ill-formed unless the specified `INTEGRAL_TYPE` is a
729 /// fundamental integral type.
730 template <class INTEGRAL_TYPE>
731 static int putIntegerValue(bsl::streambuf *streamBuf, INTEGRAL_TYPE value);
732
733 /// Write the 5 octets that comprise the 40-bit, signed, 2's-complement,
734 /// bit-endian representation of the specified integer `value` to the
735 /// specified `streamBuf`. Return 0 if successful, and a non-zero value
736 /// otherwise. The operation succeeds if all bytes corresponding to the
737 /// representation of the `value` are written to the `streamBuf` without
738 /// the write position becoming unavailable.
739 ///
740 /// \pre The behavior is undefined unless the `value` is in the half-open interval
741 /// `[-549755813888, 549755813888)`.
742 static int put40BitIntegerValue(bsl::streambuf *streamBuf,
743 bsls::Types::Int64 value);
744
745 /// Write exactly the specified `length` number of contents octets of
746 /// the BER encoding of the specified integer `value` (as defined in the
747 /// specification) to the output sequence of the specified `streamBuf`.
748 /// Return 0 if successful, and a non-zero value otherwise. The
749 /// operation succeeds if all bytes corresponding to the contents octets
750 /// are written to the `streamBuf` without the write position becoming unavailable.
751 ///
752 /// \pre The behavior is undefined unless there are exactly
753 /// `length` number of contents octets used to encode the integer
754 /// `value` according to the specification. The program is ill-formed
755 /// unless the specified `INTEGRAL_TYPE` is a fundamental integral type.
756 template <class INTEGRAL_TYPE>
757 static int putIntegerGivenLength(bsl::streambuf *streamBuf,
758 INTEGRAL_TYPE value,
759 int length);
760};
761
762 // ===============================
763 // struct BerUtil_CharacterImpUtil
764 // ===============================
765
766/// This component-private utility `struct` provides a namespace for a suite
767/// of functions used by `BerUtil` to implement BER encoding and decoding
768/// operations for byte values. Within the definition of this `struct`:
769///
770/// * **the specification**:
771/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690.
772///
773/// See @ref balber_berutil
775
776 // TYPES
777
778 /// `IntegerUtil` is an alias to a namespace for a suite of functions used
779 /// to implement BER encoding and decoding operations for integer values.
781
782 /// `LengthUtil` is an alias to a namespace for a suite of functions used
783 /// to implement BER encoding and decoding operations for length
784 /// quantities.
786
787 // CLASS METHODS
788
789 // Decoding
790
791 /// Read the specified `length` number of bytes from the input sequence
792 /// of the specified `streamBuf` and load to the specified `value` the
793 /// interpretation of those bytes as the value of the contents octets of
794 /// a BER-encoded integer according to the specification. Return 0 if
795 /// successful, and a non-zero value otherwise. The operation succeeds
796 /// if `length` bytes are successfully read from the input sequence of
797 /// the `streamBuf` without the read position becoming unavailable, and
798 /// the bytes read contain a valid representation of the contents octets of an integer value according to the specification.
799 ///
800 /// \note Note that the
801 /// signedness of the interpreted integer value is the same as the
802 /// signedness of `char` according to the current platform.
803 static int getCharValue(char *value,
804 bsl::streambuf *streamBuf,
805 int length);
806
807 /// Read the specified `length` number of bytes from the input sequence
808 /// of the specified `streamBuf` and load to the specified `value` the
809 /// interpretation of those bytes as the value of the contents octets of
810 /// a BER-encoded integer according to the specification. Return 0 if
811 /// successful, and a non-zero value otherwise. The operation succeeds
812 /// if `length` bytes are successfully read from the input sequence of
813 /// the `streamBuf` without the read position becoming unavailable, and
814 /// the bytes read contain a valid representation of the contents octets
815 /// of an integer value according to the specification.
816 static int getSignedCharValue(signed char *value,
817 bsl::streambuf *streamBuf,
818 int length);
819
820 /// Read the specified `length` number of bytes from the input sequence
821 /// of the specified `streamBuf` and load to the specified `value` the
822 /// interpretation of those bytes as the value of the contents octets of
823 /// a BER-encoded integer according to the specification. Return 0 if
824 /// successful, and a non-zero value otherwise. The operation succeeds
825 /// if `length` bytes are successfully read from the input sequence of
826 /// the `streamBuf` without the read position becoming unavailable, and
827 /// the bytes read contain a valid representation of the contents octets
828 /// of an integer value according to the specification.
829 static int getUnsignedCharValue(unsigned char *value,
830 bsl::streambuf *streamBuf,
831 int length);
832
833 // Encoding
834
835 /// Write the length and contents octets of the BER encoding of the
836 /// specified integer `value` (as defined in the specification) to the
837 /// output sequence of the specified `streamBuf`. Return 0 if
838 /// successful, and a non-zero value otherwise. The operation succeeds
839 /// if all bytes corresponding to the length and contents octets are
840 /// written to the `streamBuf` without the write position becoming
841 /// unavailable.
842 static int putCharValue(bsl::streambuf *streamBuf, char value);
843
844 /// Write the length and contents octets of the BER encoding of the
845 /// specified integer `value` (as defined in the specification) to the
846 /// output sequence of the specified `streamBuf`. Return 0 if
847 /// successful, and a non-zero value otherwise. The operation succeeds
848 /// if all bytes corresponding to the length and contents octets are
849 /// written to the `streamBuf` without the write position becoming
850 /// unavailable.
851 static int putSignedCharValue(bsl::streambuf *streamBuf,
852 signed char value);
853
854 /// Write the length and contents octets of the BER encoding of the
855 /// specified integer `value` (as defined in the specification) to the
856 /// output sequence of the specified `streamBuf`. Return 0 if
857 /// successful, and a non-zero value otherwise. The operation succeeds
858 /// if all bytes corresponding to the length and contents octets are
859 /// written to the `streamBuf` without the write position becoming
860 /// unavailable.
861 static int putUnsignedCharValue(bsl::streambuf *streamBuf,
862 unsigned char value);
863};
864
865 // ===================================
866 // struct BerUtil_FloatingPointImpUtil
867 // ===================================
868
869/// This component-private utility `struct` provides a namespace for a suite
870/// of functions used by `BerUtil` to implement BER encoding and decoding
871/// operations for floating point number values. Within the definition of
872/// this `struct`:
873///
874/// * **the specification**:
875/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690
876///
877/// * **the floating point specification**:
878/// > Refers to the 2008 revision of the IEE 754 Standard for
879/// > Floating-Point Arithemtic.
880///
881/// See @ref balber_berutil
883
884 // TYPES
885
886 /// `IntegerUtil` is an alias to a namespace for a suite of functions
887 /// used to implement BER encoding and decoding operations for integer
888 /// values.
890
891 /// `LengthUtil` is an alias to a namespace for a suite of functions
892 /// used to implement BER encoding and decoding operations for length
893 /// quantities.
895
896 private:
897 // PRIVATE TYPES
898 enum {
899 k_MAX_MULTI_WIDTH_ENCODING_SIZE = 8,
900
901 k_BINARY_NEGATIVE_NUMBER_ID = 0xC0,
902 k_BINARY_POSITIVE_NUMBER_ID = 0x80,
903
904 k_REAL_BINARY_ENCODING = 0x80,
905
906 k_DOUBLE_EXPONENT_SHIFT = 52,
907 k_DOUBLE_OUTPUT_LENGTH = 10,
908 k_DOUBLE_EXPONENT_MASK_FOR_TWO_BYTES = 0x7FF,
909 k_DOUBLE_NUM_EXPONENT_BITS = 11,
910 k_DOUBLE_NUM_MANTISSA_BITS = 52,
911 k_DOUBLE_NUM_EXPONENT_BYTES = 2,
912 k_DOUBLE_NUM_MANTISSA_BYTES = 7,
913 k_DOUBLE_BIAS = 1023,
914
915 k_POSITIVE_ZERO_LEN = 0,
916 k_NEGATIVE_ZERO_LEN = 1,
917
918 k_POSITIVE_INFINITY_ID = 0x40,
919 k_NEGATIVE_INFINITY_ID = 0x41,
920 k_NAN_ID = 0x42,
921 k_NEGATIVE_ZERO_ID = 0x43,
922
923 k_DOUBLE_INFINITY_EXPONENT_ID = 0x7FF,
924 k_INFINITY_MANTISSA_ID = 0,
925
926 k_REAL_SIGN_MASK = 0x40, // 0x40 = 0b0100'0000
927 k_REAL_BASE_MASK = 0x20, // 0x20 = 0b0010'0000
928 k_REAL_SCALE_FACTOR_MASK = 0x0C, // 0x0C = 0b0000'1100
929 k_REAL_EXPONENT_LENGTH_MASK = 0x03, // 0x03 = 0b0000'0011
930
931 k_BER_RESERVED_BASE = 3,
932 k_REAL_BASE_SHIFT = 4,
933 k_REAL_SCALE_FACTOR_SHIFT = 2,
934
935 k_REAL_MULTIPLE_EXPONENT_OCTETS = 4
936 };
937
938 // PRIVATE CLASS METHODS
939
940 // Utilities
941
942 /// Load to the specified `value` the value of the "binary64" object
943 /// having the specified `exponent` value, the bits of the specified
944 /// `mantissa` interpreted as the digits of the mantissa, and the value
945 /// of the specified `sign` interpreted as the sign bit, according to the floating point specification.
946 ///
947 /// \pre The behavior is undefined unless
948 /// `exponent` is in the range `[-1023, 1023]`, `mantissa` is in the
949 /// range `[-9007199254740991, 9007199254740991]`, and `sign` is 0 or 1.
950 /// The program is ill-formed unless the platform uses the "binary64"
951 /// interchange format encoding defined in the floating point
952 /// specification as the object representation for `double` values.
953 static void assembleDouble(double *value,
954 long long exponent,
955 long long mantissa,
956 int sign);
957
958 /// Normalize the specified `*mantissa` value by adjusting the implicit
959 /// decimal point to after the rightmost 1 bit in the mantissa. If
960 /// `false == denormalized` prepend the implicit 1 in the mantissa
961 /// before adjusting the implicit decimal point. Multiply the
962 /// `*exponent` value by 2 to the power of the number of places the
963 /// implicit decimal point moves.
964 static void normalizeMantissaAndAdjustExp(long long *mantissa,
965 int *exponent,
966 bool denormalized);
967
968 /// Parse the specified `value` and populate the specified `exponent`,
969 /// `mantissa`, and `sign` values from the exponent, mantissa, and sign
970 /// of the `value`, respectively.
971 static void parseDouble(int *exponent,
972 long long *mantissa,
973 int *sign,
974 double value);
975
976 public:
977 // CLASS METHODS
978
979 // Decoding
980
981 /// Read the specified `length` number of bytes from the input sequence
982 /// of the specified `streamBuf` and load to the specified `value` the
983 /// interpretation of those bytes as the contents octets of a
984 /// BER-encoded real value according to the specification. Return 0 if
985 /// successful, and a non-zero value otherwise. The operation succeeds
986 /// if `length` bytes are successfully read from the input sequence of
987 /// the `streamBuf` without the read position becoming unavailable, and
988 /// the bytes read contain a valid representation of the contents octets
989 /// of a real value according to the specification.
990 static int getFloatValue(float *value,
991 bsl::streambuf *streamBuf,
992 int length);
993
994 /// Read the specified `length` number of bytes from the input sequence
995 /// of the specified `streamBuf` and load to the specified `value` the
996 /// interpretation of those bytes as the contents octets of a
997 /// BER-encoded real value according to the specification. Return 0 if
998 /// successful, and a non-zero value otherwise. The operation succeeds
999 /// if `length` bytes are successfully read from the input sequence of
1000 /// the `streamBuf` without the read position becoming unavailable, and
1001 /// the bytes read contain a valid representation of the contents octets
1002 /// of a real value according to the specification.
1003 static int getDoubleValue(double *value,
1004 bsl::streambuf *streamBuf,
1005 int length);
1006
1007 /// Read the specified `length` number of bytes from the input sequence
1008 /// of the specified `streamBuf` and load to the specified `value` the
1009 /// interpretation of those bytes as the contents octets of an encoded
1010 /// 64-bit decimal value. Return 0 if successful, and a non-zero value otherwise.
1011 ///
1012 /// \pre The behavior is undefined unless length is non-negative.
1013 /// The operation succeeds if `length` bytes are successfully read from the
1014 /// input sequence of the `streamBuf` without the read position becoming
1015 /// unavailable, and the bytes read contain a valid representation of the
1016 /// contents octets of an encoded 64-bit decimal value. See the
1017 /// package-level documentation of {`balber`} for the definition of the
1018 /// format used to encode 64-bit decimal values.
1020 bsl::streambuf *streamBuf,
1021 int length);
1022
1023 // Encoding
1024
1025 /// Write the length and contents octets of the BER encoding of the
1026 /// specified real `value` (as defined in the specification) to the
1027 /// output sequence of the specified `streamBuf`. Optionally specify
1028 /// `options`, which will indicate whether `-0.0f` will be preserved or
1029 /// encoded as `+0.0f`. Return 0 if successful, and a non-zero value
1030 /// otherwise. The operation succeeds if all bytes corresponding to the
1031 /// length and contents octets are written to the `streamBuf` without
1032 /// the write position becoming unavailable.
1033 static int putFloatValue(bsl::streambuf *streamBuf,
1034 float value,
1035 const BerEncoderOptions *options = 0);
1036
1037 /// Write the length and contents octets of the BER encoding of the
1038 /// specified real `value` (as defined in the specification) to the
1039 /// output sequence of the specified `streamBuf`. Optionally specify
1040 /// `options`, which will indicate whether `-0.0` will be preserved or
1041 /// encoded as `+0.0`. Return 0 if successful, and a non-zero value
1042 /// otherwise. The operation succeeds if all bytes corresponding to the
1043 /// length and contents octets are written to the `streamBuf` without
1044 /// the write position becoming unavailable.
1045 static int putDoubleValue(bsl::streambuf *streamBuf,
1046 double value,
1047 const BerEncoderOptions *options = 0);
1048
1049 /// Write the length and contents octets of the encoding of the BER
1050 /// encoding of the specified `value` to the output sequence of the
1051 /// specified `streamBuf`. Return 0 if successful, and a non-zero value
1052 /// otherwise. The operation succeeds if all bytes corresponding to the
1053 /// length and contents octets are written to the `streamBuf` without
1054 /// the write position becoming unavailable. See the package-level
1055 /// documentation of {`balber`} for the definition of the format used to
1056 /// encode 64-bit decimal values.
1057 static int putDecimal64Value(bsl::streambuf *streamBuf,
1058 bdldfp::Decimal64 value);
1059};
1060
1061 // ============================
1062 // struct BerUtil_StringImpUtil
1063 // ============================
1064
1065/// This component-private utility `struct` provides a namespace for a suite
1066/// of functions used by `BerUtil` to implement BER encoding and decoding
1067/// operations for string values. Within the definition of this `struct`:
1068///
1069/// * **the specification**:
1070/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690.
1071///
1072/// See @ref balber_berutil
1074
1075 // TYPES
1076
1077 /// `LengthUtil` is an alias to a namespace for a suite of functions used
1078 /// to implement BER encoding and decoding operations for length
1079 /// quantities.
1081
1082 public:
1083 // CLASS METHODS
1084
1085 // Utilities
1086
1087 /// Write the length and contents octets of the BER encoding of the
1088 /// specified byte `string` having the specified `stringLength` (as defined
1089 /// in the specification) to the output sequence of the specified
1090 /// `streamBuf`. Return 0 if successful, and a non-zero value otherwise.
1091 /// The operation succeeds if all bytes corresponding to the length and
1092 /// contents octets are written to the `streamBuf` without the write
1093 /// position becoming unavailable.
1094 static int putRawStringValue(bsl::streambuf *streamBuf,
1095 const char *string,
1096 int stringLength);
1097
1098 /// Write the specified `numChars` number of bytes having the specified
1099 /// `value` to the output sequence of the specified `streamBuf`. Return 0
1100 /// if successful, and a non-zero value otherwise. The operation succeeds
1101 /// if all `numChars` bytes are written to the `streamBuf` without the
1102 /// write position becoming unavailable.
1103 static int putChars(bsl::streambuf *streamBuf, char value, int numChars);
1104
1105 // 'bsl::string' Decoding
1106
1107 /// Read the specified `length` number of bytes from the input sequence of
1108 /// the specified `streamBuf` and load to the specified `value` the
1109 /// interpretation of those bytes as the value of the contents octets of a
1110 /// BER-encoded character string (more specifically, an unrestricted
1111 /// character string) according to the specification, unless an alternate
1112 /// value is indicated by the specified `options`, in which case, the
1113 /// alternate value is loaded. If the `DefaultEmptyStrings` attribute of
1114 /// the `options` is `true` and the witnessed BER-encoded character string
1115 /// represents the empty string value, the alternate value is the current
1116 /// `*value`, otherwise there is no alternate value. Return 0 if
1117 /// successful, and a non-zero value otherwise. The operation succeeds if
1118 /// `length` bytes are successfully read from the input sequence of the
1119 /// `streamBuf` without the read position becoming unavailable, and the
1120 /// bytes read contain a valid representation of the contents octets of a
1121 /// character string value according to the specification.
1122 static int getStringValue(bsl::string *value,
1123 bsl::streambuf *streamBuf,
1124 int length,
1125 const BerDecoderOptions& options);
1126
1127 // 'bsl::string' Encoding
1128
1129 /// Write the length and contents octets of the BER encoding of the
1130 /// specified character string `value` (as defined in the specification) to
1131 /// the output sequence of the specified `streamBuf`. Return 0 if
1132 /// successful, and a non-zero value otherwise. The operation succeeds if
1133 /// all bytes corresponding to the length and contents octets are written
1134 /// to the `streamBuf` without the write position becoming unavailable.
1135 static int putStringValue(bsl::streambuf *streamBuf,
1136 const bsl::string& value);
1137
1138 // 'bsl::string_view' Encoding
1139
1140 /// Write the length and contents octets of the BER encoding of the
1141 /// specified character string `value` (as defined in the specification) to
1142 /// the output sequence of the specified `streamBuf`. Return 0 if
1143 /// successful, and a non-zero value otherwise. The operation succeeds if
1144 /// all bytes corresponding to the length and contents octets are written
1145 /// to the `streamBuf` without the write position becoming unavailable.
1146 static int putStringViewValue(bsl::streambuf *streamBuf,
1147 const bsl::string_view& value);
1148
1149 // 'bslstl::StringRef' Encoding
1150
1151 /// Write the length and contents octets of the BER encoding of the
1152 /// specified character string `value` (as defined in the specification) to
1153 /// the output sequence of the specified `streamBuf`. Return 0 if
1154 /// successful, and a non-zero value otherwise. The operation succeeds if
1155 /// all bytes corresponding to the length and contents octets are written
1156 /// to the `streamBuf` without the write position becoming unavailable.
1157 static int putStringRefValue(bsl::streambuf *streamBuf,
1158 const bslstl::StringRef& value);
1159};
1160
1161 // =============================
1162 // struct BerUtil_Iso8601ImpUtil
1163 // =============================
1164
1165/// This component-private utility `struct` provides a namespace for a suite of
1166/// functions used by `BerUtil` to implement BER encoding and decoding
1167/// operations for date and time values in the ISO 8601 format. See the
1168/// component-level documentation of @ref bdlt_iso8601util for a complete
1169/// description of the ISO 8601 format used by the functions provided by this
1170/// `struct`.
1171///
1172/// See @ref balber_berutil
1174
1175 // TYPES
1176
1177 /// `StringUtil` is an alias to a namespace for a suite of functions used
1178 /// to implement BER encoder and decoding operations for string values.
1180
1181 private:
1182 // PRIVATE CLASS METHODS
1183
1184 /// Read the specified `length` number of bytes from the input sequence of
1185 /// the specified `streamBuf` and load to the specified `value` the value
1186 /// represented by the interpretation of the bytes as an ISO 8601 date/time
1187 /// value. The specified `TYPE` defines the expected ISO 8601 date/time
1188 /// format, which is the format corresponding to the `TYPE` as specified in
1189 /// @ref bdlt_iso8601util . The operation succeeds if `length` bytes are
1190 /// successfully read from the input sequence of the `streamBuf` without
1191 /// the read position becoming unavailable, and the bytes contain a valid
1192 /// representation of the expected ISO 8601 date/time format. The program
1193 /// is ill-formed unless `TYPE` is one of: `bdlt::Date`, `bdlt::DateTz`,
1194 /// `bdlt::Datetime`, `bdlt::DatetimeTz`, `bdlt::Time`, or `bdlt::TimeTz`.
1195 template <class TYPE>
1196 static int getValue(TYPE *value, bsl::streambuf *streamBuf, int length);
1197
1198 /// Write the ISO 8601 representation of the specified `value` to the
1199 /// output sequence of the specified `streamBuf`. If the specified
1200 /// `options` is 0, use 3 decimal places of fractional second precision,
1201 /// otherwise use the number of decimal places specified by the
1202 /// `datetimeFractionalSecondPrecision` attribute of the `options`. Return
1203 /// 0 on success and a non-zero value otherwise. The operation succeeds if
1204 /// all bytes of the ISO 8601 representation of the `value` are written to
1205 /// the `streamBuf` without the write position becoming unavailable. The
1206 /// program is ill-formed unless `TYPE` is one of `bdlt::Date`,
1207 /// `bdlt::DateTz`, `bdlt::Datetime`, `bdlt::DatetimeTz`, `bdlt::Time`, or
1208 /// `bdlt::TimeTz`.
1209 template <class TYPE>
1210 static int putValue(bsl::streambuf *streamBuf,
1211 const TYPE& value,
1212 const BerEncoderOptions *options);
1213
1214 public:
1215 // CLASS METHODS
1216
1217 // Decoding
1218
1219 /// Read the specified `length` number of bytes from the input sequence of
1220 /// the specified `streamBuf` and load to the specified `value` the date
1221 /// value represented by the interpretation of the read bytes as an ISO
1222 /// 8601 date. Return 0 on success, and a non-zero value otherwise. The
1223 /// operation succeeds if `length` bytes are successfully read from the
1224 /// input sequence of the `streamBuf` without the read position becoming
1225 /// unavailable, and the bytes contain a valid representation of an ISO
1226 /// 8601 date.
1227 static int getDateValue(bdlt::Date *value,
1228 bsl::streambuf *streamBuf,
1229 int length);
1230
1231 /// Read the specified `length` number of bytes from the input sequence of
1232 /// the specified `streamBuf` and load to the specified `value` the date
1233 /// value represented by the interpretation of the read bytes as an ISO
1234 /// 8601 date and time zone. Return 0 on success, and a non-zero value
1235 /// otherwise. The operation succeeds if `length` bytes are successfully
1236 /// read from the input sequence of the `streamBuf` without the read
1237 /// position becoming unavailable, and the bytes contain a valid
1238 /// representation of an ISO 8601 date and time zone.
1239 static int getDateTzValue(bdlt::DateTz *value,
1240 bsl::streambuf *streamBuf,
1241 int length);
1242
1243 /// Read the specified `length` number of bytes from the input sequence
1244 /// of the specified `streamBuf` and load to the specified `value` the
1245 /// date value represented by the interpretation of the read bytes as an
1246 /// ISO 8601 date and time. Return 0 on success, and a non-zero value
1247 /// otherwise. The operation succeeds if `length` bytes are
1248 /// successfully read from the input sequence of the `streamBuf` without
1249 /// the read position becoming unavailable, and the bytes contain a
1250 /// valid representation of an ISO 8601 date and time.
1252 bsl::streambuf *streamBuf,
1253 int length);
1254
1255 /// Read the specified `length` number of bytes from the input sequence of
1256 /// the specified `streamBuf` and load to the specified `value` the date
1257 /// value represented by the interpretation of the read bytes as an ISO
1258 /// 8601 date, time, and time zone. Return 0 on success, and a non-zero
1259 /// value otherwise. The operation succeeds if `length` bytes are
1260 /// successfully read from the input sequence of the `streamBuf` without
1261 /// the read position becoming unavailable, and the bytes contain a valid
1262 /// representation of an ISO 8601 date, time, and time zone.
1264 bsl::streambuf *streamBuf,
1265 int length);
1266
1267 /// Read the specified `length` number of bytes from the input sequence of
1268 /// the specified `streamBuf` and load to the specified `value` the date
1269 /// value represented by the interpretation of the read bytes as an ISO
1270 /// 8601 time. Return 0 on success, and a non-zero value otherwise. The
1271 /// operation succeeds if `length` bytes are successfully read from the
1272 /// input sequence of the `streamBuf` without the read position becoming
1273 /// unavailable, and the bytes contain a valid representation of an ISO
1274 /// 8601 time.
1275 static int getTimeValue(bdlt::Time *value,
1276 bsl::streambuf *streamBuf,
1277 int length);
1278
1279 /// Read the specified `length` number of bytes from the input sequence of
1280 /// the specified `streamBuf` and load to the specified `value` the date
1281 /// value represented by the interpretation of the read bytes as an ISO
1282 /// 8601 time and time zone. Return 0 on success, and a non-zero value
1283 /// otherwise. The operation succeeds if `length` bytes are successfully
1284 /// read from the input sequence of the `streamBuf` without the read
1285 /// position becoming unavailable, and the bytes contain a valid
1286 /// representation of an ISO 8601 time and time zone.
1287 static int getTimeTzValue(bdlt::TimeTz *value,
1288 bsl::streambuf *streamBuf,
1289 int length);
1290
1291 // Encoding
1292
1293 /// Write the ISO 8601 representation of the specified `value` to the
1294 /// output sequence of the specified `streamBuf`. Return 0 on success and
1295 /// a non-zero value otherwise. The operation succeeds if all bytes of the
1296 /// ISO 8601 representation of the `value` are written to the `streamBuf`
1297 /// without the write position becoming unavailable.
1298 static int putDateValue(bsl::streambuf *streamBuf,
1299 const bdlt::Date& value,
1300 const BerEncoderOptions *options);
1301
1302 /// Write the ISO 8601 representation of the specified `value` to the
1303 /// output sequence of the specified `streamBuf`. Return 0 on success and
1304 /// a non-zero value otherwise. The operation succeeds if all bytes of the
1305 /// ISO 8601 representation of the `value` are written to the `streamBuf`
1306 /// without the write position becoming unavailable.
1307 static int putDateTzValue(bsl::streambuf *streamBuf,
1308 const bdlt::DateTz& value,
1309 const BerEncoderOptions *options);
1310
1311 /// Write the ISO 8601 representation of the specified `value` to the
1312 /// output sequence of the specified `streamBuf`. If the specified
1313 /// `options` is 0, use 3 decimal places of fractional second precision,
1314 /// otherwise use the number of decimal places specified by the
1315 /// `datetimeFractionalSecondPrecision` attribute of the `options`. Return
1316 /// 0 on success and a non-zero value otherwise. The operation succeeds if
1317 /// all bytes of the ISO 8601 representation of the `value` are written to
1318 /// the `streamBuf` without the write position becoming unavailable.
1319 static int putDatetimeValue(bsl::streambuf *streamBuf,
1320 const bdlt::Datetime& value,
1321 const BerEncoderOptions *options);
1322
1323 /// Write the ISO 8601 representation of the specified `value` to the
1324 /// output sequence of the specified `streamBuf`. If the specified
1325 /// `options` is 0, use 3 decimal places of fractional second precision,
1326 /// otherwise use the number of decimal places specified by the
1327 /// `datetimeFractionalSecondPrecision` attribute of the `options`. Return
1328 /// 0 on success and a non-zero value otherwise. The operation succeeds if
1329 /// all bytes of the ISO 8601 representation of the `value` are written to
1330 /// the `streamBuf` without the write position becoming unavailable.
1331 static int putDatetimeTzValue(bsl::streambuf *streamBuf,
1332 const bdlt::DatetimeTz& value,
1333 const BerEncoderOptions *options);
1334
1335 /// Write the ISO 8601 representation of the specified `value` to the
1336 /// output sequence of the specified `streamBuf`. If the specified
1337 /// `options` is 0, use 3 decimal places of fractional second precision,
1338 /// otherwise use the number of decimal places specified by the
1339 /// `datetimeFractionalSecondPrecision` attribute of the `options`. Return
1340 /// 0 on success and a non-zero value otherwise. The operation succeeds if
1341 /// all bytes of the ISO 8601 representation of the `value` are written to
1342 /// the `streamBuf` without the write position becoming unavailable.
1343 static int putTimeValue(bsl::streambuf *streamBuf,
1344 const bdlt::Time& value,
1345 const BerEncoderOptions *options);
1346
1347 /// Write the ISO 8601 representation of the specified `value` to the
1348 /// output sequence of the specified `streamBuf`. If the specified
1349 /// `options` is 0, use 3 decimal places of fractional second precision,
1350 /// otherwise use the number of decimal places specified by the
1351 /// `datetimeFractionalSecondPrecision` attribute of the `options`. Return
1352 /// 0 on success and a non-zero value otherwise. The operation succeeds if
1353 /// all bytes of the ISO 8601 representation of the `value` are written to
1354 /// the `streamBuf` without the write position becoming unavailable.
1355 static int putTimeTzValue(bsl::streambuf *streamBuf,
1356 const bdlt::TimeTz& value,
1357 const BerEncoderOptions *options);
1358};
1359
1360 // ====================================
1361 // struct BerUtil_TimezoneOffsetImpUtil
1362 // ====================================
1363
1364/// This component-private utility `struct` provides a namespace for a suite of
1365/// functions and constants used by `BerUtil` to encode and decode time-zone
1366/// values.
1367///
1368/// See @ref balber_berutil
1370
1371 // TYPES
1372 enum {
1374 // The minimum number of minutes in a valid time-zone offset
1375
1377 // The maximum number of minutes in a valid time-zone offset
1378
1380 // The number of octets used in the encoding of a time-zone offset
1381 // value. This number is constant: all time-zone values are
1382 // encoded using 2 octets regardless of numeric value.
1384
1385 // CLASS METHODS
1386
1387 /// Return `true` if the specified `value` is a valid time-zone offset, and
1388 /// return `false` otherwise. A time-zone offset is valid if it is greater
1389 /// than or equal to `k_MIN_OFFSET` and less than or equal to
1390 /// `k_MAX_OFFSET`.
1391 static bool isValidTimezoneOffsetInMinutes(int value);
1392
1393 /// Read from the specified `streamBuf` and load to the specified `value`
1394 /// of the time-zone offset.
1395 static int getTimezoneOffsetInMinutes(int *value,
1396 bsl::streambuf *streamBuf);
1397
1398 /// Read a time zone offset value from the specified `streamBuf`. If the
1399 /// offset is greater than or equal to `k_MIN_OFFSET` and less than or
1400 /// equal to `k_MAX_OFFSET` then load the value of the offset to the
1401 /// specified `value` and return zero, otherwise do not modify the value
1402 /// addressed by `value` and return non-zero.
1404 bsl::streambuf *streamBuf);
1405
1406 /// Write to the specified `streamBuf` the value of the specified time-zone offset `value`.
1407 ///
1408 /// \pre The behavior is undefined unless
1409 /// `k_MIN_OFFSET <= value` and `value <= k_MAX_OFFSET`.
1410 static int putTimezoneOffsetInMinutes(bsl::streambuf *streamBuf,
1411 int value);
1412};
1413
1414 // ==================================
1415 // struct BerUtil_DateAndTimeEncoding
1416 // ==================================
1417
1418/// This component-private `struct` provides a namespace for enumerating the
1419/// union of the sets of date and time formats used to encode and decode all
1420/// date and time types supported by `BerUtil`.
1421///
1422/// See @ref balber_berutil
1453
1454 // =========================================
1455 // struct BerUtil_ExtendedBinaryEncodingUtil
1456 // =========================================
1457
1458/// This component-private utility `struct` provides a namespace for a suite of
1459/// functions used by `BerUtil` to determine if a particular date and/or time
1460/// value should be encoded using its corresponding extended-binary-encoding
1461/// format, its corresponding compact-binary-encoding format, or neither
1462/// format.
1463///
1464/// See @ref balber_berutil
1466
1467 // TYPES
1468
1469 /// `Encoding` is an alias to a namespace for enumerating the union of the
1470 /// sets of date and time formats used to encode and decode all date and
1471 /// time types supported by `BerUtil`.
1473
1474 // CLASS METHODS
1475
1476 /// Return `true` if the specified `value` must be encoded using its
1477 /// corresponding extended-binary-encoding format according to the
1478 /// specified `options`, and return `false` otherwise.
1479 static bool useExtendedBinaryEncoding(const bdlt::Time& value,
1480 const BerEncoderOptions *options);
1481 static bool useExtendedBinaryEncoding(const bdlt::TimeTz& value,
1482 const BerEncoderOptions *options);
1483 static bool useExtendedBinaryEncoding(const bdlt::Datetime& value,
1484 const BerEncoderOptions *options);
1485 static bool useExtendedBinaryEncoding(const bdlt::DatetimeTz& value,
1486 const BerEncoderOptions *options);
1487
1488 /// Return `true` if a date and/or time value must be encoded using
1489 /// either its corresponding extended-binary-encoding format or its
1490 /// corresponding compact-binary-encoding format according to the specified `options`, and return `false` otherwise.
1491 ///
1492 /// \note Note that, for
1493 /// any given `value` and `options`, the `value` must be encoded using
1494 /// its corresponding compact-binary-encoding format if
1495 /// `useExtendedBinaryEncoding(value, options)` returns `false` and
1496 /// `useBinaryEncoding(options)` returns `true`.
1497 static bool useBinaryEncoding(const BerEncoderOptions *options);
1498};
1499
1500 // ====================================
1501 // struct BerUtil_DateAndTimeHeaderType
1502 // ====================================
1503
1504/// This component-private `struct` provides a namespace for enumerating the
1505/// set of "header type" values that may be encoded in the 2-byte header of
1506/// an extended-binary-encoding formatted date-and-time value.
1507///
1508/// See @ref balber_berutil
1510
1511 // TYPES
1512 enum Value {
1514 // header-type value that indicates the encoded value is in either
1515 // its corresponding compact-binary encoding or its corresponding
1516 // ISO 8601 encoding
1517
1519 // header-type value that indicates the encoded value is in its
1520 // corresponding extended-binary encoding and does not carry a
1521 // time-zone offset value
1522
1524 // header-type value that indicates the encoded value is in its
1525 // corresponding extended-binary encoding and carries a time-zone
1526 // offset value
1528};
1529
1530 // ===============================
1531 // class BerUtil_DateAndTimeHeader
1532 // ===============================
1533
1534/// This component-private, in-core, value-semantic attribute class provides
1535/// a representation of the information available in the first two bytes of
1536/// any extended-binary-encoding formatted data. All extended-binary
1537/// encoding schemes for date-and-time types contain a 2-byte header in the
1538/// same format, which can be unambiguously distinguished from the first 2
1539/// bytes of a date-and-time type in its corresponding
1540/// compact-binary-encoding format or its ISO 8601 format.
1541///
1542/// See @ref balber_berutil
1544
1545 public:
1546 // TYPES
1547
1548 /// `Type` is an alias to a namespace for enumerating the set of "header
1549 /// type" values that may be encoded in the 2-byte header of an
1550 /// extended-binary-encoding formatted date-and-time value.
1552
1553 /// `TimezoneUtil` is an alias to a namespace for a suite of functions
1554 /// used to implement BER encoding and decoding operations for time-zone
1555 /// offset values.
1557
1558 private:
1559 // DATA
1560
1561 // date-and-time header type
1562 Type::Value d_type;
1563
1564 // offset in minutes from UTC indicated by the date-and-time header if
1565 // the header contains a time-zone offset, and 0 otherwise
1566 int d_timezoneOffsetInMinutes;
1567
1568 public:
1569 // CREATORS
1570
1571 /// Create a `BerUtil_DateAndTimeHeader` object having a `type`
1572 /// attribute with the `Type::e_NOT_EXTENDED_BINARY` value and a
1573 /// `timezoneOffsetInMinutes` attribute with the 0 value.
1575
1576 /// Create a 'BerUtil_DateAndTimeHeader' object having the same value as
1577 /// the specified 'original' object.
1579 const BerUtil_DateAndTimeHeader& original) = default;
1580
1581 /// Destroy this object.
1583
1584 // MANIPULATORS
1585
1586 /// Assign to this object the value of the specified 'rhs' object, and
1587 /// return a non-'const' reference to this object.
1590
1591 /// Set the `type` attribute of this object to the
1592 /// `Type::e_NOT_EXTENDED_BINARY` value and the
1593 /// `timezoneOffsetInMinutes` attribute of this object to the 0 value.
1594 void makeNotExtendedBinary();
1595
1596 /// Set the `type` attribute of this object to the
1597 /// `Type::e_EXTENDED_BINARY_WITHOUT_TIMEZONE` value and the
1598 /// `timezoneOffsetInMinutes` attribute of this object to the 0 value.
1600
1601 /// Set the `type` attribute of this object to the
1602 /// `Type::e_EXTENDED_BINARY_WITH_TIMEZONE` value and the
1603 /// `timezoneOffsetInMinutes` attribute of this object to the specified `offset`.
1604 ///
1605 /// \pre The behavior is undefined unless
1606 /// `TimezoneUtil::k_MIN_OFFSET <= offset` and
1607 /// `TimezoneUtil::k_MAX_OFFSET >= offset`.
1608 void makeExtendedBinaryWithTimezone(int offset);
1609
1610 // ACCESSORS
1611
1612 /// Return `true` if the `type` attribute of this object is
1613 /// `Type::e_EXTENDED_BINARY_WITH_TIMEZONE` or
1614 /// `Type::e_EXTENDED_BINARY_WITHOUT_TIMEZONE`, and `false` otherwise.
1615 bool isExtendedBinary() const;
1616
1617 /// Return `true` if the `type` attribute of this object is
1618 /// `Type::e_EXTENDED_BINARY_WITHOUT_TIMEZONE`, and `false` otherwise.
1620
1621 /// Return `true` if the `type` attribute of this object is
1622 /// `Type::e_EXTENDED_BINARY_WITH_TIMEZONE`, and `false` otherwise.
1623 bool isExtendedBinaryWithTimezone() const;
1624
1625 /// Return the value of the `timezoneOffsetInMinutes` attribute of this
1626 /// object.
1627 int timezoneOffsetInMinutes() const;
1628};
1629
1630 // =======================================
1631 // struct BerUtil_DateAndTimeHeaderImpUtil
1632 // =======================================
1633
1634/// This component-private utility `struct` provides a namespace for a suite
1635/// of functions used by `BerUtil` to implement encoding and decoding
1636/// operations for the 2-byte header of extended-binary-encoding formatted
1637/// date-and-time value.
1638///
1639/// See @ref balber_berutil
1641
1642 // TYPES
1643
1644 /// `Header` is an alias to an in-core, value-semantic attribute class
1645 /// that represents the range of valid values of the 2-byte header of
1646 /// extended-binary-encoding formatted date-and-time values.
1648
1649 /// `Type` is an alias to a namespace for enumerating the set of "header
1650 /// type" values that may be encoded in the 2-byte header of an
1651 /// extended-binary-encoding formatted date-and-time value.
1653
1654 /// `StreambufUtil` is an alias to a namespace for a suite of functions
1655 /// used to implement input and output operations on `bsl::streambuf`
1656 /// objects.
1658
1659 /// `TimezoneUtil` is an alias to a namespace for a suite of functions
1660 /// used to implement BER encoding and decoding operations for time-zone
1661 /// offset values.
1663
1664 // CLASS DATA
1665
1666 /// Number of octets used to encode an extended-binary-encoding header.
1667 static const int k_HEADER_LENGTH = 2;
1668
1669 // CLASS METHODS
1670
1671 /// Return `true` if the specified `firstByte` of an encoded
1672 /// date-and-time value indicates it is in a format reserved for future use, and return `false` otherwise.
1673 ///
1674 /// \note Note that this may indicate the
1675 /// value was encoded incorrectly or using a newer version of this
1676 /// component.
1677 static bool isReserved(unsigned char firstByte);
1678
1679 /// Return `true` if the specified `firstByte` of an encoded
1680 /// date-and-time value indicates it is in the extended-binary-encoding
1681 /// format, and return `false` otherwise.
1682 static bool isExtendedBinary(unsigned char firstByte);
1683
1684 /// Return `true` if the specified `firstByte` of an encoded
1685 /// date-and-time value indicates it is in the extended-binary-encoding
1686 /// format and does not carry a time-zone offset value, and return
1687 /// `false` otherwise.
1688 static bool isExtendedBinaryWithoutTimezone(unsigned char firstByte);
1689
1690 /// Return `true` if the specified `firstByte` if an encoded
1691 /// date-and-time value indicates is is in the extended-binary-encoding
1692 /// format and carries a time-zone offset value, and return `false`
1693 /// otherwise.
1694 static bool isExtendedBinaryWithTimezone(unsigned char firstByte);
1695
1696 /// If the specified `firstByte` of an encoded date-and-time value
1697 /// indicates it is in a compact-binary-encoding format or an ISO 8601
1698 /// format, load the value `Type::e_NOT_EXTENDED_BINARY` to the
1699 /// specified `type` and `false` to the specified `reserved` flag. If
1700 /// it indicates it is in an extended-binary format that carries a
1701 /// time-zone offset value, load the value
1702 /// `Type::e_EXTENDED_BINARY_WITH_TIMEZONE` to the `type` and `false` to
1703 /// `reserved`. If it indicates it is in an extended-binary format that
1704 /// does not carry a time-zone offset value, load the value
1705 /// `Type::e_EXTENDED_BINARY_WITHOUT_TIMEZONE` to the `type` and `false`
1706 /// to `reserved`. Otherwise, load the value `true` to `reserved` and leave the `type` in a valid but unspecified state.
1707 ///
1708 /// \note Note that this
1709 /// operation has a wide contract because all possible values of
1710 /// `firstByte` can be interpreted to indicate one of the conditions
1711 /// described above.
1712 static void detectTypeIfNotReserved(bool *reserved,
1713 Type::Value *type,
1714 unsigned char firstByte);
1715
1716 /// If the specified `firstByte` of an encoded date-and-time value
1717 /// indicates it is in a compact-binary-encoding format or an ISO 8601
1718 /// format, load the value `Type::e_NOT_EXTENDED_BINARY` to the
1719 /// specified `type`. If it indicates it is in an extended-binary
1720 /// format that carries a time-zone offset value, load the value
1721 /// `Type::e_EXTENDED_BINARY_WITH_TIMEZONE` to the `type`. If it
1722 /// indicates it is in an extended-binary format that does not carry a
1723 /// time-zone offset value, load the value
1724 /// `Type::e_EXTENDED_BINARY_WITHOUT_TIMEZONE` to the `type`.
1725 ///
1726 /// \pre The behavior is undefined unless `isReserved(firstByte)` returns
1727 /// `false`.
1728 static void detectType(Type::Value *type, unsigned char firstByte);
1729
1730 /// Read 2 bytes from the input sequence of the specified `streamBuf`
1731 /// and load to the specified `value` the interpretation of those bytes
1732 /// as an extended-binary header value, if that header indicates the
1733 /// value is not in a format reserved for future use. Return 0 on
1734 /// success, and a non-zero value otherwise.
1735 static int getValueIfNotReserved(Header *value, bsl::streambuf *streamBuf);
1736
1737 /// Load to the specified `value` the interpretation of the specified
1738 /// `headerByte0` and `headerByte1` as the 2 bytes that comprise an
1739 /// encoded extended-binary header value if that value indicates it is
1740 /// not in a format reserved for future use. Return 0 on success, and a
1741 /// non-zero value otherwise.
1742 static int getValueIfNotReserved(Header *value,
1743 unsigned char headerByte0,
1744 unsigned char headerByte1);
1745
1746 /// Read 2 bytes from the input sequence of the specified `streamBuf`
1747 /// and load to the specified `value` the interpretation of those bytes
1748 /// as an extended-binary header value Return 0 on success, and a non-zero value otherwise.
1749 ///
1750 /// \pre The behavior is undefined if 2 bytes are
1751 /// successfully read from the `streamBuf`, but the interpretation of
1752 /// those bytes as an extended-binary header indicates the value is in a
1753 /// format reserved for future use.
1754 static int getValue(Header *value, bsl::streambuf *streamBuf);
1755
1756 /// Load to the specified `value` the interpretation of the specified
1757 /// `headerByte0` and `headerByte1` as the 2 bytes that comprise an
1758 /// encoded extended-binary header value. Return 0 on success, and a non-zero value otherwise.
1759 ///
1760 /// \pre The behavior is undefined if the
1761 /// interpretation of the 2 bytes as an extended-binary header indicates
1762 /// the value is in a format reserved for future use.
1763 static int getValue(Header *value,
1764 unsigned char headerByte0,
1765 unsigned char headerByte1);
1766
1767 /// Write a representation of an extended-binary header value that does
1768 /// not carry a time-zone offset value to the specified `streamBuf`.
1769 /// Return 0 on success, and a non-zero value otherwise.
1771 bsl::streambuf *streamBuf);
1772
1773 /// Write a representation of an extended-binary header value that
1774 /// carries the specified `timezoneOffsetInMinutes` time-zone offset
1775 /// value to the specified `streamBuf`. Return 0 on success, and a
1776 /// non-zero value otherwise.
1778 bsl::streambuf *streamBuf,
1779 int timezoneOffsetInMinutes);
1780};
1781
1782 // ===========================
1783 // struct BerUtil_DateEncoding
1784 // ===========================
1785
1786/// This component-private `struct` provides a namespace for enumerating the
1787/// set of formats that may be used by `BerUtil` to encode and decode values
1788/// of `bdlt::Date` type.
1789///
1790/// See @ref balber_berutil
1792
1793 // TYPES
1794
1795 /// `Encoding` is an alias to a namespace for enumerating the union of
1796 /// the sets of date and time formats used to encode and decode all date
1797 /// and time types supported by `BerUtil`.
1799
1804};
1805
1806 // =============================
1807 // struct BerUtil_DateTzEncoding
1808 // =============================
1809
1810/// This component-private `struct` provides a namespace for enumerating the
1811/// set of formats that may be used by `BerUtil` to encode and decode values
1812/// of `bdlt::DateTz` type.
1813///
1814/// See @ref balber_berutil
1816
1817 // TYPES
1818
1819 /// `Encoding` is an alias to a namespace for enumerating the union of
1820 /// the sets of date and time formats used to encode and decode all date
1821 /// and time types supported by `BerUtil`.
1823
1829};
1830
1831 // ===================================
1832 // struct BerUtil_DateOrDateTzEncoding
1833 // ===================================
1834
1835/// This component-private `struct` provides a namespace for enumerating the
1836/// set of formats that may be used by `BerUtil` to encode and decode values
1837/// of `bdlb::Variant2<bdlt::Date, bdlt::DateTz>` type.
1838///
1839/// See @ref balber_berutil
1841
1842 // TYPES
1843
1844 /// `Encoding` is an alias to a namespace for enumerating the union of
1845 /// the sets of date and time formats used to encode and decode all date
1846 /// and time types supported by `BerUtil`.
1848
1855};
1856
1857 // ==========================
1858 // struct BerUtil_DateImpUtil
1859 // ==========================
1860
1861/// This component-private `struct` provides a namespace for a suite of
1862/// functions used by `BerUtil` to implement BER encoding and decoding
1863/// operations for date values. Within the definition of this `struct`:
1864///
1865/// * **the specification**:
1866/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690.
1867///
1868/// * **the default set of options**:
1869/// > Refers to a `balber::BerEncoderOptions` value having a
1870/// > `datetimeFractionalSecondPrecision` attribute of 3 and a
1871/// > `encodeDateAndTimeTypesAsBinary` attribute of `false`.
1872///
1873/// See the package level documentation of `balber` for a definition of the
1874/// compact and extended binary formats for date and time values.
1875///
1876/// See @ref balber_berutil
1878
1879 // TYPES
1880
1881 /// `DateAndTimeHeaderUtil` is an alias to a namespace for a suite of
1882 /// functions used to implement encoding and decoding operations for the
1883 /// 2-byte header of an extended-binary-encoding formatted date-and-time
1884 /// value.
1886
1887 /// `DateEncoding` is an alias to a namespace for enumerating the set of
1888 /// formats that may be used by `BerUtil` to encode and decode values of
1889 /// `bdlt::Date` type.
1891
1892 /// `DateEncoding` is an alias to a namespace for enumerating the set of
1893 /// formats that may be used by `BerUtil` to encode and decode values of
1894 /// `bdlt::DateTz` type.
1896
1897 /// `DateEncoding` is an alias to a namespace for enumerating the set of
1898 /// formats that may be used by `BerUtil` to decode to values of
1899 /// `bdlb::Variant2<bdlt::Date, bdlt::DateTz>` type.
1901
1902 /// `IntegerUtil` is an alias to a namespace for a suite of functions
1903 /// used to implement BER encoding and decoding operations for integer
1904 /// values.
1906
1907 /// `Iso8601Util` is an alias to a namespace for a suite of functions
1908 /// used to implementing the encoding and decoding of date and time
1909 /// values using the ISO 8601 format.
1911
1912 /// `LengthUtil` is an alias to a namespace for a suite of functions
1913 /// used to implement BER encoding and decoding operations for length
1914 /// quantities.
1916
1917 /// `StreambufUtil` is an alias to a namespace for a suite of functions
1918 /// used to implement input and output operations on `bsl::streambuf`
1919 /// objects.
1921
1922 /// `StringUtil` is an alias to a namespace for a suite of functions
1923 /// used by `BerUtil` to implement BER encoding and decoding operations
1924 /// for string values.
1926
1927 /// `TimezoneUtil` is an alias to a namespace for a suite of functions
1928 /// used to implement BER encoding and decoding operations for time-zone
1929 /// offset values.
1931
1932 /// `DateOrDateTz` is a convenient alias for
1933 /// `bdlb::Variant2<bdlt::Date, bdlt::DateTz>`.
1935
1936 enum {
1938 // The serial date of January 1st, 2020. Note that the serial date
1939 // of a date is defined as the number of days between that date and
1940 // January 1st year 1 in the Proleptic Gregorian calendar.
1942
1943 private:
1944 // PRIVATE TYPES
1945 enum {
1946 k_MAX_ISO8601_DATE_LENGTH = bdlt::Iso8601Util::k_DATE_STRLEN,
1947 // the maximum number of content octets used by 'BerUtil' to encode
1948 // a date value using the ISO 8601 format
1949
1950 k_MAX_ISO8601_DATETZ_LENGTH = bdlt::Iso8601Util::k_DATETZ_STRLEN,
1951 // the maximum number of content octets used by 'BerUtil' to
1952 // encode a date and time zone value using the ISO 8601 format
1953
1954 k_MAX_COMPACT_BINARY_DATE_LENGTH = 3,
1955 // the maximum number of content octets used by 'BerUtil' to
1956 // encode a date value using the compact-binary format
1957
1958 k_MIN_COMPACT_BINARY_DATETZ_LENGTH =
1959 k_MAX_COMPACT_BINARY_DATE_LENGTH + 1,
1960 // the minimum number of content octets used by 'BerUtil' to
1961 // encode a date and time zone value using the compact-binary
1962 // format
1963
1964 k_MAX_COMPACT_BINARY_DATETZ_LENGTH = 5
1965 // the maximum number of content octets used by 'BerUtil' to
1966 // encode a date and time zone value using the compact-binary
1967 // format
1968 };
1969
1970 // PRIVATE CLASS METHODS
1971
1972 // 'bdlt::Date' Decoding
1973
1974 /// Load to the specified `encoding` the enumerator that describes the
1975 /// format used to encode a `bdlt::Date` value given the specified
1976 /// `length` and `firstByte` of the encoded representation. Return 0 on
1977 /// success, -1 if the format is reserved for future use, and some other
1978 /// non-zero value otherwise.
1979 static int detectDateEncoding(DateEncoding::Value *encoding,
1980 int length,
1981 unsigned char firstByte);
1982
1983 /// Read the specified `length` number of bytes from the input sequence
1984 /// of the specified `streamBuf` and load to the specified `value` the
1985 /// date value represented by the interpretation of the read bytes as an
1986 /// ISO 8601 date. Return 0 on success, and a non-zero value otherwise.
1987 /// The operation succeeds if `length` bytes are successfully read from
1988 /// the input sequence of the `streamBuf` without the read position
1989 /// becoming unavailable, and the bytes contain a valid representation
1990 /// of an ISO 8601 date.
1991 static int getIso8601DateValue(bdlt::Date *value,
1992 bsl::streambuf *streamBuf,
1993 int length);
1994
1995 /// Read the specified `length` number of bytes from the input sequence
1996 /// of the specified `streamBuf` and load to the specified `value` the
1997 /// date value represented by the interpretation of the read bytes as a
1998 /// compact-binary date. Return 0 on success, and a non-zero value
1999 /// otherwise. The operation succeeds if `length` bytes are
2000 /// successfully read from the input sequence of the `streamBuf` without
2001 /// the read position becoming unavailable, and the bytes contain a
2002 /// valid representation of a compact-binary date.
2003 static int getCompactBinaryDateValue(bdlt::Date *value,
2004 bsl::streambuf *streamBuf,
2005 int length);
2006
2007 // 'bdlt::Date' Encoding
2008
2009 /// Determine the format that should be used to encode the specified
2010 /// `value` given the `value` and the specified `options`. If `options`
2011 /// is 0, the default set of options is used. Return an enumerator
2012 /// identifying the selected format.
2013 static DateEncoding::Value selectDateEncoding(
2014 const bdlt::Date& value,
2015 const BerEncoderOptions *options);
2016
2017 /// Write the ISO 8601 representation of the specified `value` to the
2018 /// output sequence of the specified `streamBuf` according to the
2019 /// specified `options`. If `options` is 0, the default set of options
2020 /// is used. Return 0 on success, and a non-zero value otherwise. The
2021 /// operation succeeds if all bytes of the ISO 8601 representation of
2022 /// the `value` are written to the `streamBuf` without the write
2023 /// position becoming unavailable.
2024 static int putIso8601DateValue(bsl::streambuf *streamBuf,
2025 const bdlt::Date& value,
2026 const BerEncoderOptions *options);
2027
2028 /// Write the compact-binary date representation of the specified
2029 /// `value` to the output sequence of the specified `streamBuf`
2030 /// according to the specified `options`. If `options` is 0, the
2031 /// default set of options is used. Return 0 on success, and a non-zero
2032 /// value otherwise. The operation succeeds if all bytes of the
2033 /// compact-binary date representation of the `value` are written to the
2034 /// `streamBuf` without the write position becoming unavailable.
2035 static int putCompactBinaryDateValue(bsl::streambuf *streamBuf,
2036 const bdlt::Date& value,
2037 const BerEncoderOptions *options);
2038
2039 // 'bdlt::DateTz' Decoding
2040
2041 /// Load to the specified `encoding` the enumerator that describes the
2042 /// format used to encode a `bdlt::DateTz` value given the specified
2043 /// `length` and `firstByte` of the encoded representation. Return 0 on
2044 /// success, -1 if the format is reserved for future use, and some other
2045 /// non-zero value otherwise.
2046 static int detectDateTzEncoding(DateTzEncoding::Value *encoding,
2047 int length,
2048 unsigned char firstByte);
2049
2050 /// Read the specified `length` number of bytes from the input sequence
2051 /// of the specified `streamBuf` and load to the specified `value` the
2052 /// date and time zone value represented by the interpretation of the
2053 /// read bytes as an ISO 8601 date and time zone. Return 0 on success,
2054 /// and a non-zero value otherwise. The operation succeeds if `length`
2055 /// bytes are successfully read from the input sequence of the
2056 /// `streamBuf` without the read position becoming unavailable, and the
2057 /// bytes contain a valid representation of an ISO 8601 date and time
2058 /// zone.
2059 static int getIso8601DateTzValue(bdlt::DateTz *value,
2060 bsl::streambuf *streamBuf,
2061 int length);
2062
2063 /// Read the specified `length` number of bytes from the input sequence
2064 /// of the specified `streamBuf` and load to the specified `value` the
2065 /// date and time zone value represented by the interpretation of the
2066 /// read bytes as a compact-binary date. Return 0 on success, and a
2067 /// non-zero value otherwise. The operation succeeds if `length` bytes
2068 /// are successfully read from the input sequence of the `streamBuf`
2069 /// without the read position becoming unavailable, and the bytes
2070 /// contain a valid representation of a compact-binary date.
2071 static int getCompactBinaryDateValue(bdlt::DateTz *value,
2072 bsl::streambuf *streamBuf,
2073 int length);
2074
2075 /// Read the specified `length` number of bytes from the input sequence
2076 /// of the specified `streamBuf` and load to the specified `value` the
2077 /// date and time zone value represented by the interpretation of the
2078 /// read bytes as a compact-binary date and time zone. Return 0 on
2079 /// success, and a non-zero value otherwise. The operation succeeds if
2080 /// `length` bytes are successfully read from the input sequence of the
2081 /// `streamBuf` without the read position becoming unavailable, and the
2082 /// bytes contain a valid representation of a compact-binary date.
2083 static int getCompactBinaryDateTzValue(bdlt::DateTz *value,
2084 bsl::streambuf *streamBuf,
2085 int length);
2086
2087 // 'bdlt::DateTz' Encoding
2088
2089 /// Determine the format that should be used to encode the specified
2090 /// `value` given the `value` and the specified `options`. If `options`
2091 /// is 0, the default set of options is used. Return an enumerator
2092 /// identifying the selected format.
2093 static DateTzEncoding::Value selectDateTzEncoding(
2094 const bdlt::DateTz& value,
2095 const BerEncoderOptions *options);
2096
2097 /// Write the ISO 8601 representation of the specified `value` to the
2098 /// output sequence of the specified `streamBuf` according to the
2099 /// specified `options`. If `options` is 0, the default set of options
2100 /// is used. Return 0 on success, and a non-zero value otherwise. The
2101 /// operation succeeds if all bytes of the ISO 8601 representation of
2102 /// the `value` are written to the `streamBuf` without the write
2103 /// position becoming unavailable.
2104 static int putIso8601DateTzValue(bsl::streambuf *streamBuf,
2105 const bdlt::DateTz& value,
2106 const BerEncoderOptions *options);
2107
2108 /// Write the compact-binary date representation of the specified
2109 /// `value` to the output sequence of the specified `streamBuf`
2110 /// according to the specified `options`. If `options` is 0, the
2111 /// default set of options is used. Return 0 on success, and a non-zero
2112 /// value otherwise. The operation succeeds if all bytes of the
2113 /// compact-binary date representation of the `value` are written to the
2114 /// `streamBuf` without the write position becoming unavailable.
2115 ///
2116 /// \pre The behavior is undefined unless the `offset` of the `value` is 0.
2117 static int putCompactBinaryDateValue(bsl::streambuf *streamBuf,
2118 const bdlt::DateTz& value,
2119 const BerEncoderOptions *options);
2120
2121 /// Write the compact-binary date and time zone representation of the
2122 /// specified `value` to the output sequence of the specified
2123 /// `streamBuf` according to the specified `options`. If `options` is
2124 /// 0, the default set of options is used. Return 0 on success, and a
2125 /// non-zero value otherwise. The operation succeeds if all bytes of
2126 /// the compact-binary date representation of the `value` are written to
2127 /// the `streamBuf` without the write position becoming unavailable.
2128 static int putCompactBinaryDateTzValue(bsl::streambuf *streamBuf,
2129 const bdlt::DateTz& value,
2130 const BerEncoderOptions *options);
2131
2132 // Variant Decoding
2133
2134 /// Load to the specified `encoding` the enumerator that describes the
2135 /// format used to encode a `bdlt::Date` or `bdlt::DateTz` value given
2136 /// the specified `length` and `firstByte` of the encoded
2137 /// representation. Return 0 on success, -1 if the format is reserved
2138 /// for future use, and some other non-zero value otherwise.
2139 static int detectDateOrDateTzEncoding(
2141 int length,
2142 unsigned char firstByte);
2143
2144 /// Read the specified `length` number of bytes from the input sequence
2145 /// of the specified `streamBuf` and load to the specified `value` the
2146 /// date value represented by the interpretation of the read bytes as an
2147 /// ISO 8601 date. Return 0 on success, and a non-zero value otherwise.
2148 /// The operation succeeds if `length` bytes are successfully read from
2149 /// the input sequence of the `streamBuf` without the read position
2150 /// becoming unavailable, and the bytes contain a valid representation
2151 /// of an ISO 8601 date.
2152 static int getIso8601DateValue(DateOrDateTz *value,
2153 bsl::streambuf *streamBuf,
2154 int length);
2155
2156 /// Read the specified `length` number of bytes from the input sequence
2157 /// of the specified `streamBuf` and load to the specified `value` the
2158 /// date value represented by the interpretation of the read bytes as an
2159 /// ISO 8601 date and time zone. Return 0 on success, and a non-zero
2160 /// value otherwise. The operation succeeds if `length` bytes are
2161 /// successfully read from the input sequence of the `streamBuf` without
2162 /// the read position becoming unavailable, and the bytes contain a
2163 /// valid representation of an ISO 8601 date and time zone.
2164 static int getIso8601DateTzValue(DateOrDateTz *value,
2165 bsl::streambuf *streamBuf,
2166 int length);
2167
2168 /// Read the specified `length` number of bytes from the input sequence
2169 /// of the specified `streamBuf` and load to the specified `value` the
2170 /// date value represented by the interpretation of the read bytes as a
2171 /// compact-binary date. Return 0 on success, and a non-zero value
2172 /// otherwise. The operation succeeds if `length` bytes are
2173 /// successfully read from the input sequence of the `streamBuf` without
2174 /// the read position becoming unavailable, and the bytes contain a
2175 /// valid representation of a compact-binary date.
2176 static int getCompactBinaryDateValue(DateOrDateTz *value,
2177 bsl::streambuf *streamBuf,
2178 int length);
2179
2180 /// Read the specified `length` number of bytes from the input sequence
2181 /// of the specified `streamBuf` and load to the specified `value` the
2182 /// date and time zone value represented by the interpretation of the
2183 /// read bytes as a compact-binary date and time zone. Return 0 on
2184 /// success, and a non-zero value otherwise. The operation succeeds if
2185 /// `length` bytes are successfully read from the input sequence of the
2186 /// `streamBuf` without the read position becoming unavailable, and the
2187 /// bytes contain a valid representation of a compact-binary date and
2188 /// time zone.
2189 static int getCompactBinaryDateTzValue(DateOrDateTz *value,
2190 bsl::streambuf *streamBuf,
2191 int length);
2192
2193 public:
2194 // CLASS METHODS
2195
2196 // Utilities
2197
2198 /// Load to the specified `daysSinceEpoch` the number of days between
2199 /// the compact-binary date epoch and the specified `date`. The
2200 /// compact-binary date epoch is the date defined by the `k_COMPACT_BINARY_DATE_EPOCH` serial date.
2201 ///
2202 /// \note Note that this quantity
2203 /// may be negative if the specified `date` occurs before the
2204 /// compact-binary date epoch.
2205 static void dateToDaysSinceEpoch(bsls::Types::Int64 *daysSinceEpoch,
2206 const bdlt::Date& date);
2207
2208 /// Load to the specified `date` the date represented by the serial date
2209 /// indicated by adding the specified `daysSinceEpoch` to
2210 /// `k_COMPACT_BINARY_DATE_EPOCH`. Return 0 on success, and a non-zero
2211 /// value otherwise. This operation succeeds if the resulting value
2212 /// represents a date in the range `[0001JAN01 .. 9999DEC31]`.
2213 ///
2214 /// \note Note that `daysSinceEpoch` may be negative to indicate a serial date that
2215 /// occurs before `k_COMPACT_BINARY_DATE_EPOCH`.
2216 static int daysSinceEpochToDate(bdlt::Date *date,
2217 bsls::Types::Int64 daysSinceEpoch);
2218
2219 // 'bdlt::Date' Decoding
2220
2221 /// Read the specified `length` number of bytes from the input sequence
2222 /// of the specified `streamBuf` and load to the specified `value` the
2223 /// date value represented those bytes. Return 0 on success, and a
2224 /// non-zero value otherwise. The operation succeeds if `length` bytes
2225 /// are successfully read from the input sequence of the `streamBuf`
2226 /// without the read position becoming unavailable, and the bytes
2227 /// contain a valid representation of a date value. See the
2228 /// package-level documentation of {`balber`} for a description of the
2229 /// decision procedure used to detect the encoding format for a
2230 /// `bdlt::Date` value.
2231 static int getDateValue(bdlt::Date *date,
2232 bsl::streambuf *streamBuf,
2233 int length);
2234
2235 // 'bdlt::Date' Encoding
2236
2237 /// Write a representation of the specified `value` date to the output
2238 /// sequence of the specified `streamBuf` according to the specified
2239 /// `options`. If `options` is 0, the default set of options is used.
2240 /// Return 0 on success, and a non-zero value otherwise. This operation
2241 /// succeeds if all bytes in the representation of the `value` are
2242 /// written to the output sequence of the `streamBuf` without the write
2243 /// position becoming unavailable. See the class documentation for a
2244 /// description of the default options. See the package-level
2245 /// documentation of {`balber`} for a description of the decision
2246 /// procedure used to select an encoding format for the `value`.
2247 static int putDateValue(bsl::streambuf *streamBuf,
2248 const bdlt::Date& value,
2249 const BerEncoderOptions *options);
2250
2251 // 'bdlt::DateTz' Decoding
2252
2253 /// Read the specified `length` number of bytes from the input sequence
2254 /// of the specified `streamBuf` and load to the specified `value` the
2255 /// date and time zone value represented by those bytes. Return 0 on
2256 /// success, and a non-zero value otherwise. The operation succeeds if
2257 /// `length` bytes are successfully read from the input sequence of the
2258 /// `streamBuf` without the read position becoming unavailable, and the
2259 /// bytes contain a valid representation of a date and time zone value.
2260 /// See the package-level documentation of {`balber`} for a description
2261 /// of the decision procedure used to detect the encoding format for a
2262 /// `bdlt::DateTz` value.
2263 static int getDateTzValue(bdlt::DateTz *value,
2264 bsl::streambuf *streamBuf,
2265 int length);
2266
2267 // 'bdlt::DateTz' Encoding
2268
2269 /// Write a representation of the specified `value` date and time zone
2270 /// to the output sequence of the specified `streamBuf` according to the
2271 /// specified `options`. If `options` is 0, the default set of options
2272 /// is used. Return 0 on success, and a non-zero value otherwise. This
2273 /// operation succeeds if all bytes in the representation of the `value`
2274 /// are written to the output sequence of the `streamBuf` without the
2275 /// write position becoming unavailable. See the class documentation
2276 /// for a description of the default options. See the package-level
2277 /// documentation of {`balber`} for a description of the decision
2278 /// procedure used to select an encoding format for the `value`.
2279 static int putDateTzValue(bsl::streambuf *streamBuf,
2280 const bdlt::DateTz& date,
2281 const BerEncoderOptions *options);
2282
2283 // Variant Decoding
2284
2285 /// Read the specified `length` number of bytes from the input sequence
2286 /// of the specified `streamBuf` and load to the specified `value` the
2287 /// date and optional time zone value represented by those bytes.
2288 /// Return 0 on success, and a non-zero value otherwise. The operation
2289 /// succeeds if `length` bytes are successfully read from the input
2290 /// sequence of the `streamBuf` without the read position becoming
2291 /// unavailable, and the bytes contain a valid representation of a date
2292 /// and optional time zone value. See the package-level documentation
2293 /// of {`balber`} for a description of the decision procedure used to
2294 /// detect the encoding format for a `DateOrDateTz` value.
2295 static int getDateOrDateTzValue(DateOrDateTz *value,
2296 bsl::streambuf *streamBuf,
2297 int length);
2298};
2299
2300 // ===========================
2301 // struct BerUtil_TimeEncoding
2302 // ===========================
2303
2304/// This component-private utility `struct` provides a namespace for
2305/// enumerating the set of formats that may be used by `BerUtil` to encode and
2306/// decode values of `bdlt::Time` type.
2307///
2308/// See @ref balber_berutil
2310
2311 // TYPES
2312
2313 /// `Encoding` is an alias to a namespace for enumerating the union of the
2314 /// sets of date and time formats used to encode and decode all date and
2315 /// time types supported by `BerUtil`.
2317
2323
2324 enum {
2328};
2329
2330 // =============================
2331 // struct BerUtil_TimeTzEncoding
2332 // =============================
2333
2334/// This component-private utility `struct` provides a namespace for
2335/// enumerating the set of formats that may be used by `BerUtil` to encode
2336/// and decode values of `bdlt::TimeTz` type.
2337///
2338/// See @ref balber_berutil
2340
2341 // TYPES
2342
2343 /// `Encoding` is an alias to a namespace for enumerating the union of
2344 /// the sets of date and time formats used to encode and decode all date
2345 /// and time types supported by `BerUtil`.
2347
2354
2355 enum {
2359};
2360
2361 // ===================================
2362 // struct BerUtil_TimeOrTimeTzEncoding
2363 // ===================================
2364
2365/// This component-private utility `struct` provides a namespace for
2366/// enumerating the set of formats that may be used by `BerUtil` to decode
2367/// values of `bdlb::Variant2<bdlt::Time, bdlt::TimeTz>` type.
2368///
2369/// See @ref balber_berutil
2371
2372 // TYPES
2373
2374 /// `Encoding` is an alias to a namespace for enumerating the union of
2375 /// the sets of date and time formats used to encode and decode all date
2376 /// and time types supported by `BerUtil`.
2378
2387};
2388
2389 // ==========================
2390 // struct BerUtil_TimeImpUtil
2391 // ==========================
2392
2393/// This component-private `struct` provides a namespace for a suite of
2394/// functions used by `BerUtil` to implement BER encoding and decoding
2395/// operations for time values. Within the definition of this `struct`:
2396///
2397/// * **the specification**:
2398/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690.
2399///
2400/// * **the default set of options**:
2401/// > Refers to a `balber::BerEncoderOptions` value having a
2402/// > `datetimeFractionalSecondPrecision` attribute of 3 and a
2403/// > `encodeDateAndTimeTypesAsBinary` attribute of `false`.
2404///
2405/// See the package level documentation of {`balber`} for a definition of
2406/// the compact and extended binary formats for date and time values.
2407///
2408/// See @ref balber_berutil
2410
2411 // TYPES
2412
2413 /// `DateAndTimeHeaderUtil` is an alias to a namespace for a suite of
2414 /// functions used to implement encoding and decoding operations for the
2415 /// 2-byte header of an extended-binary-encoding formatted date-and-time
2416 /// value.
2418
2419 /// `Header` is an alias to an in-core, value-semantic attribute class
2420 /// that represents the range of valid values of the 2-byte header of
2421 /// extended-binary-encoding formatted date-and-time values.
2423
2424 /// `Type` is an alias to a namespace for enumerating the set of "header
2425 /// type" values that may be encoded in the 2-byte header of an
2426 /// extended-binary-encoding formatted date-and-time value.
2428
2429 /// `DateAndTimeHeaderUtil` is an alias to a namespace for a suite of
2430 /// functions used to implement encoding and decoding operations for the
2431 /// 2-byte header of an extended-binary-encoding formatted date-and-time
2432 /// value.
2434
2435 /// `IntegerUtil` is an alias to a namespace for a suite of functions
2436 /// used to implement BER encoding and decoding operations for integer
2437 /// values.
2439
2440 /// `Iso8601Util` is an alias to a namespace for a suite of functions
2441 /// used to implementing the encoding and decoding of date and time
2442 /// values using the ISO 8601 format.
2444
2445 /// `LengthUtil` is an alias to a namespace for a suite of functions
2446 /// used to implement BER encoding and decoding operations for length
2447 /// quantities.
2449
2450 /// `StringUtil` is an alias to a namespace for a suite of functions
2451 /// used by `BerUtil` to implement BER encoding and decoding operations
2452 /// for string values.
2454
2455 /// `StreambufUtil` is an alias to a namespace for a suite of functions
2456 /// used to implement input and output operations on `bsl::streambuf`
2457 /// objects.
2459
2460 /// `TimeEncoding` is an alias to a namespace for enumerating the set of
2461 /// formats that may be used by `BerUtil` to encode and decode values of
2462 /// `bdlt::Time` type.
2464
2465 /// `TimeTzEncoding` is an alias to a namespace for enumerating the set
2466 /// of formats that may be used by `BerUtil` to encode and decode values
2467 /// of `bdlt::TimeTz` type.
2469
2470 /// `TimeOrTimeTzEncoding` is an alias to a namespace for enumerating
2471 /// the set of formats that may be used by `BerUtil` to decode to values
2472 /// of `bdlb::Variant2<bdlt::Time, bdlt::TimeTz>` type.
2474
2475 /// `TimezoneUtil` is an alias to a namespace for a suite of functions
2476 /// used to implement BER encoding and decoding operations for time-zone
2477 /// offset values.
2479
2480 /// `TimeOrTimeTz` is a convenient alias for
2481 /// `bdlb::Variant2<bdlt::Time, bdlt::TimeTz>`.
2483
2484 private:
2485 // PRIVATE TYPES
2486 enum {
2487 k_EXTENDED_BINARY_TIME_LENGTH =
2490 // the number of content octets used by 'BerUtil' to encode
2491 // a time value using the extended-binary time and time zone format
2492
2493 k_EXTENDED_BINARY_TIMETZ_LENGTH =
2496 // the number of contents octets used by 'BerUtil' to encode
2497 // a time and time zone value using the extended-binary time and
2498 // time zone format
2499
2500 k_MAX_ISO8601_TIME_LENGTH = bdlt::Iso8601Util::k_TIME_STRLEN,
2501 // the maximum number of content octets used by 'BerUtil' to encode
2502 // a time value using the ISO 8601 format
2503
2504 k_MAX_ISO8601_TIMETZ_LENGTH = bdlt::Iso8601Util::k_TIMETZ_STRLEN,
2505 // the maximum number of content octets used by 'BerUtil to encode
2506 // a time and time zone value using the ISO 8601 format
2507
2508 k_MIN_COMPACT_BINARY_TIME_LENGTH = 1,
2509 // the minimum number of content octets used by 'BerUtil' to encode
2510 // a time value using the compact-binary time format
2511
2512 k_MAX_COMPACT_BINARY_TIME_LENGTH = 4,
2513 // the maximum number of content octets used by 'BerUtil' to encode
2514 // a time value using the compact-binary time format
2515
2516 k_MIN_COMPACT_BINARY_TIMETZ_LENGTH =
2517 k_MAX_COMPACT_BINARY_TIME_LENGTH + 1,
2518 // the minimum number of content octets used by 'BerUtil' to encode
2519 // a time and time zone value using the compact-binary time and
2520 // time zone format
2521
2522 k_MAX_COMPACT_BINARY_TIMETZ_LENGTH = 6
2523 // the maximum number of content octets used by 'BerUtil' to encode
2524 // a time and time zone value using the compact-binary time and
2525 // time zone format
2526 };
2527
2528 // PRIVATE CLASS METHODS
2529
2530 // 'bdlt::Time' Decoding
2531
2532 /// Load to the specified `encoding` the enumerator that describes the
2533 /// format used to encode a `bdlt::Time` value given the specified
2534 /// `length` and `firstByte` of the encoded representation. Return 0 on
2535 /// success, -1 if the format is reserved for future use, and some other
2536 /// non-zero value otherwise.
2537 static int detectTimeEncoding(TimeEncoding::Value *encoding,
2538 int length,
2539 unsigned char firstByte);
2540
2541 /// Read the specified `length` number of bytes from the input sequence
2542 /// of the specified `streamBuf` and load to the specified `value` the
2543 /// time value represented by the interpretation of the read bytes as an
2544 /// ISO 8601 time. Return 0 on success, and a non-zero value otherwise.
2545 /// The operation succeeds if `length` bytes are successfully read from
2546 /// the input sequence of the `streamBuf` without the read position
2547 /// becoming unavailable, and the bytes contain a valid representation
2548 /// of an ISO 8601 time.
2549 static int getIso8601TimeValue(bdlt::Time *value,
2550 bsl::streambuf *streamBuf,
2551 int length);
2552
2553 /// Read the specified `length` number of bytes from the input sequence
2554 /// of the specified `streamBuf` and load to the specified `value` the
2555 /// time value represented by the interpretation of the read bytes as a
2556 /// compact-binary time. Return 0 on success, and a non-zero value
2557 /// otherwise. The operation succeeds if `length` bytes are
2558 /// successfully read from the input sequence of the `streamBuf` without
2559 /// the read position becoming unavailable, and the bytes contain a
2560 /// valid representation of a compact-binary time.
2561 static int getCompactBinaryTimeValue(bdlt::Time *value,
2562 bsl::streambuf *streamBuf,
2563 int length);
2564
2565 /// Read the specified `length` number of bytes from the input sequence
2566 /// of the specified `streamBuf` and load to the specified `value` the
2567 /// time value represented by the interpretation of the read bytes as an
2568 /// extended-binary time. Return 0 on success, and a non-zero value
2569 /// otherwise. The operation succeeds if `length` bytes are
2570 /// successfully read from the input sequence of the `streamBuf` without
2571 /// the read position becoming unavailable, and the bytes contain a
2572 /// valid representation of a extended-binary time.
2573 static int getExtendedBinaryTimeValue(bdlt::Time *value,
2574 bsl::streambuf *streamBuf,
2575 int length);
2576
2577 // 'bdlt::Time' Encoding
2578
2579 /// Determine the format that should be used to encode the specified
2580 /// `value` given the `value` and the specified `options`. If `options`
2581 /// is 0, the default set of options is used. Return an enumerator
2582 /// identifying the selected format.
2583 static TimeEncoding::Value selectTimeEncoding(
2584 const bdlt::Time& value,
2585 const BerEncoderOptions *options);
2586
2587 /// Write the ISO 8601 representation of the specified `value` to the
2588 /// output sequence of the specified `streamBuf` according to the
2589 /// specified `options`. If `options` is 0, the default set of options
2590 /// is used. Return 0 on success, and a non-zero value otherwise. The
2591 /// operation succeeds if all bytes of the ISO 8601 representation of
2592 /// the `value` are written to the `streamBuf` without the write
2593 /// position becoming unavailable.
2594 static int putIso8601TimeValue(bsl::streambuf *streamBuf,
2595 const bdlt::Time& value,
2596 const BerEncoderOptions *options);
2597
2598 /// Write the compact-binary time representation of the specified
2599 /// `value` to the output sequence of the specified `streamBuf`
2600 /// according to the specified `options`. If `options` is 0, the
2601 /// default set of options is used. Return 0 on success, and a non-zero
2602 /// value otherwise. The operation succeeds if all bytes of the
2603 /// compact-binary time representation of the `value` are written to the
2604 /// `streamBuf` without the write position becoming unavailable.
2605 static int putCompactBinaryTimeValue(bsl::streambuf *streamBuf,
2606 const bdlt::Time& value,
2607 const BerEncoderOptions *options);
2608
2609 /// Write the extended-binary time representation of the specified
2610 /// `value` to the output sequence of the specified `streamBuf`
2611 /// according to the specified `options`. If `options` is 0, the
2612 /// default set of options is used. Return 0 on success, and a non-zero
2613 /// value otherwise. The operation succeeds if all bytes of the
2614 /// extended-binary time representation of the `value` are written to
2615 /// the `streamBuf` without the write position becoming unavailable.
2616 static int putExtendedBinaryTimeValue(bsl::streambuf *streamBuf,
2617 const bdlt::Time& value,
2618 const BerEncoderOptions *options);
2619
2620 // 'bdlt::TimeTz' Decoding
2621
2622 /// Load to the specified `encoding` the enumerator that describes the
2623 /// format used to encode a `bdlt::Time` value given the specified
2624 /// `length` and `firstByte` of the encoded representation. Return 0 on
2625 /// success, -1 if the format is reserved for future use, and some other
2626 /// non-zero value otherwise.
2627 static int detectTimeTzEncoding(TimeTzEncoding::Value *encoding,
2628 int length,
2629 unsigned char firstByte);
2630
2631 /// Read the specified `length` number of bytes from the input sequence
2632 /// of the specified `streamBuf` and load to the specified `value` the
2633 /// time and time zone value represented by the interpretation of the
2634 /// read bytes as an ISO 8601 time and time zone. Return 0 on success,
2635 /// and a non-zero value otherwise. The operation succeeds if `length`
2636 /// bytes are successfully read from the input sequence of the
2637 /// `streamBuf` without the read position becoming unavailable, and the
2638 /// bytes contain a valid representation of an ISO 8601 time and time
2639 /// zone.
2640 static int getIso8601TimeTzValue(bdlt::TimeTz *value,
2641 bsl::streambuf *streamBuf,
2642 int length);
2643
2644 /// Read the specified `length` number of bytes from the input sequence
2645 /// of the specified `streamBuf` and load to the specified `value` the
2646 /// time value represented by the interpretation of the read bytes as a
2647 /// compact-binary time. Return 0 on success, and a non-zero value
2648 /// otherwise. The operation succeeds if `length` bytes are
2649 /// successfully read from the input sequence of the `streamBuf` without
2650 /// the read position becoming unavailable, and the bytes contain a
2651 /// valid representation of a compact-binary time.
2652 static int getCompactBinaryTimeValue(bdlt::TimeTz *value,
2653 bsl::streambuf *streamBuf,
2654 int length);
2655
2656 /// Read the specified `length` number of bytes from the input sequence
2657 /// of the specified `streamBuf` and load to the specified `value` the
2658 /// time and time zone value represented by the interpretation of the
2659 /// read bytes as a compact-binary time and time zone. Return 0 on
2660 /// success, and a non-zero value otherwise. The operation succeeds if
2661 /// `length` bytes are successfully read from the input sequence of the
2662 /// `streamBuf` without the read position becoming unavailable, and the
2663 /// bytes contain a valid representation of a compact-binary time and
2664 /// time zone.
2665 static int getCompactBinaryTimeTzValue(bdlt::TimeTz *value,
2666 bsl::streambuf *streamBuf,
2667 int length);
2668
2669 /// Read the specified `length` number of bytes from the input sequence
2670 /// of the specified `streamBuf` and load to the specified `value` the
2671 /// time and time zone value represented by the interpretation of the
2672 /// read bytes as an extended-binary time and time zone. Return 0 on
2673 /// success, and a non-zero value otherwise. The operation succeeds if
2674 /// `length` bytes are successfully read from the input sequence of the
2675 /// `streamBuf` without the read position becoming unavailable, and the
2676 /// bytes contain a valid representation of an extended-binary time and
2677 /// time zone.
2678 static int getExtendedBinaryTimeTzValue(bdlt::TimeTz *value,
2679 bsl::streambuf *streamBuf,
2680 int length);
2681
2682 // 'bdlt::TimeTz' Encoding
2683
2684 /// Determine the format that should be used to encode the specified
2685 /// `value` given the `value` and the specified `options`. If `options`
2686 /// is 0, the default set of options is used. Return an enumerator
2687 /// identifying the selected format.
2688 static TimeTzEncoding::Value selectTimeTzEncoding(
2689 const bdlt::TimeTz& value,
2690 const BerEncoderOptions *options);
2691
2692 /// Write the ISO 8601 representation of the specified `value` to the
2693 /// output sequence of the specified `streamBuf` according to the
2694 /// specified `options`. If `options` is 0, the default set of options
2695 /// is used. Return 0 on success, and a non-zero value otherwise. The
2696 /// operation succeeds if all bytes of the ISO 8601 representation of
2697 /// the `value` are written to the `streamBuf` without the write
2698 /// position becoming unavailable.
2699 static int putIso8601TimeTzValue(bsl::streambuf *streamBuf,
2700 const bdlt::TimeTz& value,
2701 const BerEncoderOptions *options);
2702
2703 /// Write the compact-binary time representation of the specified
2704 /// `value` to the output sequence of the specified `streamBuf`
2705 /// according to the specified `options`. If `options` is 0, the
2706 /// default set of options is used. Return 0 on success, and a non-zero
2707 /// value otherwise. The operation succeeds if all bytes of the
2708 /// compact-binary time representation of the `value` are written to the
2709 /// `streamBuf` without the write position becoming unavailable.
2710 ///
2711 /// \pre The behavior is undefined unless the `offset` of the `value` is 0.
2712 static int putCompactBinaryTimeValue(bsl::streambuf *streamBuf,
2713 const bdlt::TimeTz& value,
2714 const BerEncoderOptions *options);
2715
2716 /// Write the compact-binary date and time zone representation of the
2717 /// specified `value` to the output sequence of the specified
2718 /// `streamBuf` according to the specified `options`. If `options` is
2719 /// 0, the default set of options is used. Return 0 on success, and a
2720 /// non-zero value otherwise. The operation succeeds if all bytes of
2721 /// the compact-binary date representation of the `value` are written to
2722 /// the `streamBuf` without the write position becoming unavailable.
2723 static int putCompactBinaryTimeTzValue(bsl::streambuf *streamBuf,
2724 const bdlt::TimeTz& value,
2725 const BerEncoderOptions *options);
2726
2727 /// Write the extended-binary date and time zone representation of the
2728 /// specified `value` to the output sequence of the specified
2729 /// `streamBuf` according to the specified `options`. If `options` is
2730 /// 0, the default set of options is used. Return 0 on success, and a
2731 /// non-zero value otherwise. The operation succeeds if all bytes of
2732 /// the extended-binary date representation of the `value` are written
2733 /// to the `streamBuf` without the write position becoming unavailable.
2734 static int putExtendedBinaryTimeTzValue(bsl::streambuf *streamBuf,
2735 const bdlt::TimeTz& value,
2736 const BerEncoderOptions *options);
2737
2738 // Variant Decoding
2739
2740 /// Load to the specified `encoding` the enumerator that describes the
2741 /// format used to encode a `bdlt::Time` or `bdlt::TimeTz` value given
2742 /// the specified `length` and `firstByte` of the encoded
2743 /// representation. Return 0 on success, -1 if the format is reserved
2744 /// for future use, and some other non-zero value otherwise.
2745 static int detectTimeOrTimeTzEncoding(
2747 int length,
2748 unsigned char firstByte);
2749
2750 /// Read the specified `length` number of bytes from the input sequence
2751 /// of the specified `streamBuf` and load to the specified `value` the
2752 /// time value represented by the interpretation of the read bytes as an
2753 /// ISO 8601 time. Return 0 on success, and a non-zero value otherwise.
2754 /// The operation succeeds if `length` bytes are successfully read from
2755 /// the input sequence of the `streamBuf` without the read position
2756 /// becoming unavailable, and the bytes contain a valid representation
2757 /// of an ISO 8601 time.
2758 static int getIso8601TimeValue(TimeOrTimeTz *value,
2759 bsl::streambuf *streamBuf,
2760 int length);
2761
2762 /// Read the specified `length` number of bytes from the input sequence
2763 /// of the specified `streamBuf` and load to the specified `value` the
2764 /// time and time zone value represented by the interpretation of the
2765 /// read bytes as an ISO 8601 time and time zone. Return 0 on success,
2766 /// and a non-zero value otherwise. The operation succeeds if `length`
2767 /// bytes are successfully read from the input sequence of the
2768 /// `streamBuf` without the read position becoming unavailable, and the
2769 /// bytes contain a valid representation of an ISO 8601 time and time
2770 /// zone.
2771 static int getIso8601TimeTzValue(TimeOrTimeTz *value,
2772 bsl::streambuf *streamBuf,
2773 int length);
2774
2775 /// Read the specified `length` number of bytes from the input sequence
2776 /// of the specified `streamBuf` and load to the specified `value` the
2777 /// time value represented by the interpretation of the read bytes as a
2778 /// compact-binary time. Return 0 on success, and a non-zero value
2779 /// otherwise. The operation succeeds if `length` bytes are
2780 /// successfully read from the input sequence of the `streamBuf` without
2781 /// the read position becoming unavailable, and the bytes contain a
2782 /// valid representation of a compact-binary time.
2783 static int getCompactBinaryTimeValue(TimeOrTimeTz *value,
2784 bsl::streambuf *streamBuf,
2785 int length);
2786
2787 /// Read the specified `length` number of bytes from the input sequence
2788 /// of the specified `streamBuf` and load to the specified `value` the
2789 /// time and time zone value represented by the interpretation of the
2790 /// read bytes as a compact-binary time and time zone. Return 0 on
2791 /// success, and a non-zero value otherwise. The operation succeeds if
2792 /// `length` bytes are successfully read from the input sequence of the
2793 /// `streamBuf` without the read position becoming unavailable, and the
2794 /// bytes contain a valid representation of a compact-binary time and
2795 /// time zone.
2796 static int getCompactBinaryTimeTzValue(TimeOrTimeTz *value,
2797 bsl::streambuf *streamBuf,
2798 int length);
2799
2800 /// Read the specified `length` number of bytes from the input sequence
2801 /// of the specified `streamBuf` and load to the specified `value` the
2802 /// time value represented by the interpretation of the read bytes as a
2803 /// extended-binary time. Return 0 on success, and a non-zero value
2804 /// otherwise. The operation succeeds if `length` bytes are
2805 /// successfully read from the input sequence of the `streamBuf` without
2806 /// the read position becoming unavailable, and the bytes contain a
2807 /// valid representation of an extended-binary time.
2808 static int getExtendedBinaryTimeValue(TimeOrTimeTz *value,
2809 bsl::streambuf *streamBuf,
2810 int length);
2811
2812 /// Read the specified `length` number of bytes from the input sequence
2813 /// of the specified `streamBuf` and load to the specified `value` the
2814 /// time and time zone value represented by the interpretation of the
2815 /// read bytes as an extended-binary time and time zone. Return 0 on
2816 /// success, and a non-zero value otherwise. The operation succeeds if
2817 /// `length` bytes are successfully read from the input sequence of the
2818 /// `streamBuf` without the read position becoming unavailable, and the
2819 /// bytes contain a valid representation of an extended-binary time and
2820 /// time zone.
2821 static int getExtendedBinaryTimeTzValue(TimeOrTimeTz *value,
2822 bsl::streambuf *streamBuf,
2823 int length);
2824
2825 public:
2826 // CLASS METHODS
2827
2828 // Utilities
2829
2830 /// Load to the specified `millisecondsSinceMidnight` the number of
2831 /// milliseconds in the specified `time` value.
2833 int *millisecondsSinceMidnight,
2834 const bdlt::Time& time);
2835
2836 /// Load to the specified `microsecondsSinceMidnight` the number of
2837 /// microseconds in the specified `time` value.
2839 bsls::Types::Int64 *microsecondsSinceMidnight,
2840 const bdlt::Time& time);
2841
2842 /// Load to the specified `time` the time value represented by the
2843 /// specified `millisecondsSinceMidnight`.
2845 bdlt::Time *time,
2846 int millisecondsSinceMidnight);
2847
2848 /// Load to the specified `time` the time value represented by the
2849 /// specified `microsecondsSinceMidnight`.
2851 bdlt::Time *time,
2852 bsls::Types::Int64 microsecondsSinceMidnight);
2853
2854 // 'bdlt::Time' Decoding
2855
2856 /// Read the specified `length` number of bytes from the input sequence
2857 /// of the specified `streamBuf` and load to the specified `value` the
2858 /// time value represented those bytes. Return 0 on success, and a
2859 /// non-zero value otherwise. The operation succeeds if `length` bytes
2860 /// are successfully read from the input sequence of the `streamBuf`
2861 /// without the read position becoming unavailable, and the bytes
2862 /// contain a valid representation of a time value. See the
2863 /// package-level documentation of {`balber`} for a description of the
2864 /// decision procedure used to detect the encoding format for a
2865 /// `bdlt::Time` value.
2866 static int getTimeValue(bdlt::Time *value,
2867 bsl::streambuf *streamBuf,
2868 int length);
2869
2870 // 'bdlt::Time' Encoding
2871
2872 /// Write a representation of the specified time `value` to the output
2873 /// sequence of the specified `streamBuf` according to the specified
2874 /// `options`. If `options` is 0, the default set of options is used.
2875 /// Return 0 on success, and a non-zero value otherwise. This operation
2876 /// succeeds if all bytes in the representation of the `value` are
2877 /// written to the output sequence of the `streamBuf` without the write
2878 /// position becoming unavailable. See the class documentation for a
2879 /// description of the default options. See the package-level
2880 /// documentation of {`balber`} for a description of the decision
2881 /// procedure used to select an encoding format for the `value`.
2882 static int putTimeValue(bsl::streambuf *streamBuf,
2883 const bdlt::Time& value,
2884 const BerEncoderOptions *options);
2885
2886 // 'bdlt::TimeTz' Decoding
2887
2888 /// Read the specified `length` number of bytes from the input sequence
2889 /// of the specified `streamBuf` and load to the specified `value` the
2890 /// time and time zone value represented by those bytes. Return 0 on
2891 /// success, and a non-zero value otherwise. The operation succeeds if
2892 /// `length` bytes are successfully read from the input sequence of the
2893 /// `streamBuf` without the read position becoming unavailable, and the
2894 /// bytes contain a valid representation of a time and time zone value.
2895 /// See the package-level documentation of {`balber`} for a description
2896 /// of the decision procedure used to detect the encoding format for a
2897 /// `bdlt::TimeTz` value.
2898 static int getTimeTzValue(bdlt::TimeTz *value,
2899 bsl::streambuf *streamBuf,
2900 int length);
2901
2902 // 'bdlt::TimeTz' Encoding
2903
2904 /// Write a representation of the specified time and time-zone `value`
2905 /// to the output sequence of the specified `streamBuf` according to the
2906 /// specified `options`. If `options` is 0, the default set of options
2907 /// is used. Return 0 on success, and a non-zero value otherwise. This
2908 /// operation succeeds if all bytes in the representation of the `value`
2909 /// are written to the output sequence of the `streamBuf` without the
2910 /// write position becoming unavailable. See the class documentation
2911 /// for a description of the default options. See the package-level
2912 /// documentation of {`balber`} for a description of the decision
2913 /// procedure used to select an encoding format for the `value`.
2914 static int putTimeTzValue(bsl::streambuf *streamBuf,
2915 const bdlt::TimeTz& value,
2916 const BerEncoderOptions *options);
2917
2918 // Variant Decoding
2919
2920 /// Read the specified `length` number of bytes from the input sequence
2921 /// of the specified `streamBuf` and load to the specified `value` the
2922 /// time and optional time zone value represented by those bytes.
2923 /// Return 0 on success, and a non-zero value otherwise. The operation
2924 /// succeeds if `length` bytes are successfully read from the input
2925 /// sequence of the `streamBuf` without the read position becoming
2926 /// unavailable, and the bytes contain a valid representation of a time
2927 /// and optional time zone value. See the package-level documentation
2928 /// of {`balber`} for a description of the decision procedure used to
2929 /// detect the encoding format for a `TimeOrTimeTz` value.
2930 static int getTimeOrTimeTzValue(TimeOrTimeTz *value,
2931 bsl::streambuf *streamBuf,
2932 int length);
2933};
2934
2935 // ===============================
2936 // struct BerUtil_DatetimeEncoding
2937 // ===============================
2938
2939/// This component-private utility `struct` provides a namespace for
2940/// enumerating the set of formats that may be used by `BerUtil` to encode
2941/// and decode values of `bdlt::Datetime` type.
2942///
2943/// See @ref balber_berutil
2945
2946 // TYPES
2947
2948 /// `Encoding` is an alias to a namespace for enumerating the union of
2949 /// the sets of date and time formats used to encode and decode all date
2950 /// and time types supported by `BerUtil`.
2952
2959
2960 enum {
2964};
2965
2966 // =================================
2967 // struct BerUtil_DatetimeTzEncoding
2968 // =================================
2969
2970/// This component-private utility `struct` provides a namespace for
2971/// enumerating the set of formats that may be used by `BerUtil` to encode
2972/// and decode values of `bdlt::DatetimeTz` type.
2973///
2974/// See @ref balber_berutil
2976
2977 // TYPES
2978
2979 /// `Encoding` is an alias to a namespace for enumerating the union of
2980 /// the sets of date and time formats used to encode and decode all date
2981 /// and time types supported by `BerUtil`.
2983
2990
2991 enum {
2995};
2996
2997 // ===========================================
2998 // struct BerUtil_DatetimeOrDatetimeTzEncoding
2999 // ===========================================
3000
3001/// This component-private utility `struct` provides a namespace for
3002/// enumerating the set of formats that may be used by `BerUtil` to decode
3003/// to values of `bdlb::Variant2<bdlt::Datetime, bdlt::DatetimeTz>` type.
3004///
3005/// See @ref balber_berutil
3024
3025 // ==============================
3026 // struct BerUtil_DatetimeImpUtil
3027 // ==============================
3028
3029/// This component-private `struct` provides a namespace for a suite of
3030/// functions used by `BerUtil` to implement BER encoding and decoding
3031/// operations for date and time values. Within the definition of this
3032/// `struct`:
3033///
3034/// * **the specification**:
3035/// > Refers to the August 2015 revision of the ITU-T Recommendation X.690.
3036///
3037/// * **the default set of optionsi**:
3038/// > Refers to a `balber::BerEncoderOptions` value having a
3039/// > `datetimeFractionalSecondPrecision` attribute of 3 and a
3040/// > `encodeDateAndTimeTypesAsBinary` attribute of `false`.
3041///
3042/// See the package level documentation of {`balber`} for a definition of
3043/// the compact and extended binary formats for date and time values.
3044///
3045/// See @ref balber_berutil
3047
3048 // TYPES
3049
3050 /// `Constants` is an alias to a namespace for a suite of general-purpose
3051 /// constants that occur when encoding or decoding BER data.
3053
3054 /// `DateAndTimeHeaderUtil` is an alias to a namespace for a suite of
3055 /// functions used to implement encoding and decoding operations for the
3056 /// 2-byte header of an extended-binary-encoding formatted date-and-time
3057 /// value.
3059
3060 /// `Header` is an alias to an in-core, value-semantic attribute class
3061 /// that represents the range of valid values of the 2-byte header of
3062 /// extended-binary-encoding formatted date-and-time values.
3064
3065 /// `DateAndTimeHeaderUtil` is an alias to a namespace for a suite of
3066 /// functions used to implement encoding and decoding operations for the
3067 /// 2-byte header of an extended-binary-encoding formatted date-and-time
3068 /// value.
3070
3071 /// `DateUtil` is an alias to a namespace for a suite of functions used
3072 /// to implement BER encoding and decoding operations for date values.
3074
3075 /// `DatetimeEncoding` is an alias to a namespace for enumerating the
3076 /// set of formats that may be used by `BerUtil` to encode and decode
3077 /// values of `bdlt::Datetime` type.
3079
3080 /// `DatetimeTzEncoding` is an alias to a namespace for enumerating the
3081 /// set of formats that may be used by `BerUtil` to encode and decode
3082 /// values of `bdlt::DatetimeTz` type.
3084
3085 /// `DatetimeOrDatetimeTzEncoding` is an alias to a namespace for
3086 /// enumerating the set of formats that may be used by `BerUtil` to
3087 /// decode to values of
3088 /// `bdlb::Variant2<bdlt::Datetime, bdlt::DatetimeTz>` type.
3090
3091 /// `IntegerUtil` is an alias to a namespace for a suite of functions
3092 /// used to implement BER encoding and decoding operations for integer
3093 /// values.
3095
3096 /// `Iso8601Util` is an alias to a namespace for a suite of functions
3097 /// used to implementing the encoding and decoding of date and time
3098 /// values using the ISO 8601 format.
3100
3101 /// `LengthUtil` is an alias to a namespace for a suite of functions
3102 /// used to implement BER encoding and decoding operations for length
3103 /// quantities.
3105
3106 /// `StreambufUtil` is an alias to a namespace for a suite of functions
3107 /// used to implement input and output operations on `bsl::streambuf`
3108 /// objects.
3110
3111 /// `StringUtil` is an alias to a namespace for a suite of functions
3112 /// used by `BerUtil` to implement BER encoding and decoding operations
3113 /// for string values.
3115
3116 /// `DateUtil` is an alias to a namespace for a suite of functions used
3117 /// to implement BER encoding and decoding operations for time values.
3119
3120 /// `TimezoneUtil` is an alias to a namespace for a suite of functions
3121 /// used to implement BER encoding and decoding operations for time-zone
3122 /// offset values.
3124
3125 /// `DatetimeOrDatetimeTz` is a convenient alias for
3126 /// `bdlb::Variant2<bdlt::Datetime, bdlt::DatetimeTz>`.
3129
3130 private:
3131 // PRIVATE TYPES
3132 enum {
3133 k_EXTENDED_BINARY_SERIAL_DATE_LENGTH = 3,
3134
3135 k_EXTENDED_BINARY_DATETIME_LENGTH =
3137 k_EXTENDED_BINARY_SERIAL_DATE_LENGTH +
3139 // the number of content octets used by 'BerUtil' to encode a date
3140 // and time value using the extended-binary date and time format
3141
3142 k_EXTENDED_BINARY_DATETIMETZ_LENGTH =
3144 k_EXTENDED_BINARY_SERIAL_DATE_LENGTH +
3146 // the number of contents octets used by 'BerUtil' to encode a
3147 // date, time, and time zone value using the extended-binary date,
3148 // time, and time zone format
3149
3150 k_MAX_ISO8601_DATETIME_LENGTH = bdlt::Iso8601Util::k_DATETIME_STRLEN,
3151 // the maximum number of content octets used by 'BerUtil' to
3152 // encode a date and time value using the ISO 8601 format
3153
3154 k_MAX_ISO8601_DATETIMETZ_LENGTH =
3156 // the maximum number of content octets used by 'BerUtil' to
3157 // encode a date, time, and time zone value using the ISO 8601
3158 // format
3159
3160 k_MAX_COMPACT_BINARY_DATETIME_LENGTH = 6,
3161 // the maximum number of content octets used by 'BerUtil' to encode
3162 // a date and time value using the compact-binary date and time
3163 // format
3164
3165 k_MIN_COMPACT_BINARY_DATETIMETZ_LENGTH =
3166 k_MAX_COMPACT_BINARY_DATETIME_LENGTH + 1,
3167 // the minimum number of content octets used by 'BerUtil' to
3168 // encode a date, time, and time zone value using the
3169 // compact-binary date, time, and time zone format
3170
3171 k_MAX_COMPACT_BINARY_DATETIMETZ_LENGTH = 9
3172 // the maximum number of content octets used by 'BerUtil' to
3173 // encode a date, time, and time zone value using the
3174 // compact-binary date, time, and time zone format
3175 };
3176
3177 // PRIVATE CLASS METHODS
3178
3179 // Utilities
3180
3181 /// Load to the specified `millisecondsFromEpoch` the number of
3182 /// milliseconds between the start of the day on the compact-binary date
3183 /// epoch and the specified `value`. The compact-binary date epoch is
3184 /// the date defined by the `DateUtil::k_COMPACT_BINARY_DATE_EPOCH` serial date.
3185 ///
3186 /// \note Note that this quantity may be negative if the
3187 /// specified `value` occurs before the compact-binary date epoch.
3188 static void datetimeToMillisecondsSinceEpoch(
3189 bsls::Types::Int64 *millisecondsSinceEpoch,
3190 const bdlt::Datetime& value);
3191
3192 /// Load to the specified `value` the date and time represented by the
3193 /// specified `millisecondsSinceEpoch` number of milliseconds from the
3194 /// compact-binary date epoch. The compact-binary date epoch is the
3195 /// date defined by the `DateUtil::k_COMPACT_BINARY_DATE_EPOCH` serial
3196 /// date. Return 0 on success, and a non-zero value otherwise. The
3197 /// operation succeeds if the resulting date and time is a valid `bdlt::Datetime` value.
3198 ///
3199 /// \note Note that `millisecondsSinceEpoch` may be
3200 /// negative to indicate a date and time that occurs before the
3201 /// compact-binary date epoch.
3202 static int millisecondsSinceEpochToDatetime(
3203 bdlt::Datetime *value,
3204 bsls::Types::Int64 millisecondsSinceEpoch);
3205
3206 // 'bdlt::Datetime' Decoding
3207
3208 /// Load to the specified `encoding` the enumerator that describes the
3209 /// format used to encode a `bdlt::Datetime` value given the specified
3210 /// `length` and `firstByte` of the encoded representation. Return 0 on
3211 /// success, -1 if the format is reserved for future use, and some other
3212 /// non-zero value otherwise.
3213 static int detectDatetimeEncoding(DatetimeEncoding::Value *encoding,
3214 int length,
3215 unsigned char firstByte);
3216
3217 /// Read the specified `length` number of bytes from the input sequence
3218 /// of the specified `streamBuf` and load to the specified `value` the
3219 /// date and time value represented by the interpretation of the read
3220 /// bytes as an ISO 8601 date and time. Return 0 on success, and a
3221 /// non-zero value otherwise. The operation succeeds if `length` bytes
3222 /// are successfully read from the input sequence of the `streamBuf`
3223 /// without the read position becoming unavailable, and the bytes
3224 /// contain a valid representation of an ISO 8601 date and time.
3225 static int getIso8601DatetimeValue(bdlt::Datetime *value,
3226 bsl::streambuf *streamBuf,
3227 int length);
3228
3229 /// Read the specified `length` number of bytes from the input sequence
3230 /// of the specified `streamBuf` and load to the specified `value` the
3231 /// date and time value represented by the interpretation of the read
3232 /// bytes as a compact-binary date and time. Return 0 on success, and a
3233 /// non-zero value otherwise. The operation succeeds if `length` bytes
3234 /// are successfully read from the input sequence of the `streamBuf`
3235 /// without the read position becoming unavailable, and the bytes
3236 /// contain a valid representation of a compact-binary date and time.
3237 static int getCompactBinaryDatetimeValue(bdlt::Datetime *value,
3238 bsl::streambuf *streamBuf,
3239 int length);
3240
3241 /// Read the specified `length` number of bytes from the input sequence
3242 /// of the specified `streamBuf` and load to the specified `value` the
3243 /// date and time value represented by the interpretation of the read
3244 /// bytes as a compact-binary date, time, and time zone. Return 0 on
3245 /// success, and a non-zero value otherwise. The operation succeeds if
3246 /// `length` bytes are successfully read from the input sequence of the
3247 /// `streamBuf` without the read position becoming unavailable, and the
3248 /// bytes contain a valid representation of a compact-binary date, time,
3249 /// and time zone.
3250 static int getCompactBinaryDatetimeTzValue(bdlt::Datetime *value,
3251 bsl::streambuf *streamBuf,
3252 int length);
3253
3254 /// Read the specified `length` number of bytes from the input sequence
3255 /// of the specified `streamBuf` and load to the specified `value` the
3256 /// date and time value represented by the interpretation of the read
3257 /// bytes as an extended-binary date, time, and time zone. Return 0 on
3258 /// success, and a non-zero value otherwise. The operation succeeds if
3259 /// `length` bytes are successfully read from the input sequence of the
3260 /// `streamBuf` without the read position becoming unavailable, and the
3261 /// bytes contain a valid representation of an extended-binary date,
3262 /// time, and time zone.
3263 static int getExtendedBinaryDatetimeValue(bdlt::Datetime *value,
3264 bsl::streambuf *streamBuf,
3265 int length);
3266
3267 // 'bdlt::Datetime' Encoding
3268
3269 /// Determine the format that should be used to encode the specified
3270 /// `value` given the `value` and the specified `options`. Load to the
3271 /// specified `serialDatetime` the number of milliseconds since the
3272 /// start of the day on the compact-binary date epoch to the `value`,
3273 /// and load to the specified `length` the number of contents octets
3274 /// that would be used by the BER encoding of `serialDatetime` according
3275 /// to the specification. If `options` is 0, the default set of options
3276 /// is used. Return an enumerator identifying the selected format.
3277 ///
3278 /// \note Note that the `serialDatetime` and `length` of a date and time value
3279 /// are frequently used as arguments to date and time encoding
3280 /// operations defined in this `struct`.
3281 static DatetimeEncoding::Value selectDatetimeEncoding(
3282 bsls::Types::Int64 *serialDatetime,
3283 int *length,
3284 const bdlt::Datetime& value,
3285 const BerEncoderOptions *options);
3286
3287 /// Write the ISO 8601 representation of the specified `value` to the
3288 /// output sequence of the specified `streamBuf` according to the
3289 /// specified `options`. If `options` is 0, the default set of options
3290 /// is used. Return 0 on success, and a non-zero value otherwise. The
3291 /// operation succeeds if all bytes of the ISO 8601 representation of
3292 /// the `value` are written to the `streamBuf` without the write
3293 /// position becoming unavailable.
3294 static int putIso8601DatetimeValue(bsl::streambuf *streamBuf,
3295 const bdlt::Datetime& value,
3296 const BerEncoderOptions *options);
3297
3298 /// Write the specified `length` number of octets of the compact-binary
3299 /// date and time representation of the specified `serialDatetime`
3300 /// number of milliseconds from the start of the day on the
3301 /// compact-binary serial epoch to the output sequence of the specified
3302 /// `streamBuf` according to the specified `options`. If `options` is
3303 /// 0, the default set of options is used. Return 0 on success, and a
3304 /// non-zero value otherwise. The operation succeeds if all `length`
3305 /// bytes of the representation of the `serialDatetime` are written to
3306 /// the `streamBuf` without the write position becoming unavailable.
3307 static int putCompactBinaryDatetimeValue(
3308 bsl::streambuf *streamBuf,
3309 bsls::Types::Int64 serialDatetime,
3310 int length,
3311 const BerEncoderOptions *options);
3312
3313 /// Write the compact-binary date and time representation of the
3314 /// specified `value` to the output sequence of the specified
3315 /// `streamBuf` according to the specified `options`. If `options` is
3316 /// 0, the default set of options is used. Return 0 on success, and a
3317 /// non-zero value otherwise. The operation succeeds if all bytes of
3318 /// the compact-binary date and time representation of the `value` are
3319 /// written to the `streamBuf` without the write position becoming
3320 /// unavailable.
3321 static int putCompactBinaryDatetimeValue(
3322 bsl::streambuf *streamBuf,
3323 const bdlt::Datetime& value,
3324 const BerEncoderOptions *options);
3325
3326 /// Write the specified `length` number of octets of the compact-binary
3327 /// date, time, and time zone representation of the specified
3328 /// `serialDatetime` number of milliseconds from the start of the day on
3329 /// the compact-binary serial epoch to the output sequence of the
3330 /// specified `streamBuf` according to the specified `options`. If
3331 /// `options` is 0, the default set of options is used. Return 0 on
3332 /// success, and a non-zero value otherwise. The operation succeeds if
3333 /// all `length` bytes of the representation of the `serialDatetime` are
3334 /// written to the `streamBuf` without the write position becoming
3335 /// unavailable.
3336 static int putCompactBinaryDatetimeTzValue(
3337 bsl::streambuf *streamBuf,
3338 bsls::Types::Int64 serialDatetime,
3339 int length,
3340 const BerEncoderOptions *options);
3341
3342 /// Write the extended-binary date and time representation of the
3343 /// specified `value` to the output sequence of the specified
3344 /// `streamBuf` according to the specified `options`. If `options` is
3345 /// 0, the default set of options is used. Return 0 on success, and a
3346 /// non-zero value otherwise. The operation succeeds if all bytes of
3347 /// the extended-binary date and time representation of the `value` are
3348 /// written to the `streamBuf` without the write position becoming
3349 /// unavailable.
3350 static int putExtendedBinaryDatetimeValue(
3351 bsl::streambuf *streamBuf,
3352 const bdlt::Datetime& value,
3353 const BerEncoderOptions *options);
3354
3355 // 'bdlt::DatetimeTz' Decoding
3356
3357 /// Load to the specified `encoding` the enumerator that describes the
3358 /// format used to encode a `bdlt::DatetimeTz` value given the specified
3359 /// `length` and `firstByte` of the encoded representation. Return 0 on
3360 /// success, -1 if the format is reserved for future use, and some other
3361 /// non-zero value otherwise.
3362 static int detectDatetimeTzEncoding(
3363 DatetimeTzEncoding::Value *encoding,
3364 int length,
3365 unsigned char firstByte);
3366
3367 /// Read the specified `length` number of bytes from the input sequence
3368 /// of the specified `streamBuf` and load to the specified `value` the
3369 /// date, time, and time zone value represented by the interpretation of
3370 /// the read bytes as an ISO 8601 date, time, and time zone. Return 0
3371 /// on success, and a non-zero value otherwise. The operation succeeds
3372 /// if `length` bytes are successfully read from the input sequence of
3373 /// the `streamBuf` without the read position becoming unavailable, and
3374 /// the bytes contain a valid representation of an ISO 8601 date, time,
3375 /// and time zone .
3376 static int getIso8601DatetimeTzValue(bdlt::DatetimeTz *value,
3377 bsl::streambuf *streamBuf,
3378 int length);
3379
3380 /// Read the specified `length` number of bytes from the input sequence
3381 /// of the specified `streamBuf` and load to the specified `value` the
3382 /// date value represented by the interpretation of the read bytes as a
3383 /// compact-binary date and time. Return 0 on success, and a non-zero
3384 /// value otherwise. The operation succeeds if `length` bytes are
3385 /// successfully read from the input sequence of the `streamBuf` without
3386 /// the read position becoming unavailable, and the bytes contain a
3387 /// valid representation of a compact-binary date and time.
3388 static int getCompactBinaryDatetimeValue(bdlt::DatetimeTz *value,
3389 bsl::streambuf *streamBuf,
3390 int length);
3391
3392 /// Read the specified `length` number of bytes from the input sequence
3393 /// of the specified `streamBuf` and load to the specified `value` the
3394 /// date, time, and time zone value represented by the interpretation of
3395 /// the read bytes as a compact-binary date, time, and time zone.
3396 /// Return 0 on success, and a non-zero value otherwise. The operation
3397 /// succeeds if `length` bytes are successfully read from the input
3398 /// sequence of the `streamBuf` without the read position becoming
3399 /// unavailable, and the bytes contain a valid representation of a
3400 /// compact-binary date, time, and time zone.
3401 static int getCompactBinaryDatetimeTzValue(bdlt::DatetimeTz *value,
3402 bsl::streambuf *streamBuf,
3403 int length);
3404
3405 /// Read the specified `length` number of bytes from the input sequence
3406 /// of the specified `streamBuf` and load to the specified `value` the
3407 /// date and time zone value represented by the interpretation of the
3408 /// read bytes as an extended-binary date, time, and time zone. Return
3409 /// 0 on success, and a non-zero value otherwise. The operation
3410 /// succeeds if `length` bytes are successfully read from the input
3411 /// sequence of the `streamBuf` without the read position becoming
3412 /// unavailable, and the bytes contain a valid representation of an
3413 /// extended-binary date, time, and time zone.
3414 static int getExtendedBinaryDatetimeTzValue(bdlt::DatetimeTz *value,
3415 bsl::streambuf *streamBuf,
3416 int length);
3417
3418 // 'bdlt::DatetimeTz' Encoding
3419
3420 /// Determine the format that should be used to encode the specified
3421 /// `value` given the `value` and the specified `options`. If `options`
3422 /// is 0, the default set of options is used. Return an enumerator
3423 /// identifying the selected format.
3424 static DatetimeTzEncoding::Value selectDatetimeTzEncoding(
3425 bsls::Types::Int64 *serialDatetime,
3426 int *length,
3427 const bdlt::DatetimeTz& value,
3428 const BerEncoderOptions *options);
3429
3430 /// Write the ISO 8601 representation of the specified `value` to the
3431 /// output sequence of the specified `streamBuf` according to the
3432 /// specified `options`. If `options` is 0, the default set of options
3433 /// is used. Return 0 on success, and a non-zero value otherwise. The
3434 /// operation succeeds if all bytes of the ISO 8601 representation of
3435 /// the `value` are written to the `streamBuf` without the write
3436 /// position becoming unavailable.
3437 static int putIso8601DatetimeTzValue(bsl::streambuf *streamBuf,
3438 const bdlt::DatetimeTz& value,
3439 const BerEncoderOptions *options);
3440
3441 /// Write the specified `serialDatetimeLength` number of octets of the
3442 /// compact-binary date, time, and time zone representation using the
3443 /// specified the date and time defined by the specified
3444 /// `serialDatetime` number of milliseconds from the start of the day on
3445 /// the compact-binary serial epoch and the specified
3446 /// `timezoneOffsetInMinutes` time zone to the output sequence of the
3447 /// specified `streamBuf` according to the specified `options`. If
3448 /// `options` is 0, the default set of options is used. Return 0 on
3449 /// success, and a non-zero value otherwise. The operation succeeds if
3450 /// all `length` bytes of the compact-binary date, time, and time zone
3451 /// representation of the `serialDatetime` and `timezoneOffsetInMinutes`
3452 /// are written to the `streamBuf` without the write position becoming
3453 /// unavailable.
3454 static int putCompactBinaryDatetimeTzValue(
3455 bsl::streambuf *streamBuf,
3456 int timezoneOffsetInMinutes,
3457 bsls::Types::Int64 serialDatetime,
3458 int serialDatetimeLength,
3459 const BerEncoderOptions *options);
3460
3461 /// Write the extended-binary date, time, and time zone representation
3462 /// of the specified `value` to the output sequence of the specified
3463 /// `streamBuf` according to the specified `options`. If `options` is
3464 /// 0, the default set of options is used. Return 0 on success, and a
3465 /// non-zero value otherwise. The operation succeeds if all bytes of
3466 /// the extended-binary date, time, and time zone representation of the
3467 /// `value` are written to the `streamBuf` without the write position
3468 /// becoming unavailable.
3469 static int putExtendedBinaryDatetimeTzValue(
3470 bsl::streambuf *streamBuf,
3471 const bdlt::DatetimeTz& value,
3472 const BerEncoderOptions *options);
3473
3474 // Variant Decoding
3475
3476 /// Load to the specified `encoding` the enumerator that describes the
3477 /// format used to encode a `bdlt::Datetime` or `bdlt::DatetimeTz` value
3478 /// given the specified `length` and `firstByte` of the encoded
3479 /// representation. Return 0 on success, -1 if the format is reserved
3480 /// for future use, and some other non-zero value otherwise.
3481 static int detectDatetimeOrDatetimeTzEncoding(
3483 int length,
3484 unsigned char firstByte);
3485
3486 /// Read the specified `length` number of bytes from the input sequence
3487 /// of the specified `streamBuf` and load to the specified `value` the
3488 /// date, time, and optional time zone value represented by the
3489 /// interpretation of the read bytes as an ISO 8601 date and time.
3490 /// Return 0 on success, and a non-zero value otherwise. The operation
3491 /// succeeds if `length` bytes are successfully read from the input
3492 /// sequence of the `streamBuf` without the read position becoming
3493 /// unavailable, and the bytes contain a valid representation of an ISO
3494 /// 8601 date and time.
3495 static int getIso8601DatetimeValue(DatetimeOrDatetimeTz *value,
3496 bsl::streambuf *streamBuf,
3497 int length);
3498
3499 /// Read the specified `length` number of bytes from the input sequence
3500 /// of the specified `streamBuf` and load to the specified `value` the
3501 /// date, time, and optional time zone value represented by the
3502 /// interpretation of the read bytes as an ISO 8601 date, time, and time
3503 /// zone. Return 0 on success, and a non-zero value otherwise. The
3504 /// operation succeeds if `length` bytes are successfully read from the
3505 /// input sequence of the `streamBuf` without the read position becoming
3506 /// unavailable, and the bytes contain a valid representation of an ISO
3507 /// 8601 date, time, and time zone.
3508 static int getIso8601DatetimeTzValue(DatetimeOrDatetimeTz *value,
3509 bsl::streambuf *streamBuf,
3510 int length);
3511
3512 /// Read the specified `length` number of bytes from the input sequence
3513 /// of the specified `streamBuf` and load to the specified `value` the
3514 /// date, time, and optional time zone value represented by the
3515 /// interpretation of the read bytes as a compact-binary date and time.
3516 /// Return 0 on success, and a non-zero value otherwise. The operation
3517 /// succeeds if `length` bytes are successfully read from the input
3518 /// sequence of the `streamBuf` without the read position becoming
3519 /// unavailable, and the bytes contain a valid representation of a
3520 /// compact-binary date and time.
3521 static int getCompactBinaryDatetimeValue(DatetimeOrDatetimeTz *value,
3522 bsl::streambuf *streamBuf,
3523 int length);
3524
3525 /// Read the specified `length` number of bytes from the input sequence
3526 /// of the specified `streamBuf` and load to the specified `value` the
3527 /// date, time, and optional time zone value represented by the
3528 /// interpretation of the read bytes as a compact-binary date, time, and
3529 /// time zone. Return 0 on success, and a non-zero value otherwise.
3530 /// The operation succeeds if `length` bytes are successfully read from
3531 /// the input sequence of the `streamBuf` without the read position
3532 /// becoming unavailable, and the bytes contain a valid representation
3533 /// of a compact-binary date, time, and time zone.
3534 static int getCompactBinaryDatetimeTzValue(DatetimeOrDatetimeTz *value,
3535 bsl::streambuf *streamBuf,
3536 int length);
3537
3538 /// Read the specified `length` number of bytes from the input sequence
3539 /// of the specified `streamBuf` and load to the specified `value` the
3540 /// time value represented by the interpretation of the read bytes as a
3541 /// extended-binary date and time. Return 0 on success, and a non-zero
3542 /// value otherwise. The operation succeeds if `length` bytes are
3543 /// successfully read from the input sequence of the `streamBuf` without
3544 /// the read position becoming unavailable, and the bytes contain a
3545 /// valid representation of an extended-binary date and time.
3546 static int getExtendedBinaryDatetimeValue(DatetimeOrDatetimeTz *value,
3547 bsl::streambuf *streamBuf,
3548 int length);
3549
3550 /// Read the specified `length` number of bytes from the input sequence
3551 /// of the specified `streamBuf` and load to the specified `value` the
3552 /// time value represented by the interpretation of the read bytes as a
3553 /// extended-binary date, time, and time zone. Return 0 on success, and
3554 /// a non-zero value otherwise. The operation succeeds if `length`
3555 /// bytes are successfully read from the input sequence of the
3556 /// `streamBuf` without the read position becoming unavailable, and the
3557 /// bytes contain a valid representation of an extended-binary date,
3558 /// time, and time zone.
3559 static int getExtendedBinaryDatetimeTzValue(
3560 DatetimeOrDatetimeTz *value,
3561 bsl::streambuf *streamBuf,
3562 int length);
3563
3564 public:
3565 // CLASS METHODS
3566
3567 // 'bdlt::Datetime' Decoding
3568
3569 /// Read the specified `length` number of bytes from the input sequence
3570 /// of the specified `streamBuf` and load to the specified `value` the
3571 /// date and time value represented those bytes. Return 0 on success,
3572 /// and a non-zero value otherwise. The operation succeeds if `length`
3573 /// bytes are successfully read from the input sequence of the
3574 /// `streamBuf` without the read position becoming unavailable, and the
3575 /// bytes contain a valid representation of a date and time value. See
3576 /// the package-level documentation of
3577 /// {`balber`} for a description of the decision procedure used to
3578 /// detect the encoding format for a `bdlt::Datetime` value.
3579 static int getDatetimeValue(bdlt::Datetime *value,
3580 bsl::streambuf *streamBuf,
3581 int length);
3582
3583 // 'bdlt::Datetime' Encoding
3584
3585 /// Write a representation of the specified `value` date and time to the
3586 /// output sequence of the specified `streamBuf` according to the
3587 /// specified `options`. If `options` is 0, the default set of options
3588 /// is used. Return 0 on success, and a non-zero value otherwise. This
3589 /// operation succeeds if all bytes in the representation of the `value`
3590 /// are written to the output sequence of the `streamBuf` without the
3591 /// write position becoming unavailable. See the class documentation
3592 /// for a description of the default options. See the package-level
3593 /// documentation of {`balber`} for a description of the decision
3594 /// procedure used to select an encoding format for the `value`.
3595 static int putDatetimeValue(bsl::streambuf *streamBuf,
3596 const bdlt::Datetime& value,
3597 const BerEncoderOptions *options);
3598
3599 // 'bdlt::DatetimeTz' Decoding
3600
3601 /// Read the specified `length` number of bytes from the input sequence
3602 /// of the specified `streamBuf` and load to the specified `value` the
3603 /// date, time, and time zone value represented those bytes. Return 0
3604 /// on success, and a non-zero value otherwise. The operation succeeds
3605 /// if `length` bytes are successfully read from the input sequence of
3606 /// the `streamBuf` without the read position becoming unavailable, and
3607 /// the bytes contain a valid representation of a date, time, and time
3608 /// zone value. See the package-level documentation of {`balber`} for a
3609 /// description of the decision procedure used to detect the encoding
3610 /// format for a `bdlt::Datetime` value.
3611 static int getDatetimeTzValue(bdlt::DatetimeTz *value,
3612 bsl::streambuf *streamBuf,
3613 int length);
3614
3615 // 'bdlt::DatetimeTz' Encoding
3616
3617 /// Write a representation of the specified `value` date, time, and time
3618 /// zone to the output sequence of the specified `streamBuf` according
3619 /// to the specified `options`. If `options` is 0, the default set of
3620 /// options is used. Return 0 on success, and a non-zero value
3621 /// otherwise. This operation succeeds if all bytes in the
3622 /// representation of the `value` are written to the output sequence of
3623 /// the `streamBuf` without the write position becoming unavailable.
3624 /// See the class documentation for a description of the default
3625 /// options. See the package-level documentation of {`balber`} for a
3626 /// description of the decision procedure used to select an encoding
3627 /// format for the `value`.
3628 static int putDatetimeTzValue(bsl::streambuf *streamBuf,
3629 const bdlt::DatetimeTz& value,
3630 const BerEncoderOptions *options);
3631
3632 // Variant Decoding
3633
3634 /// Write a representation of the specified `value` date, time, and
3635 /// optional time zone to the output sequence of the specified
3636 /// `streamBuf` according to the specified `options`. If `options` is
3637 /// 0, the default set of options is used. Return 0 on success, and a
3638 /// non-zero value otherwise. This operation succeeds if all bytes in
3639 /// the representation of the `value` are written to the output sequence
3640 /// of the `streamBuf` without the write position becoming unavailable.
3641 /// See the class documentation for a description of the default
3642 /// options. See the package-level documentation of {`balber`} for a
3643 /// description of the decision procedure used to select an encoding
3644 /// format for the `value`.
3646 bsl::streambuf *streamBuf,
3647 int length);
3648};
3649
3650 // ==============================
3651 // struct BerUtil_GetValueImpUtil
3652 // ==============================
3653
3654/// This component-private utility `struct` provides a namespace for a suite
3655/// of functions that define the overload set for the implementation of
3656/// `balber::BerUtil::getValue`. The set of types used for the `value`
3657/// parameters in the overload set of `getValue` in this `struct` define the
3658/// set of types that `balber::BerUtil::getValue` supports.
3659///
3660/// See @ref balber_berutil
3662
3663 // TYPES
3664
3665 /// `BooleanUtil` is an alias to a namespace for a suite of functions
3666 /// used by `BerUtil` to implement BER encoding and decoding operations
3667 /// for boolean values.
3669
3670 /// `CharacterUtil` is an alias to a namespace for a suite of functions
3671 /// used by `BerUtil` to implement BER encoding and decoding operations
3672 /// for byte values.
3674
3675 /// `DateUtil` is an alias to a namespace for a suite of functions used
3676 /// by `BerUtil` to implement BER encoding and decoding operations for
3677 /// date values.
3679
3680 /// `DatetimeUtil` is an alias to a namespace for a suite of functions
3681 /// used by `BerUtil` to implement BER encoding and decoding operations
3682 /// for date and time values.
3684
3685 /// `FloatingPointUtil` is an alias to a namespace for a suite of
3686 /// functions used by `BerUtil` to implement BER encoding and decoding
3687 /// operations for floating-point number values.
3689
3690 /// `IntegerUtil` is an alias to a namespace for a suite of functions
3691 /// used by `BerUtil` to implement BER encoding and decoding operations
3692 /// for integer values.
3694
3695 /// `StringUtil` is an alias to a namespace for a suite of functions
3696 /// used by `BerUtil` to implement BER encoding and decoding operations
3697 /// for string values.
3699
3700 /// `TimeUtil` is an alias to a namespace for a suite of functions used
3701 /// by `BerUtil` to implement BER encoding and decoding operations for
3702 /// time values.
3704
3705 /// `DateOrDateTz` is a convenient alias for
3706 /// `bdlb::Variant2<bdlt::Date, bdlt::DateTz>`.
3708
3709 /// `DatetimeOrDatetimeTz` is a convenient alias for
3710 /// `bdlb::Variant2<bdlt::Datetime, bdlt::DatetimeTz>`.
3713
3714 /// `TimeOrTimeTz` is a convenient alias for
3715 /// `bdlb::Variant2<bdlt::Time, bdlt::TimeTz>`.
3717
3718 // CLASS METHODS
3719
3720 /// Decode the specified `value` from the specified `streamBuf`,
3721 /// consuming exactly the specified `length` bytes. Return 0 on
3722 /// success, and a non-zero value otherwise. Optionally specify
3723 /// decoding `options` to control aspects of the decoding.
3724 ///
3725 /// \note Note that the value consists of the contents of the bytes only (no length
3726 /// prefix). Also note that only fundamental C++ types, `bsl::string`,
3727 /// and BDE date/time types are supported.
3728 template <typename TYPE>
3729 static int getValue(
3730 TYPE *value,
3731 bsl::streambuf *streamBuf,
3732 int length,
3733 const BerDecoderOptions& options = BerDecoderOptions());
3734 static int getValue(
3735 bool *value,
3736 bsl::streambuf *streamBuf,
3737 int length,
3738 const BerDecoderOptions& options = BerDecoderOptions());
3739 static int getValue(
3740 char *value,
3741 bsl::streambuf *streamBuf,
3742 int length,
3743 const BerDecoderOptions& options = BerDecoderOptions());
3744 static int getValue(
3745 unsigned char *value,
3746 bsl::streambuf *streamBuf,
3747 int length,
3748 const BerDecoderOptions& options = BerDecoderOptions());
3749 static int getValue(
3750 signed char *value,
3751 bsl::streambuf *streamBuf,
3752 int length,
3753 const BerDecoderOptions& options = BerDecoderOptions());
3754 static int getValue(
3755 float *value,
3756 bsl::streambuf *streamBuf,
3757 int length,
3758 const BerDecoderOptions& options = BerDecoderOptions());
3759 static int getValue(
3760 double *value,
3761 bsl::streambuf *streamBuf,
3762 int length,
3763 const BerDecoderOptions& options = BerDecoderOptions());
3764 static int getValue(
3765 bdldfp::Decimal64 *value,
3766 bsl::streambuf *streamBuf,
3767 int length,
3768 const BerDecoderOptions& options = BerDecoderOptions());
3769 static int getValue(
3770 bsl::string *value,
3771 bsl::streambuf *streamBuf,
3772 int length,
3773 const BerDecoderOptions& options = BerDecoderOptions());
3774 static int getValue(
3775 bdlt::Date *value,
3776 bsl::streambuf *streamBuf,
3777 int length,
3778 const BerDecoderOptions& options = BerDecoderOptions());
3779 static int getValue(
3780 bdlt::DateTz *value,
3781 bsl::streambuf *streamBuf,
3782 int length,
3783 const BerDecoderOptions& options = BerDecoderOptions());
3784 static int getValue(
3785 DateOrDateTz *value,
3786 bsl::streambuf *streamBuf,
3787 int length,
3788 const BerDecoderOptions& options = BerDecoderOptions());
3789 static int getValue(
3790 bdlt::Datetime *value,
3791 bsl::streambuf *streamBuf,
3792 int length,
3793 const BerDecoderOptions& options = BerDecoderOptions());
3794 static int getValue(
3795 bdlt::DatetimeTz *value,
3796 bsl::streambuf *streamBuf,
3797 int length,
3798 const BerDecoderOptions& options = BerDecoderOptions());
3799 static int getValue(
3800 DatetimeOrDatetimeTz *value,
3801 bsl::streambuf *streamBuf,
3802 int length,
3803 const BerDecoderOptions& options = BerDecoderOptions());
3804 static int getValue(
3805 bdlt::Time *value,
3806 bsl::streambuf *streamBuf,
3807 int length,
3808 const BerDecoderOptions& options = BerDecoderOptions());
3809 static int getValue(
3810 bdlt::TimeTz *value,
3811 bsl::streambuf *streamBuf,
3812 int length,
3813 const BerDecoderOptions& options = BerDecoderOptions());
3814 static int getValue(
3815 TimeOrTimeTz *value,
3816 bsl::streambuf *streamBuf,
3817 int length,
3818 const BerDecoderOptions& options = BerDecoderOptions());
3819};
3820
3821 // ==============================
3822 // struct BerUtil_PutValueImpUtil
3823 // ==============================
3824
3825/// This component-private utility `struct` provides a namespace for a suite
3826/// of functions that define the overload set for the implementation of
3827/// `balber::BerUtil::putValue`. The set of types used for the `value`
3828/// parameters in the overload set of `putValue` in this `struct` define the
3829/// set of types that `balber::BerUtil::putValue` supports.
3830///
3831/// See @ref balber_berutil
3833
3834 // TYPES
3835
3836 /// `BooleanUtil` is an alias to a namespace for a suite of functions
3837 /// used by `BerUtil` to implement BER encoding and decoding operations
3838 /// for boolean values.
3840
3841 /// `CharacterUtil` is an alias to a namespace for a suite of functions
3842 /// used by `BerUtil` to implement BER encoding and decoding operations
3843 /// for byte values.
3845
3846 /// `DateUtil` is an alias to a namespace for a suite of functions used
3847 /// by `BerUtil` to implement BER encoding and decoding operations for
3848 /// date values.
3850
3851 /// `DatetimeUtil` is an alias to a namespace for a suite of functions
3852 /// used by `BerUtil` to implement BER encoding and decoding operations
3853 /// for date and time values.
3855
3856 /// `FloatingPointUtil` is an alias to a namespace for a suite of
3857 /// functions used by `BerUtil` to implement BER encoding and decoding
3858 /// operations for floating-point number values.
3860
3861 /// `IntegerUtil` is an alias to a namespace for a suite of functions
3862 /// used by `BerUtil` to implement BER encoding and decoding operations
3863 /// for integer values.
3865
3866 /// `StringUtil` is an alias to a namespace for a suite of functions
3867 /// used by `BerUtil` to implement BER encoding and decoding operations
3868 /// for string values.
3870
3871 /// `TimeUtil` is an alias to a namespace for a suite of functions used
3872 /// by `BerUtil` to implement BER encoding and decoding operations for
3873 /// time values.
3875
3876 // CLASS METHODS
3877
3878 /// Encode the specified `value` to the specified `streamBuf`. Return 0 on success, and a non-zero value otherwise.
3879 ///
3880 /// \note Note that the value
3881 /// consists of the length and contents primitives. Also note that only
3882 /// fundamental C++ types, `bsl::string`, `bsl::string_view`,
3883 /// `bslstl::StringRef` and BDE date/time types are supported.
3884 template <typename TYPE>
3885 static int putValue(bsl::streambuf *streamBuf,
3886 const TYPE& value,
3887 const BerEncoderOptions *options);
3888 static int putValue(bsl::streambuf *streamBuf,
3889 bool value,
3890 const BerEncoderOptions *options);
3891 static int putValue(bsl::streambuf *streamBuf,
3892 char value,
3893 const BerEncoderOptions *options);
3894 static int putValue(bsl::streambuf *streamBuf,
3895 unsigned char value,
3896 const BerEncoderOptions *options);
3897 static int putValue(bsl::streambuf *streamBuf,
3898 signed char value,
3899 const BerEncoderOptions *options);
3900 static int putValue(bsl::streambuf *streamBuf,
3901 float value,
3902 const BerEncoderOptions *options);
3903 static int putValue(bsl::streambuf *streamBuf,
3904 double value,
3905 const BerEncoderOptions *options);
3906 static int putValue(bsl::streambuf *streamBuf,
3907 bdldfp::Decimal64 value,
3908 const BerEncoderOptions *options);
3909 static int putValue(bsl::streambuf *streamBuf,
3910 const bsl::string& value,
3911 const BerEncoderOptions *options);
3912 static int putValue(bsl::streambuf *streamBuf,
3913 const bsl::string_view& value,
3914 const BerEncoderOptions *options);
3915 static int putValue(bsl::streambuf *streamBuf,
3916 const bslstl::StringRef& value,
3917 const BerEncoderOptions *options);
3918 static int putValue(bsl::streambuf *streamBuf,
3919 const bdlt::Date& value,
3920 const BerEncoderOptions *options);
3921 static int putValue(bsl::streambuf *streamBuf,
3922 const bdlt::DateTz& value,
3923 const BerEncoderOptions *options);
3924 static int putValue(bsl::streambuf *streamBuf,
3925 const bdlt::Datetime& value,
3926 const BerEncoderOptions *options);
3927 static int putValue(bsl::streambuf *streamBuf,
3928 const bdlt::DatetimeTz& value,
3929 const BerEncoderOptions *options);
3930 static int putValue(bsl::streambuf *streamBuf,
3931 const bdlt::Time& value,
3932 const BerEncoderOptions *options);
3933 static int putValue(bsl::streambuf *streamBuf,
3934 const bdlt::TimeTz& value,
3935 const BerEncoderOptions *options);
3936};
3937
3938 // ==================
3939 // struct BerUtil_Imp
3940 // ==================
3941
3942/// This component-private utility `struct` exists to provide
3943/// backwards-compatability for external components that depend upon the
3944/// facilities provided by this `struct`.
3945///
3946/// See @ref balber_berutil
3948
3949 // CLASS METHODS
3950
3951 /// Write the length and contents octets of the BER encoding of the
3952 /// specified character `string` having the specified `stringLength` (as
3953 /// defined in the specification) to the output sequence of the specified
3954 /// `streamBuf`. Return 0 if successful, and a non-zero value otherwise.
3955 /// The operation succeeds if and only if all bytes corresponding to the
3956 /// length and contents octets are written to the `streamBuf` without the
3957 /// write position becoming unavailable.
3958 static int putStringValue(bsl::streambuf *streamBuf,
3959 const char *string,
3960 int stringLength);
3961};
3962
3963// ============================================================================
3964// INLINE FUNCTION DEFINITIONS
3965// ============================================================================
3966
3967 // --------------
3968 // struct BerUtil
3969 // --------------
3970
3971// CLASS METHODS
3972inline
3973int BerUtil::getEndOfContentOctets(bsl::streambuf *streamBuf,
3974 int *accumNumBytesConsumed)
3975{
3976 return BerUtil_LengthImpUtil::getEndOfContentOctets(accumNumBytesConsumed,
3977 streamBuf);
3978}
3979
3980inline
3981int BerUtil::getLength(bsl::streambuf *streamBuf,
3982 int *result,
3983 int *accumNumBytesConsumed)
3984{
3986 result, accumNumBytesConsumed, streamBuf);
3987}
3988
3989template <class TYPE>
3990inline
3991int BerUtil::getValue(bsl::streambuf *streamBuf,
3992 TYPE *value,
3993 int length,
3994 const BerDecoderOptions& options)
3995{
3997 value, streamBuf, length, options);
3998}
3999
4000template <typename TYPE>
4001inline
4002int BerUtil::getValue(bsl::streambuf *streamBuf,
4003 TYPE *value,
4004 int *accumNumBytesConsumed,
4005 const BerDecoderOptions& options)
4006{
4007 int length;
4009 &length, accumNumBytesConsumed, streamBuf)) {
4010 return -1; // RETURN
4011 }
4012
4013 if (BerUtil::getValue(streamBuf, value, length, options)) {
4014 return -1; // RETURN
4015 }
4016
4017 *accumNumBytesConsumed += length;
4018 return 0;
4019}
4020
4021inline
4022int BerUtil::putEndOfContentOctets(bsl::streambuf *streamBuf)
4023{
4025}
4026
4027inline
4028int BerUtil::putIndefiniteLengthOctet(bsl::streambuf *streamBuf)
4029{
4031}
4032
4033inline
4034int BerUtil::putLength(bsl::streambuf *streamBuf, int length)
4035{
4036 return BerUtil_LengthImpUtil::putLength(streamBuf, length);
4037}
4038
4039template <typename TYPE>
4040inline
4041int BerUtil::putValue(bsl::streambuf *streamBuf,
4042 const TYPE& value,
4043 const BerEncoderOptions *options)
4044{
4045 return BerUtil_PutValueImpUtil::putValue(streamBuf, value, options);
4046}
4047
4048 // ----------------------------
4049 // struct BerUtil_StreambufUtil
4050 // ----------------------------
4051
4052// CLASS METHODS
4053inline
4054int BerUtil_StreambufUtil::peekChar(char *value, bsl::streambuf *streamBuf)
4055{
4056 const bsl::streambuf::int_type byte = streamBuf->sgetc();
4057 if (bsl::streambuf::traits_type::eof() == byte) {
4058 return -1; // RETURN
4059 }
4060
4061 *value = bsl::streambuf::traits_type::to_char_type(byte);
4062 return 0;
4063}
4064
4065inline
4067 bsl::streambuf *streamBuf,
4068 int bufferLength)
4069{
4070 const bsl::streamsize numCharsRead =
4071 streamBuf->sgetn(buffer, static_cast<bsl::streamsize>(bufferLength));
4072
4073 if (numCharsRead != static_cast<bsl::streamsize>(bufferLength)) {
4074 return -1; // RETURN
4075 }
4076
4077 return 0;
4078}
4079
4080inline
4081int BerUtil_StreambufUtil::putChars(bsl::streambuf *streamBuf,
4082 const char *buffer,
4083 int bufferLength)
4084{
4085 const bsl::streamsize numCharsWritten =
4086 streamBuf->sputn(buffer, static_cast<bsl::streamsize>(bufferLength));
4087
4088 if (numCharsWritten != bufferLength) {
4089 return -1; // RETURN
4090 }
4091
4092 return 0;
4093}
4094
4095 // --------------------------------
4096 // struct BerUtil_RawIntegerImpUtil
4097 // --------------------------------
4098
4099// CLASS METHODS
4100template <typename TYPE>
4102 TYPE value,
4103 int length)
4104{
4105 enum { k_BDEM_SUCCESS = 0, k_BDEM_FAILURE = -1 };
4106
4107 if (length <= 0) {
4108 return k_BDEM_FAILURE; // RETURN
4109 }
4110
4111 static const bool isUnsigned = (TYPE(-1) > TYPE(0));
4112
4113 if (isUnsigned && (unsigned)length == sizeof(TYPE) + 1) {
4114 static const TYPE SGN_BIT = static_cast<TYPE>(
4115 static_cast<TYPE>(1)
4116 << (sizeof(TYPE) * Constants::k_NUM_BITS_PER_OCTET - 1));
4117 // Length may be one greater than 'sizeof(TYPE)' only if type is
4118 // unsigned and the high bit (normally the sign bit) is set. In this
4119 // case, a leading zero octet is emitted.
4120
4121 if (!(value & SGN_BIT)) {
4122 return k_BDEM_FAILURE; // RETURN
4123 }
4124
4125 if (0 != streamBuf->sputc(0)) {
4126 return k_BDEM_FAILURE; // RETURN
4127 }
4128
4129 --length;
4130 }
4131
4132 if (static_cast<unsigned>(length) > sizeof(TYPE)) {
4133 return k_BDEM_FAILURE; // RETURN
4134 }
4135
4136#if BSLS_PLATFORM_IS_BIG_ENDIAN
4137 return length == streamBuf->sputn(
4138 static_cast<char *>(static_cast<void *>(&value)) +
4139 sizeof(TYPE) - length,
4140 length)
4141 ? k_BDEM_SUCCESS
4142 : k_BDEM_FAILURE;
4143#else
4144
4145 char *dst = static_cast<char *>(static_cast<void *>(&value)) + length;
4146 for (; length > 0; --length) {
4147 unsigned char c = *--dst;
4148 if (c != streamBuf->sputc(c)) {
4149 return k_BDEM_FAILURE; // RETURN
4150 }
4151 }
4152
4153 return k_BDEM_SUCCESS;
4154
4155#endif
4156}
4157
4158 // -----------------------------
4159 // struct BerUtil_BooleanImpUtil
4160 // -----------------------------
4161
4162// Decoding
4163
4164inline
4166 bsl::streambuf *streamBuf,
4167 int length)
4168{
4169 if (1 != length) {
4170 return -1; // RETURN
4171 }
4172
4173 int intValue = streamBuf->sbumpc();
4174 if (bsl::streambuf::traits_type::eof() == intValue) {
4175 return -1; // RETURN
4176 }
4177
4178 *value = 0 != intValue;
4179
4180 return 0;
4181}
4182
4183// Encoding
4184
4185inline
4186int BerUtil_BooleanImpUtil::putBoolValue(bsl::streambuf *streamBuf, bool value)
4187{
4188 // It has been observed in practice that 'value' may refer to uninitialized
4189 // or overwritten memory, in which case its value may neither be 'true' (1)
4190 // nor 'false' (0). We assert here to ensure that users get a useful error
4191 // message. Note that we assert (rather than returning an error code), as
4192 // it is undefined behavior to examine the value of such an uninitialized
4193 // 'bool'. Also note that gcc complains about this assert when used with
4194 // the '-Wlogical-op' flag. Therefore, to silence this warning/error we
4195 // cast the 'bool' value to a 'char *' and check the value referred to by
4196 // the 'char *'.
4197
4198 BSLMF_ASSERT(sizeof(bool) == sizeof(char));
4199 BSLS_ASSERT(0 == *static_cast<char *>(static_cast<void *>(&value)) ||
4200 1 == *static_cast<char *>(static_cast<void *>(&value)));
4201
4202 typedef bsl::streambuf::char_type char_type;
4203
4204 if (0 != LengthUtil::putLength(streamBuf, 1)) {
4205 return -1; // RETURN
4206 }
4207
4208 if (static_cast<int>(value) !=
4209 streamBuf->sputc(static_cast<char_type>(value ? 1 : 0))) {
4210 return -1; // RETURN
4211 }
4212
4213 return 0;
4214}
4215
4216 // -----------------------------
4217 // struct BerUtil_IntegerImpUtil
4218 // -----------------------------
4219
4220// CLASS METHODS
4221template <typename TYPE>
4223{
4224 int numBytes = sizeof(TYPE);
4225
4226 BSLMF_ASSERT(sizeof(TYPE) > 1);
4227
4228 // The 2 double casts to 'TYPE' in this function are necessary because if
4229 // the type is 64 bits the innermost cast is need to widen the constant
4230 // before the shift, and the outermost cast is needed if the type is
4231 // narrower than 'int'.
4232
4233 static const TYPE NEG_MASK = static_cast<TYPE>(
4234 static_cast<TYPE>(0xff80)
4235 << ((sizeof(TYPE) - 2) * Constants::k_NUM_BITS_PER_OCTET));
4236 if (0 == value) {
4237 numBytes = 1;
4238 }
4239 else if (value > 0) {
4240 static const TYPE SGN_BIT = static_cast<TYPE>(
4241 static_cast<TYPE>(1)
4242 << (sizeof(TYPE) * Constants::k_NUM_BITS_PER_OCTET - 1));
4243 if (value & SGN_BIT) {
4244 // If 'value > 0' but the high bit (sign bit) is set, then this is
4245 // an unsigned value and a leading zero byte must be emitted to
4246 // prevent the value from looking like a negative value on the
4247 // wire. The leading zero is followed by all of the bytes of the
4248 // unsigned value.
4249
4250 return static_cast<int>(sizeof(TYPE) + 1); // RETURN
4251 }
4252
4253 // This mask zeroes out the most significant byte and the first bit of
4254 // the next byte.
4255
4256 static const TYPE POS_MASK = TYPE(~NEG_MASK);
4257 while ((value & POS_MASK) == value) {
4258 value = static_cast<TYPE>(value << 8);
4259
4260 // shift out redundant high-order 0x00
4261
4262 --numBytes;
4263 }
4264 }
4265 else { // 0 > value
4266 while ((value | NEG_MASK) == value) {
4267 value = static_cast<TYPE>(
4268 static_cast<unsigned long long>(value) << 8);
4269
4270 // shift out redundant high-order 0xFF
4271
4272 --numBytes;
4273 }
4274 }
4275
4276 BSLS_ASSERT(numBytes > 0);
4277 return numBytes;
4278}
4279
4280template <typename TYPE>
4282 bsl::streambuf *streamBuf,
4283 int length)
4284{
4285 enum { k_SUCCESS = 0, k_FAILURE = -1 };
4286
4287 enum { k_SIGN_BIT_MASK = 0x80 };
4288
4289 static const bool isUnsigned = (TYPE(-1) > TYPE(0));
4290
4291 if (isUnsigned && static_cast<unsigned>(length) == sizeof(TYPE) + 1) {
4292 // Length of an unsigned is allowed to be one larger then
4293 // 'sizeof(TYPE)' only if first byte is zero. (This is so that large
4294 // unsigned numbers do not appear as negative numbers in the BER
4295 // stream). Remove the leading zero byte.
4296
4297 if (0 != streamBuf->sbumpc()) {
4298 // First byte was not zero. Fail.
4299
4300 return k_FAILURE; // RETURN
4301 }
4302
4303 --length;
4304 }
4305
4306 if (static_cast<unsigned>(length) > sizeof(TYPE)) {
4307 // Overflow.
4308
4309 return k_FAILURE; // RETURN
4310 }
4311
4312 *value = static_cast<TYPE>(streamBuf->sgetc() & k_SIGN_BIT_MASK ? -1 : 0);
4313
4314 for (int i = 0; i < length; ++i) {
4315 int nextOctet = streamBuf->sbumpc();
4316 if (bsl::streambuf::traits_type::eof() == nextOctet) {
4317 return k_FAILURE; // RETURN
4318 }
4319
4320 const unsigned long long mask =
4321 (1ull << ((sizeof(TYPE) - 1) * Constants::k_NUM_BITS_PER_OCTET)) -
4322 1;
4323 *value = static_cast<TYPE>((*value & mask)
4325 *value =
4326 static_cast<TYPE>(*value | static_cast<unsigned char>(nextOctet));
4327 }
4328
4329 return k_SUCCESS;
4330}
4331
4332inline
4334 bsl::streambuf *streamBuf)
4335{
4336 char bytes[5];
4337 if (0 != StreambufUtil::getChars(bytes, streamBuf, sizeof(bytes))) {
4338 return -1; // RETURN
4339 }
4340
4341 const bsls::Types::Uint64 byte0 =
4342 static_cast<bsls::Types::Uint64>(static_cast<unsigned char>(bytes[0]))
4343 << (8 * 4);
4344
4345 const bsls::Types::Uint64 byte1 =
4346 static_cast<bsls::Types::Uint64>(static_cast<unsigned char>(bytes[1]))
4347 << (8 * 3);
4348
4349 const bsls::Types::Uint64 byte2 =
4350 static_cast<bsls::Types::Uint64>(static_cast<unsigned char>(bytes[2]))
4351 << (8 * 2);
4352
4353 const bsls::Types::Uint64 byte3 =
4354 static_cast<bsls::Types::Uint64>(static_cast<unsigned char>(bytes[3]))
4355 << (8 * 1);
4356
4357 const bsls::Types::Uint64 byte4 =
4358 static_cast<bsls::Types::Uint64>(static_cast<unsigned char>(bytes[4]))
4359 << (8 * 0);
4360
4361 const bsls::Types::Uint64 unsignedValue =
4362 byte0 + byte1 + byte2 + byte3 + byte4;
4363
4364 *value = static_cast<bsls::Types::Int64>(unsignedValue);
4365
4366 return 0;
4367}
4368
4369template <typename TYPE>
4370int BerUtil_IntegerImpUtil::putIntegerValue(bsl::streambuf *streamBuf,
4371 TYPE value)
4372{
4373 typedef bsl::streambuf::char_type char_type;
4374
4375 const int length = getNumOctetsToStream(value);
4376 if (length != streamBuf->sputc(static_cast<char_type>(length))) {
4377 return -1; // RETURN
4378 }
4379
4380 return putIntegerGivenLength(streamBuf, value, length);
4381}
4382
4383template <typename TYPE>
4385 TYPE value,
4386 int length)
4387{
4388 return RawIntegerUtil::putIntegerGivenLength(streamBuf, value, length);
4389}
4390
4391/// # Implementation Note
4392/// This implementation requires the platform use a 2's complement
4393/// representation for signed integer values.
4394inline
4396 bsls::Types::Int64 value)
4397{
4398 BSLS_ASSERT(-549755813888ll <= value);
4399 BSLS_ASSERT(549755813888ll > value);
4400
4401 const bsls::Types::Uint64 unsignedValue = value;
4402
4403 const char bytes[5] = {
4404 static_cast<char>(
4405 static_cast<unsigned char>((unsignedValue >> (8 * 4)) & 0xFF)),
4406 static_cast<char>(
4407 static_cast<unsigned char>((unsignedValue >> (8 * 3)) & 0xFF)),
4408 static_cast<char>(
4409 static_cast<unsigned char>((unsignedValue >> (8 * 2)) & 0xFF)),
4410 static_cast<char>(
4411 static_cast<unsigned char>((unsignedValue >> (8 * 1)) & 0xFF)),
4412 static_cast<char>(
4413 static_cast<unsigned char>((unsignedValue >> (8 * 0)) & 0xFF))};
4414
4415 return StreambufUtil::putChars(streamBuf, bytes, sizeof(bytes));
4416}
4417
4418 // -------------------------------
4419 // struct BerUtil_CharacterImpUtil
4420 // -------------------------------
4421
4422// CLASS METHODS
4423
4424// Decoding
4425
4426inline
4428 bsl::streambuf *streamBuf,
4429 int length)
4430{
4431 switch (length) {
4432 case 1: {
4433 ; // do nothing
4434 } break;
4435 case 2: {
4436 if (0 != streamBuf->sbumpc()) {
4437 // see 'getIntegerValue', if this 'char' had been encoded as
4438 // 'unsigned' there might be a leading 0 which is acceptable, but
4439 // any other value for the first byte is invalid
4440
4441 return -1; // RETURN
4442 }
4443 } break;
4444 default: {
4445 return -1; // RETURN
4446 }
4447 }
4448
4449 int valueOctet = streamBuf->sbumpc();
4450 if (bsl::streambuf::traits_type::eof() == valueOctet) {
4451 return -1; // RETURN
4452 }
4453
4454 *value = static_cast<char>(valueOctet);
4455 return 0;
4456}
4457
4458inline
4460 bsl::streambuf *streamBuf,
4461 int length)
4462{
4463 char temp;
4464 if (0 != getCharValue(&temp, streamBuf, length)) {
4465 return -1; // RETURN
4466 }
4467
4468 *value = static_cast<signed char>(temp);
4469 return 0;
4470}
4471
4472inline
4474 bsl::streambuf *streamBuf,
4475 int length)
4476{
4477 short temp;
4478 if (IntegerUtil::getIntegerValue(&temp, streamBuf, length)) {
4479 return -1; // RETURN
4480 }
4481
4482 *value = static_cast<unsigned char>(temp);
4483 return 0;
4484}
4485
4486// Encoding
4487
4488inline
4489int BerUtil_CharacterImpUtil::putCharValue(bsl::streambuf *streamBuf,
4490 char value)
4491{
4492 if (0 != LengthUtil::putLength(streamBuf, 1)) {
4493 return -1; // RETURN
4494 }
4495
4496 if (static_cast<unsigned char>(value) != streamBuf->sputc(value)) {
4497 return -1; // RETURN
4498 }
4499
4500 return 0;
4501}
4502
4503inline
4505 signed char value)
4506{
4507 return putCharValue(streamBuf, static_cast<char>(value));
4508}
4509
4510inline
4512 unsigned char value)
4513{
4514 return IntegerUtil::putIntegerValue(streamBuf,
4515 static_cast<unsigned short>(value));
4516}
4517
4518 // -----------------------------------
4519 // struct BerUtil_FloatingPointImpUtil
4520 // -----------------------------------
4521
4522// CLASS METHODS
4523
4524// Decoding
4525
4526inline
4528 bsl::streambuf *streamBuf,
4529 int length)
4530{
4531 double tentativeValue;
4532 if (0 != getDoubleValue(&tentativeValue, streamBuf, length)) {
4533 return -1; // RETURN
4534 }
4535
4536 *value = static_cast<float>(tentativeValue);
4537
4538 return 0;
4539}
4540
4541// Encoding
4542
4543inline
4545 bsl::streambuf *streamBuf,
4546 float value,
4547 const BerEncoderOptions *options)
4548{
4549 return putDoubleValue(streamBuf,
4550 static_cast<double>(value),
4551 options);
4552}
4553
4554 // ----------------------------
4555 // struct BerUtil_StringImpUtil
4556 // ----------------------------
4557
4558// CLASS METHODS
4559
4560// Encoding Utilities
4561
4562inline
4563int BerUtil_StringImpUtil::putRawStringValue(bsl::streambuf *streamBuf,
4564 const char *value,
4565 int valueLength)
4566{
4567 if (0 != LengthUtil::putLength(streamBuf, valueLength)) {
4568 return -1; // RETURN
4569 }
4570
4571 if (valueLength != streamBuf->sputn(value, valueLength)) {
4572 return -1; // RETURN
4573 }
4574
4575 return 0;
4576}
4577
4578// 'bsl::string' Encoding
4579
4580inline
4581int BerUtil_StringImpUtil::putStringValue(bsl::streambuf *streamBuf,
4582 const bsl::string& value)
4583{
4584 return putRawStringValue(
4585 streamBuf, value.data(), static_cast<int>(value.length()));
4586}
4587
4588// 'bsl::string_view' Encoding
4589
4590inline
4592 bsl::streambuf *streamBuf,
4593 const bsl::string_view& value)
4594{
4595 return putRawStringValue(
4596 streamBuf, value.data(), static_cast<int>(value.length()));
4597}
4598
4599// 'bslstl::StringRef' Encoding
4600
4601inline
4603 bsl::streambuf *streamBuf,
4604 const bslstl::StringRef& value)
4605{
4606 return putRawStringValue(
4607 streamBuf, value.data(), static_cast<int>(value.length()));
4608}
4609
4610 // -----------------------------
4611 // struct BerUtil_Iso8601ImpUtil
4612 // -----------------------------
4613
4614// PRIVATE CLASS METHODS
4615template <class TYPE>
4616int BerUtil_Iso8601ImpUtil::getValue(TYPE *value,
4617 bsl::streambuf *streamBuf,
4618 int length)
4619{
4620 if (length <= 0) {
4621 return -1; // RETURN
4622 }
4623
4624 // DoS attack mitigation: Any reasonable ISO8601 string will be smaller
4625 // than this. Even an ISO 8601 duration (not currently supported) with all
4626 // its elements (years, months, days, hours, minutes, and seconds) present
4627 // with 17 significant digits and negative signs would be 117 characters.
4628 if (length > 126) {
4629 return -1; // RETURN
4630 }
4631
4632 char localBuf[32]; // for common case where length <= 32
4633 bsl::vector<char> vecBuf; // for length > 32
4634 char *buf;
4635
4636 if (length <= 32) {
4637 buf = localBuf;
4638 }
4639 else {
4640 vecBuf.resize(length);
4641 buf = &vecBuf[0]; // First byte of contiguous string
4642 }
4643
4644 const bsl::streamsize bytesConsumed = streamBuf->sgetn(buf, length);
4645 if (static_cast<int>(bytesConsumed) != length) {
4646 return -1; // RETURN
4647 }
4648
4649 return bdlt::Iso8601Util::parse(value, buf, length);
4650}
4651
4652template <class TYPE>
4653int BerUtil_Iso8601ImpUtil::putValue(bsl::streambuf *streamBuf,
4654 const TYPE& value,
4655 const BerEncoderOptions *options)
4656{
4659 int datetimeFractionalSecondPrecision =
4660 options ? options->datetimeFractionalSecondPrecision() : 6;
4661 config.setFractionalSecondPrecision(datetimeFractionalSecondPrecision);
4662 int len = bdlt::Iso8601Util::generate(buf, sizeof(buf), value, config);
4663
4664 return StringUtil::putStringRefValue(streamBuf,
4665 bslstl::StringRef(buf, len));
4666}
4667
4668 // --------------------------------------
4669 // struct BerUtil_ExtendedBinaryEncodingUtil
4670 // --------------------------------------
4671
4672// CLASS METHODS
4673inline
4675 const bdlt::Time& value,
4676 const BerEncoderOptions *options)
4677{
4678 if (!options) {
4679 // If encoding options are not specified, by default the ISO8601 format
4680 // is used.
4681
4682 return false; // RETURN
4683 }
4684
4685 const bool useBinaryEncoding = options->encodeDateAndTimeTypesAsBinary();
4686
4687 const bool useMicrosecondPrecision =
4688 (6 == options->datetimeFractionalSecondPrecision());
4689
4690 const bool compactBinaryEncodingOfValueIsBuggy = (bdlt::Time() == value);
4691 // The compact binary encoding format ambiguously encodes both the
4692 // '00:00:00' time value and the '24:00:00' time value to the same bit
4693 // pattern. The decoder treats this bit pattern as the '00:00:00' time
4694 // value. The extended binary encoding format does not have this
4695 // limitation. Therefore, if the extended binary format is allowed, it
4696 // should be used to encode default time values even if the fractional
4697 // second precision is not 6.
4698
4699 const bool useExtendedBinaryEncodingIfAllowed =
4700 useMicrosecondPrecision || compactBinaryEncodingOfValueIsBuggy;
4701
4702 const bool extendedBinaryEncodingIsAllowed =
4703 (options->bdeVersionConformance() >=
4705
4706 return useBinaryEncoding && useExtendedBinaryEncodingIfAllowed &&
4707 extendedBinaryEncodingIsAllowed;
4708}
4709
4710inline
4712 const bdlt::TimeTz& value,
4713 const BerEncoderOptions *options)
4714{
4715 return useExtendedBinaryEncoding(value.localTime(), options);
4716}
4717
4718inline
4720 const bdlt::Datetime& value,
4721 const BerEncoderOptions *options)
4722{
4723 return useExtendedBinaryEncoding(value.time(), options);
4724}
4725
4726inline
4728 const bdlt::DatetimeTz& value,
4729 const BerEncoderOptions *options)
4730{
4731 return useExtendedBinaryEncoding(value.localDatetime().time(), options);
4732}
4733
4734inline
4736 const BerEncoderOptions *options)
4737{
4738 return options && options->encodeDateAndTimeTypesAsBinary();
4739}
4740
4741 // -------------------------------
4742 // class BerUtil_DateAndTimeHeader
4743 // -------------------------------
4744
4745// CREATORS
4746inline
4748: d_type(Type::e_NOT_EXTENDED_BINARY)
4749, d_timezoneOffsetInMinutes(0)
4750{
4751}
4752
4753// MANIPULATORS
4754inline
4756{
4758 d_timezoneOffsetInMinutes = 0;
4759}
4760
4761inline
4763{
4765 d_timezoneOffsetInMinutes = 0;
4766}
4767
4768inline
4770{
4772
4774 d_timezoneOffsetInMinutes = offset;
4775}
4776
4777// ACCESSORS
4778inline
4784
4785inline
4790
4791inline
4796
4797inline
4799{
4800 return d_timezoneOffsetInMinutes;
4801}
4802
4803 // ---------------------------------------
4804 // struct BerUtil_DateAndTimeHeaderImpUtil
4805 // ---------------------------------------
4806
4807// CLASS METHODS
4808inline
4810{
4811 // A date-and-time header has a reserved bit pattern if:
4812 //..
4813 // o the first bit is 1, and any of the following are true:
4814 // o the second bit is 1
4815 // o the third bit is 1
4816 //..
4817
4818 const bool bit0 = firstByte & 0x80;
4819 const bool bit1 = firstByte & 0x40;
4820 const bool bit2 = firstByte & 0x20;
4821
4822 return bit0 && (bit1 || bit2);
4823}
4824
4825inline
4827 unsigned char firstByte)
4828{
4829 const bool bit0 = firstByte & 0x80;
4830 const bool bit1 = firstByte & 0x40;
4831 const bool bit2 = firstByte & 0x20;
4832
4833 return bit0 && !(bit1 || bit2);
4834}
4835
4836inline
4838 unsigned char firstByte)
4839{
4840 const bool bit0 = firstByte & 0x80;
4841 const bool bit1 = firstByte & 0x40;
4842 const bool bit2 = firstByte & 0x20;
4843 const bool bit3 = firstByte & 0x10;
4844
4845 return bit0 && !(bit1 || bit2) && !bit3;
4846}
4847
4848inline
4850 unsigned char firstByte)
4851{
4852 const bool bit0 = firstByte & 0x80;
4853 const bool bit1 = firstByte & 0x40;
4854 const bool bit2 = firstByte & 0x20;
4855 const bool bit3 = firstByte & 0x10;
4856
4857 return bit0 && !(bit1 || bit2) && bit3;
4858}
4859
4860inline
4862 bool *reserved,
4863 Type::Value *type,
4864 unsigned char firstByte)
4865{
4866 if (isReserved(firstByte)) {
4867 *reserved = true;
4868 return; // RETURN
4869 }
4870
4871 *reserved = false;
4872 detectType(type, firstByte);
4873}
4874
4875inline
4877 unsigned char firstByte)
4878{
4879 BSLS_ASSERT_OPT(!isReserved(firstByte));
4880
4881 const bool bit0 = firstByte & 0x80;
4882 const bool bit3 = firstByte & 0x10;
4883
4884 if (bit0 & bit3) {
4886 return; // RETURN
4887 }
4888
4889 if (bit0 & !bit3) {
4891 return; // RETURN
4892 }
4893
4895}
4896
4897inline
4899 Header *value,
4900 bsl::streambuf *streamBuf)
4901{
4902 char headerBytes[2];
4903 if (0 !=
4904 StreambufUtil::getChars(headerBytes, streamBuf, sizeof(headerBytes))) {
4905 return -1; // RETURN
4906 }
4907
4908 const unsigned char headerByte0 =
4909 static_cast<unsigned char>(headerBytes[0]);
4910 const unsigned char headerByte1 =
4911 static_cast<unsigned char>(headerBytes[1]);
4912
4913 return getValueIfNotReserved(value, headerByte0, headerByte1);
4914}
4915
4916inline
4918 Header *value,
4919 unsigned char headerByte0,
4920 unsigned char headerByte1)
4921{
4922 if (isReserved(headerByte0)) {
4923 return -1; // RETURN
4924 }
4925
4926 return getValue(value, headerByte0, headerByte1);
4927}
4928
4929inline
4931 bsl::streambuf *streamBuf)
4932{
4933 char headerBytes[2];
4934 if (0 !=
4935 StreambufUtil::getChars(headerBytes, streamBuf, sizeof(headerBytes))) {
4936 return -1; // RETURN
4937 }
4938
4939 const unsigned char headerByte0 =
4940 static_cast<unsigned char>(headerBytes[0]);
4941 const unsigned char headerByte1 =
4942 static_cast<unsigned char>(headerBytes[1]);
4943
4944 return getValue(value, headerByte0, headerByte1);
4945}
4946
4947inline
4949 unsigned char headerByte0,
4950 unsigned char headerByte1)
4951{
4952 BSLS_ASSERT_OPT(!isReserved(headerByte0));
4953
4954 Type::Value type;
4955 detectType(&type, headerByte0);
4956
4957 switch (type) {
4959 value->makeNotExtendedBinary();
4960 return 0; // RETURN
4961 } break;
4963 // If the header indicates that it does not carry time-zone
4964 // information, and the low 12 bits of the header are non-zero, then
4965 // the header is malformed.
4966
4967 if ((headerByte0 & 0x0F) | (headerByte1 & 0xFF)) {
4968 return -1; // RETURN
4969 }
4970
4972 return 0; // RETURN
4973 } break;
4975 enum { k_TIMEZONE_SIGN_BIT = 0x08 };
4976
4977 // If the time-zone offset's sign bit is 1, then sign-extend the low
4978 // nibble of the first byte, which encodes the 4 hi bits of the
4979 // 12-bit, 2's-complement number that represents the time-zone offset
4980 // in minutes.
4981
4982 const unsigned char timezoneOffsetHi =
4983 (headerByte0 & k_TIMEZONE_SIGN_BIT)
4984 ? ((0x0F & headerByte0) | 0xF0)
4985 : ((0x0F & headerByte0) | 0x00);
4986
4987 const signed char signedTimezoneOffsetHi =
4988 static_cast<signed char>(timezoneOffsetHi);
4989
4990 const unsigned char timezoneOffsetLo = headerByte1;
4991
4992 const int timezoneOffset =
4993 (static_cast<unsigned>(signedTimezoneOffsetHi) << 8) |
4994 (static_cast<unsigned>(timezoneOffsetLo) << 0);
4995
4996 if (!TimezoneUtil::isValidTimezoneOffsetInMinutes(timezoneOffset)) {
4997 return -1; // RETURN
4998 }
4999
5000 value->makeExtendedBinaryWithTimezone(timezoneOffset);
5001 return 0; // RETURN
5002 } break;
5003 }
5004
5005 BSLS_ASSERT_OPT(0 == "Unreachable");
5006#if BSLA_UNREACHABLE_IS_ACTIVE
5008#else
5009 return -1; // RETURN
5010#endif
5011}
5012
5013inline
5015 bsl::streambuf *streamBuf)
5016{
5017 static const char header[k_HEADER_LENGTH] = {'\x80', '\x00'};
5018 return StreambufUtil::putChars(streamBuf, header, k_HEADER_LENGTH);
5019}
5020
5021inline
5023 bsl::streambuf *streamBuf,
5024 int timezoneOffsetInMinutes)
5025{
5027 TimezoneUtil::isValidTimezoneOffsetInMinutes(timezoneOffsetInMinutes));
5028
5029 const unsigned short offsetWord =
5030 static_cast<unsigned short>(timezoneOffsetInMinutes);
5031
5032 static const unsigned short k_OFFSET_MASK = 0x0FFF;
5033
5034 const unsigned short headerWord = 0x9000 | (offsetWord & k_OFFSET_MASK);
5035
5036 const char header[k_HEADER_LENGTH] = {
5037 static_cast<char>((headerWord >> 8) & 0xFF),
5038 static_cast<char>((headerWord >> 0) & 0xFF)};
5039
5040 return StreambufUtil::putChars(streamBuf, header, k_HEADER_LENGTH);
5041}
5042
5043 // --------------------------
5044 // struct BerUtil_DateImpUtil
5045 // --------------------------
5046
5047// PRIVATE CLASS METHODS
5048
5049// 'bdlt::Date' Decoding
5050
5051inline
5052int BerUtil_DateImpUtil::detectDateEncoding(DateEncoding::Value *encoding,
5053 int length,
5054 unsigned char firstByte)
5055{
5056 if (k_MAX_COMPACT_BINARY_DATE_LENGTH >= length) {
5058 return 0; // RETURN
5059 }
5060
5061 BSLS_ASSERT_SAFE(k_MAX_COMPACT_BINARY_DATE_LENGTH < length);
5062
5063 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5064 return -1; // RETURN
5065 }
5066
5067 *encoding = DateEncoding::e_ISO8601_DATE;
5068 return 0;
5069}
5070
5071// 'bdlt::Date' Encoding
5072
5073inline
5074BerUtil_DateEncoding::Value BerUtil_DateImpUtil::selectDateEncoding(
5075 const bdlt::Date&,
5076 const BerEncoderOptions *options)
5077{
5078 if (options && options->encodeDateAndTimeTypesAsBinary()) {
5079 return DateEncoding::e_COMPACT_BINARY_DATE; // RETURN
5080 }
5081
5083}
5084
5085// 'bdlt::DateTz' Decoding
5086
5087inline
5088int BerUtil_DateImpUtil::detectDateTzEncoding(DateTzEncoding::Value *encoding,
5089 int length,
5090 unsigned char firstByte)
5091{
5092 BSLMF_ASSERT(k_MAX_COMPACT_BINARY_DATE_LENGTH <
5093 k_MIN_COMPACT_BINARY_DATETZ_LENGTH);
5094
5095 if (k_MIN_COMPACT_BINARY_DATETZ_LENGTH > length) {
5097 return 0; // RETURN
5098 }
5099
5100 if (k_MAX_COMPACT_BINARY_DATETZ_LENGTH >= length) {
5102 return 0; // RETURN
5103 }
5104
5105 BSLS_ASSERT_SAFE(k_MAX_COMPACT_BINARY_DATETZ_LENGTH < length);
5106
5107 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5108 return -1; // RETURN
5109 }
5110
5112 return 0;
5113}
5114
5115// 'bdlt::DateTz' Encoding
5116
5117inline
5118BerUtil_DateTzEncoding::Value BerUtil_DateImpUtil::selectDateTzEncoding(
5119 const bdlt::DateTz& value,
5120 const BerEncoderOptions *options)
5121{
5122 if (options && options->encodeDateAndTimeTypesAsBinary() &&
5123 0 == value.offset()) {
5125 }
5126
5127 if (options && options->encodeDateAndTimeTypesAsBinary()) {
5129 }
5130
5132}
5133
5134// Variant Decoding
5135
5136inline
5137int BerUtil_DateImpUtil::detectDateOrDateTzEncoding(
5138 DateOrDateTzEncoding::Value *encoding,
5139 int length,
5140 unsigned char firstByte)
5141{
5142 if (k_MAX_COMPACT_BINARY_DATE_LENGTH >= length) {
5144 return 0; // RETURN
5145 }
5146
5147 BSLS_ASSERT_SAFE(k_MAX_COMPACT_BINARY_DATE_LENGTH < length);
5148
5149 if (k_MAX_COMPACT_BINARY_DATETZ_LENGTH >= length) {
5151 return 0; // RETURN
5152 }
5153
5154 BSLS_ASSERT_SAFE(k_MAX_COMPACT_BINARY_DATETZ_LENGTH < length);
5155
5156 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5157 return -1; // RETURN
5158 }
5159
5160 if (k_MAX_ISO8601_DATE_LENGTH >= length) {
5162 return 0; // RETURN
5163 }
5164
5165 BSLS_ASSERT_SAFE(k_MAX_ISO8601_DATE_LENGTH < length);
5166
5168 return 0;
5169}
5170
5171inline
5172int BerUtil_DateImpUtil::getIso8601DateValue(DateOrDateTz *value,
5173 bsl::streambuf *streamBuf,
5174 int length)
5175{
5176 value->createInPlace<bdlt::Date>();
5177 return getIso8601DateValue(&value->the<bdlt::Date>(), streamBuf, length);
5178}
5179
5180inline
5181int BerUtil_DateImpUtil::getIso8601DateTzValue(DateOrDateTz *value,
5182 bsl::streambuf *streamBuf,
5183 int length)
5184{
5185 value->createInPlace<bdlt::DateTz>();
5186 return getIso8601DateTzValue(
5187 &value->the<bdlt::DateTz>(), streamBuf, length);
5188}
5189
5190inline
5191int BerUtil_DateImpUtil::getCompactBinaryDateValue(DateOrDateTz *value,
5192 bsl::streambuf *streamBuf,
5193 int length)
5194{
5195 value->createInPlace<bdlt::Date>();
5196 return getCompactBinaryDateValue(
5197 &value->the<bdlt::Date>(), streamBuf, length);
5198}
5199
5200inline
5201int BerUtil_DateImpUtil::getCompactBinaryDateTzValue(DateOrDateTz *value,
5202 bsl::streambuf *streamBuf,
5203 int length)
5204{
5205 value->createInPlace<bdlt::DateTz>();
5206 return getCompactBinaryDateTzValue(
5207 &value->the<bdlt::DateTz>(), streamBuf, length);
5208}
5209
5210// CLASS METHODS
5211
5212// Variant Decoding
5213
5214inline
5216 bsl::streambuf *streamBuf,
5217 int length)
5218{
5219 char firstByte;
5220 if (0 != StreambufUtil::peekChar(&firstByte, streamBuf)) {
5221 return -1; // RETURN
5222 }
5223
5225 int rc = detectDateOrDateTzEncoding(&encoding, length, firstByte);
5226
5227 if (0 != rc) {
5228 return -1; // RETURN
5229 }
5230
5231 switch (encoding) {
5233 return getIso8601DateValue(value, streamBuf, length); // RETURN
5234 } break;
5236 return getIso8601DateTzValue(value, streamBuf, length); // RETURN
5237 } break;
5239 return getCompactBinaryDateValue(value, streamBuf, length); // RETURN
5240 } break;
5242 return getCompactBinaryDateTzValue(value, streamBuf, length);
5243 // RETURN
5244 } break;
5245 }
5246
5247 BSLS_ASSERT_OPT(0 == "Unreachable");
5248#if BSLA_UNREACHABLE_IS_ACTIVE
5250#else
5251 return -1; // RETURN
5252#endif
5253}
5254
5255 // --------------------------
5256 // struct BerUtil_TimeImpUtil
5257 // --------------------------
5258
5259// PRIVATE CLASS METHODS
5260
5261// Utilities
5262
5263inline
5265 bsls::Types::Int64 *daysSinceEpoch,
5266 const bdlt::Date& date)
5267{
5268 const int serialDate = bdlt::ProlepticDateImpUtil::ymdToSerial(
5269 date.year(), date.month(), date.day());
5270
5271 *daysSinceEpoch = serialDate - k_COMPACT_BINARY_DATE_EPOCH;
5272}
5273
5274inline
5276 bdlt::Date *date,
5277 bsls::Types::Int64 daysSinceEpoch)
5278{
5279 const bsls::Types::Int64 serialDate =
5280 daysSinceEpoch + k_COMPACT_BINARY_DATE_EPOCH;
5281
5283 static_cast<int>(serialDate))) {
5284 return -1; // RETURN
5285 }
5286
5287 int year;
5288 int month;
5289 int day;
5291 &year, &month, &day, static_cast<int>(serialDate));
5292
5293 date->setYearMonthDay(year, month, day);
5294 return 0;
5295}
5296
5297// 'bdlt::Time' Decoding
5298
5299inline
5300int BerUtil_TimeImpUtil::detectTimeEncoding(TimeEncoding::Value *encoding,
5301 int length,
5302 unsigned char firstByte)
5303{
5304 if (k_MAX_COMPACT_BINARY_TIME_LENGTH >= length) {
5306 return 0; // RETURN
5307 }
5308
5309 BSLS_ASSERT_SAFE(k_MAX_COMPACT_BINARY_TIME_LENGTH < length);
5310
5311 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5312 return -1; // RETURN
5313 }
5314
5317 return 0; // RETURN
5318 }
5319
5320 *encoding = TimeEncoding::e_ISO8601_TIME;
5321 return 0;
5322}
5323
5324inline
5325int BerUtil_TimeImpUtil::getIso8601TimeValue(bdlt::Time *value,
5326 bsl::streambuf *streamBuf,
5327 int length)
5328{
5329 return Iso8601Util::getTimeValue(value, streamBuf, length);
5330}
5331
5332// 'bdlt::Time' Encoding
5333
5334inline
5335BerUtil_TimeEncoding::Value BerUtil_TimeImpUtil::selectTimeEncoding(
5336 const bdlt::Time& value,
5337 const BerEncoderOptions *options)
5338{
5340 options)) {
5341 return TimeEncoding::e_EXTENDED_BINARY_TIME; // RETURN
5342 }
5343
5345 return TimeEncoding::e_COMPACT_BINARY_TIME; // RETURN
5346 }
5347
5349}
5350
5351inline
5352int BerUtil_TimeImpUtil::putIso8601TimeValue(
5353 bsl::streambuf *streamBuf,
5354 const bdlt::Time& value,
5355 const BerEncoderOptions *options)
5356{
5357 return Iso8601Util::putTimeValue(streamBuf, value, options);
5358}
5359
5360// 'bdlt::Time' Decoding
5361
5362inline
5363int BerUtil_TimeImpUtil::detectTimeTzEncoding(TimeTzEncoding::Value *encoding,
5364 int length,
5365 unsigned char firstByte)
5366{
5367 BSLMF_ASSERT(k_MAX_COMPACT_BINARY_TIME_LENGTH <
5368 k_MIN_COMPACT_BINARY_TIMETZ_LENGTH);
5369
5370 BSLMF_ASSERT(k_MIN_COMPACT_BINARY_TIMETZ_LENGTH <=
5371 k_MAX_COMPACT_BINARY_TIMETZ_LENGTH);
5372
5373 if (k_MAX_COMPACT_BINARY_TIME_LENGTH >= length) {
5375 return 0; // RETURN
5376 }
5377
5378 if (k_MAX_COMPACT_BINARY_TIMETZ_LENGTH >= length) {
5380 return 0; // RETURN
5381 }
5382
5383 BSLS_ASSERT(k_MAX_COMPACT_BINARY_TIMETZ_LENGTH < length);
5384
5385 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5386 return -1; // RETURN
5387 }
5388
5391 return 0; // RETURN
5392 }
5393
5395 return 0;
5396}
5397
5398inline
5399int BerUtil_TimeImpUtil::getIso8601TimeTzValue(bdlt::TimeTz *value,
5400 bsl::streambuf *streamBuf,
5401 int length)
5402{
5403 return Iso8601Util::getTimeTzValue(value, streamBuf, length);
5404}
5405
5406// 'bdlt::TimeTz' Encoding
5407
5408inline
5409BerUtil_TimeTzEncoding::Value BerUtil_TimeImpUtil::selectTimeTzEncoding(
5410 const bdlt::TimeTz& value,
5411 const BerEncoderOptions *options)
5412{
5414 options)) {
5416 }
5417
5419 (0 == value.offset())) {
5421 }
5422
5425 }
5426
5428}
5429
5430inline
5431int BerUtil_TimeImpUtil::putIso8601TimeTzValue(
5432 bsl::streambuf *streamBuf,
5433 const bdlt::TimeTz& value,
5434 const BerEncoderOptions *options)
5435{
5436 return Iso8601Util::putTimeTzValue(streamBuf, value, options);
5437}
5438
5439// Variant Decoding
5440
5441inline
5442int BerUtil_TimeImpUtil::detectTimeOrTimeTzEncoding(
5443 TimeOrTimeTzEncoding::Value *encoding,
5444 int length,
5445 unsigned char firstByte)
5446{
5447 if (k_MAX_COMPACT_BINARY_TIME_LENGTH >= length) {
5449 return 0; // RETURN
5450 }
5451
5452 if (k_MAX_COMPACT_BINARY_TIMETZ_LENGTH >= length) {
5454 return 0; // RETURN
5455 }
5456
5457 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5458 return -1; // RETURN
5459 }
5460
5463 return 0; // RETURN
5464 }
5465
5468 return 0; // RETURN
5469 }
5470
5471 if (k_MAX_ISO8601_TIME_LENGTH >= length) {
5473 return 0; // RETURN
5474 }
5475
5477 return 0;
5478}
5479
5480inline
5481int BerUtil_TimeImpUtil::getIso8601TimeValue(TimeOrTimeTz *value,
5482 bsl::streambuf *streamBuf,
5483 int length)
5484{
5485 value->createInPlace<bdlt::Time>();
5486 return getIso8601TimeValue(&value->the<bdlt::Time>(), streamBuf, length);
5487}
5488
5489inline
5490int BerUtil_TimeImpUtil::getIso8601TimeTzValue(TimeOrTimeTz *value,
5491 bsl::streambuf *streamBuf,
5492 int length)
5493{
5494 value->createInPlace<bdlt::TimeTz>();
5495 return getIso8601TimeTzValue(
5496 &value->the<bdlt::TimeTz>(), streamBuf, length);
5497}
5498
5499inline
5500int BerUtil_TimeImpUtil::getCompactBinaryTimeValue(TimeOrTimeTz *value,
5501 bsl::streambuf *streamBuf,
5502 int length)
5503{
5504 value->createInPlace<bdlt::Time>();
5505 return getCompactBinaryTimeValue(
5506 &value->the<bdlt::Time>(), streamBuf, length);
5507}
5508
5509inline
5510int BerUtil_TimeImpUtil::getCompactBinaryTimeTzValue(TimeOrTimeTz *value,
5511 bsl::streambuf *streamBuf,
5512 int length)
5513{
5514 value->createInPlace<bdlt::TimeTz>();
5515 return getCompactBinaryTimeTzValue(
5516 &value->the<bdlt::TimeTz>(), streamBuf, length);
5517}
5518
5519inline
5520int BerUtil_TimeImpUtil::getExtendedBinaryTimeValue(TimeOrTimeTz *value,
5521 bsl::streambuf *streamBuf,
5522 int length)
5523{
5524 value->createInPlace<bdlt::Time>();
5525 return getExtendedBinaryTimeValue(
5526 &value->the<bdlt::Time>(), streamBuf, length);
5527}
5528
5529inline
5530int BerUtil_TimeImpUtil::getExtendedBinaryTimeTzValue(
5531 TimeOrTimeTz *value,
5532 bsl::streambuf *streamBuf,
5533 int length)
5534{
5535 value->createInPlace<bdlt::TimeTz>();
5536 return getExtendedBinaryTimeTzValue(
5537 &value->the<bdlt::TimeTz>(), streamBuf, length);
5538}
5539
5540// CLASS METHODS
5541
5542// Utilities
5543
5544inline
5546 int *millisecondsSinceMidnight,
5547 const bdlt::Time& time)
5548{
5549 const bdlt::Time defaultTime;
5550 *millisecondsSinceMidnight =
5551 static_cast<int>((time - defaultTime).totalMilliseconds());
5552}
5553
5554inline
5556 bsls::Types::Int64 *millisecondsSinceMidnight,
5557 const bdlt::Time& time)
5558{
5559 typedef bdlt::TimeUnitRatio Ratio;
5560 typedef bsls::Types::Int64 Int64;
5561
5562 *millisecondsSinceMidnight =
5563 static_cast<Int64>(time.hour()) * Ratio::k_MICROSECONDS_PER_HOUR +
5564 static_cast<Int64>(time.minute()) * Ratio::k_MICROSECONDS_PER_MINUTE +
5565 static_cast<Int64>(time.second()) * Ratio::k_MICROSECONDS_PER_SECOND +
5566 static_cast<Int64>(time.millisecond()) *
5567 Ratio::k_MICROSECONDS_PER_MILLISECOND +
5568 static_cast<Int64>(time.microsecond());
5569}
5570
5571inline
5573 bdlt::Time *time,
5574 int millisecondsSinceMidnight)
5575{
5576 typedef bdlt::TimeUnitRatio Ratio;
5577
5578 static const int k_MIN_NUM_MILLISECONDS = 0;
5579 static const int k_MAX_NUM_MILLISECONDS =
5580 24 * Ratio::k_MILLISECONDS_PER_HOUR;
5581
5582 if (k_MIN_NUM_MILLISECONDS > millisecondsSinceMidnight) {
5583 return -1; // RETURN
5584 }
5585
5586 if (k_MAX_NUM_MILLISECONDS < millisecondsSinceMidnight) {
5587 return -1; // RETURN
5588 }
5589
5590 const int serialTime = millisecondsSinceMidnight;
5591
5592 const int hour = serialTime / Ratio::k_MILLISECONDS_PER_HOUR_32;
5593
5594 const int minute =
5595 (serialTime - hour * Ratio::k_MILLISECONDS_PER_HOUR_32) /
5596 Ratio::k_MILLISECONDS_PER_MINUTE_32;
5597
5598 const int second = (serialTime - hour * Ratio::k_MILLISECONDS_PER_HOUR_32 -
5599 minute * Ratio::k_MILLISECONDS_PER_MINUTE_32) /
5600 Ratio::k_MILLISECONDS_PER_SECOND_32;
5601
5602 const int millisecond =
5603 (serialTime - hour * Ratio::k_MILLISECONDS_PER_HOUR_32 -
5604 minute * Ratio::k_MILLISECONDS_PER_MINUTE_32 -
5605 second * Ratio::k_MILLISECONDS_PER_SECOND_32);
5606
5607 time->setTime(hour, minute, second, millisecond);
5608 return 0;
5609}
5610
5611inline
5613 bdlt::Time *time,
5614 bsls::Types::Int64 microsecondsSinceMidnight)
5615{
5616 typedef bdlt::TimeUnitRatio Ratio;
5617
5618 static const bsls::Types::Int64 k_MIN_NUM_MICROSECONDS = 0;
5619 static const bsls::Types::Int64 k_MAX_NUM_MICROSECONDS =
5620 24 * Ratio::k_MICROSECONDS_PER_HOUR;
5621
5622 if (k_MIN_NUM_MICROSECONDS > microsecondsSinceMidnight) {
5623 return -1; // RETURN
5624 }
5625
5626 if (k_MAX_NUM_MICROSECONDS < microsecondsSinceMidnight) {
5627 return -1; // RETURN
5628 }
5629
5630 const bsls::Types::Int64 serialTime = microsecondsSinceMidnight;
5631
5632 const int hour =
5633 static_cast<int>(serialTime / Ratio::k_MICROSECONDS_PER_HOUR);
5634
5635 const int minute =
5636 static_cast<int>((serialTime - hour * Ratio::k_MICROSECONDS_PER_HOUR) /
5637 Ratio::k_MICROSECONDS_PER_MINUTE);
5638
5639 const int second =
5640 static_cast<int>((serialTime - hour * Ratio::k_MICROSECONDS_PER_HOUR -
5641 minute * Ratio::k_MICROSECONDS_PER_MINUTE) /
5642 Ratio::k_MICROSECONDS_PER_SECOND);
5643
5644 const int millisecond =
5645 static_cast<int>((serialTime - hour * Ratio::k_MICROSECONDS_PER_HOUR -
5646 minute * Ratio::k_MICROSECONDS_PER_MINUTE -
5647 second * Ratio::k_MICROSECONDS_PER_SECOND) /
5648 Ratio::k_MICROSECONDS_PER_MILLISECOND);
5649
5650 const int microsecond = static_cast<int>(
5651 (serialTime - hour * Ratio::k_MICROSECONDS_PER_HOUR -
5652 minute * Ratio::k_MICROSECONDS_PER_MINUTE -
5653 second * Ratio::k_MICROSECONDS_PER_SECOND -
5654 millisecond * Ratio::k_MICROSECONDS_PER_MILLISECOND));
5655
5656 time->setTime(hour, minute, second, millisecond, microsecond);
5657 return 0;
5658}
5659
5660// 'bdlt::Time' Decoding
5661
5662inline
5664 bsl::streambuf *streamBuf,
5665 int length)
5666{
5667 char firstByte;
5668 if (0 != StreambufUtil::peekChar(&firstByte, streamBuf)) {
5669 return -1; // RETURN
5670 }
5671
5672 TimeEncoding::Value encoding;
5673 int rc = detectTimeEncoding(&encoding, length, firstByte);
5674
5675 if (0 != rc) {
5676 return -1; // RETURN
5677 }
5678
5679 switch (encoding) {
5681 return getIso8601TimeValue(value, streamBuf, length); // RETURN
5682 } break;
5684 return getCompactBinaryTimeValue(value, streamBuf, length); // RETURN
5685 } break;
5687 return getExtendedBinaryTimeValue(value, streamBuf, length); // RETURN
5688 } break;
5689 }
5690
5691 BSLS_ASSERT_OPT(0 == "Unreachable");
5692#if BSLA_UNREACHABLE_IS_ACTIVE
5694#else
5695 return -1; // RETURN
5696#endif
5697}
5698
5699// 'bdlt::Time' Encoding
5700
5701inline
5702int BerUtil_TimeImpUtil::putTimeValue(bsl::streambuf *streamBuf,
5703 const bdlt::Time& value,
5704 const BerEncoderOptions *options)
5705{
5706 switch (selectTimeEncoding(value, options)) {
5708 return putIso8601TimeValue(streamBuf, value, options); // RETURN
5709 } break;
5711 return putCompactBinaryTimeValue(streamBuf, value, options);
5712 // RETURN
5713 } break;
5715 return putExtendedBinaryTimeValue(streamBuf, value, options);
5716 // RETURN
5717 } break;
5718 }
5719
5720 BSLS_ASSERT_OPT(0 == "Unreachable");
5721#if BSLA_UNREACHABLE_IS_ACTIVE
5723#else
5724 return -1; // RETURN
5725#endif
5726}
5727
5728// 'bdlt::TimeTz' Decoding
5729
5730inline
5732 bsl::streambuf *streamBuf,
5733 int length)
5734{
5735 char firstByte;
5736 if (0 != StreambufUtil::peekChar(&firstByte, streamBuf)) {
5737 return -1; // RETURN
5738 }
5739
5740 TimeTzEncoding::Value encoding;
5741 int rc = detectTimeTzEncoding(&encoding, length, firstByte);
5742
5743 if (0 != rc) {
5744 return -1; // RETURN
5745 }
5746
5747 switch (encoding) {
5749 return getIso8601TimeTzValue(value, streamBuf, length); // RETURN
5750 } break;
5752 return getCompactBinaryTimeValue(value, streamBuf, length); // RETURN
5753 } break;
5755 return getCompactBinaryTimeTzValue(value, streamBuf, length);
5756 // RETURN
5757 } break;
5759 return getExtendedBinaryTimeTzValue(value, streamBuf, length);
5760 // RETURN
5761 } break;
5762 }
5763
5764 BSLS_ASSERT_OPT(0 == "Unreachable");
5765#if BSLA_UNREACHABLE_IS_ACTIVE
5767#else
5768 return -1; // RETURN
5769#endif
5770}
5771
5772// 'bdlt::TimeTz' Encoding
5773
5774inline
5775int BerUtil_TimeImpUtil::putTimeTzValue(bsl::streambuf *streamBuf,
5776 const bdlt::TimeTz& value,
5777 const BerEncoderOptions *options)
5778{
5779 switch (selectTimeTzEncoding(value, options)) {
5781 return putIso8601TimeTzValue(streamBuf, value, options); // RETURN
5782 } break;
5784 return putCompactBinaryTimeValue(streamBuf, value, options);
5785 // RETURN
5786 } break;
5788 return putCompactBinaryTimeTzValue(streamBuf, value, options);
5789 // RETURN
5790 } break;
5792 return putExtendedBinaryTimeTzValue(streamBuf, value, options);
5793 // RETURN
5794 } break;
5795 }
5796
5797 BSLS_ASSERT_OPT(0 == "Unreachable");
5798#if BSLA_UNREACHABLE_IS_ACTIVE
5800#else
5801 return -1; // RETURN
5802#endif
5803}
5804
5805// Variant Decoding
5806
5807inline
5809 bsl::streambuf *streamBuf,
5810 int length)
5811{
5812 char firstByte;
5813 if (0 != StreambufUtil::peekChar(&firstByte, streamBuf)) {
5814 return -1; // RETURN
5815 }
5816
5818 int rc = detectTimeOrTimeTzEncoding(&encoding, length, firstByte);
5819
5820 if (0 != rc) {
5821 return -1; // RETURN
5822 }
5823
5824 switch (encoding) {
5826 return getIso8601TimeValue(value, streamBuf, length); // RETURN
5827 } break;
5829 return getIso8601TimeTzValue(value, streamBuf, length); // RETURN
5830 } break;
5832 return getCompactBinaryTimeValue(value, streamBuf, length); // RETURN
5833 } break;
5835 return getCompactBinaryTimeTzValue(value, streamBuf, length);
5836 // RETURN
5837 } break;
5839 return getExtendedBinaryTimeValue(value, streamBuf, length); // RETURN
5840 } break;
5842 return getExtendedBinaryTimeTzValue(value, streamBuf, length);
5843 // RETURN
5844 } break;
5845 }
5846
5847 BSLS_ASSERT_OPT(0 == "Unreachable");
5848#if BSLA_UNREACHABLE_IS_ACTIVE
5850#else
5851 return -1; // RETURN
5852#endif
5853}
5854
5855 // ------------------------------
5856 // struct BerUtil_DatetimeImpUtil
5857 // ------------------------------
5858
5859// PRIVATE CLASS METHODS
5860
5861// 'bdlt::Datetime' Decoding
5862
5863inline
5864int BerUtil_DatetimeImpUtil::detectDatetimeEncoding(
5865 DatetimeEncoding::Value *encoding,
5866 int length,
5867 unsigned char firstByte)
5868{
5869 if (k_MAX_COMPACT_BINARY_DATETIME_LENGTH >= length) {
5871 return 0; // RETURN
5872 }
5873
5874 if (k_MAX_COMPACT_BINARY_DATETIMETZ_LENGTH >= length) {
5876 return 0; // RETURN
5877 }
5878
5879 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5880 return -1; // RETURN
5881 }
5882
5885 return 0; // RETURN
5886 }
5887
5889 return 0;
5890}
5891
5892// 'bdlt::Datetime' Encoding
5893
5894inline
5896BerUtil_DatetimeImpUtil::selectDatetimeEncoding(
5897 bsls::Types::Int64 *serialDatetime,
5898 int *serialDatetimeLength,
5899 const bdlt::Datetime& value,
5900 const BerEncoderOptions *options)
5901{
5903 options)) {
5905 }
5906
5908 bsls::Types::Int64 serialDatetimeValue;
5909 datetimeToMillisecondsSinceEpoch(&serialDatetimeValue, value);
5910
5911 const int serialDatetimeLengthValue =
5912 IntegerUtil::getNumOctetsToStream(serialDatetimeValue);
5913
5914 if (k_MIN_COMPACT_BINARY_DATETIMETZ_LENGTH <=
5915 serialDatetimeLengthValue) {
5916 *serialDatetime = serialDatetimeValue;
5917 *serialDatetimeLength = serialDatetimeLengthValue;
5919 }
5920
5921 *serialDatetime = serialDatetimeValue;
5922 *serialDatetimeLength = serialDatetimeLengthValue;
5924 }
5925
5927}
5928
5929// 'bdlt::DatetimeTz' Decoding
5930
5931inline
5932int BerUtil_DatetimeImpUtil::detectDatetimeTzEncoding(
5933 DatetimeTzEncoding::Value *encoding,
5934 int length,
5935 unsigned char firstByte)
5936{
5937 if (k_MAX_COMPACT_BINARY_DATETIME_LENGTH >= length) {
5939 return 0; // RETURN
5940 }
5941
5942 if (k_MAX_COMPACT_BINARY_DATETIMETZ_LENGTH >= length) {
5944 return 0; // RETURN
5945 }
5946
5947 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
5948 return -1; // RETURN
5949 }
5950
5953 return 0; // RETURN
5954 }
5955
5957 return 0;
5958}
5959
5960// 'bdlt::DatetimeTz' Encoding
5961
5962inline
5964BerUtil_DatetimeImpUtil::selectDatetimeTzEncoding(
5965 bsls::Types::Int64 *serialDatetime,
5966 int *length,
5967 const bdlt::DatetimeTz& value,
5968 const BerEncoderOptions *options)
5969{
5971 options)) {
5973 }
5974
5976 bsls::Types::Int64 serialDatetimeValue;
5977 datetimeToMillisecondsSinceEpoch(&serialDatetimeValue,
5978 value.localDatetime());
5979
5980 const int lengthValue =
5981 IntegerUtil::getNumOctetsToStream(serialDatetimeValue);
5982
5983 if (0 == value.offset() &&
5984 k_MIN_COMPACT_BINARY_DATETIMETZ_LENGTH > lengthValue) {
5985 *serialDatetime = serialDatetimeValue;
5986 *length = lengthValue;
5988 }
5989
5990 *serialDatetime = serialDatetimeValue;
5991 *length = lengthValue;
5993 }
5994
5996}
5997
5998// Variant Decoding
5999
6000inline
6001int BerUtil_DatetimeImpUtil::detectDatetimeOrDatetimeTzEncoding(
6002 DatetimeOrDatetimeTzEncoding::Value *encoding,
6003 int length,
6004 unsigned char firstByte)
6005{
6006 BSLS_ASSERT(0 < length);
6007
6008 if (k_MAX_COMPACT_BINARY_DATETIME_LENGTH >= length) {
6010 return 0; // RETURN
6011 }
6012
6013 if (k_MAX_COMPACT_BINARY_DATETIMETZ_LENGTH >= length) {
6015 return 0; // RETURN
6016 }
6017
6018 if (DateAndTimeHeaderUtil::isReserved(firstByte)) {
6019 return -1; // RETURN
6020 }
6021
6024 return 0; // RETURN
6025 }
6026
6029 return 0; // RETURN
6030 }
6031
6032 if (k_MAX_ISO8601_DATETIME_LENGTH >= length) {
6034 return 0; // RETURN
6035 }
6036
6038 return 0;
6039}
6040
6041inline
6042int BerUtil_DatetimeImpUtil::getIso8601DatetimeValue(
6043 DatetimeOrDatetimeTz *value,
6044 bsl::streambuf *streamBuf,
6045 int length)
6046{
6047 value->createInPlace<bdlt::Datetime>();
6048 return getIso8601DatetimeValue(
6049 &value->the<bdlt::Datetime>(), streamBuf, length);
6050}
6051
6052inline
6053int BerUtil_DatetimeImpUtil::getIso8601DatetimeTzValue(
6054 DatetimeOrDatetimeTz *value,
6055 bsl::streambuf *streamBuf,
6056 int length)
6057{
6058 value->createInPlace<bdlt::DatetimeTz>();
6059 return getIso8601DatetimeTzValue(
6060 &value->the<bdlt::DatetimeTz>(), streamBuf, length);
6061}
6062
6063inline
6064int BerUtil_DatetimeImpUtil::getCompactBinaryDatetimeValue(
6065 DatetimeOrDatetimeTz *value,
6066 bsl::streambuf *streamBuf,
6067 int length)
6068{
6069 value->createInPlace<bdlt::Datetime>();
6070 return getCompactBinaryDatetimeValue(
6071 &value->the<bdlt::Datetime>(), streamBuf, length);
6072}
6073
6074inline
6075int BerUtil_DatetimeImpUtil::getCompactBinaryDatetimeTzValue(
6076 DatetimeOrDatetimeTz *value,
6077 bsl::streambuf *streamBuf,
6078 int length)
6079{
6080 value->createInPlace<bdlt::DatetimeTz>();
6081 return getCompactBinaryDatetimeTzValue(
6082 &value->the<bdlt::DatetimeTz>(), streamBuf, length);
6083}
6084
6085inline
6086int BerUtil_DatetimeImpUtil::getExtendedBinaryDatetimeValue(
6087 DatetimeOrDatetimeTz *value,
6088 bsl::streambuf *streamBuf,
6089 int length)
6090{
6091 value->createInPlace<bdlt::Datetime>();
6092 return getExtendedBinaryDatetimeValue(
6093 &value->the<bdlt::Datetime>(), streamBuf, length);
6094}
6095
6096inline
6097int BerUtil_DatetimeImpUtil::getExtendedBinaryDatetimeTzValue(
6098 DatetimeOrDatetimeTz *value,
6099 bsl::streambuf *streamBuf,
6100 int length)
6101{
6102 value->createInPlace<bdlt::DatetimeTz>();
6103 return getExtendedBinaryDatetimeTzValue(
6104 &value->the<bdlt::DatetimeTz>(), streamBuf, length);
6105}
6106
6107// CLASS METHODS
6108
6109// 'bdlt::Datetime' Encoding
6110
6111inline
6113 bsl::streambuf *streamBuf,
6114 const bdlt::Datetime& value,
6115 const BerEncoderOptions *options)
6116{
6117 const bdlt::Time& time = value.time();
6118 bdlt::Date date = value.date();
6119
6120 if (0 != date.addDaysIfValid(0) ||
6122 time.hour(), time.minute(), time.second(), time.millisecond())) {
6123 return -1; // RETURN
6124 }
6125
6126 bsls::Types::Int64 serialDatetime;
6127 int length;
6128
6129 switch (selectDatetimeEncoding(&serialDatetime, &length, value, options)) {
6131 return putIso8601DatetimeValue(streamBuf, value, options); // RETURN
6132 } break;
6134 return putCompactBinaryDatetimeValue(
6135 streamBuf, serialDatetime, length, options); // RETURN
6136 } break;
6138 return putCompactBinaryDatetimeTzValue(
6139 streamBuf, serialDatetime, length, options); // RETURN
6140 } break;
6142 return putExtendedBinaryDatetimeValue(streamBuf, value, options);
6143 // RETURN
6144 } break;
6145 }
6146
6147 BSLS_ASSERT_OPT(0 == "Unreachable");
6148#if BSLA_UNREACHABLE_IS_ACTIVE
6150#else
6151 return -1; // RETURN
6152#endif
6153}
6154
6155// 'bdlt::Datetime' Decoding
6156
6157inline
6159 bsl::streambuf *streamBuf,
6160 int length)
6161{
6162 char firstByte;
6163 if (0 != StreambufUtil::peekChar(&firstByte, streamBuf)) {
6164 return -1; // RETURN
6165 }
6166
6167 DatetimeEncoding::Value encoding;
6168 int rc = detectDatetimeEncoding(&encoding, length, firstByte);
6169
6170 if (0 != rc) {
6171 return -1; // RETURN
6172 }
6173
6174 switch (encoding) {
6176 return getIso8601DatetimeValue(value, streamBuf, length); // RETURN
6177 } break;
6179 return getCompactBinaryDatetimeValue(value, streamBuf, length);
6180 // RETURN
6181 } break;
6183 return getCompactBinaryDatetimeTzValue(value, streamBuf, length);
6184 // RETURN
6185 } break;
6187 return getExtendedBinaryDatetimeValue(value, streamBuf, length);
6188 // RETURN
6189 } break;
6190 }
6191
6192 BSLS_ASSERT_OPT(0 == "Unreachable");
6193#if BSLA_UNREACHABLE_IS_ACTIVE
6195#else
6196 return -1; // RETURN
6197#endif
6198}
6199
6200// 'bdlt::DatetimeTz' Encoding
6201
6202inline
6204 bsl::streambuf *streamBuf,
6205 const bdlt::DatetimeTz& value,
6206 const BerEncoderOptions *options)
6207{
6208 // Applications can create invalid 'bdlt::DatetimeTz' objects in optimized
6209 // build modes. As this function assumes that 'value' is valid, it is
6210 // possible to encode an invalid 'bdlt::DatetimeTz' without returning an
6211 // error. Decoding the corresponding output can result in hard-to-trace
6212 // decoding errors. So to identify such errors early, we return an error
6213 // if 'value' is not valid.
6214
6215 const bdlt::DateTz& dateTz = value.dateTz();
6216 const bdlt::TimeTz& timeTz = value.timeTz();
6217 if (0 != dateTz.localDate().addDaysIfValid(0) ||
6218 !bdlt::DateTz::isValid(dateTz.localDate(), dateTz.offset()) ||
6219 !bdlt::TimeTz::isValid(timeTz.utcTime(), timeTz.offset())) {
6220 return -1; // RETURN
6221 }
6222
6223 bsls::Types::Int64 serialDatetime;
6224 int serialDatetimeLength;
6225
6226 switch (selectDatetimeTzEncoding(
6227 &serialDatetime, &serialDatetimeLength, value, options)) {
6229 return putIso8601DatetimeTzValue(streamBuf, value, options);
6230 // RETURN
6231 } break;
6233 return putCompactBinaryDatetimeValue(
6234 streamBuf, serialDatetime, serialDatetimeLength, options);
6235 // RETURN
6236 } break;
6238 return putCompactBinaryDatetimeTzValue(streamBuf,
6239 value.offset(),
6240 serialDatetime,
6241 serialDatetimeLength,
6242 options);
6243 // RETURN
6244 } break;
6246 return putExtendedBinaryDatetimeTzValue(streamBuf, value, options);
6247 // RETURN
6248 } break;
6249 }
6250
6251 BSLS_ASSERT_OPT(0 == "Unreachable");
6252#if BSLA_UNREACHABLE_IS_ACTIVE
6254#else
6255 return -1; // RETURN
6256#endif
6257}
6258
6259// 'bdlt::DatetimeTz' Decoding
6260
6261inline
6263 bsl::streambuf *streamBuf,
6264 int length)
6265{
6266 char firstByte;
6267 if (0 != StreambufUtil::peekChar(&firstByte, streamBuf)) {
6268 return -1; // RETURN
6269 }
6270
6272 int rc = detectDatetimeTzEncoding(&encoding, length, firstByte);
6273
6274 if (0 != rc) {
6275 return -1; // RETURN
6276 }
6277
6278 switch (encoding) {
6280 return getIso8601DatetimeTzValue(value, streamBuf, length); // RETURN
6281 } break;
6283 return getCompactBinaryDatetimeValue(value, streamBuf, length);
6284 // RETURN
6285 } break;
6287 return getCompactBinaryDatetimeTzValue(value, streamBuf, length);
6288 // RETURN
6289 } break;
6291 return getExtendedBinaryDatetimeTzValue(value, streamBuf, length);
6292 // RETURN
6293 } break;
6294 }
6295
6296 BSLS_ASSERT_OPT(0 == "Unreachable");
6297#if BSLA_UNREACHABLE_IS_ACTIVE
6299#else
6300 return -1; // RETURN
6301#endif
6302}
6303
6304// Variant Decoding
6305
6306inline
6308 DatetimeOrDatetimeTz *value,
6309 bsl::streambuf *streamBuf,
6310 int length)
6311{
6312 char firstByte;
6313 if (0 != StreambufUtil::peekChar(&firstByte, streamBuf)) {
6314 return -1; // RETURN
6315 }
6316
6318 int rc = detectDatetimeOrDatetimeTzEncoding(&encoding, length, firstByte);
6319
6320 if (0 != rc) {
6321 return -1; // RETURN
6322 }
6323
6324 switch (encoding) {
6326 return getIso8601DatetimeValue(value, streamBuf, length); // RETURN
6327 } break;
6329 return getIso8601DatetimeTzValue(value, streamBuf, length); // RETURN
6330 } break;
6332 return getCompactBinaryDatetimeValue(value, streamBuf, length);
6333 // RETURN
6334 } break;
6336 return getCompactBinaryDatetimeTzValue(value, streamBuf, length);
6337 // RETURN
6338 } break;
6340 return getExtendedBinaryDatetimeValue(value, streamBuf, length);
6341 // RETURN
6342 } break;
6344 return getExtendedBinaryDatetimeTzValue(value, streamBuf, length);
6345 // RETURN
6346 } break;
6347 }
6348
6349 BSLS_ASSERT_OPT(0 == "Unreachable");
6350#if BSLA_UNREACHABLE_IS_ACTIVE
6352#else
6353 return -1; // RETURN
6354#endif
6355}
6356
6357 // ------------------------------
6358 // struct BerUtil_GetValueImpUtil
6359 // ------------------------------
6360
6361// CLASS METHODS
6362template <typename TYPE>
6364 bsl::streambuf *streamBuf,
6365 int length,
6366 const BerDecoderOptions&)
6367{
6368 return IntegerUtil::getIntegerValue(value, streamBuf, length);
6369}
6370
6371inline
6373 bsl::streambuf *streamBuf,
6374 int length,
6375 const BerDecoderOptions&)
6376{
6377 return BooleanUtil::getBoolValue(value, streamBuf, length);
6378}
6379
6380inline
6382 bsl::streambuf *streamBuf,
6383 int length,
6384 const BerDecoderOptions&)
6385{
6386 return CharacterUtil::getCharValue(value, streamBuf, length);
6387}
6388
6389inline
6390int BerUtil_GetValueImpUtil::getValue(unsigned char *value,
6391 bsl::streambuf *streamBuf,
6392 int length,
6393 const BerDecoderOptions&)
6394{
6395 return CharacterUtil::getUnsignedCharValue(value, streamBuf, length);
6396}
6397
6398inline
6400 bsl::streambuf *streamBuf,
6401 int length,
6402 const BerDecoderOptions&)
6403{
6404 return CharacterUtil::getSignedCharValue(value, streamBuf, length);
6405}
6406
6407inline
6409 bsl::streambuf *streamBuf,
6410 int length,
6411 const BerDecoderOptions&)
6412{
6413 return FloatingPointUtil::getFloatValue(value, streamBuf, length);
6414}
6415
6416inline
6418 bsl::streambuf *streamBuf,
6419 int length,
6420 const BerDecoderOptions&)
6421{
6422 return FloatingPointUtil::getDoubleValue(value, streamBuf, length);
6423}
6424
6426 bsl::streambuf *streamBuf,
6427 int length,
6428 const BerDecoderOptions &) {
6429 if (BerUtil::k_INDEFINITE_LENGTH == length) {
6430 return -1; // RETURN
6431 }
6432 return FloatingPointUtil::getDecimal64Value(value, streamBuf, length);
6433}
6434
6435inline
6437 bsl::streambuf *streamBuf,
6438 int length,
6439 const BerDecoderOptions& options)
6440{
6441 return StringUtil::getStringValue(value, streamBuf, length, options);
6442}
6443
6444inline
6446 bsl::streambuf *streamBuf,
6447 int length,
6448 const BerDecoderOptions&)
6449{
6450 return DateUtil::getDateValue(value, streamBuf, length);
6451}
6452
6453inline
6455 bsl::streambuf *streamBuf,
6456 int length,
6457 const BerDecoderOptions&)
6458{
6459 return DateUtil::getDateTzValue(value, streamBuf, length);
6460}
6461
6462inline
6464 bsl::streambuf *streamBuf,
6465 int length,
6466 const BerDecoderOptions&)
6467{
6468 return DateUtil::getDateOrDateTzValue(value, streamBuf, length);
6469}
6470
6471inline
6473 bsl::streambuf *streamBuf,
6474 int length,
6475 const BerDecoderOptions&)
6476{
6477 return DatetimeUtil::getDatetimeValue(value, streamBuf, length);
6478}
6479
6480inline
6482 bsl::streambuf *streamBuf,
6483 int length,
6484 const BerDecoderOptions&)
6485{
6486 return DatetimeUtil::getDatetimeTzValue(value, streamBuf, length);
6487}
6488
6489inline
6490int BerUtil_GetValueImpUtil::getValue(DatetimeOrDatetimeTz *value,
6491 bsl::streambuf *streamBuf,
6492 int length,
6493 const BerDecoderOptions&)
6494{
6496 value, streamBuf, length);
6497}
6498
6499inline
6501 bsl::streambuf *streamBuf,
6502 int length,
6503 const BerDecoderOptions&)
6504{
6505 return TimeUtil::getTimeValue(value, streamBuf, length);
6506}
6507
6508inline
6510 bsl::streambuf *streamBuf,
6511 int length,
6512 const BerDecoderOptions&)
6513{
6514 return TimeUtil::getTimeTzValue(value, streamBuf, length);
6515}
6516
6517inline
6518int BerUtil_GetValueImpUtil::getValue(TimeOrTimeTz *value,
6519 bsl::streambuf *streamBuf,
6520 int length,
6521 const BerDecoderOptions&)
6522{
6523 return TimeUtil::getTimeOrTimeTzValue(value, streamBuf, length);
6524}
6525
6526 // ------------------------------
6527 // struct BerUtil_PutValueImpUtil
6528 // ------------------------------
6529
6530// CLASS METHODS
6531template <class TYPE>
6532int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6533 const TYPE& value,
6534 const BerEncoderOptions *)
6535{
6536 return IntegerUtil::putIntegerValue(streamBuf, value);
6537}
6538
6539inline
6540int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6541 bool value,
6542 const BerEncoderOptions *)
6543{
6544 return BooleanUtil::putBoolValue(streamBuf, value);
6545}
6546
6547inline
6548int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6549 char value,
6550 const BerEncoderOptions *)
6551{
6552 return CharacterUtil::putCharValue(streamBuf, value);
6553}
6554
6555inline
6556int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6557 unsigned char value,
6558 const BerEncoderOptions *)
6559{
6560 return CharacterUtil::putUnsignedCharValue(streamBuf, value);
6561}
6562
6563inline
6564int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6565 signed char value,
6566 const BerEncoderOptions *)
6567{
6568 return CharacterUtil::putSignedCharValue(streamBuf, value);
6569}
6570
6571inline
6572int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6573 float value,
6574 const BerEncoderOptions *options)
6575{
6576 return FloatingPointUtil::putFloatValue(streamBuf,
6577 value,
6578 options);
6579}
6580
6581inline
6582int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6583 double value,
6584 const BerEncoderOptions *options)
6585{
6586 return FloatingPointUtil::putDoubleValue(streamBuf,
6587 value,
6588 options);
6589}
6590
6591inline
6592int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6593 bdldfp::Decimal64 value,
6594 const BerEncoderOptions *)
6595{
6596 return FloatingPointUtil::putDecimal64Value(streamBuf, value);
6597}
6598
6599inline
6600int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6601 const bsl::string& value,
6602 const BerEncoderOptions *)
6603{
6604 return StringUtil::putStringValue(streamBuf, value);
6605}
6606
6607inline
6608int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6609 const bsl::string_view& value,
6610 const BerEncoderOptions *)
6611{
6612 return StringUtil::putStringViewValue(streamBuf, value);
6613}
6614
6615inline
6616int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6617 const bslstl::StringRef& value,
6618 const BerEncoderOptions *)
6619{
6620 return StringUtil::putStringRefValue(streamBuf, value);
6621}
6622
6623inline
6624int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6625 const bdlt::Date& value,
6626 const BerEncoderOptions *options)
6627{
6628 return DateUtil::putDateValue(streamBuf, value, options);
6629}
6630
6631inline
6632int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6633 const bdlt::DateTz& value,
6634 const BerEncoderOptions *options)
6635{
6636 return DateUtil::putDateTzValue(streamBuf, value, options);
6637}
6638
6639inline
6640int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6641 const bdlt::Datetime& value,
6642 const BerEncoderOptions *options)
6643{
6644 return DatetimeUtil::putDatetimeValue(streamBuf, value, options);
6645}
6646
6647inline
6648int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6649 const bdlt::DatetimeTz& value,
6650 const BerEncoderOptions *options)
6651{
6652 return DatetimeUtil::putDatetimeTzValue(streamBuf, value, options);
6653}
6654
6655inline
6656int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6657 const bdlt::Time& value,
6658 const BerEncoderOptions *options)
6659{
6660 return TimeUtil::putTimeValue(streamBuf, value, options);
6661}
6662
6663inline
6664int BerUtil_PutValueImpUtil::putValue(bsl::streambuf *streamBuf,
6665 const bdlt::TimeTz& value,
6666 const BerEncoderOptions *options)
6667{
6668 return TimeUtil::putTimeTzValue(streamBuf, value, options);
6669}
6670
6671 // ------------------
6672 // struct BerUtil_Imp
6673 // ------------------
6674
6675// CLASS METHODS
6676inline
6677int BerUtil_Imp::putStringValue(bsl::streambuf *streamBuf,
6678 const char *string,
6679 int stringLength)
6680{
6681 typedef BerUtil_StringImpUtil StringUtil;
6682 return StringUtil::putRawStringValue(streamBuf, string, stringLength);
6683}
6684
6685} // close package namespace
6686
6687
6688#endif
6689
6690// ----------------------------------------------------------------------------
6691// Copyright 2015 Bloomberg Finance L.P.
6692//
6693// Licensed under the Apache License, Version 2.0 (the "License");
6694// you may not use this file except in compliance with the License.
6695// You may obtain a copy of the License at
6696//
6697// http://www.apache.org/licenses/LICENSE-2.0
6698//
6699// Unless required by applicable law or agreed to in writing, software
6700// distributed under the License is distributed on an "AS IS" BASIS,
6701// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6702// See the License for the specific language governing permissions and
6703// limitations under the License.
6704// ----------------------------- END-OF-FILE ----------------------------------
6705
6706/** @} */
6707/** @} */
6708/** @} */
Definition balber_berdecoderoptions.h:76
Definition balber_berencoderoptions.h:70
bool encodeDateAndTimeTypesAsBinary() const
Definition balber_berencoderoptions.h:794
int datetimeFractionalSecondPrecision() const
Definition balber_berencoderoptions.h:800
int & bdeVersionConformance()
Definition balber_berencoderoptions.h:598
Definition balber_berutil.h:1543
void makeExtendedBinaryWithoutTimezone()
Definition balber_berutil.h:4762
BerUtil_DateAndTimeHeader & operator=(const BerUtil_DateAndTimeHeader &rhs)=default
BerUtil_DateAndTimeHeader()
Definition balber_berutil.h:4747
BerUtil_DateAndTimeHeader(const BerUtil_DateAndTimeHeader &original)=default
bool isExtendedBinaryWithoutTimezone() const
Definition balber_berutil.h:4786
~BerUtil_DateAndTimeHeader()=default
Destroy this object.
void makeExtendedBinaryWithTimezone(int offset)
Definition balber_berutil.h:4769
BerUtil_TimezoneOffsetImpUtil TimezoneUtil
Definition balber_berutil.h:1556
void makeNotExtendedBinary()
Definition balber_berutil.h:4755
bool isExtendedBinaryWithTimezone() const
Definition balber_berutil.h:4792
BerUtil_DateAndTimeHeaderType Type
Definition balber_berutil.h:1551
int timezoneOffsetInMinutes() const
Definition balber_berutil.h:4798
bool isExtendedBinary() const
Definition balber_berutil.h:4779
Definition bdlb_variant.h:2592
Definition bdldfp_decimal.h:1890
Definition bdlt_datetz.h:161
static bool isValid(const Date &localDate, int offset)
Definition bdlt_datetz.h:405
int offset() const
Definition bdlt_datetz.h:513
Date localDate() const
Definition bdlt_datetz.h:507
Definition bdlt_date.h:294
int day() const
Return the day of the month in the range [1 .. 31] of this date.
Definition bdlt_date.h:955
void setYearMonthDay(int year, int month, int day)
Definition bdlt_date.h:899
int addDaysIfValid(int numDays)
int year() const
Return the year in the range [1 .. 9999] of this date.
Definition bdlt_date.h:1005
int month() const
Return the month of the year in the range [1 .. 12] of this date.
Definition bdlt_date.h:993
Definition bdlt_datetimetz.h:308
Datetime localDatetime() const
Definition bdlt_datetimetz.h:677
DateTz dateTz() const
Definition bdlt_datetimetz.h:671
TimeTz timeTz() const
Definition bdlt_datetimetz.h:689
int offset() const
Definition bdlt_datetimetz.h:683
Definition bdlt_datetime.h:330
Date date() const
Return the value of the "date" part of this object.
Definition bdlt_datetime.h:2234
Time time() const
Return the value of the "time" part of this object.
Definition bdlt_datetime.h:2345
Definition bdlt_iso8601utilconfiguration.h:224
void setFractionalSecondPrecision(int value)
Definition bdlt_timetz.h:190
Time localTime() const
Definition bdlt_timetz.h:531
static bool isValid(const Time &localTime, int offset)
Definition bdlt_timetz.h:421
Time utcTime() const
Definition bdlt_timetz.h:543
int offset() const
Return the time zone offset of this object in minutes from UTC.
Definition bdlt_timetz.h:537
Definition bdlt_time.h:195
void setTime(int hour, int minute=0, int second=0, int millisecond=0, int microsecond=0)
int microsecond() const
Return the value of the microsecond attribute of this time object.
Definition bdlt_time.h:933
static bool isValid(int hour, int minute=0, int second=0, int millisecond=0, int microsecond=0)
Definition bdlt_time.h:725
int second() const
Return the value of the second attribute of this time object.
Definition bdlt_time.h:956
int millisecond() const
Return the value of the millisecond attribute of this time object.
Definition bdlt_time.h:940
int minute() const
Return the value of the minute attribute of this time object.
Definition bdlt_time.h:948
int hour() const
Return the value of the hour attribute of this time object.
Definition bdlt_time.h:926
Definition bslstl_stringview.h:471
BSLS_KEYWORD_CONSTEXPR size_type length() const BSLS_KEYWORD_NOEXCEPT
Return the length of this view.
Definition bslstl_stringview.h:1913
BSLS_KEYWORD_CONSTEXPR const_pointer data() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1988
Definition bslstl_string.h:1252
size_type length() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7301
CHAR_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7177
Definition bslstl_vector.h:1120
void resize(size_type newSize)
Definition bslstl_vector.h:4189
Definition bslstl_stringref.h:374
const CHAR_TYPE * data() const
Definition bslstl_stringref.h:962
size_type length() const
Definition bslstl_stringref.h:984
#define BSLA_UNREACHABLE
Definition bsla_unreachable.h:159
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:2045
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balber_berconstants.h:84
TagType
Definition balber_berconstants.h:117
TagClass
Definition balber_berconstants.h:96
Definition balber_berutil.h:598
static int getBoolValue(bool *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:4165
BerUtil_LengthImpUtil LengthUtil
Definition balber_berutil.h:605
static int putBoolValue(bsl::streambuf *streamBuf, bool value)
Definition balber_berutil.h:4186
Definition balber_berutil.h:774
static int putSignedCharValue(bsl::streambuf *streamBuf, signed char value)
Definition balber_berutil.h:4504
static int getCharValue(char *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:4427
BerUtil_IntegerImpUtil IntegerUtil
Definition balber_berutil.h:780
BerUtil_LengthImpUtil LengthUtil
Definition balber_berutil.h:785
static int putUnsignedCharValue(bsl::streambuf *streamBuf, unsigned char value)
Definition balber_berutil.h:4511
static int putCharValue(bsl::streambuf *streamBuf, char value)
Definition balber_berutil.h:4489
static int getUnsignedCharValue(unsigned char *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:4473
static int getSignedCharValue(signed char *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:4459
Definition balber_berutil.h:331
@ k_NUM_BITS_PER_OCTET
Definition balber_berutil.h:334
Definition balber_berutil.h:1423
@ k_EXTENDED_BINARY_MIN_BDE_VERSION
Definition balber_berutil.h:1447
Value
Definition balber_berutil.h:1426
@ e_ISO8601_TIMETZ
Definition balber_berutil.h:1432
@ e_COMPACT_BINARY_DATETZ
Definition balber_berutil.h:1434
@ e_COMPACT_BINARY_TIMETZ
Definition balber_berutil.h:1438
@ e_COMPACT_BINARY_DATETIME
Definition balber_berutil.h:1435
@ e_COMPACT_BINARY_DATE
Definition balber_berutil.h:1433
@ e_EXTENDED_BINARY_TIME
Definition balber_berutil.h:1441
@ e_ISO8601_DATE
Definition balber_berutil.h:1427
@ e_EXTENDED_BINARY_TIMETZ
Definition balber_berutil.h:1442
@ e_COMPACT_BINARY_DATETIMETZ
Definition balber_berutil.h:1436
@ e_ISO8601_TIME
Definition balber_berutil.h:1431
@ e_ISO8601_DATETIME
Definition balber_berutil.h:1429
@ e_EXTENDED_BINARY_DATETIME
Definition balber_berutil.h:1439
@ e_COMPACT_BINARY_TIME
Definition balber_berutil.h:1437
@ e_ISO8601_DATETZ
Definition balber_berutil.h:1428
@ e_EXTENDED_BINARY_DATETIMETZ
Definition balber_berutil.h:1440
@ e_ISO8601_DATETIMETZ
Definition balber_berutil.h:1430
Definition balber_berutil.h:1640
static bool isExtendedBinary(unsigned char firstByte)
Definition balber_berutil.h:4826
static void detectType(Type::Value *type, unsigned char firstByte)
Definition balber_berutil.h:4876
BerUtil_StreambufUtil StreambufUtil
Definition balber_berutil.h:1657
BerUtil_DateAndTimeHeaderType Type
Definition balber_berutil.h:1652
static bool isExtendedBinaryWithoutTimezone(unsigned char firstByte)
Definition balber_berutil.h:4837
static int putExtendedBinaryWithoutTimezoneValue(bsl::streambuf *streamBuf)
Definition balber_berutil.h:5014
BerUtil_TimezoneOffsetImpUtil TimezoneUtil
Definition balber_berutil.h:1662
static int putExtendedBinaryWithTimezoneValue(bsl::streambuf *streamBuf, int timezoneOffsetInMinutes)
Definition balber_berutil.h:5022
BerUtil_DateAndTimeHeader Header
Definition balber_berutil.h:1647
static bool isReserved(unsigned char firstByte)
Definition balber_berutil.h:4809
static const int k_HEADER_LENGTH
Number of octets used to encode an extended-binary-encoding header.
Definition balber_berutil.h:1667
static void detectTypeIfNotReserved(bool *reserved, Type::Value *type, unsigned char firstByte)
Definition balber_berutil.h:4861
static int getValue(Header *value, bsl::streambuf *streamBuf)
Definition balber_berutil.h:4930
static int getValueIfNotReserved(Header *value, bsl::streambuf *streamBuf)
Definition balber_berutil.h:4898
static bool isExtendedBinaryWithTimezone(unsigned char firstByte)
Definition balber_berutil.h:4849
Definition balber_berutil.h:1509
Value
Definition balber_berutil.h:1512
@ e_EXTENDED_BINARY_WITH_TIMEZONE
Definition balber_berutil.h:1523
@ e_EXTENDED_BINARY_WITHOUT_TIMEZONE
Definition balber_berutil.h:1518
@ e_NOT_EXTENDED_BINARY
Definition balber_berutil.h:1513
Definition balber_berutil.h:1791
Value
Definition balber_berutil.h:1800
@ e_COMPACT_BINARY_DATE
Definition balber_berutil.h:1802
@ e_ISO8601_DATE
Definition balber_berutil.h:1801
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:1798
Definition balber_berutil.h:1877
BerUtil_DateTzEncoding DateTzEncoding
Definition balber_berutil.h:1895
bdlb::Variant2< bdlt::Date, bdlt::DateTz > DateOrDateTz
Definition balber_berutil.h:1934
BerUtil_Iso8601ImpUtil Iso8601Util
Definition balber_berutil.h:1910
@ k_COMPACT_BINARY_DATE_EPOCH
Definition balber_berutil.h:1937
BerUtil_StringImpUtil StringUtil
Definition balber_berutil.h:1925
static int putDateTzValue(bsl::streambuf *streamBuf, const bdlt::DateTz &date, const BerEncoderOptions *options)
static int getDateOrDateTzValue(DateOrDateTz *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:5215
static int daysSinceEpochToDate(bdlt::Date *date, bsls::Types::Int64 daysSinceEpoch)
Definition balber_berutil.h:5275
BerUtil_TimezoneOffsetImpUtil TimezoneUtil
Definition balber_berutil.h:1930
BerUtil_DateAndTimeHeaderImpUtil DateAndTimeHeaderUtil
Definition balber_berutil.h:1885
static int getDateTzValue(bdlt::DateTz *value, bsl::streambuf *streamBuf, int length)
BerUtil_LengthImpUtil LengthUtil
Definition balber_berutil.h:1915
BerUtil_IntegerImpUtil IntegerUtil
Definition balber_berutil.h:1905
BerUtil_StreambufUtil StreambufUtil
Definition balber_berutil.h:1920
static int getDateValue(bdlt::Date *date, bsl::streambuf *streamBuf, int length)
static void dateToDaysSinceEpoch(bsls::Types::Int64 *daysSinceEpoch, const bdlt::Date &date)
Definition balber_berutil.h:5264
BerUtil_DateOrDateTzEncoding DateOrDateTzEncoding
Definition balber_berutil.h:1900
BerUtil_DateEncoding DateEncoding
Definition balber_berutil.h:1890
static int putDateValue(bsl::streambuf *streamBuf, const bdlt::Date &value, const BerEncoderOptions *options)
Definition balber_berutil.h:1840
Value
Definition balber_berutil.h:1849
@ e_COMPACT_BINARY_DATETZ
Definition balber_berutil.h:1853
@ e_COMPACT_BINARY_DATE
Definition balber_berutil.h:1852
@ e_ISO8601_DATETZ
Definition balber_berutil.h:1851
@ e_ISO8601_DATE
Definition balber_berutil.h:1850
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:1847
Definition balber_berutil.h:1815
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:1822
Value
Definition balber_berutil.h:1824
@ e_COMPACT_BINARY_DATETZ
Definition balber_berutil.h:1827
@ e_COMPACT_BINARY_DATE
Definition balber_berutil.h:1826
@ e_ISO8601_DATETZ
Definition balber_berutil.h:1825
Definition balber_berutil.h:2944
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:2951
@ k_EXTENDED_BINARY_MIN_BDE_VERSION
Definition balber_berutil.h:2961
Value
Definition balber_berutil.h:2953
@ e_COMPACT_BINARY_DATETIME
Definition balber_berutil.h:2955
@ e_EXTENDED_BINARY_DATETIME
Definition balber_berutil.h:2957
@ e_ISO8601_DATETIME
Definition balber_berutil.h:2954
@ e_COMPACT_BINARY_DATETIMETZ
Definition balber_berutil.h:2956
Definition balber_berutil.h:3046
static int getDatetimeTzValue(bdlt::DatetimeTz *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:6262
BerUtil_DateAndTimeHeader DateAndTimeHeader
Definition balber_berutil.h:3063
BerUtil_DatetimeEncoding DatetimeEncoding
Definition balber_berutil.h:3078
static int getDatetimeOrDatetimeTzValue(DatetimeOrDatetimeTz *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:6307
BerUtil_ExtendedBinaryEncodingUtil ExtendedBinaryEncodingUtil
Definition balber_berutil.h:3058
static int putDatetimeValue(bsl::streambuf *streamBuf, const bdlt::Datetime &value, const BerEncoderOptions *options)
Definition balber_berutil.h:6112
BerUtil_LengthImpUtil LengthUtil
Definition balber_berutil.h:3104
bdlb::Variant2< bdlt::Datetime, bdlt::DatetimeTz > DatetimeOrDatetimeTz
Definition balber_berutil.h:3128
BerUtil_Constants Constants
Definition balber_berutil.h:3052
BerUtil_DatetimeTzEncoding DatetimeTzEncoding
Definition balber_berutil.h:3083
BerUtil_Iso8601ImpUtil Iso8601Util
Definition balber_berutil.h:3099
static int putDatetimeTzValue(bsl::streambuf *streamBuf, const bdlt::DatetimeTz &value, const BerEncoderOptions *options)
Definition balber_berutil.h:6203
BerUtil_DateImpUtil DateUtil
Definition balber_berutil.h:3073
BerUtil_IntegerImpUtil IntegerUtil
Definition balber_berutil.h:3094
BerUtil_DatetimeOrDatetimeTzEncoding DatetimeOrDatetimeTzEncoding
Definition balber_berutil.h:3089
BerUtil_DateAndTimeHeaderImpUtil DateAndTimeHeaderUtil
Definition balber_berutil.h:3069
static int getDatetimeValue(bdlt::Datetime *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:6158
BerUtil_StreambufUtil StreambufUtil
Definition balber_berutil.h:3109
BerUtil_StringImpUtil StringUtil
Definition balber_berutil.h:3114
BerUtil_TimezoneOffsetImpUtil TimezoneUtil
Definition balber_berutil.h:3123
BerUtil_TimeImpUtil TimeUtil
Definition balber_berutil.h:3118
Definition balber_berutil.h:3006
Value
Definition balber_berutil.h:3015
@ e_EXTENDED_BINARY_DATETIMETZ
Definition balber_berutil.h:3021
@ e_EXTENDED_BINARY_DATETIME
Definition balber_berutil.h:3020
@ e_COMPACT_BINARY_DATETIMETZ
Definition balber_berutil.h:3019
@ e_ISO8601_DATETIMETZ
Definition balber_berutil.h:3017
@ e_COMPACT_BINARY_DATETIME
Definition balber_berutil.h:3018
@ e_ISO8601_DATETIME
Definition balber_berutil.h:3016
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:3013
Definition balber_berutil.h:2975
Value
Definition balber_berutil.h:2984
@ e_EXTENDED_BINARY_DATETIMETZ
Definition balber_berutil.h:2988
@ e_COMPACT_BINARY_DATETIME
Definition balber_berutil.h:2986
@ e_COMPACT_BINARY_DATETIMETZ
Definition balber_berutil.h:2987
@ e_ISO8601_DATETIMETZ
Definition balber_berutil.h:2985
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:2982
@ k_EXTENDED_BINARY_MIN_BDE_VERSION
Definition balber_berutil.h:2992
Definition balber_berutil.h:1465
static bool useExtendedBinaryEncoding(const bdlt::Time &value, const BerEncoderOptions *options)
Definition balber_berutil.h:4674
static bool useBinaryEncoding(const BerEncoderOptions *options)
Definition balber_berutil.h:4735
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:1472
Definition balber_berutil.h:882
BerUtil_LengthImpUtil LengthUtil
Definition balber_berutil.h:894
static int putDoubleValue(bsl::streambuf *streamBuf, double value, const BerEncoderOptions *options=0)
static int putFloatValue(bsl::streambuf *streamBuf, float value, const BerEncoderOptions *options=0)
Definition balber_berutil.h:4544
static int putDecimal64Value(bsl::streambuf *streamBuf, bdldfp::Decimal64 value)
static int getDecimal64Value(bdldfp::Decimal64 *value, bsl::streambuf *streamBuf, int length)
static int getDoubleValue(double *value, bsl::streambuf *streamBuf, int length)
BerUtil_IntegerImpUtil IntegerUtil
Definition balber_berutil.h:889
static int getFloatValue(float *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:4527
Definition balber_berutil.h:3661
BerUtil_CharacterImpUtil CharacterUtil
Definition balber_berutil.h:3673
bdlb::Variant2< bdlt::Datetime, bdlt::DatetimeTz > DatetimeOrDatetimeTz
Definition balber_berutil.h:3712
bdlb::Variant2< bdlt::Date, bdlt::DateTz > DateOrDateTz
Definition balber_berutil.h:3707
BerUtil_DatetimeImpUtil DatetimeUtil
Definition balber_berutil.h:3683
bdlb::Variant2< bdlt::Time, bdlt::TimeTz > TimeOrTimeTz
Definition balber_berutil.h:3716
BerUtil_FloatingPointImpUtil FloatingPointUtil
Definition balber_berutil.h:3688
BerUtil_BooleanImpUtil BooleanUtil
Definition balber_berutil.h:3668
BerUtil_IntegerImpUtil IntegerUtil
Definition balber_berutil.h:3693
static int getValue(DatetimeOrDatetimeTz *value, bsl::streambuf *streamBuf, int length, const BerDecoderOptions &options=BerDecoderOptions())
BerUtil_StringImpUtil StringUtil
Definition balber_berutil.h:3698
BerUtil_TimeImpUtil TimeUtil
Definition balber_berutil.h:3703
BerUtil_DateImpUtil DateUtil
Definition balber_berutil.h:3678
static int getValue(TYPE *value, bsl::streambuf *streamBuf, int length, const BerDecoderOptions &options=BerDecoderOptions())
Definition balber_berutil.h:6363
static int getValue(TimeOrTimeTz *value, bsl::streambuf *streamBuf, int length, const BerDecoderOptions &options=BerDecoderOptions())
Definition balber_berutil.h:393
BerUtil_Constants Constants
Definition balber_berutil.h:399
static int putIdentifierOctets(bsl::streambuf *streamBuf, BerConstants::TagClass tagClass, BerConstants::TagType tagType, int tagNumber)
static int getIdentifierOctets(BerConstants::TagClass *tagClass, BerConstants::TagType *tagType, int *tagNumber, int *accumNumBytesConsumed, bsl::streambuf *streamBuf)
Definition balber_berutil.h:3947
static int putStringValue(bsl::streambuf *streamBuf, const char *string, int stringLength)
Definition balber_berutil.h:6677
Definition balber_berutil.h:643
static int get40BitIntegerValue(bsls::Types::Int64 *value, bsl::streambuf *streamBuf)
Definition balber_berutil.h:4333
BerUtil_Constants Constants
Definition balber_berutil.h:650
static int putIntegerValue(bsl::streambuf *streamBuf, INTEGRAL_TYPE value)
static int getIntegerValue(INTEGRAL_TYPE *value, bsl::streambuf *streamBuf, int length)
BerUtil_StreambufUtil StreambufUtil
Definition balber_berutil.h:665
static int getIntegerValue(long long *value, bsl::streambuf *streamBuf, int length)
static int getNumOctetsToStream(int value)
static int getNumOctetsToStream(long long value)
BerUtil_RawIntegerImpUtil RawIntegerUtil
Definition balber_berutil.h:660
static int getNumOctetsToStream(INTEGRAL_TYPE value)
static int putIntegerGivenLength(bsl::streambuf *streamBuf, INTEGRAL_TYPE value, int length)
static int put40BitIntegerValue(bsl::streambuf *streamBuf, bsls::Types::Int64 value)
Definition balber_berutil.h:4395
BerUtil_LengthImpUtil LengthImpUtil
Definition balber_berutil.h:655
static int getNumOctetsToStream(short value)
static const int k_40_BIT_INTEGER_LENGTH
Number of octets used to encode a signed integer value in 40 bits.
Definition balber_berutil.h:670
Definition balber_berutil.h:1173
static int getDatetimeValue(bdlt::Datetime *value, bsl::streambuf *streamBuf, int length)
static int getDateTzValue(bdlt::DateTz *value, bsl::streambuf *streamBuf, int length)
static int getDatetimeTzValue(bdlt::DatetimeTz *value, bsl::streambuf *streamBuf, int length)
static int putDatetimeTzValue(bsl::streambuf *streamBuf, const bdlt::DatetimeTz &value, const BerEncoderOptions *options)
static int getTimeTzValue(bdlt::TimeTz *value, bsl::streambuf *streamBuf, int length)
static int putTimeValue(bsl::streambuf *streamBuf, const bdlt::Time &value, const BerEncoderOptions *options)
static int putDateTzValue(bsl::streambuf *streamBuf, const bdlt::DateTz &value, const BerEncoderOptions *options)
BerUtil_StringImpUtil StringUtil
Definition balber_berutil.h:1179
static int putTimeTzValue(bsl::streambuf *streamBuf, const bdlt::TimeTz &value, const BerEncoderOptions *options)
static int getDateValue(bdlt::Date *value, bsl::streambuf *streamBuf, int length)
static int getTimeValue(bdlt::Time *value, bsl::streambuf *streamBuf, int length)
static int putDatetimeValue(bsl::streambuf *streamBuf, const bdlt::Datetime &value, const BerEncoderOptions *options)
static int putDateValue(bsl::streambuf *streamBuf, const bdlt::Date &value, const BerEncoderOptions *options)
Definition balber_berutil.h:508
static int putIndefiniteLengthOctet(bsl::streambuf *streamBuf)
static int getEndOfContentOctets(int *accumNumBytesConsumed, bsl::streambuf *streamBuf)
BerUtil_RawIntegerImpUtil RawIntegerUtil
Definition balber_berutil.h:518
BerUtil_Constants Constants
Definition balber_berutil.h:514
static int putEndOfContentOctets(bsl::streambuf *streamBuf)
static int getLength(int *result, int *accumNumBytesConsumed, bsl::streambuf *streamBuf)
static int putLength(bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:3832
BerUtil_BooleanImpUtil BooleanUtil
Definition balber_berutil.h:3839
BerUtil_TimeImpUtil TimeUtil
Definition balber_berutil.h:3874
BerUtil_FloatingPointImpUtil FloatingPointUtil
Definition balber_berutil.h:3859
BerUtil_DatetimeImpUtil DatetimeUtil
Definition balber_berutil.h:3854
BerUtil_DateImpUtil DateUtil
Definition balber_berutil.h:3849
static int putValue(bsl::streambuf *streamBuf, const TYPE &value, const BerEncoderOptions *options)
Definition balber_berutil.h:6532
BerUtil_StringImpUtil StringUtil
Definition balber_berutil.h:3869
BerUtil_IntegerImpUtil IntegerUtil
Definition balber_berutil.h:3864
BerUtil_CharacterImpUtil CharacterUtil
Definition balber_berutil.h:3844
Definition balber_berutil.h:476
static int putIntegerGivenLength(bsl::streambuf *streamBuf, INTEGRAL_TYPE value, int length)
BerUtil_Constants Constants
Definition balber_berutil.h:482
Definition balber_berutil.h:348
static int putChars(bsl::streambuf *streamBuf, const char *buffer, int bufferLength)
Definition balber_berutil.h:4081
static int peekChar(char *value, bsl::streambuf *streamBuf)
Definition balber_berutil.h:4054
static int getChars(char *buffer, bsl::streambuf *streamBuf, int bufferLength)
Definition balber_berutil.h:4066
Definition balber_berutil.h:1073
static int putStringViewValue(bsl::streambuf *streamBuf, const bsl::string_view &value)
Definition balber_berutil.h:4591
static int putChars(bsl::streambuf *streamBuf, char value, int numChars)
static int putStringRefValue(bsl::streambuf *streamBuf, const bslstl::StringRef &value)
Definition balber_berutil.h:4602
static int putRawStringValue(bsl::streambuf *streamBuf, const char *string, int stringLength)
Definition balber_berutil.h:4563
static int getStringValue(bsl::string *value, bsl::streambuf *streamBuf, int length, const BerDecoderOptions &options)
BerUtil_LengthImpUtil LengthUtil
Definition balber_berutil.h:1080
static int putStringValue(bsl::streambuf *streamBuf, const bsl::string &value)
Definition balber_berutil.h:4581
Definition balber_berutil.h:2309
@ k_EXTENDED_BINARY_MIN_BDE_VERSION
Definition balber_berutil.h:2325
Value
Definition balber_berutil.h:2318
@ e_ISO8601_TIME
Definition balber_berutil.h:2319
@ e_COMPACT_BINARY_TIME
Definition balber_berutil.h:2320
@ e_EXTENDED_BINARY_TIME
Definition balber_berutil.h:2321
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:2316
Definition balber_berutil.h:2409
BerUtil_DateAndTimeHeaderImpUtil DateAndTimeHeaderUtil
Definition balber_berutil.h:2433
BerUtil_DateAndTimeHeaderType DateAndTimeHeaderType
Definition balber_berutil.h:2427
static int getTimeOrTimeTzValue(TimeOrTimeTz *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:5808
BerUtil_StringImpUtil StringUtil
Definition balber_berutil.h:2453
static void timeToMicrosecondsSinceMidnight(bsls::Types::Int64 *microsecondsSinceMidnight, const bdlt::Time &time)
Definition balber_berutil.h:5555
BerUtil_TimeTzEncoding TimeTzEncoding
Definition balber_berutil.h:2468
BerUtil_StreambufUtil StreambufUtil
Definition balber_berutil.h:2458
static int getTimeTzValue(bdlt::TimeTz *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:5731
BerUtil_TimeOrTimeTzEncoding TimeOrTimeTzEncoding
Definition balber_berutil.h:2473
static int microsecondsSinceMidnightToTime(bdlt::Time *time, bsls::Types::Int64 microsecondsSinceMidnight)
Definition balber_berutil.h:5612
static void timeToMillisecondsSinceMidnight(int *millisecondsSinceMidnight, const bdlt::Time &time)
Definition balber_berutil.h:5545
BerUtil_IntegerImpUtil IntegerUtil
Definition balber_berutil.h:2438
static int putTimeValue(bsl::streambuf *streamBuf, const bdlt::Time &value, const BerEncoderOptions *options)
Definition balber_berutil.h:5702
bdlb::Variant2< bdlt::Time, bdlt::TimeTz > TimeOrTimeTz
Definition balber_berutil.h:2482
BerUtil_TimezoneOffsetImpUtil TimezoneUtil
Definition balber_berutil.h:2478
BerUtil_ExtendedBinaryEncodingUtil ExtendedBinaryEncodingUtil
Definition balber_berutil.h:2417
static int putTimeTzValue(bsl::streambuf *streamBuf, const bdlt::TimeTz &value, const BerEncoderOptions *options)
Definition balber_berutil.h:5775
static int millisecondsSinceMidnightToTime(bdlt::Time *time, int millisecondsSinceMidnight)
Definition balber_berutil.h:5572
BerUtil_Iso8601ImpUtil Iso8601Util
Definition balber_berutil.h:2443
BerUtil_LengthImpUtil LengthUtil
Definition balber_berutil.h:2448
BerUtil_TimeEncoding TimeEncoding
Definition balber_berutil.h:2463
static int getTimeValue(bdlt::Time *value, bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:5663
BerUtil_DateAndTimeHeader DateAndTimeHeader
Definition balber_berutil.h:2422
Definition balber_berutil.h:2370
Value
Definition balber_berutil.h:2379
@ e_COMPACT_BINARY_TIME
Definition balber_berutil.h:2382
@ e_ISO8601_TIME
Definition balber_berutil.h:2380
@ e_COMPACT_BINARY_TIMETZ
Definition balber_berutil.h:2383
@ e_EXTENDED_BINARY_TIME
Definition balber_berutil.h:2384
@ e_ISO8601_TIMETZ
Definition balber_berutil.h:2381
@ e_EXTENDED_BINARY_TIMETZ
Definition balber_berutil.h:2385
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:2377
Definition balber_berutil.h:2339
BerUtil_DateAndTimeEncoding Encoding
Definition balber_berutil.h:2346
@ k_EXTENDED_BINARY_MIN_BDE_VERSION
Definition balber_berutil.h:2356
Value
Definition balber_berutil.h:2348
@ e_COMPACT_BINARY_TIMETZ
Definition balber_berutil.h:2351
@ e_COMPACT_BINARY_TIME
Definition balber_berutil.h:2350
@ e_ISO8601_TIMETZ
Definition balber_berutil.h:2349
@ e_EXTENDED_BINARY_TIMETZ
Definition balber_berutil.h:2352
Definition balber_berutil.h:1369
static int putTimezoneOffsetInMinutes(bsl::streambuf *streamBuf, int value)
@ k_TIMEZONE_LENGTH
Definition balber_berutil.h:1379
@ k_MIN_OFFSET
Definition balber_berutil.h:1373
@ k_MAX_OFFSET
Definition balber_berutil.h:1376
static int getTimezoneOffsetInMinutes(int *value, bsl::streambuf *streamBuf)
static bool isValidTimezoneOffsetInMinutes(int value)
static int getTimezoneOffsetInMinutesIfValid(int *value, bsl::streambuf *streamBuf)
Definition balber_berutil.h:198
static int putEndOfContentOctets(bsl::streambuf *streamBuf)
Definition balber_berutil.h:4022
static int getIdentifierOctets(bsl::streambuf *streamBuf, BerConstants::TagClass *tagClass, BerConstants::TagType *tagType, int *tagNumber, int *accumNumBytesConsumed)
static int getValue(bsl::streambuf *streamBuf, TYPE *value, int length, const BerDecoderOptions &options=BerDecoderOptions())
Definition balber_berutil.h:3991
static int putLength(bsl::streambuf *streamBuf, int length)
Definition balber_berutil.h:4034
static int getLength(bsl::streambuf *streamBuf, int *result, int *accumNumBytesConsumed)
Definition balber_berutil.h:3981
static int putIndefiniteLengthOctet(bsl::streambuf *streamBuf)
Definition balber_berutil.h:4028
static int putValue(bsl::streambuf *streamBuf, const TYPE &value, const BerEncoderOptions *options=0)
Definition balber_berutil.h:4041
static int putIdentifierOctets(bsl::streambuf *streamBuf, BerConstants::TagClass tagClass, BerConstants::TagType tagType, int tagNumber)
static int getEndOfContentOctets(bsl::streambuf *streamBuf, int *accumNumBytesConsumed)
Definition balber_berutil.h:3973
@ BDEM_INDEFINITE_LENGTH
Definition balber_berutil.h:206
@ INDEFINITE_LENGTH
Definition balber_berutil.h:207
@ k_INDEFINITE_LENGTH
Definition balber_berutil.h:201
static int parse(bsls::TimeInterval *result, const char *string, ssize_t length)
@ k_DATETZ_STRLEN
Definition bdlt_iso8601util.h:769
@ k_DATE_STRLEN
Definition bdlt_iso8601util.h:768
@ k_TIME_STRLEN
Definition bdlt_iso8601util.h:771
@ k_DATETIMETZ_STRLEN
Definition bdlt_iso8601util.h:775
@ k_MAX_STRLEN
Definition bdlt_iso8601util.h:779
@ k_TIMETZ_STRLEN
Definition bdlt_iso8601util.h:772
@ k_DATETIME_STRLEN
Definition bdlt_iso8601util.h:774
static int generate(char *buffer, ssize_t bufferLength, const bsls::TimeInterval &object)
Definition bdlt_iso8601util.h:2017
static bool isValidSerial(int serialDay)
Definition bdlt_prolepticdateimputil.h:669
static void serialToYmd(int *year, int *month, int *day, int serialDay)
static int ymdToSerial(int year, int month, int day)
Definition bdlt_timeunitratio.h:201
unsigned long long Uint64
Definition bsls_types.h:139
long long Int64
Definition bsls_types.h:134