3 Understanding Flists

Learn about flists (field lists), which pass data between Oracle Communications Billing and Revenue Management (BRM) processes.

Topics in this document:

About Flists

The flist is the primary data structure used in BRM. Flists are containers that hold fields, each of which is a pair consisting of a data field name and its value. Flists do not contain actual data, but instead provide links to where the data is located. The one exception to this is integers, which are stored in flists.

Here is a simple flist example:

LAST_NAME       STR     "Smith"
FIRST_NAME      STR     "Joe"
COMPANY         STR     "XYZ Corporation"

Many BRM processes interpret data in flist format. For example, the storage manager in the Data Manager (DM) translates flists to a format that the database can process and then translates the data from the database into an flist before passing it to the Connection Manager (CM).

BRM uses flists in these ways:

  • Objects are passed in the form of flists between opcodes or programs that manipulate the objects.

  • Opcodes use flists to pass data between BRM applications and the database. For each opcode, an input flist is passed to pcm_op and the return flist is passed back from this routine.

In an flist, you can use any data type such as decimals, buffers, arrays, and substructures. Flists can contain any number of fields. You can place flists within other flists. Remember though, that except for integers, data is not stored in the flist, just links to where the data is located.

For a description of the BRM data types you can use in an flist, see "Understanding the BRM Data Types".

Note:

[0] after the field type represents the element ID. The numbers 0, 1, 2, and so on at the beginning of each line indicate the nesting level of the field; 0 indicates the top level.

When you include a field in an flist, you must also include an abbreviation of the field's data type. Table 3-1 lists the valid BRM field types and their abbreviation.

Table 3-1 Flist Field Types

Field Type Abbreviation

PIN_FLDT_ARRAY

ARRAY

PIN_FLDT_BINSTR

BINSTR

PIN_FLDT_BUF

BUF

PIN_FLDT_DECIMAL

DECIMAL

PIN_FLDT_ENUM

ENUM

PIN_FLDT_ERRBUF

ERR

PIN_FLDT_INT

INT

PIN_FLDT_POID

POID

PIN_FLDT_STR

STR

PIN_FLDT_SUBSTRUCT

SUBSTRUCT

PIN_FLDT_TSTAMP

TSTAMP

Opcode Input and Output Specifications

Each PCM opcode requires certain data to perform its operation. The opcodes take input and output data in the form of field lists (flists), which are lists of field name and value pairs. For more information about flists, see "About Flists".

Each opcode requires its input flist to contain certain fields to perform the operation. For example, to create an object, the PCM_OP_CREATE_OBJECT() opcode requires an input flist that includes all the fields that an object of that storable class requires.

The information for each opcode in the Programmer's Reference includes the input and output flist specifications, defining the following parameters for each field in the flist:

  • The mnemonic field names used by applications to reference the field

  • The data type and size for the field

  • The permissions, which specify if a field is mandatory (M) or optional (O) for the opcode.

The flist specifications use the following syntax to define each field in an flist:

class depth field (
   type = data_type
   perms = permission permission ...,
);

Where class specifies whether it is a field, array, or a substruct, depth contains an asterisk for each nesting level of the field, and field specifies the name of the field.

Examples:

field PIN_FLD_NAME (
      type    =    PIN_FLDT_STR(255),
      perms   =    M,
);
array * PIN_FLD_INHERITED_INFO (
        type    =               PIN_FLDT_ARRAY,
        perms   =               O,
);

For fields in opcode input and output flists, the flist specifications specify if a field is mandatory or optional.

About Creating and Using an Flist

You create and manipulate flists with the flist manipulation macros in the Portal Information Network (PIN) library. You can add, remove, and modify fields in an flist by using the flist field-handling macros. For more information, see "Flist Management Macros" and "Flist Field-Handling Macros" in BRM Developer's Reference.

Each opcode has an input and output flist specification. For each opcode you call, you must create an flist for the data you want to pass in. Follow the flist specifications for the opcode when you create an input or an output flist for an opcode. See the flist specifications in the individual opcode descriptions.

Flists are dynamically allocated data structures. When a field is added to an flist, the field value is either already dynamically allocated in memory, or is copied into dynamic memory as it is added.

Note:

You must destroy the flist you create in your programs to reclaim the memory that the flist occupied. For details, see "Destroying Flists".

Adding Information to Flists

You add data to flists by replacing pointers to data using these flist management macros:

  • PIN_FLIST_ELEM_PUT

  • PIN_FLIST_FLD_PUT

  • PIN_FLIST_SUBSTR_PUT

