Information Catalog Manager Programming Guide and Reference

Reading an output structure resulting from an API call

The Information Catalog Manager API calls that return information put that information into an output structure.

To read an output structure, consider the structure as a whole, because different parts of the structure define the meaning of other parts of the structure.

For API calls that return lists of object instances, the object area can contain more than one value for each property. The object area can contain several sets of values that map to the properties defined in the definition area.

Using pointers to read an output structure

To read values in the output structure, define two or more pointers to the structure, using the pointer value returned by the API call.

When your program issues an API call that produces an output structure, your program must define a pointer that contains the address of a null pointer and pass this defined pointer to the API call as a parameter. The API function then assigns the null pointer the address of the output structure.

You need to define a second pointer that will step through the header and definition areas of the structure, and a third that will step through the object area.

In Figure 27, pOutStruct is the pointer to the beginning of the output structure. You can then define pReadStruct to step through the header area and definition area, and pObjArea to step through the object area.

Figure 27. Defining pointers that step through the output structure


Graphical representation of pOutStruct pointing to the beginning of an output structure header area and pObjArea pointing to the beginning of the object area. pReadStruct is pointing to the beginning of the header area, ready to step through the header and definition areas.

Depending on your needs, you can either read the values of the structure in the order they are returned, or you can search for a specific value. In either case, you need to:

  1. Calculate the number of properties and the number of objects returned
  2. Find the data type and data length for each property
  3. Step through the object area to read or locate values

Reading values using DG2API.H

The Information Catalog Manager provides a header file named DG2API.H that defines many of the value lengths and valid values that you need to read output structures. You can use these lengths to write the C language code you need to step through the header, definition, and object areas.

See Appendix B, The Information Catalog Manager API header file--DG2APIH for a complete list of the constants defined in the DG2API.H file.

Calculating the number of properties in the output structure

Certain API calls return an unknown number of properties, so you need to calculate this number.

Set a pointer to the beginning of the output structure using the pointer address returned by the API call.

To calculate the number of properties in the definition area, divide the numeric value of the definition length area of the header area (bytes 8-15) by the length of an individual record in the definition area (160). You need to convert the definition length character string to an integer value to perform this calculation.

DG2API.H provides the variable FLG_DEFINITION_SIZE to help you write this calculation:

Figure 28. Calculating the number of properties

number_of_properties = definition_length_integer_value / FLG_DEFINITION_SIZE

Calculating the number of sets of values returned

To calculate the number of sets of values returned in the output structure, divide the object area entry count shown in Figure 29 by the number of properties in the structure, as shown in Figure 30.

Figure 29. The object area entry count in the header area


Graphical representation of the header area of an Information Catalog Manager output structure at the byte level with the object area count bytes highlighted.

Figure 30. Calculating the number of sets of values

number_of_sets_of_values = object_area_entry_count / number_of_properties

The fields in the header area are in character format and must be converted to numeric format for use in the calculation in Figure 30. You can use the structures defined in DG2API.H to arrive at the calculation in Figure 30.

Reading the property data types and lengths in the definition area

To read the property data types and lengths, define a pointer and perform pointer arithmetic to read the correct values in the definition area. The location of the data types and lengths of the first property are highlighted in Figure 31.

Figure 31. The data type and data length of the first property


Graphical representation of the header and definition areas of an Information Catalog Manager output structure at the byte level, with the data type and data length bytes highlighted.

To read the data type for the first property in the definition area, add the length of the header area and the property name field of the first definition record to the location of the pointer to the output structure, as shown in Figure 32.

Figure 32. Calculating the position of the data type value

pLocationOfDataType = pOutStruct +
                      FLG_HEADER_SIZE +
                      FLG_D_PROPNM_LEN

pOutStruct is the pointer to the output structure, FLG_HEADER_SIZE is the length of the header area, and FLG_D_PROPNM_LEN is the length of the property name field. You can now save the value at this location in another variable.

To read the data length for the first property in the definition area, add the length of the data type field to the pointer you calculated to get to the data type, as shown in Figure 33.

Figure 33. Calculating the position of the data length value

pLocationOfDataLen = pLocationOfDataType +
                     FLG_D_DATATYP_LEN

pLocationOfDataType is a pointer to the data type field in the definition record and FLG_D_DATATYP_LEN is the length of the data type field.

To read the data types and lengths of other properties, continue to add offset values. To get to the data type field for the next property, you can add the length of an entire data record (160) to the pointer to the data type for the current property as shown in Figure 34.

Figure 34. Calculating the position of the next data type value

pLocationOfDataType = pLocationOfDataType + FLG_DEFINITION_SIZE

FLG_DEFINITION_SIZE is 160 bytes.

Stepping through the object area to read values

