![]() |
![]() |
![]() |
![]() |
![]() |
Buffer Management System
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:
- MemSize of type tBMSLength - size of the provided memory
- DataLength of type tBMSLength - size of the data written to the provided user memory
- MemPtr of type void * - pointer to the provided memory
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:
- bms_SmallBuffer - predefined buffer type (see Small Buffer Implementation)
- bms_UserBuffer - type denoting user defined buffer (see User defined Buffer Handling)
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:
- er_BER
- er_Definite
- er_Indefinite
- er_PER
- er_Aligned
- er_Unaligned
- er_NoEndPad - PER without end padding
- er_UER - User defined encoding rules
- er_NoRule
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:
- bms_ReadMode - reading mode, writing is allowed for appending. See BufSetAppendBufFunc( buffer, func ) for more information.
- bms_WriteMode - writing mode, reading is not allowed
- bms_NoMode
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):
- BufInitBuf( buffer, buffer_type )
- This function is used to initialize the buffer management. Memory used by the buffer is allocated by CUCF_ALLOC function, so memory management used in the buffer handling can be configured by means of MMS configuration opportunities (see User defined Memory Handling). The second parameter is the type of the buffer (see tBMSBufType). The function returns error status (see Error codes).
- BufCloseBuf( buffer )
- Closes a buffer and if the buffer has not been initialized by the user memory, releases buffer memory by using CUCF_FREE. The function returns error status (see Error codes).
- BufInitBufWithMemory( buffer, buffer_type, user_memory)
- This function initializes the buffer with the user memory provided in the third parameter (see tBMSUserMemory) without allocating any memory. If user memory contains any encoded data, the buffer can be used further by the decode function. The second parameter is the type of the buffer (see tBMSBufType). The function returns error status (see Error codes).
- BufCloseBufToMemory( buffer, user_memory )
- This function closes the buffer. It does not release any memory, but returns it in the user_memory parameter of type tBMSUserMemory passed by reference. The function returns error status (see Error codes).
- BufGetMemory( buffer, length )
- BufAppendMemory( buffer, append_length )
- BufGetDataCurr( buffer, bit_position )
- BufSetDataCurr( buffer, length, bit_position )
- BufGetDataEnd ( buffer, bit_position )
- BufSetDataEnd ( buffer, length, bit_position )
- BufCopyBuf( buffer_dst, buffer_src )
- This function copies the source buffer buffer_src to target buffer buffer_dst. The function returns error status (see Error codes).
- BufInitReadMode( buffer )
- Prepares the buffer for read operations (read mode, see tBMSMode) and puts the current pointer to the start of the buffer data. The buffer content is not changed or released. The function returns error status (see Error codes).
- BufCloseReadMode( buffer )
- Closes read mode for the buffer. The buffer content is not changed or released. The function returns error status (see Error codes).
- BufCloseDeleteReadMode( buffer )
- Closes read mode for the buffer and logically (without memory releasing) removes read bytes from buffer. Bytes that are not read are still in the buffer. The function returns error status (see Error codes).
- BufInitWriteMode( buffer )
- Prepares the buffer for write operations (write mode, see tBMSMode) and sets the current pointer to the start of the buffer. Previous information in buffer is logically lost (the bytes are still there but they are considered to be empty). The function returns error status (see Error codes).
- BufCloseWriteMode( buffer )
- Closes write mode for the buffer. The buffer content is not changed or released. The function returns error status (see Error codes).
- BufGetBufType( buffer )
- Returns the type of the buffer, see tBMSBufType. It can be useful when the system supports more than one buffer interface and the type of the buffer is not obvious and can change dynamically.
- BufGetDataLen( buffer )
- Returns the byte length (see tBMSLength) of all data that is physically present in the buffer.
- BufGetDataBitLen( buffer )
- Returns the bit length (see tBMSLength) of all data that is physically present in the buffer.
- BufGetReadDataLen( buffer )
- Returns the byte length (see tBMSLength) of the information which has been read from the buffer.
- BufGetReadDataBitLen( buffer )
- Returns bit length (see tBMSLength) of the information which has been read from the buffer.
- BufGetValueLen( buffer )
- Returns byte length (see tBMSLength) of the last value encoded to the buffer or decoded from the buffer.
- BufGetValueBitLen( buffer )
- Returns bit length (see tBMSLength) of the last value encoded to the buffer or decoded from the buffer.
- BufGetMode( buffer )
- Returns buffer mode, see tBMSMode.
- BufInReadMode( buffer )
- This is a boolean function returning true if the buffer is in the read mode (see tBMSMode).
- BufInWriteMode( buffer )
- This is a boolean function returning true if the buffer is in the write mode (see tBMSMode).
- BufInNoMode( buffer )
- BufSetRule( buffer, rule )
- This function sets the encoding rules to the buffer. Each setting overrides the previous. They are checked later in the encode and decode functions. The second parameter is combination of encoding rule masks of type tERRule (see tERRule), it is automatically cast to unsigned long, which is the type of the second parameter. For example, PER without end padding encoding rule is set with an expression BufSetRule(er_PER | er_NoEndPad). If not a complete set of rules is specified then BufSetRule will use default settings, for example BufSetRule(er_PER) is used (without bit masks er_Aligned, er_Unaligned and er_NoEndPad), then default PER variant will be applied which is configured by compilation switches, see Compilation switches. The BufGetRule will return the encoding rules including those that have been applied depending on default settings.
- BufGetRule( buffer )
- This function returns value of type unsigned long which can be checked by binary "AND" operation with bit masks of type ERRule (see tERRule), for example, (SpecifiedRule & er_PER) returns true if specified rule is PER.
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.
- BufGetUserData( buffer )
- This function returns a reference to the user data defined by tUserData type (see User Data).
- BufSetErrInitFunc( buffer, func )
- This function sets a reference to the user error handling function. The interface is available only if CODER_REMOVE_PATH compile switch is absent (see Error handling configuration).
- BufGetErrInitFunc( buffer )
- This function returns a reference to the user error handling function. NULL is returned if the function has not been set. The interface is available only if CODER_REMOVE_PATH compile switch is absent (see Error handling configuration).
- BufGetErrorPath( buffer )
- This function returns a reference to the tErrorPath structure that contains a path of fields from the root type up to the field where an error has occurred. The C-representation of the tErrorPath is:
typedef struct{void* Fields[CODER_PATH_DEEP];unsigned long NumOfFields;...} tErrorPath;- where CODER_PATH_DEEP is the maximum number of nested types, see Error handling configuration. It is used within the user error handling function. The interface is available only if CODER_REMOVE_PATH compile switch is absent (see Error handling configuration). The first element in the Fields array is a reference to the root Type Info - tASN1TypeInfo*. The next element might be one of the following:
- tASN1Component* - for the SEQUENCE/SET component
- tASN1Alternative* - for the CHOICE alternative
- tASN1Object* - for an open object
- long* - for the SEQUENCE OF/SET OF item index
- BufGetMainVal( buffer )
- This function returns a reference to the encode/decode value and it is used in the user error handling to assign the default contents to the value if an error has occurred. The interface is available only if CODER_REMOVE_PATH compile switch is absent(see Error handling configuration).
- BufSetErrorCode( buffer, error_code )
- This function sets an error code (see Error codes) to the buffer.
- BufGetErrorCode( buffer )
- This function returns an error code (see Error codes).
- BufGetByte( buffer )
- BufPeekByte( buffer )
- BufPutByte( buffer, byte )
- BufGetSeg( buffer, length )
- Reads a segment of length (see tBMSLength) bytes from a buffer and returns a segment pointer that points at the start of the retrieved segment. Note that this pointer should not be freed, because it is pointing into the memory segment of the buffer. The segment that has been returned will not be read from the buffer once again by another reading procedure. This function returns unsigned char*.
- BufSkipSeg( buffer, length )
- Skips length (see tBMSLength) bytes from the buffer.
- BufPeekSeg( buffer, length )
- Takes length (see tBMSLength) bytes from the buffer and returns a segment pointer from buffer without moving current pointer in a variable of type unsigned char*. The segment that has been returned can be peeked from the buffer any number of times. Note that this pointer should not be freed, because it is pointing into the memory segment of the buffer.
- BufPutSeg( buffer, segment, length )
- Puts a whole segment of length (see tBMSLength) bytes to the buffer. The second parameter segment is of type unsigned char* and is a pointer to the segment start.
- BufGetBit( buffer )
- Reads one bit from the buffer and returns it in a variable of type unsigned char after logically removing it from the buffer. The bit that has been returned will not be read from the buffer once again by another reading procedure. This function returns unsigned char, where returned bit is the right-most bit in the unsigned char value.
- BufPutBit( buffer, bit )
- BufGetBits( buffer, number )
- Reads number bits from the buffer and returns them in number right-most bits in a variable of type unsigned long after logically removing them from the buffer. The bits that have been returned will not be read from the buffer once again by another reading procedure. The second parameter number is of type unsigned char. Bits are returned in a variable of type unsigned long, so number should be less or equal to sizeof(unsigned long)*8.
- BufPutBits( buffer, bits, number )
- BufAlign( buffer )
- BufSetAppendBufFunc( buffer, func )
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:
- 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);- 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 fromprotocol or sockets or ... */BufPutSeg(buf,seg,len );}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
- BufInitBuf : CoderBuf, tBMSBufType [-> int];
- BufInitBufWithMemory : CoderBuf, tBMSBufType, ptr_tBMSUserMemory [-> int];
- BufCloseBuf : CoderBuf [-> int];
- BufCloseBufToMemory : CoderBuf, ptr_tBMSUserMemory [-> int];
- BufInitReadMode : CoderBuf [-> int];
- BufInitWriteMode : CoderBuf [-> int];
- BufCloseReadMode : CoderBuf [-> int];
- BufCloseDeleteReadMode : CoderBuf [-> int];
- BufCloseWriteMode : CoderBuf [-> int];
- BufGetDataLen : CoderBuf -> tBMSLength;
- BufGetReadDataLen : CoderBuf -> tBMSLength;
- BufGetByte : CoderBuf -> unsigned_char;
- BufPeekByte : CoderBuf -> unsigned_char;
- BufPutByte : CoderBuf, unsigned_char;
- BufSetRule : CoderBuf, tERRule;
- BufGetRule : CoderBuf -> tERRule;
- BufCopyBuf : CoderBuf, CoderBuf [-> int];
- BufPutSeg : CoderBuf, Octet_string, int;
- BufGetSeg : CoderBuf, int -> Octet_string;
- BufPeekSeg : CoderBuf, int -> Octet_string;
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:
- Define the structure UserBufFuncs of type tBaseBuf (see Types and definitions).
- Set the value bms_UserBuffer to the field BufType.
- 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.
- Compile coder library with CODER_USE_USERBUF compile switch, see Buffers configuration,
- Compile and link the application with the user buffer handling functions and the defined structures.
http://www.ibm.com/rational |
![]() |
![]() |
![]() |
![]() |