Follow these steps to create an input structure:
The Information Catalog Manager provides a C language header file named DG2API.H that defines many of the value lengths and valid values that you need to create input structures and read output structures. You can include (using the #include statement) this file in your program so that you do not need to write the code for certain data types, structures, and function prototypes yourself.
DG2API.H contains type definition (typedef) declarations of the structures needed to build the header and definition areas, as shown in Figure 9. (In Figure 9, WINDOWS refers only to Microsoft Windows 3.1.)
Figure 9. DG2API.H: Structure definitions for the header and definition areas
#pragma pack(1) /* Structure definition for the FLG header area */ typedef struct _FLG_HEADER_AREA { UCHAR pchHIdent [ FLG_H_IDENT_LEN ]; UCHAR pchHDefLength [ FLG_H_DEFAREA_LEN ]; UCHAR pchHObjLength [ FLG_H_OBJAREA_LEN ]; UCHAR pchHObjEntryCount [ FLG_H_OBJAREAENT_LEN ]; UCHAR pchHCategory [ FLG_H_CATEGORY_LEN ]; UCHAR pchHObjTypeId [ FLG_H_OBJTYPID_LEN ]; UCHAR pchHReserved [ FLG_H_RESERVED_LEN ]; } FLGHEADERAREA; #ifdef WINDOWS typedef FLGHEADERAREA __huge *PFLGHEADERAREA; #else typedef FLGHEADERAREA *PFLGHEADERAREA; #endif /* Structure definition for the FLG definition area */ typedef struct _FLG_DEFINITION_AREA { UCHAR pchDPropName [ FLG_D_PROPNM_LEN ]; UCHAR pchDDataType [ FLG_D_DATATYP_LEN ]; UCHAR pchDDataLength [ FLG_D_DATA_LEN ]; UCHAR pchDTagName [ FLG_D_PPN_LEN ]; UCHAR pchDVF [ FLG_D_VF_LEN ]; UCHAR pchDUS [ FLG_D_US_LEN ]; UCHAR pchDCS [ FLG_D_CS_LEN ]; UCHAR pchDFS [ FLG_D_FS_LEN ]; UCHAR pchDReserved [ FLG_D_RESERVED_LEN ]; } FLGDEFINITIONAREA; #ifdef WINDOWS typedef FLGDEFINITIONAREA __huge *PFLGDEFINITIONAREA; #else typedef FLGDEFINITIONAREA *PFLGDEFINITIONAREA; #endif |
Variables starting with FLG_D or FLG_H are lengths for the structure parts that are defined in DG2API.H.
See Appendix B, The Information Catalog Manager API header file--DG2APIH for a list of all the constants defined in the DG2API.H file.
You can use these defined structures to define the storage required for the header and definition areas of the input structure. Figure 10 shows a part of DG2SAMP.C that uses data types defined in the DG2API.H header file to define the structures later used to store the header and definition areas of an input structure.
Figure 10. DG2SAMP.C: Defining the header and definition areas
// This structure defines the input structure for FLGSearch. typedef _Packed struct SEARCH_STRUCT { FLGHEADERAREA srchHdr; FLGDEFINITIONAREA srchDef; OBJECTAREA Item; } SEARCHSTRUCT; typedef SEARCHSTRUCT *PSEARCHSTRUCT; |
To ensure that the input structure is defined as contiguous storage, Figure 9 uses a #pragma pack(1) instruction, and Figure 10 uses a typedef _Packed struct definition. If you build input structures using another programming language, be aware that you might need to issue similar commands to define the input structure as contiguous storage.
You need to calculate the size of the entire input structure so that you can allocate the amount of storage for the input structure. To make this calculation, you need to know the following values:
This value depends on the number of properties required by the API call. You use this value to calculate the length of the definition area.
DG2API.H provides variables that define the length of the header area (FLG_HEADER_SIZE) and the length of a single definition record (FLG_DEFINITION_SIZE).
To calculate the definition area length, multiply the fixed length of each definition record (160) by the number of records needed to define your data, as shown in Figure 11.
Figure 11. Calculating the definition area length
Definition_area_length = number_of_properties × FLG_DEFINITION_SIZE |
DG2API.H provides the variable FLG_DEFINITION_SIZE, defined as 160, to help you define this calculation in your code.
You will need this value to define the definition area length field of the header area, as shown in Defining the header area.
The object area length is the sum of the lengths of all the values that go into the object area.
You will need this value to define the object area length field of the header area, as shown in Defining the header area.
If you are creating an input structure for an API call that does not require or expect an object area, the value in the object area is zero (00000000).
To calculate the exact object area length, you need the length of all of the values in your object area. For CHAR and TIMESTAMP values, use the length defined in the definition area. However, for LONG VARCHAR and VARCHAR values, you need to check the length for each value and include the 8-byte length field as part of the length value. The formula for this calculation is shown in Figure 12.
Figure 12. Calculating the exact object area length
Object_area_length = length_of_property1 + length_of_property2 + length_of_property3 + . . . |
You can also define your object area to contain the longest possible value for all properties, including VARCHAR and LONG VARCHAR values. With this method, you can add the maximum data lengths for all the properties together to ensure that the values you define for the object area will fit in the allocated storage. For VARCHAR and LONG VARCHAR properties, be sure to include the 8-byte length field as part of the maximum length value. The formula for this calculation is the following:
Figure 13. Calculating the maximum possible object area length
Length_of_object_area = maximum_length_of_property1 + maximum_length_of_property2 + maximum_length_of_property3 + . . . |
Be aware, however, that this method can waste a lot of storage, especially if several of your properties are LONG VARCHAR fields with a maximum length of 32700 bytes.
The entire formula for determining the storage you need to allocate is shown in Figure 14.
Figure 14. Calculating the required storage for an input structure
Structure_size = FLG_HEADER_SIZE + Definition_area_length + Object_area_length |
Because the input structure is a self-defining structure, there are several values in the header area that define the structure's size and format. To define these values properly, you need to consider the entire set of information and the structure you need to create.
The header area is 160 bytes. Each byte position must be assigned a value; if you do not specify a value, you must define a blank for that position. One way of defining one or more byte positions as blanks is to use the C language memset function to set the entire structure to FLG_BLANK or all zero characters first, and then to use the C language memcpy function to copy only the information that needs to be set to something else. This method also makes it easier to use the constants defined in DG2API.H, because you only need to worry about overlaying blanks or zeroes, not about padding the values to match the data length.
Complete specifications for each byte of the header area are discussed in Header area -- always required.
The syntax for the header area for each API call is discussed in Chapter 5, The Information Catalog Manager API call syntax.
Although some values in the header area not required for certain API calls, you need to define the header area to contain the byte offset positions shown in Figure 15.
These byte offset positions are described in Table 7. Table 10 lists constants in DG2API.H that can
help you define the header area.
Table 10. Header area byte offset positions and useful constants defined in DG2API.H
Bytes | Contents | Useful constants defined in DG2API.H | Value |
---|---|---|---|
0-7 | FLG-HEAD | FLG_H_IDENT | FLG-HEAD |
8-15 | Definition area length | FLG_DEFINITION_SIZE | 160; length of one definition area record |
16-23 | Object area length |
|
|
24-31 | Object area entry count |
|
|
32 | Category | FLG_GROUPING_OBJ FLG_ELEMENTAL_OBJ FLG_CONTACT_OBJ FLG_DICTIONARY_OBJ FLG_PROGRAM_OBJ FLG_SUPPORT_OBJ FLG_ATTACHMENT_OBJ |
G E C D P S A |
33-38 | Object type ID |
|
|
39-159 | Reserved area (always blank) |
|
|
When you define the header area, three values depend on the content of the definition and object areas:
You probably already calculated this value to allocate storage for the input structure. To review the description of this calculation, see Calculating the definition area length.
You probably already calculated this value to allocate storage for the input structure. To review the description of this calculation, see Calculating the object area length.
For all API calls requiring an input structure except FLGExport and FLGManageUsers, the object area entry count equals the number of properties in the definition area. For FLGExport, the object area entry count equals five times the number of objects specified to be exported. For FLGManageUsers, the object area entry count equals two for each user added or updated.
To define the definition area, you need to know what information the API call requires in the input structure.
Each record of the definition area is 160 bytes long. Each byte position must be assigned a value; even if you do not specify a value, you must define a blank for that position. One way of defining one or more byte positions to blanks is to use the C language memset function to set the entire structure to FLG_BLANK first, and then to use the C language memcpy function to copy only the information that needs to be set to something else. This method also makes it easier to use the constants defined in DG2API.H, because you only need to worry about overlaying blanks, not about padding the values to match the data length. Although some of the values are not required for certain API calls, the definition area must always contain the full 160 bytes as shown in Figure 16.
Figure 16. A record in the definition area
These byte offset positions are described in Table 9. Table 11 lists constants in DG2API.H that can
help you define the definition area.
Table 11. Definition area byte offset positions and useful constants defined in DG2API.H.
Bytes | Contents | Useful variables in DG2API.H | Values |
---|---|---|---|
0-79 | Property name |
|
|
80-109 | Data type | FLG_DTYPE_CHAR FLG_DTYPE_VARCHAR FLG_DTYPE_LONGVARCHAR FLG_DTYPE_TIMESTAMP |
CHAR VARCHAR LONG VARCHAR TIMESTAMP |
110-117 | Data length |
|
|
118-125 | Property short name | FLG_PPN_OBJTYPID FLG_PPN_INSTIDNT FLG_PPN_INST_NAME FLG_PPN_UPDATIME FLG_PPN_UPDATEBY FLG_PPN_EXTERNAL_NAME FLG_PPN_PTNAME FLG_PPN_DPNAME FLG_PPN_CREATOR |
OBJTYPID INSTIDNT NAME UPDATIME UPDATEBY NAME PTNAME DPNAME CREATOR |
126 | Value flag |
FLG_REQUIRED FLG_OPTIONAL FLG_SYSTEM |
R O S |
127 | UUI sequence number |
FLG_UUI_1 FLG_UUI_2 FLG_UUI_3 FLG_UUI_4 FLG_UUI_5 FLG_BLANK |
1 2 3 4 5 |
128 | Case- sensitivity flag |
FLG_YES FLG_NO |
Y N |
129 | Fuzzy search flag |
FLG_YES FLG_NO |
Y N |
130-159 | Reserved area (always blank) |
|
|
For more information about the specific meanings for all the byte positions in the definition area, see Definition area -- always required. For more information about the definition for the API call you are using, see Chapter 5, The Information Catalog Manager API call syntax.
How you define the values in your object area depends on the data type of each property being defined. CHAR and TIMESTAMP values are relatively straightforward because they have fixed lengths, but variable values (VARCHAR and LONG VARCHAR) are more complicated.
TIMESTAMP values have a fixed length and format.
CHAR values are left-justified and padded with trailing blanks to fill the defined length, as in this example:
'My example '
All values must be character data. If the value is numeric, you must convert it to character data.
Null characters are not permitted in any value. If the value you specify does not fill the entire fixed length, you must define blanks or zeroes for the unfilled positions. One way of defining blanks or zeroes for unused byte positions is to use the C language memset function to set the entire structure to FLG_BLANK or zero characters ('0' or 0x30) first, and then to use the C language memcpy function to copy only the information that needs to be set to something else. This method also makes it easier to use the constants defined in DG2API.H, because you only need to worry about overlaying blanks, not about padding the values to match the data length.
To specify VARCHAR and LONG VARCHAR values, include an extra 8 bytes before the value to specify the length of the value. For example, the value you need to specify for a VARCHAR value of "Employee records -- Southwest Region" would be
00000036Employee records -- Southwest Region
Because this is a VARCHAR value, you do not need to pad the value with trailing blanks.
This section discusses the parts of DG2SAMP.C that define an input structure.
The code shown in Figure 17 calculates the object area length for an input structure.
Figure 17. DG2SAMP.C: Determining the object area length
//-------------------------------------------- // Build input structure for FLGSearch //-------------------------------------------- printf ("Enter object instance name:\n"); gets(pszObjInstName); (1) ulInstValLen = strlen(pszObjInstName); (2) ulInstLen = (FLG_VARIABLE_DATA_LENGTH_LEN + ulInstValLen); (3) convertultoa(ulInstLen, pszLength); (4) |
The code in Figure 17 performs the following steps for determining the object area:
The code in Figure 18 shows how DG2SAMP.C defines the header area of the input structure for FLGSearch. This header area contains the same values as shown in Figure 19.
Figure 18. DG2SAMP.C: Defining the header area
//-------------------------------------------- // Header //-------------------------------------------- memset(&(SearchStruct.srchHdr), FLG_BLANK, FLG_HEADER_SIZE); (1) memcpy(&SearchStruct.srchHdr.pchHIdent, FLG_H_IDENT, FLG_H_IDENT_LEN); (2) memcpy(&SearchStruct.srchHdr.pchHDefLength, "00000160", FLG_H_DEFAREA_LEN); (3) memcpy(&SearchStruct.srchHdr.pchHObjLength, pszLength , FLG_H_OBJAREA_LEN); (4) memcpy(&SearchStruct.srchHdr.pchHObjEntryCount, "00000001", FLG_H_OBJAREAENT_LEN); (5) |
The code in Figure 18 performs the following steps for defining a header area using C language.
Figure 19 shows the storage defined by the C language code in Figure 18.
Figure 19. Defined header area--SearchStruct.srchHdr
The code in Figure 20 shows how DG2SAMP.C defines the definition area of the input structure for FLGSearch. This definition area contains the values shown in Figure 21.
Figure 20. DG2SAMP.C: Defining the definition area
//-------------------------------------------- // Definition area //-------------------------------------------- memset(&(SearchStruct.srchDef), FLG_BLANK, FLG_DEFINITION_SIZE); (1) memcpy(&SearchStruct.srchDef.pchDPropName, "Name ",FLG_D_PROPNM_LEN); (2) memcpy(&SearchStruct.srchDef.pchDDataType, "VARCHAR ", FLG_D_DATATYP_LEN); (3) memcpy(&SearchStruct.srchDef.pchDDataLength, "00000080", FLG_D_DATA_LEN); (4) memcpy(&SearchStruct.srchDef.pchDTagName, "NAME ", FLG_D_PPN_LEN); (5) memset(SearchStruct.srchDef.pchDCS, 'N', FLG_D_CS_LEN); (6) memset(SearchStruct.srchDef.pchDFS, 'N', FLG_D_FS_LEN); (7) |
The code in Figure 20 performs the following steps for defining a record in the definition area using the C language:
Figure 21 shows the storage defined by the C language code in Figure 20.
Figure 21. Defined definition area--SearchStruct.srchDef
Figure 22 shows how DG2SAMP.C defines the object area of the input structure for FLGSearch. This object area contains values shown in Figure 23.
Figure 22. DG2SAMP.C: Defining the object area
//-------------------------------------------- // Object area //-------------------------------------------- memset(&(SearchStruct.Item), FLG_BLANK, FLG_INST_NAME_LEN + FLG_VARIABLE_DATA_LENGTH_LEN); (1) convertultoa(ulInstValLen, pszNameLength); (2) pszInstanceName=strncat(pszNameLength,pszObjInstName,ulInstValLen); (3) memcpy(&SearchStruct.Item.Name, pszInstanceName, ulInstLen); (4) |
The code in Figure 22 performs the following steps for defining an object area using the C language:
Figure 23 shows the storage defined by the C language code in Figure 22.
Figure 23. Defined object area--SearchStruct.Item