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.
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
![]() |
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:
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.
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 |
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
![]() |
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.
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
![]() |
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.
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.
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.
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
![]() |
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 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:
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:
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: