>This section provides the following information about how to store varying-length data:

Storing Data in a Varying-Length Structure

The mi_set_vardata( ) and mi_set_vardata_align( ) functions copy data into an existing data portion of a varying-length structure. These functions assume that the data portion is large enough to hold the data being copied. The code fragment in Figure 6 uses mi_set_vardata( ) to store data in the existing data portion of the varying-length structure that new_lvarch references.

Figure 6. Storing Data in Existing Data Portion of a Varying-Length Structure
#define TEXT_LENGTH 200
...

mi_lvarchar *new_lvarch;
mi_char *local_var;
...
/* Allocate a new varying-length structure with a 200-byte
 * data portion
 */
new_lvarch = mi_new_var(TEXT_LENGTH);

/* Allocate memory for null-terminated string */
local_var = (char *)mi_alloc(TEXT_LENGTH + 1);

/* Create the varying-length data to store */
sprintf(local_var, "%s %s %s", "A varying-length structure ",
   "stores data in a data portion, which is separate from ",
   "the varying-length structure.");

/* Update the data length to reflect the string length */
mi_set_varlen(new_lvarch, stleng(local_var));

/* Store the varying-length data in the varying-length
 * structure that new_lvarch references
 */
mi_set_vardata(new_lvarch, local_var);

In Figure 6, the call to mi_new_var( ) creates a new varying-length structure and sets the length field to 200. This call also allocates the 200-byte data portion (see Figure 5).

Figure 7 shows the format of the varying-length structure that new_lvarch references after the call to mi_set_vardata( ) successfully completes.

Figure 7. Format of a Varying-Length Structure
begin figure description - This figure is described in the surrounding text. - end figure description

The mi_set_vardata( ) function copies from the local_var buffer the number of bytes that the data length specifies. Your code must ensure that the data-length field contains the number of bytes you want to copy. In the code fragment in Figure 6, the data-length field was last set by the call to mi_set_varlen( ) to 110 bytes. However, if the mi_set_varlen( ) function executed after the mi_set_vardata( ) call, the data length would still have been 200 bytes (set by mi_new_var( )). In this case, mi_set_vardata( ) would try to copy 200 bytes starting at the location of the local_var variable. Because the actual local_var data only occupies 110 bytes of memory, 90 unused bytes remain in the data portion.

The mi_set_vardata( ) function aligns the data that it copies on four-byte boundaries. If this alignment is not appropriate for your varying-length data, use the mi_set_vardata_align( ) function to store data on a byte boundary that you specify. For example, the following call to mi_set_vardata_align( ) copies data into the var_struc varying-length structure and aligns this data on eight-byte boundaries:

char *buff;
mi_lvarchar *var_struc;
...
mi_set_vardata_align(var_struc, buff, 8);

You can determine the alignment of a data type from its type descriptor with the mi_type_align( ) function.

Tip:
You can also store data in a varying-length structure through the data pointer that you obtain with the mi_get_vardata( ) or mi_get_vardata_align( ) function. For more information, see Obtaining the Data Pointer.

The mi_set_vardata_align( ) function copies the number of bytes that the data-length field specifies.

Storing a Null-Terminated String

The mi_string_to_lvarchar( ) function copies a null-terminated string into a varying-length structure that it creates. This function performs the following steps:

  1. Allocates a new varying-length structure

    The mi_string_to_lvarchar( ) function allocates the varying-length descriptor, setting the data length and data pointer appropriately. Both the data length and the size of the data portion are the length of the null-terminated string without its null terminator.

    Server Only

    The mi_string_to_lvarchar( ) function allocates the varying-length structure that it creates with the current memory duration.

    End of Server Only
  2. Copies the data of the null-terminated string into the newly allocated data portion

    The mi_string_to_lvarchar( ) function does not copy the null terminator of the string.

  3. Returns a pointer to the newly allocated varying-length structure

The following code fragment uses mi_string_to_lvarchar( ) to store a null-terminated string in the data portion of a new varying-length structure:

