### Step 5: Perform the Read Operation

The following code fragment from example.c shows the ds_read( ) function call and the XDS calls that precede it:

/*

* Perform the Directory operations:

* (1) Initialize the directory service

* and get an OM workspace.

* (2) bind a default directory session.

* (3) read the telephone number of "name".

* (4) terminate the directory session.

*/

CHECK_DS_CALL((OM_object) !(workspace = ds_initialize()));

CHECK_DS_CALL(ds_version(bdcp_package, workspace));

CHECK_DS_CALL(ds_bind(DS_DEFAULT_SESSION, workspace,

&session));

CHECK_DS_CALL(ds_read (session, DS_DEFAULT_CONTEXT,

name, selection, &result, &invoke_id));

CHECK_DS_CALL is an error-checking macro defined in the example.h header file that is included by example.c. The ds_read( ) call returns a return code of type DS_status to indicate whether or not the read operation completed successfully. If the call was successful, ds_read( ) returns the value DS_SUCCESS. If the call fails, it returns an error code. (Refer to XDS Class Definitions for a comprehensive list of error codes.) CHECK_DS_CALL interprets this return value and returns successfully to the program or branches to an error-handling routine.

The session input parameter is a private object generated by ds_bind( ) prior to the ds_read( ) call, as shown in the preceding code fragment. DS_DEFAULT_CONTEXT describes the characteristics of a directory service interaction. Most XDS API function calls require these two input parameters because they define the operating parameters of a session with a GDS server. (Sessions are described in A Directory Session; contexts are described in The DS_C_CONTEXT Parameter.)

The result of a directory service request is returned in a private object (in this case, result) that is appropriate to the type of operation. The result of the operation is returned in a single OM object. The components of the result are represented by OM attributes in the operations result object:

· DS_C_COMPARE_RESULT
Returned by ds_compare( )

· DS_C_LIST_RESULT
Returned by ds_list( )

· DS_C_READ_RESULT
Returned by ds_read( )

· DS_C_SEARCH_RESULT
Returned by ds_search( )

The OM class returned by ds_read( ) is DS_C_READ_RESULT. The OM class returned by the ds_compare( ) call is DS_C_COMPARE_RESULT, and so on. (Refer to the reference pages in the OSF DCE Application Development Reference for a description of the OM classes associated with a particular function call; refer to XDS Class Definitions for full descriptions of the OM attributes, syntaxes, and values associated with these OM classes.)

The superclasses, subclasses, and OM attributes for DS_C_READ_RESULT are shown in the following figure.

Output from ds_read( ): DS_C_READ_RESULT

The result value is returned to the workspace in private implementation-specific format. As such, it cannot be read directly by an application program, but it requires a series of om_get( ) function calls to extract the requested information from it. The following code fragment from example.c shows how a series of om_get( ) calls extracts the list of telephone numbers associated with the distinguished name for Peter Piper. XOM Programming describes this extraction process in detail.

/*

* extract the telephone number(s) of "name" from the result

*

* There are 4 stages:

* (1) get the Entry-Information from the Read-Result.

* (2) get the Attributes from the Entry-Information.

* (3) get the list of phone numbers.

* (4) scan the list and print each number.

*/

CHECK_OM_CALL( om_get( )(result,

OM_EXCLUDE_ALL_BUT_THESE_TYPES

+ OM_EXCLUDE_SUBOBJECTS,

entry_list, OM_FALSE, 0, 0, &entry,

&total_num));

CHECK_OM_CALL( om_get( )(entry->value.object.object,

OM_EXCLUDE_ALL_BUT_THESE_TYPES

+ OM_EXCLUDE_SUBOBJECTS,

attributes_list, OM_FALSE, 0, 0, &attributes,

&total_num));

CHECK_OM_CALL( om_get( )(attributes->value.object.object,

OM_EXCLUDE_ALL_BUT_THESE_TYPES

+ OM_EXCLUDE_SUBOBJECTS,

telephone_list, OM_FALSE, 0, 0, &telephones,

&total_num));

##