To read a value in the object area, you need to calculate its position using pointer arithmetic. You need to know the data type and length of the properties to calculate positions properly.

  1. Read the first value in the object area by incrementing the pointer to the beginning of the object area, as shown in Figure 35.

    Figure 35. Moving the pointer to the beginning of the object area

    pObjArea = pOutStructure + FLG_HEADER_SIZE +
               (FLG_DEFINITION_SIZE × number_of_properties)
    

    FLG_HEADER_SIZE is the length of the header area and FLG_DEFINITION_SIZE is the length of a record in the definition area.

  2. Check the data type and data length for the property this value belongs to in the definition area.

    For CHAR or TIMESTAMP
    Read in a value that is the length specified in the definition area.

    For VARCHAR or LONG VARCHAR
    1. Read the first 8 characters for this value to determine the length of the value.
    2. Move the pointer 8 bytes to read the value itself.

    Move to the next value in the object area by adding the actual length of the current value to the pointer as shown in Figure 36.

    Figure 36. Moving the pointer to the next value

    pObjValue = pObjArea + actual_value_length
    

    Figure 37 shows how to start at the beginning of the object area, read the length of the VARCHAR value, move the pointer to the beginning of the value itself, then read the value before moving the pointer to the next value.

    Figure 37. Reading a VARCHAR value in the object area


    Graphical representation of stepping through the object area.

DG2SAMP.C example of locating a value in an output structure

The DG2SAMP.C program gets an object type name from the user, then issues an FLGListObjTypes call to retrieve a list of object types available in the information catalog database. The program tries to match the external name of an object type specified by the user with a name in the output structure returned by FLGListObjTypes.

Figure 38 shows the format of the output structure produced by an FLGListObjTypes API call.

Figure 38. FLGListObjTypes output structure


Figure FLAA2084 not displayed.

Getting values from the user and the output structure

Figure 39 shows how the program reads the value specified by the user and calculates its length. It also shows how the program copies values in the output structure into null-terminated strings and calculates the number of sets of values in the object area.

Figure 39. DG2SAMP.C: Getting a value from the user

gets(pszObjName);     (1)
ulTypeLen = strlen(pszObjName);     (2)
memcpy(&pszObjEntryCount, pListStruct->pchHObjEntryCount, FLG_H_OBJAREAENT_LEN); (3)
memcpy(&pszDefLength, pListStruct->pchHDefLength, FLG_H_DEFAREA_LEN);            (4)
ulCount = (atoi(pszObjEntryCount) / (atoi(pszDefLength) / FLG_DEFINITION_SIZE)); (5)

The code in Figure 39 performs the following steps:

(1)
Gets the object type name as input from the user

(2)
Determines the length of the object type name

(3)
Copies the object entry count into a null-terminated string

(4)
Copies the definition length into a null-terminated string

(5)
Calculates the number of sets of values in the object area

Assigning a pointer to the beginning of the object area

The code in Figure 40 assigns a pointer to the beginning of the object area.

In this example, the output for FLGListObjTypes always has the same three properties, so the program does not need to determine the number of properties, the data type, or the data length.

Figure 40. DG2SAMP.C: Assigning a pointer to the beginning of the object area

ulPosition = 0;                                                 (1)
pCurrPos = ((UCHAR *)pListStruct + FLG_HEADER_SIZE + ulDefLen); (2)

The code in Figure 40 performs the following steps:

(1)
Sets the position counter to 0.

(2)
Positions a pointer at the beginning of the object area by adding the length of the header area and definition area to the position of the pointer to the beginning of the output structure (pListStruct).

Moving through the object area

The code in Figure 41 moves a pointer through the object area, trying to find an object type name that matches the name given by the user.

Figure 41. DG2SAMP.C: Matching an object type name with one in the object area

while (fNotFound && (ulPosition < ulCount))    (1)
{
  ulPosition = (ulPosition + 1);
  memcpy(&pszObjTypeId, (void *) pCurrPos, FLG_H_OBJTYPID_LEN);      (2)
  pCurrPos = pCurrPos + FLG_H_OBJTYPID_LEN;                          (3)
  memcpy(&pszLength, (void *)pCurrPos, FLG_VARIABLE_DATA_LENGTH_LEN);(4)
  ulLength = atoi(pszLength);                                        (5)
  pCurrPos = pCurrPos + FLG_VARIABLE_DATA_LENGTH_LEN;                (6)
  strncpy (pszObjectName, (void *)pCurrPos, ulLength);               (7)
  pszObjectName[ulLength]¨ = NULLCHAR;                     (8)
 
  if (!(strcmp(pszObjName, pszObjectName)))   (9)
    {
      fNotFound = FALSE;
      printf ("The object type ID for %s is %s.\n\n", pszObjName, pszObjTypeId);
    }
  else
    { // Move temporary pointer to the next object
      pCurrPos = pCurrPos + ulLength + FLG_DPNAME_LEN;  (10)
    }
}

The code in Figure 41 performs the following steps:

(1)
Checks that the program has not yet found a matching object name, and that the pointer has not yet reached the last set of values in the object area

(2)
Copies the object type ID of the first object type into pszObjTypeId

(3)
Moves the pointer to the next value, which is the value of the object type name

(4)
Copies the first 8 characters of the object type name value, which contain the length for this VARCHAR value

(5)
Converts the length to integer data

(6)
Moves the pointer past the variable data length to the beginning of the object type name

(7)
Copies the object type name at the pointer to pszObjectName

(8)
Adds a null character to the end of the object type name to make the value a null-terminated string

(9)
Compares pszObjectName to the object type name specified by the user

(10)
If the value of pszObjectName doesn't match the object type name specified by the user, moves the cursor to the beginning of the next set of values


[ Top of Page | Previous Page | Next Page ]