char *local_var;
mi_lvarchar *lvarch;
...
/* Allocate memory for null-terminated string */
local_var = (char *)mi_alloc(200);

/* Create the varying-length data to store */
sprintf(local_var, "%s %s %s", "A varying-length structure ",
   "stores data in a data portion, which is separate from ",
   "the varying-length structure.");

/* Store the null-terminated string as varying-length data */
lvarch = mi_string_to_lvarchar(local_var);

Figure 8 shows the format of the varying-length structure that lvarch references after the preceding call to mi_string_to_lvarchar( ) successfully completes.

Figure 8. Copying a Null-Terminated String into a Varying-Length Structure
begin figure description - This figure is described in the surrounding text. - end figure description

The lvarch varying-length structure in Figure 8 has a data length of 110. The null terminator is not included in the data length because the mi_string_to_lvarchar( ) function does not copy the null terminator into the data portion.

If your DataBlade API module needs to store a null terminator as part of the varying-length data, you can take the following steps:

  1. Increment the data length accordingly and save it in the varying-length descriptor with the mi_set_varlen( ) function.
  2. Copy the data, including the null terminator, into the varying-length structure with the mi_set_vardata( ) or mi_set_vardata_align( ) function.

    These functions copy in the null terminator because the data length includes the null-terminator byte in its count. These functions assume that the data portion is large enough to hold the string and any null terminator.

After you perform these steps, you can obtain the null terminator as part of the varying-length data.

Important:
If you choose to store null terminators as part of your varying-length data, your code must keep track that this data is null-terminated. The DataBlade API functions that handle varying-length structures do not track the presence of a null terminator.

The following code fragment stores a string plus a null terminator in the varying-length structure that lvarch references:

#define TEXT_LENGTH 200
...

mi_lvarchar *lvarch;
char *var_text;
mi_integer var_len;
...
/* Allocate memory for null-terminated string */
var_text = (char *)mi_alloc(TEXT_LENGTH);

/* Create the varying-length data to store */
sprintf(var_text, "%s %s %s", "A varying-length structure ",
   "stores data in a data portion, which is separate from ",
   "the varying-length structure.");
var_len = stleng(var_text) + 1;

/* Allocate a varying-length structure to hold the 
 * null-terminated string (with its null terminator)
 */
lvarch = mi_new_var(var_len);

/* Copy the number of bytes that the data length specifies
 * (which includes the null terminator) into the 
 * varying-length structure
 */
mi_set_vardata(lvarch, var_text);

Figure 9 shows the format of this varying-length structure after the preceding call to mi_set_vardata( ) successfully completes.

Figure 9. Copying a Null-Terminated String into a Varying-Length Structure
begin figure description - This figure is described in the surrounding text. - end figure description
Setting the Data Pointer

The mi_set_varptr( ) function enables you to set the data pointer in a varying-length structure to memory that you allocate. The following code fragment creates an empty varying-length structure, which is a varying-length structure that has no data portion allocated:

#define VAR_MEM_SIZE 20
...
mi_lvarchar *new_lvarch;
char *var_text;
mi_integer var_len;
...
/* Allocate PER_COMMAND memory for varying-length data */
var_text = (char *)mi_dalloc(VAR_MEM_SIZE, PER_COMMAND);

/* Allocate an empty varying-length structure */
(void)mi_switch_mem_duration(PER_COMMAND);
new_lvarch = mi_new_var(0);

/* Store the varying-length data in the var_text buffer
 * with the fill_buffer( ) function (which you have coded). 
 * This function returns the actual length of the nonnull- 
 * terminated string. It does NOT put a null terminator at 
 * the end of the data.
 */
var_len = fill_buffer(var_text);

Figure 10 shows the format of the varying-length structure that new_lvarch references after the fill_buffer( ) function successfully completes.

Figure 10. Empty Varying-Length Structure
begin figure description - This figure is described in the surrounding text. - end figure description

