How it works
encode and decode take a list of OPERATOR => VALUE pairs. An operator
can be one of several types.
Primitive
Control
Derived
An operator can be a reference to a list of 2 elements, in this case the first
element would be the operator identifier a usual, but the second
element would be the tag value to use, this is a alternative to
creating a sub-class of Convert::BER.
The primitive operators defined are
BOOLEAN, INTEGER, STRING, NULL, OBJECT_ID
For encoding the value should be a single value of the correct type,
or a reference to a list of values of the correct type, which will
cause multiple additions to the encoding.
For decoding VALUE must be a reference to a scalar which will be set
after a sucessful decode, or a reference to a list, which will cause
the decode of all subsequent elements of the same type to be
decoded and pushed into the list
For both encode and decode VALUE can be a CODE ref. In this case the sub
will be called, and the result used. If inside SEQUENCE_OF then
@_ in the sub will be a list in indexes for the current loops.
The derived operators are
ENUM - A derived INTEGER, but with a different tag value
SET - A derived SEQUENCE, but with a different tag value
BIGINT - well not really a derived, but it takes a Math::BigInt as
an argument.
the control operators defined are
BER - The argument must be a Conver::BER object, and its buffer
is appended to the current object for encode, and for decode
it will create a new BER object from the next element.
SEQUENCE - Takes a reference to a list, encode/decode a SEQUENCE
element as described by the contents of the list.
CONSTRUCTED - Takes a reference to a list of two elements.
OPTIONAL - Takes a reference to a list. For encode, if the first
element of this list is true then the rest of the list
is passed to encode. For decode the fist element should be
a reference to a SCALAR and if the rest of the list decodes
sucessfully the scalar will be set to true.
SET_OF, SEQUENCE_OF - take a reference to a list
For decode it is a reference to
a scalar which will hold the number that were decoded.
for encode, if the itterator is a hash ref, then it will
itterate through the keys. If it is an array ref, it will
itterate through the elements. If it is a scalar it will
itterate N times.
Any CODE refs called from within one of these will be passed a
list of current itterator values. If SEQUENCE_OF's are nested
the the code ref's will be passed an index for each level of
nesting, with the index for the outermost nesting being passed
first.
THE OPERATOR interface
operators a defined in packages of thier own, an operator called STRING
defined on the Convert::BER class will be defined in a package called
Convert::BER::STRING and will be avaliable to any package that sub-classes
Convert::BER.
Users can sub-class Convert::BER to add thier own operators, thus is a package
called LDAP::BER was a sub-class of Convert::BER, then an operator (eg AND)
defined on this class would be defined in the package LDAP::BER::AND. Only the
operators defined on Convert::BER and LDAP::BER would be avaliable to
a LDAP::BER object.
There are four basic functions
pack($self,$ber,$arg)
this is called as a static method on $self, the result should be
that $arg should be encoded and packed into $ber.
unpack($self,$ber,$posref,$arg)
this is called as a static method on $self, $posref is a ref to a scalar
which holds the index of the first octet after the tag. One element
should be decoded and places into $arg (which is a reference) $posref
should the be updated to point to the first octet after the element.
On error $$arg should be undef, $$posref should be unchanged and the
return value should be undef.
pack_array($self,$ber,$arg)
This is like pack, except $are will be a reference to an array. This
method is defined by operators that want to do something different
with array refs. (eg SEQUENCE, CONSTRUCTED etc)
unpack_array($self,$ber,$posref,$arg)
this is to unpack as pack_array is to pack.
for both unpack_array and pack_array the array referenced by $arg should
not be modified (shift etc) as it may cause sebsequent calls from the
user code to break.
###
### I did start the POD a while back, but it is now so out of date I
### have placed it here
###
=head1 NAME
Convert::BER - Basic Encoding Rules for ASN.1
=head1 SYNOPSIS
use Convert::BER;
$ber = new Convert::BER;
$ber->encode(
INTEGER => 10,
STRING => "a string",
SEQUENCE => [
BOOLEAN => 1,
STRING => [ qw(a list of strings) ]
]
);
$ber->decode(
INTEGER => \$int,
STRING => \$str,
SEQUENCE => [
BOOLEAN => \$bool,
STRING => \@str_list
]
);
=head1 DESCRIPTION
=over 4
=item INTEGER => VALUE
=item STRING => VALUE
=item BOOLEAN => VALUE
=item NULL => VALUE
=item OBJECT_ID => VALUE
Encode VALUE, if VALUE is a reference to an ARRAY then encode
each element in the array.
=item SEQUENCE => ARRAY
=item SET => ARRAY
Encode the contents of ARRAY and add a SEQUENCE or SET header
=item BER => OBJ
OBJ should be a C<Convert::BER> object, the buffer of this object will just
be inserted. If OBJ is a reference to an ARRAY then each element
in the array should be a C<Convert::BER> object and all of then
will be inserted.
=item OPTIONAL => ARRAY
decode content of ARRAY if they exists, or none of them.
=item CONSTRUCTED => ARRAY
=item CONSTRUCTED => OBJ
ARRAY should be a reference to a 2 element array
OBJ should be a Convert::BER object
=back
=head1 DEFINEING NEW TYPES
=over 4
=item pack SELF, BER, ARG
pack ARG into BER, called as a static method on SELF
=item unpack SELF, BER, POSREF, ARG
unpack an element. POSREF is a reference to a scalar holding the starting point,
and should be updated with the position of the end.
ARG is a reference where the result should be placed.
=item pack_array SELF, BER, ARG
As C<pack> but ARG will be a reference to an ARRAY. Used only if type
want to do something different to the usual (eg SEQUENCE)
=item unpack_array SELF, BER, POSREF, ARG
As C<unpack> but ARG will be a reference to an ARRAY. Used only if type
want to do something different to the usual (eg SEQUENCE)
=back
=head1 AUTHOR
Graham Barr E<lt>F<gbarr@ti.com>E<gt>
=head1 CREDITS
The following people have given some useful input into the design of this
package.
Russell Fulton E<lt>F<r.fulton@auckland.ac.nz>E<gt>
Benjamin Holzman E<lt>F<bah@mail.med.cornell.edu>E<gt>
Emmanuel Tlemcani E<lt>F<Emmanuel.Tlemcani@der.edfgdf.fr>E<gt>
Ian Redfern E<lt>F<RedfernI@logica.com>E<gt>
=head1 COPYRIGHT
This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut