Requesting Information About an Open Blob
Contents
After an application opens a Blob, it can obtain information about the Blob. The isc_blob_info() call enables an application to query for Blob information such as the total number of segments in the Blob, or the length, in bytes, of the longest segment.
In addition to a pointer to the error status vector and a Blob handle, isc_blob_info() requires two application-provided buffers, an item-list buffer, where the application specifies the information it needs, and a result buffer, where InterBase returns the requested information. An application populates the item-list buffer with information requests prior to calling isc_blob_info(), and passes it both a pointer to the item-list buffer, and the size, in bytes, of that buffer.
The application must also create a result buffer large enough to hold the information returned by InterBase. It passes both a pointer to the result buffer, and the size, in bytes, of that buffer to isc_blob_info(). If InterBase attempts to pass back more information than can fit in the result buffer, it puts the value, isc_info_truncated, defined in ibase.h, in the final byte of the result buffer.
The item-list Buffer
The item-list buffer is a char array that holds a sequence of byte values, one per requested item of information. Each byte is an item type, specifying the kind of information desired. Compile-time constants for all item types are defined in ibase.h: #define isc_info_blob_num_segments 4 #define isc_info_blob_max_segment 5 #define isc_info_blob_total_length 6 #define isc_info_blob_type 7
The Result Buffer
The result buffer is a byte vector in which InterBase returns a series of clusters of information, one per item requested. Each cluster consists of three parts:
- A one-byte item type. Each is the same as one of the item types in the item-list buffer.
- A two-byte number specifying the number of bytes that follow in the remainder of the cluster.
- A value, stored in a variable number of bytes, whose interpretation depends on the item type.
A calling program is responsible for interpreting the contents of the result buffer and for deciphering each cluster as appropriate.
The clusters returned to the result buffer are not aligned. Furthermore, all numbers are represented in a generic format, with the least significant byte first, and the most significant byte last. Signed numbers have the sign in the last byte. Convert the numbers to a datatype native to your system, if necessary, before interpreting them. The API call, isc_portable_integer(), can be used to perform the conversion.
Blob Buffer Items
The following table lists items about which information can be requested and returned, and the values reported:
Table 7.2 Blob Request and Return Items
Request and Return Item | Return Value | |
---|---|---|
isc_info_blob_num_segments | Total number of segments | |
isc_info_blob_max_segment | Length of the longest segment | |
isc_info_blob_total_length | Total size, in bytes, of Blob | |
isc_info_blob_type | Type of Blob (0: segmented, or 1: stream) |
Status Messages
In addition to the information, InterBase returns in response to a request, InterBase can also return one or more of the following status messages to the result buffer. Each status message is one unsigned byte in length:
Table 7.3 Status Message Return Items
Item | Description | |
---|---|---|
isc_info_end | End of the messages | |
isc_info_truncated | Result buffer is too small to hold any more requested information | |
isc_info_error | Requested information is unavailable. Check the status vector for an error code and message |
isc_blob_info() Call Example
The following code requests the number of segments and the maximum segment size for a Blob after it is opened, then examines the result buffer:
- char blob_items[] = {isc_info_blob_max_segment, isc_info_blob_num_segments};
- char res_buffer[20], *p, item;
- short length;
- SLONG max_size = 0L, num_segments = 0L;
- ISC_STATUS statu?s_vector[20];
- isc_open_blob2(status_vector,
- &db_handle, /* database handle, set by isc_attach_database() */
- &tr_handle, /* transaction handle, set by isc_start_transaction() */
- &blob_handle, /* set by this function to refer to the Blob */
- &blob_id, /* Blob ID of the Blob to open */
- 0, /* BPB length = 0; no filter will be used */
- NULL); /* NULL BPB, since no filter will be used */
- if (status_vector[0] == 1 && status_vector[1]) {
- isc_print_status(status_vector);
- return(1);
- }
- isc_blob_info(status_vector,
- &blob_handle, /* Set in isc_open_blob2() call above. */
- sizeof(blob_items), /* Length of item-list buffer. */
- blob_items, /* Item-list buffer. */
- sizeof(res_buffer), /* Length of result buffer. */
- res_buffer); /* Result buffer */
- if (status_vector[0] == 1 && status_vector[1]) {
- /* An error occurred. */
- isc_print_status(status_vector);
- isc_close_blob(status_vector, &blob_handle);
- return(1);
- };
- /* Extract the values returned in the result buffer. */
- for (p = res_buffer; *p != isc_info_end ;) {
- item = *p++
- length = (short)isc_portable_integer(p, 2);
- p += 2;
- switch (item) {
- case isc_info_blob_max_segment:
- max_size = isc_portable_integer(p, length);
- break;
- case isc_info_blob_num_segments:
- num_segments = isc_portable_integer(p, length);
- break;
- case isc_info_truncated:
- /* handle error */
- break;
- default:
- break;
- case isc_info_blob_max_segment:
- }
- p += length;
- };