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