The varying-length structure in Figure 10 is empty because it has the following characteristics:

After you have an empty varying-length structure, you can use the mi_set_varptr( ) function to set the data pointer to the PER_COMMAND memory duration, as the following code fragment shows:

/* Set the length of the new varying-length data */
mi_set_varlen(new_lvarch, VAR_MEM_SIZE);

/* Set the pointer to the data portion of the
 * varying-length structure to the PER_COMMAND memory
 * that 'var_text' references.
 */
mi_set_varptr(new_lvarch, var_text);

The preceding call to mi_set_varlen( ) updates the length in the varying-length structure to the length of 20 bytes. Figure 11 shows the format of the varying-length structure that new_lvarch references after the preceding call to mi_set_varptr( ) successfully completes.

Figure 11. Setting the Data-Portion Pointer in a Varying-Length Structure
begin figure description - This figure is described in the surrounding text. - end figure description
Server Only

Make sure that you allocate the data-portion buffer with a memory duration appropriate to the use of the data portion.

End of Server Only

For more information in memory allocation, see Managing Memory.

Information About Varying-Length Data

Use the following DataBlade API accessor functions to obtain information about varying-length data from a varying-length structure.

Varying-Length Information DataBlade API Accessor Function
Length of varying-length data mi_get_varlen( )
Data portion mi_lvarchar_to_string( ), mi_var_to_buffer( ), mi_var_copy( )
Data pointer mi_get_vardata( ), mi_get_vardata_align( )
Obtaining the Data Length

The mi_get_varlen( ) function returns the data length from a varying-length descriptor. Keep in mind the following restrictions about data length:

For the varying-length structure in Figure 5, a call to mi_get_varlen( ) returns 200. For the varying-length structure that Figure 7 shows, a call to mi_get_varlen( ) returns 110.

Obtaining Data as a Null-Terminated String

The mi_lvarchar_to_string( ) function obtains the data from a varying-length structure and converts it to a null-terminated string. This function performs the following steps:

  1. Allocates a new buffer to hold the null-terminated string
    Server Only

    The mi_lvarchar_to_string( ) function allocates the string that it creates with the current memory duration.

    End of Server Only
  2. Copies the data in the data portion of the varying-length structure to the newly allocated buffer

    The mi_lvarchar_to_string( ) function automatically copies the number of bytes that the data length in the varying-length descriptor specifies. It then appends a null terminator to the string.

  3. Returns a pointer to the newly allocated null-terminated string

Suppose you have the varying-length structure that Figure 8 shows. The following code fragment uses the mi_lvarchar_to_string( ) function to obtain this varying-length data as a null-terminated string:

mi_lvarchar *lvarch;
char *var_str;
...
var_str = mi_lvarchar_to_string(lvarch);

The code fragment does not need to allocate memory for the var_str string because the mi_lvarchar_to_string( ) function allocates memory for the new string. After the call to mi_lvarchar_to_string( ) completes successfully, the var_str variable contains the following null-terminated string:

A varying-length structure stores data in a data portion, which is separate 
from the varying-length structure.
Copying Data into a User-Allocated Buffer

The mi_var_to_buffer( ) function copies the data of an existing varying-length structure into a user-allocated buffer. The function copies data up to the data length specified in the varying-length descriptor. You can obtain the current data length with the mi_get_varlen( ) function.

The following code fragment copies the contents of the varying-length structure in Figure 8 into the my_buffer user-allocated buffer:

mi_lvarchar *lvarch;
char *my_buffer;
...
my_buffer = (char *)mi_alloc(mi_get_varlen(lvarch));
mi_var_to_buffer(lvarch, my_buffer);

After the successful completion of mi_var_to_buffer( ), the my_buffer variable points to the following string, which is not null terminated:

A varying-length structure stores data in a data portion, which is separate 
from the varying-length structure.

