BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balber_berencoder

Detailed Description

Provide a BER encoder class.

Outline

Purpose

Provide a BER encoder class.

Classes

See also
balber_berdecoder, bdem_bdemencoder, balxml_encoder

Description

This component defines a single class, balber::BerEncoder, that contains a parameterized encode function. The encode function encodes the object of the parameterized type into the specified stream. The encode method is overloaded for two types of output streams:

This component encodes objects based on the X.690 BER specification. It can only be used with types supported by the bdlat framework.

Note that encoding top-level array objects (a.k.a. sequence-of types, in the X.680-X.693 specs) is not allowed.

Usage

This section illustrates intended use of this component.

Example 1: Encoding an Employee Record

Suppose that an "employee record" consists of a sequence of attributes – name, age, and salary – that are of types bsl::string, int, and float, respectively. Furthermore, we have a need to BER encode employee records as a sequence of values (for out-of-process consumption).

Assume that we have defined a usage::EmployeeRecord class to represent employee record values, and assume that we have provided the bdlat specializations that allow the balber codec components to represent class values as a sequence of BER primitive values. See {bdlat_sequencefunctions |Usage} for details of creating specializations for a sequence type.

First, we create an employee record object having typical values:

usage::EmployeeRecord bob("Bob", 56, 1234.00);
assert("Bob" == bob.name());
assert( 56 == bob.age());
assert(1234.00 == bob.salary());

Now, we create a balber::Encoder object and use it to encode our bob object. Here, to facilitate the examination of our results, the BER encoding data is delivered to a bdlsb::MemOutStreamBuf object:

int rc = encoder.encode(&osb, bob);
assert( 0 == rc);
assert(18 == osb.length());
Definition balber_berencoder.h:254
int encode(bsl::streambuf *streamBuf, const TYPE &value)
Definition balber_berencoder.h:802
Definition bdlsb_memoutstreambuf.h:212
bsl::size_t length() const
Return the number of valid characters in this stream buffer.
Definition bdlsb_memoutstreambuf.h:419

Finally, we confirm that the generated BER encoding has the expected layout and values. We create an bdlsb::FixedMemInStreamBuf to manage our access to the data portion of the bdlsb::MemOutStreamBuf where our BER encoding resides:

Definition bdlsb_fixedmeminstreambuf.h:187
const char * data() const
Definition bdlsb_memoutstreambuf.h:413

The balber_berutil component provides functions that allow us to decode the descriptive fields and values of the BER encoded sequence:

int tagNumber;
int accumNumBytesConsumed = 0;
int length;
&tagClass,
&tagType,
&tagNumber,
&accumNumBytesConsumed);
assert(0 == rc);
rc = balber::BerUtil::getLength(&isb, &length, &accumNumBytesConsumed);
assert(0 == rc);
TagType
Definition balber_berconstants.h:117
@ e_CONSTRUCTED
Definition balber_berconstants.h:121
TagClass
Definition balber_berconstants.h:96
@ e_UNIVERSAL
Definition balber_berconstants.h:99
@ e_BER_SEQUENCE
Definition balber_beruniversaltagnumber.h:207
static int getIdentifierOctets(bsl::streambuf *streamBuf, BerConstants::TagClass *tagClass, BerConstants::TagType *tagType, int *tagNumber, int *accumNumBytesConsumed)
static int getLength(bsl::streambuf *streamBuf, int *result, int *accumNumBytesConsumed)
Definition balber_berutil.h:3981
@ k_INDEFINITE_LENGTH
Definition balber_berutil.h:201

The UNIVERSAL value in tagClass indicates that the tagNumber value represents a type in the BER standard, a BER_SEQUENCE, as we requested of the infrastructure (see the IsSequence specialization above). The tagType value of CONSTRUCTED indicates that this is a non-primitive type. The INDEFINITE value for length is typical for sequence encodings. In these cases, the end-of-data is indicated by a sequence to two null bytes.

We now examine the tags and values corresponding to each of the data members of usage::EmployeeRecord class. For each of these the tagClass is CONTEXT_SPECIFIC (i.e., member of a larger construct) and the tagType is PRIMITIVE (bsl::string, int, and float each correspond to a primitive BER type. The tagNumber for each field was defined (in the elided definiton) to correspond the position of the field in the usage::EmployeeRecord class.

&tagClass,
&tagType,
&tagNumber,
&accumNumBytesConsumed);
assert(0 == rc);
assert(1 == tagNumber);
rc = balber::BerUtil::getValue(&isb, &name, &accumNumBytesConsumed);
assert(0 == rc);
assert("Bob" == name);
&tagClass,
&tagType,
&tagNumber,
&accumNumBytesConsumed);
assert(0 == rc);
assert(2 == tagNumber);
int age = 0;
rc = balber::BerUtil::getValue(&isb, &age, &accumNumBytesConsumed);
assert(0 == rc);
assert(56 == age);
&tagClass,
&tagType,
&tagNumber,
&accumNumBytesConsumed);
assert(0 == rc);
assert(3 == tagNumber);
float salary = 0.0;
rc = balber::BerUtil::getValue(&isb, &salary, &accumNumBytesConsumed);
assert(0 == rc);
assert(1234.00 == salary);
Definition bslstl_string.h:1252
@ e_PRIMITIVE
Definition balber_berconstants.h:120
@ e_CONTEXT_SPECIFIC
Definition balber_berconstants.h:101
static int getValue(bsl::streambuf *streamBuf, TYPE *value, int length, const BerDecoderOptions &options=BerDecoderOptions())
Definition balber_berutil.h:3991

Lastly, we confirm that end-of-data sequence (two null bytes) are found we expect them and that we have entirely consumed the data that we generated by our encoding.

rc = balber::BerUtil::getEndOfContentOctets(&isb, &accumNumBytesConsumed);
assert(0 == rc);
assert(osb.length() == static_cast<bsl::size_t>(accumNumBytesConsumed));
static int getEndOfContentOctets(bsl::streambuf *streamBuf, int *accumNumBytesConsumed)
Definition balber_berutil.h:3973

Functions

 balber::BerEncoder::MemOutStream::MemOutStream (bslma::Allocator *basicAllocator=0)
 
void balber::BerEncoder::MemOutStream::reset ()
 
const char * balber::BerEncoder::MemOutStream::data () const
 
int balber::BerEncoder::MemOutStream::length () const
 

Function Documentation

◆ data()

const char * balber::BerEncoder::MemOutStream::data ( ) const
inline

Return the address of the memory containing the values formatted to this stream. The data is not null-terminated unless a null character was appended onto this stream.

◆ length()

int balber::BerEncoder::MemOutStream::length ( ) const
inline

Return the length of the formatted data, including null characters appended to the stream, if any.

◆ MemOutStream()

balber::BerEncoder::MemOutStream::MemOutStream ( bslma::Allocator basicAllocator = 0)
inline

Create a MemOutStream object. Optionally specify a basicAllocator used to supply memory. If basicAllocator is 0, the currently installed default allocator is used.

◆ reset()

void balber::BerEncoder::MemOutStream::reset ( )
inline

Reset the internal streambuf to empty.