A varying-length structure contains the following information:
After you allocate a varying-length structure, you can access the public members of this structure with the DataBlade API accessor functions in Table 11.
When you work with varying-length data, keep the following restrictions in mind:
Instead, always use the data length (which you can obtain with the mi_get_varlen( ) function) for all operations on varying-length data.
The varying-length accessor functions in Table 11 do not automatically interpret a null-terminator character. Instead, they transfer the number of bytes that the data length in the varying-length descriptor specifies, as follows:
For more information, see Storing a Null-Terminated String.
For more information, see Obtaining the Data Pointer.
To convert between null-terminated strings and an mi_lvarchar structure, use the mi_string_to_lvarchar( ) and mi_lvarchar_to_string( ) functions. For more information, see DataBlade API Functions for String Conversion.
This section provides the following information about how to store varying-length data:
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.
#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.
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.
The mi_set_vardata_align( ) function copies the number of bytes that the data-length field specifies.
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:
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.
The mi_string_to_lvarchar( ) function allocates the varying-length structure that it creates with the current memory duration.
The mi_string_to_lvarchar( ) function does not copy the null terminator of the string.
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.
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:
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.
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.
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.
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.
Make sure that you allocate the data-portion buffer with a memory duration appropriate to the use of the data portion.
For more information in memory allocation, see Managing Memory.
Use the following DataBlade API accessor functions to obtain information about varying-length data from a varying-length structure.
The mi_get_varlen( ) function returns the data length from a varying-length descriptor. Keep in mind the following restrictions about data length:
Always use the data length to determine the end of the varying-length data when you perform operations on this data.
You must ensure that there is sufficient space in the data portion to hold the varying-length data. If there is insufficient space, allocate a new data portion with a DataBlade API memory-management function (such as mi_dalloc( )) and assign a pointer to this new memory to the data pointer of your varying-length structure.
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.
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:
The mi_lvarchar_to_string( ) function allocates the string that it creates with the current memory duration.
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.
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.
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.
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:
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.
The mi_var_copy( ) function allocates the varying-length structure that it creates with the current memory duration.
The mi_var_copy( ) function automatically copies the number of bytes that the data length in the existing varying-length descriptor specifies.
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.
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.
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 */ ... }
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.
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.
The mi_get_vardata_align( ) function obtains the number of bytes that the data-length field specifies.
Enterprise Edition Home | Express Edition Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]