ent memory duration. The mi_stream_init( ) function then returns a pointer to this newly allocated structure, which the mi_stream_open_mytype( ) function also returns.

The Stream-Open Function

Your stream-open function must take the following steps:

  1. Accept as its arguments the type-specific initialization information and use them to open the data.
  2. Call mi_stream_init( ) with appropriate information to initialize an MI_STREAM structure (see Table 7).

The stream-open function must prepare the arguments for the call to the mi_stream_init( ) function, which initializes and optionally allocates an MI_STREAM structure. The mi_stream_init( ) function takes the following arguments:

The Stream-Operations Structure

The stream-operations structure contains pointers to the C functions that implement the generic stream I/O functions for the particular stream. A valid stream-operations structure must exist for the DataBlade API to locate at runtime your type-specific implementations of these generic stream I/O functions. Therefore, it must be initialized before the call to mi_stream_init( ).

Figure 80 shows the declaration of the stream-operations structure, mi_st_ops. For the most current definition, see the mistream.h header file.

Figure 80. The Stream-Operations Structure
#define OPS_NAME_LENGTH 40

struct mi_stream_operations {
   /* the pointers to the functions */
   mi_integer (*close)(MI_STREAM *strm_desc);
   mi_integer (*read)(MI_STREAM *strm_desc, void *buf, 
      mi_integer nbytes);
   mi_integer (*write)(MI_STREAM *strm_desc, void *buf,
      mi_integer nbytes);
   mi_integer (*seek)(MI_STREAM *strm_desc, 
      mi_int8 *offset, mi_integer whence);
   mi_int8 *  (*tell)(MI_STREAM *strm_desc);
   mi_integer (*setpos)(MI_STREAM *strm_desc, 
      mi_int8 *pos);
   mi_integer (*getpos)(MI_STREAM *strm_desc, 
      mi_int8 *pos);
   mi_integer (*length)(MI_STREAM *strm_desc, 
      mi_int8 *length);
   /* names of the functions above */
   char close_name [OPS_NAME_LENGTH];
   char read_name  [OPS_NAME_LENGTH];
   char write_name [OPS_NAME_LENGTH];
   char seek_name  [OPS_NAME_LENGTH];
   char tell_name  [OPS_NAME_LENGTH];
   char setpos_name[OPS_NAME_LENGTH];
   char getpos_name[OPS_NAME_LENGTH];
   char length_name[OPS_NAME_LENGTH];
   /* the function handles for the functions above */
   void *close_fhandle;
   void *read_fhandle;
   void *write_fhandle;
   void *seek_fhandle;
   void *tell_fhandle;
   void *setpos_fhandle;
   void *getpos_fhandle;
   void *length_fhandle;
} mi_st_ops;

As Figure 80 shows, the stream-operations structure consists of the following parts:

You should initialize the pointers and names and set the handles to NULL.

Figure 81 shows a sample stream-operations structure that provides function pointers for the type-specific implementations of the mi_stream_close( ), mi_stream_read( ), and mi_stream_write( ) functions for a stream on a user-defined type named newstream.

Figure 81. A Sample Stream-Operations Structure
static struct mi_st_ops stream_ops_newstream =
{
   stream_close_newstream,
   stream_read_newstream,
   stream_write_newstream,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   "stream_close_newstream",
   "stream_read_newstream",
   "stream_write_newstream",
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL   
};

The code fragment in Figure 81 statically initializes the stream-operations structure. If you initialize this structure dynamically, do so in the stream-open function.

The Stream Data

The second argument to mi_stream_init( ) is an uninterpreted data pointer that is stored in the MI_STREAM structure initialized by the call to mi_stream_init( ). The stream interface does not interpret this pointer, which is for the benefit of the stream implementer. You can retrieve the value of this pointer through a call to mi_stream_get_dataptr( ).

The Stream Descriptor

A stream descriptor holds information about the stream that all stream I/O functions need to access. The mi_stream_init( ) function accepts as its stream-descriptor argument either of the following values:

When you pass the mi_stream_init( ) function a NULL-valued pointer for its stream-descriptor argument, the function allocates a new stream descriptor in the current memory duration. If your application requires a specific memory duration for the stream descriptor, your stream-open function can perform one of the following tasks:

Initialization of the Stream Descriptor

After your type-specific stream-open function has prepared the arguments for the mi_stream_init( ) function, it must call mi_stream_init( ) to initialize the stream descriptor.

Tip:
Whether the mi_stream_init( ) function actually allocates the stream descriptor depends on the value of its third argument. For more information, see The Stream Descriptor.

The stream descriptor, MI_STREAM, holds information about the data stream such as the data and its seek position. For the most current definition of the MI_STREAM structure, see the mistream.h header file.

Support for Stream Access

To provide access to the data in your user-defined stream, you must implement the appropriate generic stream I/O functions. The following table shows which stream I/O functions to implement for the stream characteristics that your stream supports.

Stream Characteristic Description Stream I/O Function
Stream seek position The location within the data at which the next read or write operation begins mi_stream_seek( ), mi_stream_tell( ),
mi_stream_getpos( ), mi_stream_setpos( )
Stream length The size of the data This length can be the size of the data when the stream is initialized or the current size of the data. mi_stream_length( )
Stream mode Which operations are valid: read-only, read/write, or write-only mi_stream_read( ), mi_stream_write( )

Tip:
You do not have to implement the stream I/O functions mi_stream_get_error( ) and mi_stream_eof( ) for your user-defined stream. The implementation of these functions is generic for any stream.

Consider the following information when deciding which stream I/O functions to implement:

The following general rules apply to values that the generic stream I/O functions return:

Registering a UDR That Accesses a Stream

To declare a stream as an argument or return value of a C UDR, use the MI_STREAM data type. When you register this UDR in the database, use the opaque data type stream to represent the stream descriptor.

The database server represents a stream with the stream opaque type. As for other opaque types, the database server stores information on stream in the sysxtdtypes system catalog table.

For example, suppose you have a C declaration for a UDR named get_data( ):

mi_lvarchar *get_data(strm_desc, nbytes)
   MI_STREAM *strm_desc;
   mi_integer nbytes;

The following CREATE FUNCTION statement registers the get_data( ) UDR, using the stream data type as its first argument:

CREATE FUNCTION get_data(data_source stream, nbytes INTEGER)
RETURNS VARCHAR
EXTERNAL NAME '/usr/local/udrs/stream/stream.so(get_data)'
LANGUAGE C;

Releasing Stream Resources

When your DataBlade API module no longer needs a stream, you need to assess whether you can release resources that the stream is using. A stream descriptor that the mi_stream_init( ) function allocated has the current memory duration, so it remains valid until one of the following events occurs:

To conserve resources, use the mi_stream_close( ) function to deallocate the stream descriptor explicitly when your DataBlade API module no longer needs it. The mi_stream_close( ) function is the destructor function for a stream descriptor. This function frees a stream descriptor that mi_stream_init( ) allocated and any associated resources, including the stream-data buffer.

The mi_stream_close( ) function does not automatically free a stream descriptor allocated by your stream-open function. If the mi_stream_init( ) function does not allocate a stream descriptor, your type-specific implementation of mi_stream_close( ) must handle the deallocation.

Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]