Get Direct/Chunk (23)
The Get Direct/Chunk operation (B_GET_DIRECT) can retrieve one or more portions, called chunks, of a record. This operation is especially useful on files containing records longer than 65,535 bytes. Such records are too long to be retrieved by the other Get and Step operations, due to restrictions on the length of the Data Buffer parameter. Your application specifies the record from which chunks are to be retrieved by supplying its physical address. The location of a chunk in a record is generally specified by its offset and length.
Parameters
 
Prerequisites
 
Procedure
1
For more information about locking, refer to the Pervasive PSQL Programmer's Guide.
2
3
4
Specify the Data Buffer Length as either the length of the input structure (Table 19 or Table 20) or the number of bytes you requested for the transactional interface to retrieve, whichever is larger.
Some options for the Get Direct/Chunk operation retrieve chunks to locations other than the Data Buffer. See the Details section for more information about calculating the Data Buffer Length.
5
Details
Use one of the following chunk descriptors in the Data Buffer:
Random Chunks
The following example shows a record with three randomly spaced chunks (areas containing [*]): chunk 0 (bytes 0x12 through 0x16), chunk 1 (bytes 0x2A through 0x31), and chunk 2 (bytes 0x41 through 0x4E).
To fetch random chunks, you must create a structure in the Data Buffer, based on the following table.
1For DOS applications, initialize User Data as a 16-bit offset and a 16-bit segment. User Data cannot address memory beyond the end of its segment. When Chunk Length is added to the offset portion of User Data, the result must be within the segment that User Data defines. By default, the transactional interface does not check for violations of this rule and does not properly handle such violations.
The following table shows a sample Data Buffer for a 32-bit application for fetching direct random chunks.
Rectangle Chunk Descriptor Structure
When chunks of the same length are spaced equidistantly throughout a record, you can describe all the chunks to retrieve with a rectangle chunk descriptor. For example, consider the following diagram, which represents offset 0x00 through 0x4F in a record:
The record contains three chunks (areas containing [*]): chunk 0 (bytes 0x19 through 0x1C), chunk 1 (bytes 0x29 through 0x2C), and chunk 2 (bytes 0x39 through 0x3C). Each chunk is four bytes long, and a total of 16 (0x10) bytes, calculated from the beginning of each chunk, separates the chunks from one another.
You can retrieve all three chunks using a single rectangle descriptor. To fetch rectangle chunks, you must create a structure in the Data Buffer based on the following table.
The format you should use depends on your operating system.1 The transactional interface ignores this element for direct rectangle descriptors; however, you must still allocate the element and initialize it to 0.
1For DOS applications, express User Data as a 16-bit offset followed by a 16-bit segment.
When you use an indirect descriptor, be sure that the User Data pointer is initialized so that the chunks retrieved do not overwrite your chunk descriptor. The transactional interface uses the descriptor when copying the returned chunks to the locations that the User Data elements specify. In the event that you overwrite your chunk descriptor, the transactional interface returns Status Code 62.
If the rectangle has the same number of bytes between rows when it is in memory as when it is stored as a record, set Application Distance Between Rows with the same value as Distance Between Rows. However, if the rectangle is arranged in your application’s memory with either more or fewer bytes between rows, Application Distance Between Rows allows you to pass that information to the transactional interface.
When you use an indirect rectangle descriptor, the transactional interface uses both the User Data and the Application Distance Between Rows elements to determine the locations in which to store the data after retrieving it. The transactional interface stores data from the first row in offset 0 of User Data. The transactional interface stores the second row’s data to an address specified by User Data plus Application Distance Between Rows. The transactional interface stores the third row’s data in the address specified by User Data plus (Application Distance Between Rows * 2), and so on.
The following table shows a sample Data Buffer for a 32-bit application for fetching a direct rectangle chunk.
Next-in-Record Subfunction Bias
If you add a bias of 0x40000000 to any of the subfunctions previously listed, the transactional interface calculates the subfunction’s Offset element values based on your physical intrarecord currency (that is, your current physical location within the record). When you use the Next-in-Record subfunction, the transactional interface ignores the Offset element in the chunk descriptor.
Result
If the Get Direct/Chunk operation is successful and a direct chunk descriptor is used, the transactional interface returns the chunks one after another in the Data Buffer. If you used an indirect random chunk descriptor, the transactional interface returns the data to the locations that each chunk’s User Data element specifies. If you used an indirect rectangle descriptor, the transactional interface returns the data to locations it derives from the User Data and Application Distance Between Rows elements.
The transactional interface also stores the total length of the chunks retrieved in the Data Buffer Length parameter. (The returned value reflects all bytes retrieved, whether they were retrieved and stored directly into the Data Buffer, or the indirect descriptor was used to retrieve and store the bytes elsewhere.) If the operation was partially successful, your application can use the value returned in the Data Buffer Length parameter to determine which chunks could not be retrieved and how many bytes of the final chunk were retrieved.
The Get Direct/Chunk operation is only partially successful if any chunk begins beyond the end of the record (resulting in the transactional interface returning Status Code 103), or if any chunk’s offset and length combine to exceed the length of the record. In the latter case, the transactional interface returns Status Code 0 but ceases processing subsequent chunks, if any, in the operation.
*Note: Only the Data Buffer Length parameter shows that not all of the chunks were properly retrieved. For this reason, be sure that you always check the value returned in the Data Buffer Length parameter after a Get Direct/Chunk operation.
The following status codes indicate a partially successful Get Direct/Chunk operation. When the transactional interface returns one of these status codes, your application should check the Data Buffer Length parameter’s return value to see how much data the transactional interface actually returned.
If the transactional interface returns any of the following status codes, it has returned no data.
Positioning
The Get Direct/Chunk operation has no effect on logical currency. In terms of physical currency, Get Direct/Chunk makes the record from which chunks are retrieved the physical current record.