IBM
Contents Index Previous Next



Buffer Management System


Figure 509 : Relationship between coders and buffer management

The buffer interface is a set of functions that operates with data. Buffer management stores data in the buffer memory. Data is presented as byte, bit or character segment. Available basic operations are get, put, peek and skip. The buffer interface also opens a possibility for direct access to buffer memory from BMS environment (from encode and decode). According to this there is direct access to the buffer memory which presented as one continuos piece.

The buffer management functions have an open design, where it is possible to choose between different buffer implementations with different characteristics. This choice is available in runtime mode and also within compilation by switches defined in Buffers configuration. This is possible due to an open and specified buffer interface that all encode and decode functions use and that your SDL specifications and C functions should use as well. The interface is specified as a set of C macros. See C interface to buffer management system for more information. The buffer management implements all the macros in the interface.

The buffer management is accessed from an SDL system by using operators in the buffer management Abstract Data Type. The operators are mapped to the open buffer management interface.

The only buffer management implementation at present in the SDL Suite is the small buffer (see Small Buffer Implementation).

C interface to buffer management system

This chapter describes the open buffer interface. This is the C access interface to the buffer management.

Types and definitions

The buffer access type is tBuffer. tBuffer is defined as a pointer to a structure tCoder.

Example 477 : Buffer as a reference

tBuffer buf = NULL;
BufInitBuf(buf, bms_SmallBuffer);

tCoder is used as access type only in tiny mode (see Example 487).

BMS introduces several specific types which are described below.

tBMSLength

BMS length type is defined as unsigned long.

tBMSUserMemory

This type is structure describing information about memory provided by the user. It contains three fields:

This type is used as parameter type in the buffer interface functions BaseBufInitBufWithMemory and BaseBufCloseBufToMemory.

tBMSBufType

This type is an enumeration describing all following possible types of buffers. Two types of buffers are available:

This type is used for specifying the type of buffer which will be used.

tERRule

This type is an enumeration describing possible kinds of encoding rules. It contains basic rules (BER, PER, etc.) as well as their different variations:

The enumeration values are regarded as bit masks for different kinds of encoding rules, for example, PER Aligned can be specified with er_PER | er_Aligned; expression ( SpecifiedRule & ( er_PER | er_Aligned ) ) will check if the specified type of encoding rules SpecifiedRule is PER Aligned.

tBMSMode

This type is an enumeration describing possible modes for the buffer:

Buffer Management Functions

The buffer management functions put bytes and bits into a buffer which you can use to send over a protocol. The buffer management also provide several interfaces to operate with buffer memory and buffer handling.

The internal implementation of the buffer is not shown in the buffer interface, thus all manipulation of the buffer should be done using the macros. A buffer must be created before use. It must be opened before a read/write session and closed after a session. A buffer can be in either a read mode or a write mode, but not in both modes at the same time.

The open buffer interface macros are described below (parameter buffer in all functions is of type tBuffer, see Types and definitions):

Caution! Checking specified encoding rules

unsigned long SpecifiedRule = BufGetRule( buffer );

( SpecifiedRule & er_PER & er_Aligned ) is not a correct check for PER Aligned.

( SpecifiedRule & ( er_PER | er_Aligned ) ) should be used instead.

Example 478 : Sending a buffer

unsigned char * data;
unsigned int    datalen;

BufInitReadMode(buf);
datalen = BufGetDataLen(buf);
data = BufGetSeg(buf,datalen);
send_protocol(sa,data,datalen);
BufCloseReadMode(buf);

Example 479 : Receiving from protocol and putting in a buffer

unsigned char data[MAXSIZE];
unsigned int datalen;

BufInitWriteMode(buf);
datalen=1;
while(datalen>0) {
   datalen = receive_protocol(sa,data,MAXSIZE,0);
   if (datalen>0) 
      BufPutSeg(buf,data,datalen);
}
BufCloseWriteMode(buf);

You can write an append function that will be called when there are not enough bytes left in the buffer for a read operation. An example of when this can occur is during the execution of a decode function. The calling function calculates how many bytes that must be added to the buffer. The append function can choose to add more bytes than this. An append function can be called several times during a decode execution.

The buffer is in write mode when the append function is called and will automatically be set to read mode after the append function is finished. Do not use the BufInitWriteMode or BufInitReadMode macros in the append function.

If you want to add an append function for a buffer, then do the following steps:

  1. Implement a C-procedure for appending data to the buffer. The C-procedure must have parameters compatible with tBufAppendFunc.
    typedef void (*tBufAppendBufFunc)(tBuffer buf, 
    unsigned int len);
    
  2. Use the macro BufSetAppendBufFunc, with the buffer and the append procedure as input parameters, immediately after a call to BufInitBuf.

