BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balber_berencoder

Functions

 balber::BerEncoder::MemOutStream::MemOutStream (bslma::Allocator *basicAllocator=0)
 
void balber::BerEncoder::MemOutStream::reset ()
 Reset the internal streambuf to empty.
 
const char * balber::BerEncoder::MemOutStream::data () const
 
int balber::BerEncoder::MemOutStream::length () const
 

Detailed Description

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.

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 bslsb::MemOutStreamBuf object:

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

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:394

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:113
@ e_CONSTRUCTED
Definition balber_berconstants.h:117
TagClass
Definition balber_berconstants.h:92
@ e_UNIVERSAL
Definition balber_berconstants.h:95
@ e_BER_SEQUENCE
Definition balber_beruniversaltagnumber.h:205
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:3910
@ k_INDEFINITE_LENGTH
Definition balber_berutil.h:199

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:1281
@ e_PRIMITIVE
Definition balber_berconstants.h:116
@ e_CONTEXT_SPECIFIC
Definition balber_berconstants.h:97
static int getValue(bsl::streambuf *streamBuf, TYPE *value, int length, const BerDecoderOptions &options=BerDecoderOptions())
Definition balber_berutil.h:3920

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:3902

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