For details on these macros, see "Flist Management Macros" in BRM Developer's Reference.

You add data to flists by replacing the data itself using these flist management macros:

  • PIN_FLIST_ELEM_SET

  • PIN_FLIST_FLD_SET

  • PIN_FLIST_SUBSTR_SET

For details on these macros, see "Flist Management Macros" in BRM Developer's Reference.

Removing Data (Pointers) from an Flist

You remove a pointer to data from an flist and add it to another flist by using these flist management macros:

  • PIN_FLIST_ELEM_TAKE

  • PIN_FLIST_FLD_TAKE

  • PIN_FLIST_SUBSTR_TAKE

Note:

These macros overwrite existing pointers to data, not the data itself. To free the memory used by the old data, you must destroy the memory location using PIN_FLIST_DESTROY_EX otherwise, a memory leak may occur.

You usually use the TAKE macros when you want to take data from an flist and change it.

Note:

When you use a TAKE macro to remove a pointer to data, you must free the memory when finished. If the memory is not freed, memory leaks may occur.

For details on these macros, see Flist Management Macros in BRM Developer's Reference.

Copying Data from an Flist

You copy a pointer to data from one flist to another by using these flist management macros:

  • PIN_FLIST_ELEM_GET

  • PIN_FLIST_FLD_GET

  • PIN_FLIST_SUBSTR_GET

You usually use the GET macros when you want to copy data, but not change it.

Note:

You should treat any data that you GET by using these macros as read-only because the original program may also need this data.

For details on these macros, see Flist Management Macros in BRM Developer's Reference.

Destroying Flists

You destroy an flist and free its memory by using these flist management macros in BRM Developer's Reference:

Flists use dynamically allocated memory and must be destroyed to free that memory and prevent memory leaks. These macros first determine whether the flist has a NULL value. If so, they do nothing. If the flist exists, these macros destroy the entire contents of the flist, including all fields.

PIN_FLIST_DESTROY_EX sets the reference to the flist to a NULL value after it destroys the flist.

PIN_FLIST_DESTROY frees the memory for the flist field-value pairs, but does not set a reference to that flist to NULL. If another program subsequently attempts to destroy this flist (with freed memory, but a valid flist pointer), unexpected behavior and core dumps can result.

For details on these macros, see Flist Management Macros in BRM Developer's Reference.

Flist Creation Samples

BRM SDK includes flist creation samples in C, C++, Java, and Perl. Three samples are provided for each language: one to create a simple flist, another to create an flist with a nested array, and a third to create an flist with a substructure. For information about installing and using BRM SDK, see "About BRM SDK".

You can view the following sample programs in BRM Developer's Reference:

These documents also include information about compiling and running the programs.

Flist Management Rules

Follow these rules when creating programs that manipulate flists:

  • The calling applications are responsible for allocating memory for input flists. This includes cases where you use a wrapper opcode to call another opcode.

  • The opcode being called is responsible for allocating memory for output flists. For more information, see "About Creating and Using an Flist".

  • The calling applications are responsible for destroying both input and output flists.

  • The opcode being called is responsible for destroying both input and output flists if the opcode utilizes a wrapper opcode to call another opcode. For more information, see "Destroying Flists".

  • You should never destroy an input flist within an opcode, because a calling application may need it.

  • These flist management macros in BRM Developer's Reference allocate new memory:

    You must explicitly de-allocate the memory allocated unless it is used for an output flist.

  • Memory allocation behavior depends on whether the opcode is called through a network (client/server) connection or within an internal Connection Manager (CM) process.

    • If the opcode is called through a client/server connection, the calling application and the CM do not share the same memory. An opcode with memory allocation issues may work if called by a Portal Communications Protocol (PCP) connection, but core dumps if called internally by another opcode.

Example

You use the following syntax to copy an flist:

*out_flistpp = PIN_FLIST_COPY(in_flistp, ebufp);

Flist Field Memory Management Guidelines

You use the following guidelines when creating your programs to avoid memory problems:

For details on these macros, see "Flist Management Macros" in BRM Developer's Reference.

Handling Errors

All flist routines take a pointer to pin_ebuf_t as the final argument. This pointer, called ebufp, must point to a preallocated pin_ebuf_t into which error information is written.

The BRM APIs use the pin_ebuf_t structure to pass back detailed information about the error. BRM includes standard logging routines that print formatted log messages using the date in pin_ebuf_t. You can use these log messages to determine where the error occurred.

See "Finding Errors in Your Code" for more information on how BRM handles error messages.