Example 480 : Buffer Append Procedure

void MyAppendBuf( tBuffer buf,
                  unsigned int minbytes );
{
    /* receive at least minbytes from
       protocol or sockets or ... */

    BufPutSeg(buf,seg,len );
}

Setting appending function:

BufInitBuf(buf);
BufSetAppendBufFunc(buf,MyAppendBuf);

Small Buffer Implementation

A small buffer has a memory segment, an array of unsigned char. The encoded bit patterns are written to this segment and the bit patterns to decode are read from it.

The buffer pointer is a pointer to a control structure and a data structure. The control structure and the data structure contains information and memory pointers that the small buffer uses.

In the data structure, there is a pointer that points at the beginning of the memory segment, a pointer that points at the end of the memory segment and a pointer that points at current position for a read or write operation.

Memory is allocated inside the small buffer implementation. An initial memory segment is allocated. The size of the initial segment is set by defining the macro CODER_SMALLBUF_SIZE, which has the default value equal to 0x1000, see Buffers configuration. When a memory segment is full and a bigger segment is needed, then a 2 times larger segment is allocated, the contents in the old segment copied and the old segment freed. The macros CUCF_ALLOC and CUCF_FREE are used for all memory allocation and de-allocation.

SDL Interface to Buffer Management System

SDL CoderBuf interface

In the Extended SDL Interface, encoded data is stored in the C-buffer interface. From SDL, this data is accessed via the SDL type CoderBuf. The interface is not a direct mapping of the C-interface. Some of the functions are not accessible from SDL. For more detailed information about C-interface to the buffer management system see C interface to buffer management system.

Below is a summary of the contents in the file CoderBuf.sdl.

Types

The SDL buffer interface type names are the same as the ones in the C buffer interface (see Types and definitions). The following type is introduced in the SDL buffer interface

Operators

These operators are mapped to the C buffer interface functions, so the semantics of SDL operators is the same as described for the corresponding C procedures in Buffer Management Functions.

SDL CustomCoderBuf interface

If you want a solution of your own for accessing the coder library from within SDL, you can use CustomCoderBuf. This can be achieved by modifying the file CustomCoderBuf.sdl and writing two C-procedures. CustomCoderBuf can then be used in the calls of encode and decode instead of CoderBuf.

If only minor changes are of interest, you could copy the CoderBuf.sdl file to CustomCoderBuf.sdl as a start. Even when the goal is to make a completely new access interface, CoderBuf.sdl could be used as an example.

Implementing the procedures ASN1EncodeCustomBuf and ASN1DecodeCustomBuf in a file of your own, means that the file should then be included in the build process. For further information about parameters and return values of those procedures see the file cucf_er_sdt.h in the coder library. When CustomCoderBuf is selected in the user interface, the code generator generates code that calls those two procedures.

The procedures ASN1EncodeCoderBuf/ASN1DecodeCoderBuf and ASN1EncodeOctet/ASN1DecodeOctet could be seen as SDL Suite versions of a CustomCoderBuf. The first parameter in that implementation is CoderBuf and Octet_string respectively. When implementing your own CustomCoderBuf, you can select whatever type of this first parameter you want. However, it is important that the type defined in CustomCoderBuf.sdl file corresponds to the first parameter of the two above procedures.

The choice of using a custom implementation must be selected in the Analyzer dialog. See Analyze SDL.

User defined Buffer Handling

The coder library can be configured to work with user defined buffers. It is possible to write your own specific buffer handling procedures which will be invoked instead of the default buffer handlers.

All coder library buffer implementations are based on the open buffer interface approach which allows you to introduce user types of buffer management in the same style as, for example, predefined small buffer management implementation.

If you want to use your own buffers, then perform the following steps:

  1. Define the structure UserBufFuncs of type tBaseBuf (see Types and definitions).
  2. Set the value bms_UserBuffer to the field BufType.
  3. Implement the buffer access functions and assign references to these functions to the corresponding fields of UserBufferFuncs. Buffer access functions should have compatible interfaces with the function pointer types defined for tBaseBuf structure in the file bms.h (see Buffer Management System sub-directory) and should support the semantics of buffer access functions described in Buffer Management Functions.

Note: Buffer implementation example

The small buffer implementation is based on the open buffer interface and can be used as an example of a user defined buffer implementation. Looking into the files bms_small.h and bms_small.c in the installation (see Buffer Management System sub-directory) will be helpful before starting the implementation.

  1. Compile coder library with CODER_USE_USERBUF compile switch, see Buffers configuration,
  2. Compile and link the application with the user buffer handling functions and the defined structures.

http://www.ibm.com/rational
Contents Index Previous Next