Important:
Do not assume that the data in the user-allocated buffer is null terminated. The mi_var_to_buffer( ) function does not append a null terminator to the data in the character buffer.
Copying Data into a New Varying-Length Structure

The mi_var_copy( ) function copies data from an existing varying-length structure into a new varying-length structure. This function performs the following steps:

  1. Allocates a new varying-length structure

    For the new varying-length structure, the mi_var_copy( ) function allocates a data portion whose size is that of the data in the existing varying-length structure.

    Server Only

    The mi_var_copy( ) function allocates the varying-length structure that it creates with the current memory duration.

    End of Server Only
  2. Copies the data in the data portion of the existing varying-length structure to the data portion of the newly allocated varying-length structure

    The mi_var_copy( ) function automatically copies the number of bytes that the data length in the existing varying-length descriptor specifies.

  3. Returns a pointer to the newly allocated varying-length structure as a pointer to an mi_lvarchar value

Suppose you have the varying-length structure that Figure 8 shows. The following code fragment uses the mi_var_copy( ) function to create a copy of this varying-length structure:

mi_lvarchar *lvarch, *lvarch_copy;
...
lvarch_copy = mi_var_copy(lvarch);

After the call to mi_var_copy( ) completes successfully, the lvarch_copy variable points to a new varying-length structure, as Figure 12 shows. The varying-length structure that lvarch_copy references is a completely separate structure from the structure that lvarch references.

Figure 12. Copying a Varying-Length Structure
begin figure description - This figure is described in the surrounding text. - end figure description
Obtaining the Data Pointer

The mi_get_vardata( ) and mi_get_vardata_align( ) functions obtain the actual data pointer from the varying-length descriptor. Through this data pointer, you can directly access the varying-length data.

The following code fragment uses the mi_get_vardata( ) function to obtain the data pointer from the varying-length structure in Figure 7:

mi_lvarchar *new_lvarch;
char *var_ptr;
...
/* Get the data pointer of the varying-length structure */
var_ptr = mi_get_vardata(new_lvarch);

Figure 13 shows the format of the varying-length structure that new_lvarch references after the preceding call to mi_get_vardata( ) successfully completes.

Figure 13. Getting the Data Pointer from a Varying-Length Structure
begin figure description - This figure is described in the surrounding text. - end figure description

You can then access the data through the var_ptr data pointer, as the following code fragment shows:

mi_lvarchar *new_lvarch;
mi_integer var_len, i;
mi_char one_char;
mi_char *var_ptr;

var_ptr = mi_get_vardata(new_lvarch);
var_len = mi_get_varlen(new_lvarch);
for ( i=0; i<var_len; i++ )
   {
   one_char = var_ptr[i];
   /* process the character as needed */
   ...
   }
Server Only

The database server passes text data to a UDR as an mi_lvarchar structure. Figure 69 shows the implementation of a user-defined function named initial_cap( ), which ensures that the first letter of a character string is uppercase and that subsequent letters are lowercase.

The initial_cap( ) function uses mi_get_vardata( ) to obtain each character from the data portion of the varying-length structure. This data portion contains the character value that the function receives as an argument. The function checks each letter to ensure that it has the correct case. If the case is incorrect, initial_cap( ) uses the data pointer to update the appropriate letter. The function then returns a new mi_lvarchar structure that holds the result. For more information, see Handling Character Arguments.

End of Server Only

The varying-length structure aligns data on four-byte boundaries. If this alignment is not appropriate for your varying-length data, use the mi_get_vardata_align( ) function to obtain the data aligned on a byte boundary that you specify. You can determine the alignment of a data type from its type descriptor with the mi_type_align( ) function.

Tip:
When you obtain aligned data from a varying-length structure that is associated with an extended data type, specify an alignment value to mi_get_vardata_align( ) that is appropriate for the extended data type. For more information, see Specifying the Memory Alignment of an Opaque Type.

The mi_get_vardata_align( ) function obtains the number of bytes that the data-length field specifies.

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