Previous Next

Handling the Result Object

The next goal is to extract the instances of the DS_C_ATTRIBUTE subsubclass, one for each attribute read, from the returned object. The first step is to make a public copy of readResultObject, which is a private object, and therefore does not allow access to the object descriptors themselves. Using the XOM om_get( ) function, you can make a public copy of readResultObject, and at the same time specify that only the relevant parts of it be preserved in the copy. Then with a couple of calls to om_get( ), you can reduce the object to manageable size, leaving a superobject whose immediate subobjects are fairly easily accessed.

The om_get( ) function takes as its third input parameter an OM_type_list, which is an array of OM_type. Possible parameters are DS_ENTRY, DS_ATTRIBUTES, DS_ATTRIBUTE_VALUES, and anything that can legitimately appear in an object descriptor's type field. The types specified in this parameter are interpreted according to the options specified in the preceding parameter. For example, the relevant attribute from the read result is DS_ENTRY. It contains the DS_C_ENTRY_INFO object, which in turn contains the DS_C_ATTRIBUTE objects. The DS_C_ATTRIBUTE objects contain the data read from the cell directory name entry. Therefore, you should specify the OM_EXCLUDE_ALL_BUT_THESE_TYPES option, which has the effect of excluding everything but the contents of the object's DS_ENTRY type attribute.

The OM_EXCLUDE_SUBOBJECTS option is also ORed into the parameter. Why would you not preserve the subobjects of DS_C_ENTRY_INFO? Because om_get( ) works only on private, not on public, objects. If you were to use om_get( ) on the entire object substructure, you would not be able to continue getting the subobjects, and instead you would have to follow the object pointers down to the DS_C_ATTRIBUTEs. However, when om_get( ) excludes subobjects from a copy, it does not really leave them out; it merely leaves the subobjects private, with a handle to the private objects where pointers would have been. This allows you to continue to call om_get( ) as long as there are more subobjects.

The following is the first call:

/* The DS_C_READ_RESULT object that ds_read() returns has */

/* one subobject, DS_C_ENTRY_INFO; it in turn has two sub- */

/* objects, that is a DS_C_NAME which holds the object's */

/* distinguished name (which we don't care about here), */

/* and a DS_C_ATTRIBUTE which contains the attribute info */

/* we read; that one we want. So we climb down to it ... */

/* This om_get() will "return" the entry-info object ... */


omStatus = om_get(readResultObject,

OM_EXCLUDE_ALL_BUT_THESE_TYPES +

OM_EXCLUDE_SUBOBJECTS,

I_want_entry_object,

OM_FALSE,

OM_ALL_VALUES,

OM_ALL_VALUES,

&entry,

&number_of_descriptors);

The number_of_descriptors parameter contains the number of attribute descriptors returned in the public copy, not in any excluded subobjects.

If an XOM function is successful, it returns an OM_SUCCESS code. Unsuccessful calls to XOM functions do not return error objects, but rather return simple error codes. The interface assumes that if the XOM function does not accept your object, then you will not be able to get much information from any further objects. The return status is not checked in this example.

The return parameter entry should now contain a pointer to the DS_C_ENTRY_INFO object with the following immediate structure. (The number of instances of DS_ATTRIBUTES depends on the number of attributes read from the entry.)

DS_C_ENTRY_INFO

DS_FROM_ENTRY: OM_S_BOOLEAN

DS_OBJECT_NAME: object(DS_C_NAME)

DS_ATTRIBUTES: object(DS_C_ATTRIBUTE)

DS_C_ATTRIBUTE

DS_ATTRIBUTE_TYPE: OID string

DS_ATTRIBUTE_VALUES: anything

DS_ATTRIBUTES: object(DS_C_ATTRIBUTE)

object(DS_C_ATTRIBUTE)

DS_C_ATTRIBUTE

DS_ATTRIBUTE_TYPE: OID string

DS_ATTRIBUTE_VALUES: anything

The italics indicate private subobjects. The following figure shows the DS_C_ENTRY_INFO object. Only one instance of a DS_C_ATTRIBUTE subobject is shown in the figure; usually there are several such subobjects, all at the same level, each containing information about one of the attributes read from the entry. These subobjects are represented in DS_C_ENTRY_INFO as a series of descriptors of type DS_ATTRIBUTES, each of which has as its value a separate DS_C_ATTRIBUTE subobject.


The DS_C_ENTRY_INFO Object Structure

Now extract the separate attribute values of the entry that was read. These were returned as separate object values of DS_ATTRIBUTES; each one has an object class of DS_C_ATTRIBUTE. To return any one of these subobjects, a second call to om_get( ) is necessary, as follows:

/* The second om_get() returns one selected subobject */

/* from the DS_C_ENTRY_INFO subobject we just got. The */

/* contents of "entry" as we enter this call is the */

/* private subobject which is the value of DS_ATTRIBUTES. */

/* If we were to make the following call with the */

/* OM_EXCLUDE_SUBOBJECTS and without the */

/* OM_EXCLUDE_ALL_BUT_THESE_VALUES flags, we would get */

/* back an object consisting of six private subobjects, */

/* one for each of the attributes returned. Note the */

/* values for initial and limiting position: "2" */

/* specifies that we want only the third DS_C_ATTRIBUTE */

/* subobject to be gotten (the subobjects are numbered */

/* from 0, not from 1), and the "3" specifies that we want */

/* no more than that -- in other words, the limiting value */

/* must always be one more than the initial value if the */

/* latter is to have any effect. */

/* OM_EXCLUDE_ALL_BUT_THESE_VALUES is likewise required */

/* for the initial and limiting values to have any */

/* effect ... */


omStatus = om_get(entry->value.object.object,

OM_EXCLUDE_ALL_BUT_THESE_TYPES

+ OM_EXCLUDE_SUBOBJECTS

+ OM_EXCLUDE_ALL_BUT_THESE_VALUES,

I_want_attribute_list,

OM_FALSE,

((OM_value_position) 2),

((OM_value_position) 3),

&entry,

&number_of_descriptors);

Note the value that is passed as the first parameter. Since om_get( ) does not work on public objects, pass it the handle of the private subobject explicitly. To do this you have to know the arrangement of the descriptor's value union, which is defined in xom.h.