NAME

Convert::BER - ASN.1 Basic Encoding Rules

SYNOPSIS

    use Convert::BER;
    
    $ber = new Convert::BER;
    
    $ber->encode(
	INTEGER => 1,
	SEQUENCE => [
	    STRING => [ qw(a b c) ]
	]
    );
    
    $ber->decode(
	INTEGER => \$i,
	SEQUENCE => [
	    STRING => \@str
	]
    );
    
    $ber->buffer("");
    
    $ber->encode(
	SEQUENCE_OF => [ \%hash
	    STRING  => sub { $_[0] },
	    INTEGER => sub { $hash{ $_[0] } }
	]
    );
    
    $ber->decode(
	SEQUENCE_OF => [ \$count
	    STRING  => sub { push @keys, undef; \$keys[-1] },
	    INTEGER => sub { push @values, undef; \$values[-1] }
	]
    );

NOTE

This documentation is still under construction. Convert::BER is a a very flexable package that supports a lot of options. see the tests in t/ for examples

DESCRIPTION

Convert::BER provides an OO interface to encoding and decoding data into packets using the ASN.1 Basic Encoding Rules (BER)

METHODS

new
new ( BUFFER )
new ( opList )

new creates a new Convert::BER object.

encode ( opList )

Encode data in opList appending to the data in the buffer.

decode ( opList )

Decode the data in the buffer as described by opList, starting where the last decode finished or position set by pos

buffer ( [ BUFFER ] )

Return the buffer contents. If BUFFER is specified the set the buffer contents and reset pos to zero.

pos ( [ POS ] )

Without any arguments pos returns the offset where the last decode finished, or the last offset set by pos. If POS is specified then POS will be where the next decode starts.

IO METHODS

read ( IO )
write ( IO )
recv ( SOCK )
send ( SOCK [, ADDR ] )

OPLIST

An opList is a list of operator-value pairs. An operator can be any defined below, or any defined by a sub-class of Convert::BER, which will probably be derived from the primitives given here.

For the following operators if encoding the value is the value of the data to be encoded, if decoding it is a reference to where the decoded will be put.

If value is a reference to a list then, for encode each item in the list will be encoded in turn. If decoding then as many a possible items of teh given type will be decoded an placed into the array, but there must be at least one or the whole decode will fail.

If value is a CODE reference, then the code will be evaluated and the result used. For encode the code should return either the data to be encoded or a reference to a list of data to be encoded. For decode the code should return a reference to where the decoded data should be placed or a reference to a list. The arguments that are passed to the code are described below in the SEQUENCE_OF section.

BOOLEAN
INTEGER
STRING
NULL
OBJECT_ID
ENUM

Other operators avaliable are

SEQUENCE

A SEQUENCE can be encoded ....

SET

A set it treated in an identical way to a SEQUENCE.

SEQUENCE_OF

SPECIAL OPERATORS

BER

Encode: value should be a Convert::BER object, which will be inserted into the buffer

Decode: value should be a reference to a scalar, which will contain a Convert::BER object. This object will contain the remainder of the current sequence.

ANY

Like BER except that when decoding only the next item is decoded and placed into the Convert::BER object returned.

OPTIONAL

The value to this operator must be a reference to an opList.

Encode: The contents value are encoded into the buffer.

Decode: The contents of value are decoded if possible, if not then decode continues at the next operator-value pair.

TAGS

Each operator, other than the special operators, has a tag value associated with it. Some applications require these tag values to be different from the default values. Convert::BER supports two ways of doing this. One method is to sub-class Convert::BER, which is described in the next section. For small applications or those that think sub-classing is just too much then the operatorm may be passed an arrayref. The array must contain two elements, the first is the usual operator name and the second if the tag value to use, as shown below.

    $ber->encode(
	[ SEQUENCE => 0x34 ] => [
	    INTEGER => 10,
	    STRING  => "A"
	]
    );

This will encode a sequence, with a tag value of 0x34, which will contain and integer and a string which will have thier default tag values.

SUB-CLASSING

For large applications where operators with non default tags are used a lot the above maechanism can be very erroroneous, for this porpose Convert::BER may be sub-classed.

To do this the sub-class must call a method define as a static method on the sub-class. The arguments to define is a list if arrayref's. Each arrayref will define one new operator. Each arrayref contains three values, the first is the name of the operator, the second is how the data is encoded and the third is the tag value. To aid with the creation of these arguments Convert::BER exports some variables and constant subroutines.

For each operator defined by Convert::BER, or a Convert::BER sub-class, a scalar variable with the same name is avaliable for import, for example $INTEGER is avaliable from Convert::BER. And any operators defined by a new sub-class will be avaliable for import from that class. One of these variables may be used as the second element of each arrayref.

Convert::BER also exports some constant subroutines that can be used to create the tag value. The subroutines exported are.

	BER_BOOLEAN
	BER_INTEGER
	BER_BIT_STR
	BER_OCTET_STR
	BER_NULL
	BER_OBJECT_ID
	BER_SEQUENCE
	BER_SET
    
	BER_UNIVERSAL
	BER_APPLICATION
	BER_CONTEXT
	BER_PRIVATE
	BER_PRIMITIVE
	BER_CONSTRUCTOR

Using this information a sub-class of Convert::BER can be created as shown below.

    package Net::LDAP::BER;

    use Convert::BER qw(/^(\$|BER_)/);

    use strict;
    use vars qw($VERSION @ISA);

    @ISA = qw(Convert::BER);
    $VERSION = "1.00";

    Net::LDAP::BER->define(

      # Name		Type      Tag
      ########################################

      [ REQ_UNBIND     => $NULL,
			  BER_APPLICATION  	 	    | 0x02 ],
    
      [ REQ_COMPARE    => $SEQUENCE,
			  BER_APPLICATION | BER_CONSTRUCTOR | 0x0E ],
    
      [ REQ_ABANDON    => $INTEGER,
			  BER_APPLICATION  		    | 0x10 ],
    );

This will create a new class Net::LDAP::BER which has three new operators avaliable. This class then may be used as follows

    $ber = new Net::LDAP::BER;
    
    $ber->encode(
	REQ_UNBIND => 0,
	REQ_COMPARE => [
	    REQ_ABANDON => 123,
	]
    );

    $ber->decode(
	REQ_UNBIND => \$var,
	REQ_COMPARE => [
	    REQ_ABANDON => \$num,
	]
    );

Which will encode or decode the data using the formats and tags defined in the Net::LDAP::BER sub-class. It also helps to make the code more readable.

DEFINING NEW PACKING OPERATORS

As well as defining new operators which inherit from existing operators it is also possible to define a new operator and how data is encoded and decoded. The interface for doing this is still changing but will be documented here when it is done. to be continued ...

LIMITATIONS

Convert::BER cannot support tags that contain more bits than can be stored in a scalar variable, typically this is 32 bits.

Convert::BER cannot support items that have a packed length which cannot be stored in 32 bits

TODO

CONSTRUCTED operator

BUGS

None known, but there may be some

AUTHOR

Graham Barr <gbarr@pobox.com>

COPYRIGHT

Copyright (c) 1995-8 Graham Barr. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 308:

'=item' outside of any '=over'

Around line 312:

You forgot a '=back' before '=head1'