Solstice Enterprise Manager 4.1 C++ API Reference Doc Set ContentsPreviousNextIndex


Chapter 3

High-Level PMI

The Solstice EM product provides a Portable Management Interface (PMI) with a suite of classes and member functions that provide effective access to the Solstice EM Management Information Server (MIS) without requiring detailed specification of the underlying MIS or mechanism. For most applications, the high-level usage of the PMI is sufficient for all interactions with the Solstice EM MIS.

This chapter comprises the following topics:

3.1 Design Objectives

The PMI seeks to balance two contrasting goals:

To achieve location transparency, you need:

To achieve location flexibility, you need to:

3.2 Object Management Model

Low-level routines for manipulating objects tend to manage objects by sending them messages and waiting for replies. In Common Management Information Service (CMIS), for instance, there are messages to create and delete objects, to get and set attributes, and to perform various actions or to signal events.

The PMI replaces these notions with a model in which objects appear (as far as possible) to be local. The remote object is tracked in the application process by a local class object called an image, which acts as a surrogate for the remote object and tracks where it is and what it is doing.

3.2.1 Naming Objects

Objects are named by starting from a known starting point in a tree and traversing a map of containment relationships. The object's name is formed by concatenating the "key" for each of the steps in the traversal, with slashes between the components. To find an object's container, you have only to strip off the final component of the object's name.

An object name that begins without a slash is a local distinguished name and is under the local root. In the case of the Solstice EM MIS, the local root is /systemID. An object name that begins with a slash is a distinguished name, and refers to an object that is global (in the literal sense). Names used in the PMI can comprise a superset of the OSI naming tree. Names that are not part of the OSI naming tree must not conflict with those on the OSI naming tree.

Within the application, any object can also have a nickname. Nicknames offer a convenient way for you to program readably, and also provide a level of indirection that helps in the quest for abstraction.

3.2.2 Relationships Between Objects

The relationships between objects are represented using album objects.

You can think of undirected sibling-like relationships as a form of set membership. The album contains a set of images, so membership of an image in an album can model the inclusion of objects in a mathematical set. The application can build up an album by enumerating the images that it wants to include.

Other relationships are of a directed nature. The PMI models these relationships as albums built by a derivational rule rather than by enumeration. A simple derivation might form the set of objects that are "children" of another object. A more complex derivation might examine all the objects in another album, select a subset of them, and for each of that subset specify a relational attribute that defines a new set of objects.

3.2.3 Managing Notifications

An image (or an album of images) can alert the application when a change of state in which the application has expressed an interest occurs. The PMI transmits the event to the application by invoking the callback function that the application registered earlier.

3.2.4 Managing Data Types

Each image knows the attributes that a given object class supports. It also knows the type of each attribute. That lets the application deal with the object on a purely textual basis if it chooses.

The language in which textual data is expressed looks much like ASN.1 textual data. Scoping is indicated by curly braces, choice names are delimited by a colon, and so on. This approach was decided upon because ASN.1 specification is complete and mature, at least when compared with other abstract syntax notations. You can represent other abstract notations with this data language, but it maps most easily onto ASN.1.

Sometimes the application needs to deal with data apart from the definition of any particular object. While this can be done using text, as mentioned above, it is sometimes more convenient to pass around encoded data. The PMI supports the notion of typed, encoded data. Such an object is called a Morf. You can think of a Morf as a bare attribute without any associated object. It knows its type and the associated syntax, so you can convert its value to and from textual representation, as you would an attribute of an image object.

3.2.5 Object Schema Management

The application program can discover various facts about the object class and its various attributes by using the get_prop() and get_attr_prop() functions. These routines work much like the UNIX getenv call, but acquire their information from the MIS or from some associated repository of metadata. To avoid confusing these facts with the ordinary attributes contained in a managed object instance, these attribute-like facts are called "properties."

Properties occur among attributes used by the Image class, and in the arguments or results of methods of the Image, Album, and Platform classes. TABLE 3-1 summarizes where various properties occur. See also the descriptions of:

3.2.6 Filtering as an Aspect of Album Derivation

The Album function set_derivation() (or its more general form set_prop) can specify a derivation that includes a CMIS filter. The derivation specifies three items, in this order:

A slash separates the scope from the object name. If there is a filter, a slash separates the scope from the filter.

3.2.6.1 Object Name

An object name is a distinguished name in slash form. The object name specifies the base object for scoping. This base object is not necessarily one of the objects in the album.

It is permissible to omit the object name. If you omit the object name, the system object is assumed. Also if you omit the object name, you should not insert the slash that would separate the name from the derivation. If you write /ALL, you are indicating an object name of / (indicating the system object), followed by the scope ALL.

3.2.6.2 Scope

The scope can be any of those shown in TABLE 3-2.

TABLE 3-2   Scoping Parameters
Parameter
Description
ALL
All descendants of named object, including object.
LV n
Level n descendants only. Children are at LV(1). Grandchildren are at LV(2). The base object is at LV(0).
TO n
All levels down to level n, including object
*
Short for LV(1), i.e. children only
*/*
Short for LV(2), i.e. grandchildren only.
*/*/*
Short for LV(3), i.e. great-grandchildren only.


If omitted, the scope defaults to the base object only. The asterisk forms are short for LV(n), not TO(n).

3.2.6.3 Filter

The filter is currently specified in raw ASN.1 format. The definition of the filter goes inside the parentheses that follow CMISFilter. This syntax makes CMISFilter look like a function. In fact, it is not a function; the use of parentheses is a convention for delimiting the filter definition.

Omitting the filter has the same effect as a filter whose definition is TRUE, meaning "include everything specified by the scope." The definition of a legal CMISFilter is specified in etc/asn1/x711.asn1, which is a formalization of the X.711 standard.

As an example of filtering, to find all of the OMNIPoint logs under the system object, any of the expressions shown below would be a valid argument to Album::set_derivation().

/systemId="mysys"/LV(1)/
CMISFilter(item:equality:{objectClass,log})
 or
LV(1)/CMISFilter(item: equality: {objectClass, log})
 or
*/CMISFilter(item:equality:{objectClass,log})

Building on the previous examples, to get only logs that are enabled, filter on operationalState, using and, as shown below:

LV(1)/CMISFilter(
     and: {
     item: equality: {objectClass, log},
     item: equality: {operationalState, enabled}
}
)

For the PMI, newlines are allowed and might enhance readability. The newlines might not be accepted by a shell.

3.2.6.4 Operation of a Filtering Derivation

When a filtered album is derived, the filtering is done automatically by the platform, so you never see any callbacks for the objects that are bypassed by the filter. If the album's TRACKMODE is set to TRACK, the album is maintained on the basis of the filter. That is, if an attribute changes in a way that makes the value of the filter TRUE (when it has been FALSE) or FALSE (when it has been TRUE), the album is automatically updated so that the image of the object is included (or excluded, as appropriate).

If the album is not set to TRACK, you can perform another scoped and filtered M-GET by calling derive() again.

If you execute all_destroy() on an album that has a derivation and that album is in a DOWN state, or is an AUTOIMAGE album, then the request is optimized to do a single scoped M-DELETE using the scope and filter specified for the album. (Otherwise a separate M-DELETE is issued for each member of the album, as before.)

The other ALL operations are not yet optimized in this way, but you can get the effect of an optimized all_boot(). If you execute derive() on an AUTOIMAGE album, the initial scoped M-GET fetches all the attributes at that time, rather than issuing a subsequent M-GET for each image.

3.3 Meta Data Repository

The Meta Data Repository (MDR) is where descriptions of managed objects are stored. A description for every object known to the MIS is stored in the MDR. This data encompasses everything from the syntax required to refer to the attribute, to the composition of an object package. The MDR is initialized and updated by using the GDMO and ASN.1 compilers. MDR supports the following actions to provide information about the objects.

3.3.1 getAttribute Action

getAttribute '"GDMO DOCNAME":attrName'

This action provides information about an attribute. It gives information about which ASN.1 module the attribute is actually defined.

3.3.2 getAllDocuments Action

getAllDocuments getAllDocuments

This action provides a list of all documents. You still have to provide either a class name or an oid as the argument.

3.3.3 getAsn1Module Action

getAsn1Module '"ASN1 DOCNAME"'

This action provides the complete information about an attribute in textual form. You can provide either the ASN.1 module name or the oid as the argument.

3.3.4 getObjectClass Action

getObjectClass '"GDMO DOCNAME":objectClass' 

This action provides the complete information about a class in textual form, which includes all the class attributes and their properties. You can provide either the class name or the oid as the argument.

3.3.5 getDocument Action

getDocument '"GDMO DOCNAME"'

This action provides a list of all objects (and the oids) defined in a particular document. This action expects the document name.

3.3.6 getPackage Action

This action provides the following information about the content of the given package:

CODE EXAMPLE 3-1 shows the input syntax (information syntax) and the output syntax (reply syntax) of the getPackage action. The input syntax can be either the fully qualified name of the package (for example, docLabel : { document "CD", label "cdPlayOptionsPackage" }), or the object identifier of the package (for example, oid : {1 3 6 1 4 1 42 2 2 3 20 1 6 1}).

CODE EXAMPLE 3-1   Input/Output Syntax of the getPackage Action 
Input Syntax is CHOICE {
    docLabel SEQUENCE {
        document [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
        label    [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64))
    },
    oid      OBJECT IDENTIFIER
}
Result Syntax is SEQUENCE {
    oid           [0] IMPLICIT OBJECT IDENTIFIER,
    labels        SEQUENCE OF SEQUENCE {
        document [0] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
        label    [1] IMPLICIT OCTET STRING (SIZE (0 .. 64))
    },
    attributes    SEQUENCE OF SEQUENCE {
        oid           [0] IMPLICIT OBJECT IDENTIFIER,
        labels        SEQUENCE OF SEQUENCE {
            document [0] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
            label    [1] IMPLICIT OCTET STRING (SIZE (0 .. 64))
        },
        types         SEQUENCE {
            name ASN-1.Reference,
            type ASN-1.Asn1-Type
        },
        defaultval    SEQUENCE {
            value ASN-1.Asn1-Parsed-Value OPTIONAL
        },
        initialval    SEQUENCE {
            value ASN-1.Asn1-Parsed-Value OPTIONAL
        },
        permittedvals SEQUENCE {
            value ASN-1.Asn1-Type OPTIONAL
        },
        requiredvals  SEQUENCE {
            value ASN-1.Asn1-Type OPTIONAL
        },
        props         SET OF ENUMERATED {
            get(0),
            replace(1),
            add(2),
            remove(3),
            replace-with-default(4)
        }
    },
    actions       SET OF SEQUENCE {
        document    [0] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
        label       [1] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
        infosyntax  SEQUENCE {
            module PrintableString,
            name   PrintableString
        },
        replysyntax SEQUENCE {
            module PrintableString,
            name   PrintableString
        } OPTIONAL
    },
    notifications SET OF SEQUENCE {
        document     [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
        label        [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
        attributeids SET OF SEQUENCE {
            oid   [0] IMPLICIT OBJECT IDENTIFIER,
            field [1] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
            label [2] IMPLICIT OCTET STRING (SIZE (0 .. 64))
        }
    }
}

CODE EXAMPLE 3-2   Output of the getPackage Action Example 
On running the "mdr_action" sample program 
from /opt/SUNWconn/em/src/pmi_hi
# ./mdr_action -a getPackage -l 'docLabel :
{ document "CD", label "cdPlayOptionsPackage" }'
Input Morf-->  {
    document "CD",
    label "cdPlayOptionsPackage"
}
Result --> {
    oid "CD":cdPlayOptionsPackage,
    labels {
        {
            document "CD",
            label "cdPlayOptionsPackage"
        }
    },
    attributes {
        {
            oid "CD":cdPlayList,
            labels {
                {
                    document "CD",
                    label "cdPlayList"
                }
            },
            types {
                name "TrackList",
                type choice : {
                    {
                        name "all",
                        type null : NULL
                    },
                    {
                        name "selection",
                        type set-of : defined : {
                            module "CD-asn1Module",
                            name "TrackId"
                        }
                    }
                }
            },
            defaultval {
                value defined : {
                    module "CD-asn1Module",
                    value "playAllTracks"
                }
            },
            initialval {
                value defined : {
                    module "CD-asn1Module",
                    value "playAllTracks"
                }
            },
            permittedvals {
            },
            requiredvals {
            },
            props {
                get,
                replace,
                add,
                remove,
                replace-with-default
            }
        }
    },
    actions {
        {
            document "CD",
            label "cdPlayerPlayTrack",
            infosyntax {
                module "CD-asn1Module",
                name "TrackId"
            }
        }
    },
    notifications {
        {
            document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
            label "attributeValueChange",
            attributeids {
                {
                    oid "Rec. X.721 | ISO/IEC 10165-2 : 1992":sourceIndicator,
                    field "sourceIndicator",
                    label """Rec. X.721 | ISO/IEC 10165-2 : 
1992"":sourceIndicator"
                },
                {
                    oid "Rec. X.721 | ISO/IEC 10165-2 : 
1992":attributeIdentifierList,
                    field "attributeIdentifierList",
                    label """Rec. X.721 | ISO/IEC 10165-2 : 
1992"":attributeIdentifierList"
                },
                {
                    oid "Rec. X.721 | ISO/IEC 10165-2 : 
1992":attributeValueChangeDefinition,
                    field "attributeValueChangeDefinition",
                    label """Rec. X.721 | ISO/IEC 10165-2 : 
1992"":attributeValueChangeDefinition"
                },
                {
                    oid "Rec. X.721 | ISO/IEC 10165-2 : 
1992":notificationIdentifier,
                    field "notificationIdentifier",
                    label """Rec. X.721 | ISO/IEC 10165-2 : 
1992"":notificationIdentifier"
                },
                {
                    oid "Rec. X.721 | ISO/IEC 10165-2 : 
1992":correlatedNotifications,
                    field "correlatedNotifications",
                    label """Rec. X.721 | ISO/IEC 10165-2 : 
1992"":correlatedNotifications"
                },
                {
                    oid "Rec. X.721 | ISO/IEC 10165-2 : 1992":additionalText,
                    field "additionalText",
                    label """Rec. X.721 | ISO/IEC 10165-2 : 
1992"":additionalText"
                },
                {
                    oid "Rec. X.721 | ISO/IEC 10165-2 : 
1992":additionalInformation,
                    field "additionalInformation",
                    label """Rec. X.721 | ISO/IEC 10165-2 : 
1992"":additionalInformation"
                }
            }
        }
    }
}

CODE EXAMPLE 3-2 shows the output of the getPackage action.

3.3.7 getPackagesByOC Action

This action provides a list of all the packages defined in the given GDMO Managed Object Class (MOC), and provides the following information about each package:

CODE EXAMPLE 3-3 shows the input syntax (information syntax) and the output syntax (reply syntax) of the getPackagesByOC action. The input syntax can be either the fully qualified name of the object class (for example, docLabel : { document "Rec. X.721 | ISO/IEC 10165-2 : 1992", label "log" }), or the object identifier of the object class (for example, oid : {2 9 3 2 3 6}).

CODE EXAMPLE 3-3   Input and Output Syntax for the getPackagesByOC Action Example 
Input Syntax is CHOICE {
    docLabel SEQUENCE {
        document [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
        label    [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64))
    },
    oid      OBJECT IDENTIFIER
}
Result Syntax is SET OF SEQUENCE {
    document  [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
    label     [UNIVERSAL 19] IMPLICIT OCTET STRING (SIZE (0 .. 64)),
    type      ENUMERATED {
        mandatory(0),
        conditional(1)
    },
    hierarchy ENUMERATED {
        originated(0),
        inherited(1)
    } OPTIONAL
}

CODE EXAMPLE 3-4 shows the output of the getPackagesByOC action example.

CODE EXAMPLE 3-4   Output of the getPackagesByOC Action Example 
On running the "mdr_action" sample program from 
/opt/SUNWconn/em/src/pmi_hi
# ./mdr_action -a getPackagesByOC -l 'docLabel : 
{ document "Rec. X.721 | ISO/IEC 10165-2 : 1992", label "log" }'
Input Morf-->  {
    document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
    label "log"
}
Result --> {
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "logPackage",
        type mandatory
    },
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "finiteLogSizePackage",
        type conditional
    },
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "logAlarmPackage",
        type conditional
    },
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "availabilityStatusPackage",
        type conditional
    },
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "duration",
        type conditional
    },
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "dailyScheduling",
        type conditional
    },
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "weeklyScheduling",
        type conditional
    },
    {
        document "Rec. X.721 | ISO/IEC 10165-2 : 1992",
        label "externalScheduler",
        type conditional
    }
}

3.3.8 getOidName Action

getOidName '{oid}'

For a given object identifier, returns the name of the object.

3.3.9 Sample MDR Action Program

CODE EXAMPLE 3-5 gives a sample program so you can try out these different actions of the MDR.

CODE EXAMPLE 3-5   MDR Actions 
#include stdio.h
Platform plat;
main(int argc, char **argv)
{
        char dn[1024];
        if (argc != 4) {
                printf("Usage dummy: mdr hostname < MDR action> <arglist> \n");
                printf("\nSupported Actions:\n \n");
                printf("\t getObjectClass '\"GDMO DOCNAME\":objectClass'\n");
                printf("\t getAllDocuments getAllDocuments\n");
                printf("\t getDocument '\"GDMO DOCNAME\"'\n");
                printf("\t getAttribute '\"GDMO DOCNAME\":attrName'\n");
                printf("\t getAsn1Module '\"ASN1 DOCNAME\"'\n");
                printf("\t getOidName '{oid}'\n");
                printf("\nSample Usage commands:\n\n");
                printf("\t mdr host getAsn1Module '\"EM-TOPO-ASN1\"'\n");
                printf("\t mdr host getOidName '{ 1 3 6 1 4 1 42 2 2 2 5 3 1
}'\n");
                printf("\t mdr host getAttribute '\"EM
TOPOLOGY\":topoNodeName'\n");
                printf("\t mdr host getDocument '\"EM Topology\"'\n");
                printf("\t mdr host getObjectClass '\"EM TOPOLOGY\":topoNode'\n");
                printf("\t mdr host getAllDocuments getAllDocuments\n");
                exit(0);
        }
        char *host = argv[1];
        char *host = argv[1];
        char *action = argv[2];
        char *mod = argv[3];
        plat = Platform(duEM);
        printf("Connecting to %s ... ",host);
        plat.connect(host, "test_get");
        printf("Done.\n");
        printf(dn,"/systemId=\"%s\"/metaName=\"MDR\"", host);
        Image mdr = Image(dn);
        mdr.boot();
        Syntax in = mdr.get_param_syntax(action);
        Syntax res = mdr.get_result_syntax(action);
        printf("Input Syntax is %s\n",in.get().chp());
        printf("\n-------------------------------------\n");
        printf("Result Syntax is %s\n",res.get().chp());
        DU mdr_data = mdr.call(action, mod);
        printf("--> %s\n",mdr_data.chp());
}

3.4 Symbolic Constants

The following is an example of a symbolic constant.

const Timeout DEFAULT_TIMEOUT = -12345.0;

DEFAULT_TIMEOUT is the default argument to several of the member functions of the Platform class. -12345.0 is a distinguished value that causes those functions to substitute the value of the TIME_OUT property from the Platform instance. Refer to Section 3.5.5.2 Timeout, for more information. For example:

const DU duREPLACE = "REPLACE";
 
const Callback NO_CALLBACK;
 
enum Platformid
     { VOID_PLATFORM_ID,
       G2_PLATFORM_ID,
     };

TABLE 3-3 is a list of often used string constants.

TABLE 3-3   String Constants 
Constant Definition
duACCESS
"ACCESS"
duACCESS_DENIED
"ACCESS_DENIED"
duAPPLICATION_OBJNAME
"APPLICATION_OBJNAME"
duAPPLICATION_TYPE
"APPLICATION_TYPE"
duATTR_CHANGED
"ATTR_CHANGED"
duAUTOIMAGE
"AUTOIMAGE"
duBOOT
"BOOT"
duCHANGED
"CHANGED"
duDEFAULT
"DEFAULT"
duDEFAULT_ALLOWED
"DEFAULT_ALLOWED"
duDEFAULT_TIMEOUT
"DEFAULT_TIMEOUT"
duDERIVATION
"DERIVATION"
duDISCONNECTED
"DISCONNECTED"
duDOWN
"DOWN"
duEFFECTIVE_USER
"EFFECTIVE_USER"
duERROR
"PMI_ERROR"
duEXCLUDE
"EXCLUDE"
duEXCLUDE_ALLOWED
"EXCLUDE_ALLOWED"
duEXISTS
"EXISTS"
duFALSE
"FALSE"
duIGNORE
"IGNORE"
duIGNORE_ALLOWED
"IGNORE_ALLOWED"
duIMAGE_EXCLUDED
"IMAGE_EXCLUDED"
duINCLUDE
"INCLUDE"
duINCLUDE_ALLOWED
"INCLUDE_ALLOWED"
duLAST_ERROR
"LAST_ERROR"
duLOCATION
"LOCATION"
duMAYBE
"MAYBE"
duMISC_EVENT
"MISC_EVENT"
duMODIFIABLE
"MODIFIABLE"
duMOD_PENDING
"MOD_PENDING"
duNICKNAME
"NICKNAME"
duNICKNAME_IS_PERMANENT
"NICKNAME_IS_PERMANENT"
duNO
"NO"
duNONE
"NONE"
duNOT_LOADED
"NOT_LOADED"
duNO_VALUE
"NO_VALUE"
duOBJCLASS
"OBJCLASS"
duOBJECT_CREATED
"OBJECT_CREATED"
duOBJECT_DESTROYED
"OBJECT_DESTROYED"
duOBJNAME
"OBJNAME"
duOBJFULLNAME
"OBJFULLNAME"
duOWNERSHIP
"OWNERSHIP"
duEM
"EM"
duPLATFORM_NICKNAME
"PLATFORM_NICKNAME"
duPLATFORM_OBJNAME
"PLATFORM_OBJNAME"
duPLATFORM_TYPE
"PLATFORM_TYPE"
duPOLL
"POLL"
duRAW_EVENT
"RAW_EVENT"
duREPLACE
"REPLACE"
duREPLACE_ALLOWED
"REPLACE_ALLOWED"
duSHARED
"SHARED"
duSHUTDOWN
"SHUTDOWN"
duSNAP
"SNAP"
duSTATE
"STATE"
duTICKET
"TICKET"
duTRACK
"TRACK"
duTRACKMODE
"TRACKMODE"
duTRUE
"TRUE"
duUP
"UP"
duUSER
"USER"
duWAIT
"WAIT"
duYES
"YES"
duACTUALCLASS
"ACTUAL_CLASS"


3.5 Defined Types

The defined types are shown in this section. They are declared in the /opt/SUNWconn/em/include/pmi/hi.hh file.

3.5.1 Asn1Int

typedef GenInt Asn1Int;

3.5.2 CCB

typedef const Callback& CCB;

3.5.3 CDU

typedef const DU& CDU;

3.5.4 DU

typedef DataUnit DU;

3.5.5 FBits

typedef U32 FBits;

The bits have the meanings on a get shown in TABLE 3-4.

TABLE 3-4   Format Bit Values on get Function Calls 
Format Bit Description
USE_NUMERIC_NAMES
Do not translate OIDs to names
OMIT_NEWLINES
Do not "pretty-print". Format only one line of output
USE_C_ESCAPES
Format control characters as C does: \n, \033, etc
USE_EXPLICIT_TYPES
Format type tags on ANY values
OMIT_SPACES
Omit all nonessential space characters
USE_HEX
Formats the string in the usual C hex format with a leading 0x.Valid for octet strings only.
USE_EXPLICIT_CHOICE
Format choice with an explicit choice tag


The bits have the meanings on a set as shown in TABLE 3-5.

TABLE 3-5   Format Bit Values on set Function Calls
Format Bit Description
USE_NUMERIC_NAMES
(Ignored)
OMIT_NEWLINES
(Ignored)
USE_C_ESCAPES
Parse control characters as C does: \n, \033, etc.
USE_EXPLICIT_TYPES
Require type tags on ANY values
OMIT_SPACES
(Ignored)
USE_HEX
(Ignored)
USE_EXPLICIT_CHOICE
Expect choice to have an explicit choice tag.


3.5.5.1 FormatBits

Enum FormatBits
{ USE_NUMERIC_NAMES  = 1,
  OMIT_NEWLINES      = 2,
  USE_C_ESCAPES      = 4,
  USE_EXPLICIT_TYPES = 8,
  OMIT_SPACES        = 16,
USE_HEX = 32,
USE_EXPLICIT_CHOICE = 65536
};

3.5.5.2 Timeout

typedef double Timeout ;

3.6 Error Handling and Event Dispatching

Error handling is provided by the base class Error. Each of the object classes is derived from the Error class, except for the class, AlbumImage.

The function dispatch_recursive() maintains queues of callback routines. One queue is maintained for each of the following: input, output, exception, and timers. These queues are scanned in the following order:

You associate a file descriptor with each callback on a queue when you use a function such as post_fd_read_callback(). When you call dispatch_recursive(), this function does a select on all the open file descriptors to determine their state, and then goes through each queue in the order indicated above to determine if there is outstanding data to be read from, or written to, the file descriptor.

Either FALSE or TRUE can be passed as a value to the dispatcher as an argument. If FALSE is the value passed, then the select on the open file descriptors is done with a time-out value of 0. If TRUE is passed, then a short time interval is specified as the time-out.

3.6.1 Event Dispatching Functions

The following functions maintain the queues of the callback routines.

void dispatch_main_loop();// Event dispatch queue for user applications

void dispatch_recursive(Boolean wait); // Flush scheduler buffer function

The following functions maintain critical region handling.

int writecallback_exists();// Checks callback queue for pending writes

void flush_events_callbacks();// Flush all pending events to the MIS

3.7 pmi_sched_get_fds Function

pmi_sched_get_fds

void pmi_sched_get_fds(fd_set &rd_mask, fd_set 
&wr_mask, fd_set 
&expt_mask)

The pmi_sched_get_fds function returns the file descriptors that are set by the scheduler for read, write and exception conditions into the corresponding file descriptors rd_mask, wr_mask, expt_mask.

3.8 High-Level PMI Classes

Each of the classes shown in TABLE 3-6 is implemented as a reference-counting outer class wrapped around an inner abstract-base class. The PMI requires no access to the inner class.

TABLE 3-6   High-Level PMI Classes 
Class Description
Album Class
Represents a set of related objects
AlbumImage Class
Represents the state of an iterator
AppTarget Class
Represents target applications
AuthApps Class
Used when you need to know which applications a user is authorized to use
AuthFeatures Class
Used to implement the feature level access control in your application
Coder Class
Represents a pair of methods for encoding and decoding values
CurrentEvent Class
Represents an event
Error Class
Stores details of errors related to an object instance
Image Class
Represents an actual or potential object in an MIS' framework
Morf Class
Represents a unit of data
MorfBuilder Class
Provides flexibility with Morf objects
PasswordTty Class
Implements the TTY based password query mechanism
Platform Class
Represents a potential or actual connect to a MIS
Syntax Class
Represents a type
Waiter Class
Represents an ongoing asynchronous operation



Note – As all class destructors have an identical format, such as ~class name(), the various class destructors are not specified in the following sections. Each class destructor might or might not destroy the underlying class name object, depending on the reference count.

3.9 Album Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

An album contains a set of related objects, implemented as a set of images. Like mathematical sets, albums can be constructed either by rule or by enumeration. An album instance allows you to perform certain operations on each of the images that it contains. Like images, albums can be synchronized either manually or automatically.

The Album class allows an attribute list to be specified as an argument; in this way memory consumption of images is reduced. As examples, see derive() and start_derive().

TABLE 3-7   Album Method Types  
Method Name Method Type
find_by_nickname
Global lookup
get_prop
set_prop
all_set_prop
all_set_attr_prop
Control properties
get_derivation
set_derivation
derive
start_derive
Define membership of a derived album
include
exclude
clear
Manipulate membership of an enumerated album
num_images
Census info
get_userdata
set_userdata
User-defined properties
first_image
all
Iterate over all images
all_boot
all_start_boot
all_shutdown
all_start_shutdown
Image activation
start_m_get
start_m_set
start_m_action
start_m_action_raw
start_m_delete
asynchronous CMIS
all_set
all_set_long
all_set_str
all_set_gint
all_set_dbl
all_set_raw
all_revert
all_store
all_start_store
all_set_from_ref
Setting attributes
all_create
all_start_create
all_create_within
all_start_create_within
all_destroy
all_start_destroy
Object existence
all_call
all_start_raw
all_start
Miscellaneous methods
all_when
Object events
get_when_syntax
when
Album events



Note – When in use, the start_m_get(), start_m_set(), start_m_action(), start_m_action_raw(), and start_m_delete() methods do not populate the album like the start_derive() method does. Only the start_derive() and include() methods populate the album with images. Also, the existing all_start() method and the new all_start_raw() method only address already populated albums. For more information, refer to the examples of start_m_get() and all_start() method utilization.

3.9.1 Constructors

Default Constructor

Album()

The default constructor creates an album instance that refers to no actual album object. The value tests FALSE until you assign it a real album value.

Copy Constructor

Album(const Album& other);

This is an ordinary copy constructor. After the copy, both copies still refer to the same album object. The reference count on the album object is incremented.

Album Constructor

Album(CDU nickname,
     Platform& p = 
Platform::default_platform(), 
)

This constructor constructs an album instance for a particular kind of Platform. Because an album is really a wrapper for a set of related classes, this function actually works somewhat like a virtual constructor.


Note – A nickname is an album's unique identifier. If you create two albums with the same nickname in one application, the second will be the same as the first.

3.9.2 Album Operator Overloading

Assignment Operator

Album& operator = (const Album& other)

The assignment operator works the same as the copy constructor.

Cast Operator

operator void *();

The cast operator is for use in conditionals. It returns TRUE if this album refers to an actual album object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

Not Operator

operator !();

This is provided so that you can say "if (!album) ..."

3.9.3 Album Member Functions

This section describes the member functions of the Album class.

all

Purpose: Apply a function, provided as an argument, over all of the images in the album.

virtual Result all(Result 
(*f)( Image 
&im, 
void* data),
     void* data = 0)

The subfunction's syntax (embedded in the declaration of all) is therefore required to be:

Result (*f)(Image &im, void* data) ;

The implementation of all calls the subfunction repeatedly, supplying an appropriate value for im to refer in turn to each of the album's images, and passing to it each time the arbitrary data that was passed to all.

The all function itself returns a TRUE value if all the calls to the subfunction designated by f return TRUE. A thrown exception terminates the iteration.

all_boot

Purpose: Perform a boot on each of the images in the album.

Result all_boot(Timeout to = DEFAULT_TIMEOUT)

The timeout value is reset on completion of each successful boot. This function returns a TRUE value if all image operations succeeded.

Example: Boot all images in an album.

Album bunch = Album("demoalbum"); // Define, construct 
bunch.
bunch.set.derivation( "/LV(2)" ); // Derive the album.
Timeout to ;
...
if ( !bunch.all_boot( to )) { 
    // Boot all images in bunch.
	 cout << "Using all_boot(): boot of one image 
failed." ; 
	 exit ( 1 ) ;
}

all_call

Purpose: Perform a call on each of the images in the album.

Result all_call(CDU name,
	 CDU param,
	 const Timeout to = DEFAULT_TIMEOUT)

name is the name of the action.

param is the parameter associated with the action.

to is the timeout.

If param is not provided (or if it is set to duNONE), there is no parameter associated with this action. The time-out is reset on completion of each successful call. Returns a TRUE value if all image operations succeeded.

Example: Call all images in an album.

Album bunch = Album("demoalbum"); // Define, construct 
bunch.
bunch.set.derivation( "/LV(2)" ); // Derive the album.
CDU nm, prm ;
Timeout to ;
...
if (!bunch.all_call( nm, prm, 
to)) {  // Call all images in bunch.
	 cout << "Using all_call(): call of one image 
failed." ; 
	 exit ( 1 ) ;
}

all_create

Purpose: Perform a create on each image in the album.

Result all_create( Image 
&refobj = Image(),
	 const Timeout to = 
DEFAULT_TIMEOUT)

The Timeout value is reset on completion of each successful create call. Returns a TRUE value if all image operations succeeded.

Example: Create an object for each image in an album.

Album bunch = Album("demoalbum"); // Define, construct 
bunch.
bunch.set.derivation( "/LV(2)" ); // Derive the album.
Image robj;
Timeout to ;
// Set name and class before invoking 
bunch.all_create().See 
create.cc
// Create object of each image in bunch.
if ( !bunch.all_create(robj, 
to)) { 
	 cout << "Using all_create(): create of one 
object failed." ; 
	 exit ( 1 ) ;
}

all_create_within

Purpose: Perform a create_within on each of the images in the album.

Result all_create_within(CDU container_objname,
	 Image &refobj = Image(),
	 Timeout to = DEFAULT_TIMEOUT)

The Timeout value is reset on completion of each successful create_within call. Returns a TRUE value if all image operations succeeded.

Example: Create an object within a container, for each image in an album.

// Create object of each image in bunch.
if ( !bunch.all_create_within(cobj, 
robj, to)) {
cout << "Using all_create_within(): create of one 
object failed.";
	 exit ( 1 ) ; 
}

all_destroy

Purpose: Perform a destroy on each of the images in the album.

Result all_destroy(Timeout 
to = 
DEFAULT_TIMEOUT)

The Timeout value is reset on completion of each successful destroy call. Returns a TRUE value if all image operations succeeded.

Example: Destroy each image in an album.

if ( !bunch.all_destroy(to)) 
{// Create object of each image in 
bunch.
	 cout << "Using all_destroy(): create of one 
object failed." ; 
	 exit ( 1 ) ;
}

all_revert

Purpose: Perform a revert on each of the images in the album.

Result all_revert()

Returns a TRUE value if all image operations succeeded.

all_set

Purpose: Perform a set on each of the images in the album.

Result all_set(CDU name,
	 CDU value,
	 CDU op 
= duREPLACE)

Returns a TRUE value if all image operations succeeded.

all_set_attr_prop

Purpose: Set a property of an attribute in each of the images of current MIS.

Result all_set_attr_prop(CDU 
name,
	  CDU key,
	  CDU value)

This function sets a property for some attribute in each of the images of the current MIS, provided that:

If all_set_attr_prop cannot do what you ask, it throws an invalid exception.

Refer to get_attr_prop, under the description of Image, for some typical properties. Returns a TRUE value if all image operations succeeded.

all_set_dbl

Purpose: Perform a set_dbl on each of the images in the album.

Result all_set_dbl(CDU name,
	  double value,
	  CDU op 
= duREPLACE)

Returns a TRUE value if all image operations succeeded.

all_set_from_ref

Purpose: Perform a set_from_ref on each of the images in the album.

Result all_set_from_ref( 
Image& refobj)

Returns a TRUE value if all image operations succeeded.

all_set_gint

Purpose: Perform a set_gint on each of the images in the album.

Result all_set_gint(CDU name,
	  GenInt& value,
	  CDU op 
= duREPLACE)

Returns a TRUE value if all image operations succeeded.

all_set_long

Purpose: Perform a set_long on each of the

s in the album.

Result all_set_long(CDU name,
	  long value,
	  CDU op 
= duREPLACE)

Returns a TRUE value if all image operations succeeded.

all_set_prop

Purpose: Set a property for each of the images of the current album.

This function sets a property for each of the images of the current album, provided that:

If all_set_prop cannot do what you ask, it throws an invalid exception.

Result all_set_prop(CDU key, CDU value)

Refer to get_prop, under the description of Image, for some typical properties. Returns a TRUE value if all image operations succeeded.

all_set_raw

Purpose: Perform a set_raw on each of the images in the album. Returns a TRUE value if all image operations succeeded.

Result all_set_raw(CDU name,
	 Morf& value,
	 CDU op 
= duREPLACE)

all_set_str

Purpose: Perform a set_str on each of the images in the album.

Returns a TRUE value if all image operations succeeded.

Result all_set_str(CDU name,
     CDU value,
     CDU op 
= duREPLACE,
     FBits fb = 0)

The difference between set_str and set is that the data language used by set requires quotes as part of the string, while set_str assumes them if necessary. (They are not always necessary; you can also pass numeric values as strings, and they are converted for you.)

Refer to TABLE 3-13 for a description of legal operations. For a list of possible fb values, refer to Section 3.5.5.1 FormatBits.

all_shutdown

Purpose: Perform a shutdown on each of the images in the album.

The Timeout value is reset on completion of each successful shutdown. Returns a TRUE value if all image shutdowns succeed.

Result all_shutdown(const 
Timeout to = 
DEFAULT_TIMEOUT)

all_start

Purpose: Perform an asynchronous version of all_call.

The callback is called only once when all images are complete.

Waiter all_start(CDU name,
     CDU param,
     CCB cb 
= NO_CALLBACK)

all_start_boot

Purpose: Perform an asynchronous version of all_boot.

The callback is called only once, when all images are complete.

Waiter all_start_boot(CCB 
cb = 
NO_CALLBACK)

all_start_create

Purpose: Perform an asynchronous version of all_create.

The callback is called only once, when all images are complete.

Waiter all_start_create( 
Image& 
refobj = Image(),
     CCB cb 
= NO_CALLBACK)

all_start_create_within

Waiter all_start_create_within(CDU container_objname,
     Image & refobj = Image(),
     CCB cb 
= NO_CALLBACK)

The preceding function call is the asynchronous version of all_create_within. The callback is called only once, when all images are complete.

all_start_destroy

Waiter all_start_destroy (CCB cb = NO_CALLBACK)

The preceding function call is the asynchronous version of all_destroy. The callback is called only once, after all images are destroyed.

all_start_raw

Waiter all_start_raw(CDU name, Morf param, 
CCB cb = NO_CALLBACK)

Performs a start_raw() action asynchronously on each image in the album. This method offers exactly the same functionality as the existing Waiter all_start method. It differs in that the parameter param is a Morf rather than a DataUnit.

The callback is called only once when all asynchronous start_raw() or start() actions on images are completed.


Note – The all_start method performs a start() asynchronously on each image in an album.

all_start_shutdown

Waiter all_start_shutdown(CCB cb = NO_CALLBACK)

The preceding function call is the asynchronous version of all_shutdown. The callback is called only once, after all image shutdowns are complete.

all_start_store

Waiter all_start_store(CCB cb = NO_CALLBACK)

The preceding function call is the asynchronous version of all_store. The callback is called only once, after all image stores are complete.

all_store

Result all_store(const Timeout to = DEFAULT_TIMEOUT)

The preceding function call performs a store on each of the images in the album. The Timeout value is reset on completion of each successful store. It returns a TRUE value if all image stores succeed.

all_when

Result all_when(CDU eventname,
	 CCB cb 
= NO_CALLBACK)

The preceding function call performs a when on each of the images in the album. For a list of supported events, refer to when, under the description of Image. Returns a TRUE value if all image when operations succeed.

clear

Result clear()

The preceding function call nulls out this album, which is presumably of the enumerated variety. (The clear function is not as useful with derived albums, since such albums either track membership automatically or are repopulated by calling Album::derive again.)

derive

Result derive(const Timeout to = DEFAULT_TIMEOUT)

The preceding function call causes the album membership list to be computed (or recomputed) using the derivation specified in the property DERIVATION. All previous membership information is lost. You can initialize a non-tracking album with a derive and then maintain it with include and exclude. A tracking album does not track until the first derive is done, so it works much like a boot does on an image.

derive

virtual Result derive (Array (DU) attrlist, 
Timeout to = DEFAULT_TIMEOUT)= 0;

This function call allows a user to supply a list of attributes to be tracked when deriving an auto-imaging album. Attributes that are specified in the list are automatically tracked in each of the images in the derived album.

exclude

Result exclude(Album& *ai)

This function call deletes from this album the set of images that are in the album ai.


Note – Inclusion and exclusion are simple procedural operations for use on enumerated albums, and do not "define" the membership of the album in any way that would override subsequent membership operations.

find_by_nickname

static Album find_by_nickname(CDU name,
     Platform& plat = 
Platform::def_platform))

The preceding function call looks up an album by its nickname and returns a pointer to the corresponding instance of album. Because albums do not generally have object names, this is the only way to find an album by name.

first_image

AlbumImage first_image()

The preceding function call returns the first image in the album, in the form of an AlbumImage iterator. The AlbumImage::next_image function returns subsequent images until there are no more.


Note – If you are tempted to use this iterator to see whether an image is a member of an album, remember that the Image::is_in_album function does this much more efficiently.

get_derivation

DU get_derivation()

The preceding function call is a shortcut function for the get_prop function.

get_prop

Du get_prop(CDU key)

The preceding function call returns a property of the current album. If the key does not specify an existing property, a null DataUnit is returned, which tests FALSE in a conditional.

Most albums support the properties described in TABLE 3-8.

TABLE 3-8   Properties Supported by Most Albums 
Properties Description
STATE
Whether the album is actively tracking:
DOWN - The album is not tracking.
BOOT - The album is currently being derived.
UP - The album is tracking.
SHUTDOWN - The album is shutting down.
DERIVATION
How this album relates to other albums and images by scoping and filtering. Refer to Section 3.2.6 Filtering as an Aspect of Album Derivation.
NICKNAME
The nickname of the album.
TRACKMODE
How the membership of the album is to be maintained:
SNAP - the album does not maintain its membership list, but relies on explicit derive(), include(), and exclude() calls to tell the album which images are to be included. Note that a SNAP album might contain tracking images.
TRACK -- the album analyzes its derivation rule and automatically includes or excludes images as they change, when they match or fail to match the derivation rule. Refer to the AUTOIMAGE property if you want included images to boot and start tracking automatically.
AUTOIMAGE
(YES, NO)
For any image included in the album, also automatically boots the image as a tracking image. (This happens before any of the registered callbacks, if any, are called.)
ACCESS (RWRWRW)
The access permissions for this album, if persistent.
BEST_EFFORT
(YES, NO)
When set to 'NO', any error will return an error response message.


get_userdata

DU get_userdata(CDU key)

The preceding function call returns any data stored by the application under the key specified. There are no predefined values. If there is no data under that key for this instance, the return value (a null DataUnit) evaluates to FALSE.

get_when_syntax

Syntax get_when_syntax(CDU eventname)

The preceding function call returns the Syntax of a given event type. The event information comes into the callback as a CurrentEvent, from which the event information can be extracted.

include

Result include(Image& im)

The preceding function call adds the specified image to this album.

Result include(Album& al)

The preceding function call adds the set of images in the album al to this album.


Note – Inclusion and exclusion are simple procedural operations for use on enumerated albums, and do not "define" the membership of the album in any way that would override subsequent membership operations.

num_images

U32 num_images()

The preceding function call returns the number of images in this album.

set_derivation

Result set_derivation(CDU derivation)

The preceding function call is a shortcut function for the following:

Result set_prop(CDU key, CDU value)

The preceding function call sets a property of the current album, provided that key specifies a supported property and value specifies a legal value. If set_prop cannot do what you ask, it throws an invalid exception. Refer to get_prop under the description of the Album class for some typical properties.

set_userdata

Result set_userdata(CDU key, CDU value)

The preceding function call stores arbitrary data supplied by the application under the key specified. There are no predefined values. If this instance already has data under that key, the new data replaces the old without comment. Essentially, user data is an associative array belonging to the album; an application can use it in any way.

start_derive

Waiter start_derive(CCB cb = NO_CALLBACK)

The preceding function call is the asynchronous version of derive.

virtual Waiter start_derive( Array (DU) attrlist, 

CCB cb = NO_CALLBACK)=0 ;

This function call is the asynchronous version of the derive function that accepts a list of attributes.

start_m_get

Waiter start_m_get(Array(DU) attrlist, CCB cb = 
NO_CALLBACK)

The preceding function performs an asynchronous CMIS M_GET. The scope and filter are built from the derivation string of the album. attrlist is the attribute list whose values need to be retrieved. The callback is called only once upon completion of the request.

start_m_set

Waiter start_m_set(Queue(AttrModifier)& attrmodq,
CCB cb = NO_CALLBACK,CDU sync = duBEST_EFFORT)

The preceding function performs an asynchronous CMIS M_SET. The scope and filter are built from the derivation string of the Album. The parameter attrmodq represents a set of attributes, operations on the attributes, and, depending on the operation, the new values of these attributes.

The callback is called only once upon completion of the request. The parameter sync is intended for further implementation to indicate whether the synchronization mode is best effort or atomic. Currently, the supported mode is best effort.

start_m_action

Waiter start_m_action(CDU name, CDU param = duNONE,
CCB cb = NO_CALLBACK,CDU sync = duBEST_EFFORT)

The preceding function performs an asynchronous CMIS M_ACTION. The scope and filter are built from the derivation string of the album. The name is the action name and param is the parameter associated with the action. The param is required in DataUnit format.

The callback is called only once upon completion of the request. The parameter sync is intended for further implementation to indicate whether the synchronization mode is best effort or atomic. Currently, the supported mode is best effort.

Waiter start_m_action_raw(CDU name, Morf param = Morf(),
CCB cb = NO_CALLBACK,CDU sync = duBEST_EFFORT)

start_m_action_raw

The preceding function performs an asynchronous CMIS M_ACTION. The scope and filter are built from the derivation string of the album. The name is the action name and param is the parameter associated with the action. The param is required in Morf format.

The callback is called only once upon completion of the request. The parameter sync is intended for further implementation to indicate whether the synchronization mode is best effort or atomic. Currently, the supported mode is best effort.

start_m_delete

Waiter start_m_delete(CCB cb = NO_CALLBACK)

The preceding function performs an asynchronous CMIS M_DELETE. The scope and filter are built from the derivation string of the album. The callback is called only once upon completion of the request.

Example

CODE EXAMPLE 3-6   start_m_get() and all_start() Method Utilization 
#include netdb.h
#include sys/systeminfo.h
#include stdio.h
#include hi.hh
#include message.hh
void done_cb( Ptr userData, Ptr );
void asyn_cb( Ptr , Ptr calldata);
int main( int argc, char **argv)
{
        // Get the host name from the environment variable.
        char *host = getenv("EM_SERVER");
        if (!host) {
                host = new char[MAXHOSTNAMELEN+1];
                sysinfo(SI_HOSTNAME, host, MAXHOSTNAMELEN);
        }
        // Set the fdn for the reference object.
        char fdn[1024];
        sprintf(fdn, "/systemId=name:\"%s\"/topoNodeDBId=NULL/LV(0)",host);
        Platform plat = Platform(duEM);
        if (plat.get_error_type() != PMI_SUCCESS) {
                cout << plat.get_error_string() << endl;
	 	 exit(1);
        }
        cout << "Connecting to ... " << host << endl;
        // Connect to the host MIS.
        if (!plat.connect(host, "em_sample")) {
                cout << "Failed to connect to "<< host << endl;
                cout << plat.get_error_string() << endl;
                exit(2);
        } else {
                cout << "Connected. " << endl;
        }
        // Construct test_album.
        Album test_album = Album("myalbum");
        if (test_album.get_error_type() != PMI_SUCCESS) 
{
                cout << test_album.get_error_string() << endl;
                exit(3);
        }
	 // fill up the derivation property
	 if (!test_album.set_derivation(fdn)) {
                cout << test_album.get_error_string() << endl;
                exit(4);
        }
       // fill up all kinds of properties on this album
	 if (!test_album.set_prop(duREPORT_ANY_ERROR,duYES)) 
{
                cout << test_album.get_error_string() << endl;
                exit(5);
        }
	 if (!test_album.set_prop(duREPORT_GET_LIST_ERROR,duYES)) {
                cout << test_album.get_error_string() << endl;
                exit(6);
        }
        if (!test_album.set_prop(duAUTOIMAGE,duYES)) {
                cout << test_album.get_error_string() << endl;
                exit(7);
        }
	 // populate the album with image
	 if (!test_album.derive()) {
                cout << test_album.get_error_string() << endl;
                exit(8);
        }
	 cout << "The album contents " << 
test_album.num_images() << " image(s)\n" << endl;
        // Will be set to 1 when Callback is done.
        int done = 0;
	 Waiter cur;
	 
        if 
(!(cur=test_album.all_start(DU("topoGetNodeReport"),DU("NULL"),Callback(done_cb, &done)))) {
                cout << test_album.get_error_string() << endl;
                exit(9);
        }
        if (cur.get_except()) {
                cout << cur.get_except()->reason() << endl;
                exit(10);
        }
        // subscribe to any future incoming replies
        cur.when_resp(Callback(asyn_cb,0));
        // Enter the listen loop to wait for asyn operation to complete
        cout << "Waiting for asyn operation to complete...\n";
        cout << endl << endl;
        while (!done) {
            dispatch_recursive(TRUE);
        }
        exit(0);
}
void done_cb( Ptr userData, Ptr )
{
        cout << "\nExecuting THE LAST asyn callback function..." << endl;
	 cout << "--------------------------------------------" << endl;
        cout << "After the operation is completed ";
        cout << "\n" << endl;
        // Set main done.
        (*((int*)userData))++;
}
void asyn_cb( Ptr , Ptr calldata)
{
static int num = 1;
        cout << "\nExecuting asyn1 callback function for ";
	 cout << num << " times";
        cout << endl;
	 cout << "----------------------------------------------" << endl;
	 num++;
        // Get and print the new attribute value.
        cout << "During the all_start operation ";
        cout << endl;
if(calldata)
	 {
        CurrentEvent ce(calldata);
        cout << "OBJNAME = " << ce.get_objname().chp() << endl;
        cout << "OBJCLASS = " << ce.get_objclass().chp() << endl;
        MessagePtr msg = (MessagePtr)ce.get_message();
	 if(msg->type()==ACTION_RES)
	 {
	 ActionRes* srmsg = (ActionRes*)msg;
	 cout << "OBJCLASS = " << oc2name(srmsg->oc).chp() << endl;
	 cout << "FDN = " << oi2fdn(srmsg->oi).chp() << endl;
	 cout << "ACTION-TYPE = " << endl;
	 (srmsg->action_type).print(stdout);
	 cout << "\n" << endl;
	 cout << "ACTION-REPLY = " << endl;
	 (srmsg->action_reply).print(stdout);
	 cout << "\n" << endl;
	 }
        Morf mf = ce.get_info_raw();
        Asn1Value val = mf.get_value();
        if(val)
        {
        cout << "info_raw() field of current event ACTION-REPLY = " << endl;
        val.print(stdout);
        cout << "\n" << endl;
        }
	 cout << "eventtype() field of current event ACTION-TYPE = " << ce.get_eventtype().chp() << endl;
        cout << "Information setting in the current event related Album " << endl;
        cout << "Derivation rule for the Album " << ce.get_album().get_prop(duNICKNAME).chp() << 
" is : " << ce.get_album().get_derivation().chp() << endl;
        cout << "\n" << endl;
        cout << "Information setting in the current event related Image" << endl;
        Image im = ce.get_image();
        cout << " image name is " << im.get_objname().chp() << endl;
        cout << " image class is " << im.get_objclass().chp() << endl;
        cout << " image state is " << im.get_state().chp() << endl;
        cout << " image last_error is " << im.get_last_error().chp() << endl;
        if (im.exists())
        cout << " image exists " << endl;
        else
        cout << " image does not exist " << endl;
	 cout << " attribute(s) and attribute value(s) setting in the image " << endl;
        Array(DU) attr_names = im.get_attr_names();
        for (int i=0; i<attr_names.size; i++) {
                char *name = strdup(attr_names[i].chp());
                cout << name;
                cout << ":  ";
                cout << im.get_str(name).chp() << endl;
        }
        cout << "\n" << endl;
	 }
}

when

Result when(CDU eventname,
     CCB cb = NO_CALLBACK)

The Platform object receives all events at which time all callbacks registered for by the Platform objects are executed. Next, all of the callbacks registered for by image objects are executed, then all of the callbacks registered for by album objects are executed.

The preceding function call establishes a callback routine to handle an album-specific asynchronous event.

For example, you might want to know if any object was destroyed. You could say:

when("OBJECT_DESTROYED",Callback(destroyed_cb, 0)) ;


Caution – For the same album (albums having the same nickname are the same), multiple callbacks for the same event type are not supported.

The Album events shown in TABLE 3-9 are supported.

TABLE 3-9   Events Supported by Album
Events Description
IMAGE_INCLUDED
An image was added to the album by some means. The new image is not automatically booted unless the AUTOIMAGE property was set. The CurrentEvent::do_something() function does nothing. This is an internal event, and has no MIS event info associated with it. Note: Use the method Image::exists() to see whether a given image from within IMAGE_INCLUDED exists.
IMAGE_EXCLUDED
An image was deleted from the album by some means or other. The CurrentEvent::do_something() function does nothing. Note that this is an internal event, and has no MIS event info associated with it.
OBJECT_CREATED
An object in the album came into existence.
Call CurrentEvent::do_something() to cause inclusion in a tracking album before the end of the callback.
OBJECT_DESTROYED
An object in the album was destroyed.
Call CurrentEvent::do_something() to cause exclusion in a tracking album before the end of the callback.
RAW_EVENT
Some album-related event occurred. You can examine it before the PMI does anything with it.
The CurrentEvent::do_something() function does nothing.


Refer to the description of the CurrentEvent::do_something and CurrentEvent::do_nothing member functions in Section 3.15.3 CurrentEvent Member Functions for more information on these CurrentEvent member functions.

3.10 AlbumImage Class

Inheritance: class AlbumImage

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

An instance of the AlbumImage class is an iterator that represents the current album in a list of albums or the current image in a list of images. It can also be viewed as a two-way association between a given image and a given album.

3.10.1 Constructors

Default Constructor

AlbumImage()

The default constructor creates an AlbumImage instance that refers to no actual AlbumImage. The value tests FALSE until you assign it a real AlbumImage value.

Copy Constructor

AlbumImage( AlbumImage& other)

This is an ordinary copy constructor. After the copy, both copies still refer to the same AlbumImage object. The reference count on the AlbumImage object is incremented.

3.10.2 Destructors

Default Destructor

~AlbumImage()

3.10.3 AlbumImage Operator Overloading

Assignment Operator

AlbumImage& operator = (const AlbumImage& other)

The assignment operator works like the copy constructor.

Cast Operator

operator void *()

The cast operator is for use in conditionals. It returns TRUE if this AlbumImage refers to an actual AlbumImage object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

Not Operator

int operator !()

This operator definition is provided so that you can say "if (!albumimage)..."

Album Operator

operator Album()

This returns the album pointed to by the current AlbumImage association.

Image Operator

operator Image()

This returns the image pointed to by the current AlbumImage association.

3.10.4 AlbumImage Member Functions

This section describes the member functions of the AlbumImage class.

next_album

Purpose: Return the next album.

This is used when iterating over all of the albums of an image.

AlbumImage next_album()

next_image

Purpose: Return the next image.

This is used when iterating over all of the images of an album.

AlbumImage next_image()

3.11 AppTarget Class

Inheritance: public Album

Data Members: No public data members are declared in this class.

3.11.1 Constructors

AppTarget::operator !()

AppTarget is an abstraction that represents target applications.

3.11.2 AppTarget Operator Overloading

The ! is overloaded to check whether the Album is NULL or non NULL.

3.12 AuthApps Class

Inheritance: class AuthPriv

#include pmi/auth_apps.hh

Data Members: No public data members are declared in this class.

This class is derived from AuthPriv, which is an abstract base class for this class as well as the AuthFeatures class.


Note – AuthPriv is not documented since it is not directly used.

This class is used when you need to know which applications a user is authorized to use. Currently, this is used by the Launcher application to gray out the application icons which the user is not authorized to use.

After the application has successfully connected to the platform (using Platform::connect), an instance of this class is passed as an argument to the Platform::get_authorized_apps method. The method fills in the instance with the information about the applications the user is authorized to use. After the successful completion of this method, one can use the AuthApps::is_authorized method to find out whether an application is authorized or not. For more information, please refer to the description of the Platform::get_authorized_apps method.

3.12.1 Constructors

AuthApps ()

The default constructor, above, creates an empty instance of this class which can be passed as an argument to the Platform::get_authorized_apps method.

3.12.2 AuthApps Operator Overloading

No public operators are defined for this class.

3.12.3 AuthApps Member Functions

The following are member functions for the AuthApps class.

all_authorized

Result all_authorized( ) const

This function determines if a given user has access to all applications or access to all the features of an application. This is an inherited function from the AuthPriv class.

is_authorized

Result is_authorized (const char 
*appname) const

Alternately,

 virtual Result is_authorized 
(const char *appname, 
const char *path) const;

This is an inherited function from the AuthPriv class. The function returns OK if the user is authorized to access the given application or its features. It should be called after successful completion of the Platform::get_authorized_apps function. Otherwise, it will always return NOT_OK.

3.13 AuthFeatures Class

Inheritance: class AuthPriv

#include pmi/auth_features.hh

Data Members: No public data members are declared in this class.

This class is derived from AuthPriv, which is an abstract base class for this class as well as the AuthApps class.


Note – AuthPriv is not documented because it is not directly used.

This class is used when you need to implement the feature level access control in your application. The application writer decides which features the application should have and what they control. The user who is running the application might not have access to all features. The application should query the list of features the user is authorized to use and accordingly restrict the operations the user can perform using the application.

After the application has successfully connected to the platform (using Platform::connect), an instance of this class is passed as an argument to the Platform::get_authorized_features method. This method fills in the instance with the information about the features the user is authorized to use. After the successful completion of the method, you can use the AuthFeatures::is_authorized method to find out whether a feature is authorized or not. For more information, please refer to the description of the Platform::get_authorized_features method. For an example program, please refer to $EM_HOME/src/access_sample/access_feature_leve l.cc.

3.13.1 Constructor

AuthFeatures ()

The default constructor, above, creates an empty instance of this class which can be passed as an argument to the Platform::get_authorized_features method.

3.13.2 AuthFeatures Operator Overloading

No public operators are defined for this class.

3.13.3 AuthFeatures Member Functions

The following are member functions for the AuthFeatures class.

all_authorized

virtual Result all_authorized () 
const

This function determines if a given user has access to all applications or access to all the features of an application. This is an inherited function from the AuthPriv class.

is_authorized

virtual Result is_authorized (const 
char *feature) const

Alternately,

virtual Result is_authorized (const 
char *appname, 
const char *path) const;

This is an inherited function from the AuthPriv class. The function returns OK if the user is authorized to access the given application or its features. It should be called after successful completion of the Platform::get_authorized_apps function. Otherwise, it will always return NOT_OK.

3.14 Coder Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

An instance of the Coder class specifies custom encoding and decoding functions for getting and setting the string value of a Morf or attribute. In general you would not call the methods of this class yourself. The PMI calls them when doing translation for various get_str and set_str operations. You set up these translation functions by deriving from the inner CoderData class, supplying virtual functions to do the appropriate translation, along with a virtual destructor to correctly destroy your CoderData. You can also declare other items in your derived class that are available to your routines.

The base CoderData class supplies an operator Coder to construct a Coder from a CoderData. Hence, the correct C++ incantation for creating a Coder is shown below.

Coder(*new OiCoderData(arg1, arg2...));

You then register the Coder with either Platform::set_attr_coder or Syntax::set_coder.

3.14.1 Constructors

Default Constructor

Coder()

The default constructor creates a Coder instance that refers to no actual Coder. The value tests FALSE until you assign it a real Coder value.

Copy Constructor

Coder(const Coder& other)

This is an ordinary copy constructor. After the copy, both copies still refer to the same Coder object. The reference count on the Coder object is incremented.

3.14.2 Coder Operator Overloading

Assignment Operator

Coder& operator = (const Coder& other)

The assignment operator works like the copy constructor.

Cast Operator

operator void*()

This cast operator is for use in conditionals. It returns TRUE if this Coder refers to an actual Coder object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

Not Operator

int operator!()

This operator definition is provided for conditionals such as:

	 if ( !albumimage ) ...

3.14.3 Coder Member Functions

This section describes the member functions of the Coder class.

get_str

Translate a Morf's value into a textual DU value.

DU get_str( Morf& mf, FBits fb )

set_str

Translate a textual DU value into a Morf's value.

Morf& set_str( Morf& mf, CDU data, FBits fb )

3.15 CurrentEvent Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

An instance of the CurrentEvent class represents all the information that is known about an asynchronous event, available in a form that doesn't require the arbitrarily dangerous casting of various pointer values. A CurrentEvent is passed into every callback function, and is also returned by the Waiter::wait function. Within a callback, control is available both before and after any action that the PMI itself would perform on your behalf.

TABLE 3-10   CurrentEvent Method Types 
Method Name Method Type
do_nothing
do_something
handled
Control PMI performance
get_event
get_event_raw
get_info
get_info_raw
get_message
get_name
get_oid
Extract event information
get_album
get_eventtype
get_image
get_objclass
get_objname
get_platform
get_time
Extract contextual information
something_to_do
Set control information
set_event_raw
set_info_raw
set_message
set_name
set_oid
Set event information (called primarily by the PMI)
set_album
set_eventtype
set_image
set_objclass
set_objname
set_time
Set contextual information (called primarily by the PMI)


3.15.1 Constructors

Default Constructor

CurrentEvent()

The default constructor creates a CurrentEvent instance that refers to no actual CurrentEvent. The value tests FALSE until you assign it a real CurrentEvent value.

Copy Constructor

CurrentEvent(const CurrentEvent& other)

This is an ordinary copy constructor. After the copy, both copies still refer to the same CurrentEvent object. The reference count on the CurrentEvent object is incremented.

Calldata Constructor

CurrentEvent( Ptr calldata)

This constructs a CurrentEvent from the calldata pointer passed into a callback as its second argument.

3.15.2 CurrentEvent Operator Overloading

Assignment Operator

CurrentEvent& operator = ( const CurrentEvent& 
other )

This assignment operator works like the copy constructor.

Cast Operator

operator void*()

This cast operator is for use in conditionals. It returns TRUE if this CurrentEvent refers to an actual CurrentEvent object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

Not Operator

int operator !()

This operator definition is provided for conditionals such as:

if ( !cur_event ) ...

3.15.3 CurrentEvent Member Functions

This section describes the member functions of the CurrentEvent class.

do_nothing

Purpose: Throw away the current event by removing callbacks from the CurrentEvent queue so that the PMI does nothing.

void do_nothing()

The PMI does not perform the action it would otherwise perform. This is meaningful only within a callback. If multiple objects receive callbacks for a given event (for example, one callback for an image, and one for the album containing the image), then each callback needs to call this function to disable the operations ordinarily done by the corresponding object.

Refer to TABLE 3-9 for information on how the member function CurrentEvent::do_nothing applies to the Album::when member function.

do_something

Purpose: Perform the customary action for this event by scheduling a callback in the CurrentEvent queue "something."

void do_something()

This is meaningful only within a callback. Before a callback is executed in response to an event, the PMI figures out what it wants to do and queues that operation using the something_to_do function. At the end of the callback, if you have not handled the event explicitly by calling either do_something or do_nothing, the PMI calls do_something on your behalf.

Refer to TABLE 3-9 for information on how the member function CurrentEvent::do_something applies to the Album::when member function.

get_album

Purpose: Return the associated album, if any.

Album get_album()

get_event

Purpose: Return, in textual form, the entire event message, if one exists.

DU get_event()

get_event_raw

Purpose: Return, in encoded form, the entire event message, if one exists.

Morf get_event_raw()

get_eventtype

Purpose: Return the type of event as specified by the when function that established the current callback.

DU get_eventtype()

get_image

Purpose: Return the image associated with this event, if one exists.

Image get_image(Boolean create = FALSE)

get_info

Purpose: Return, in textual form, the central event information.

DU get_info()

get_info_raw

The preceding function call returns in encoded form the central event information.

Morf get_info_raw()

get_message

Purpose: Return a pointer to the event message.

Ptr get_message()

This customarily returns a pointer to the event message, if one exists, though it could be used for any arbitrary data, depending on the event. You would not generally call this function unless you were in some fashion cheating on the PMI. The returned pointer is unlikely to be meaningful outside the scope of the CurrentEvent, but if you're already cheating, you probably know what to do about that.

get_name

Purpose: Return the name of the event.

Every event has a unique OID associated with it in its GDMO definition. The get_name method returns the English name which corresponds to this OID (CommunicationsAlarm, for example). Use get_oid to return the OID.

DU get_name()

The get_name method returns the actual event name, which is not necessarily the same as the one used in the when function call that caused the callback to be invoked. Calling get_eventtype returns the internal event name used in the when function call, such as RAW_EVENT, whereas get_name returns a real event name such as CommunicationsAlarm.

get_objclass

Purpose: Return the name of the class of the associated image, if it exists.

DU get_objclass()

get_objname

Purpose: Return the name of the associated image, if it exists.

DU get_objname()

get_oid

Purpose: Return the OID.

The get_oid method returns the OID corresponding to the event name, if one exists. Internal events like IMAGE_INCLUDED have no OID.

Oid get_oid()

get_platform

Purpose: Return the platform.

This returns the MIS platform associated with this event.

Platform get_platform()

get_time

Purpose: Return, in ISO format, the time of the event, if available.

DU get_time()

handled

Purpose: Determine if the CurrentEvent was handled.

Boolean handled()

The handled method returns TRUE if and only if either of do_something or do_nothing has been called on the CurrentEvent for the current callback.

set_album

Purpose: Set the associated album.

void set_album( Album& al )

set_event_raw

Purpose: Set the encoded event message.

void set_event_raw( Morf& mf )

set_eventtype

Purpose: Set the event type.

void set_eventtype( CDU eventtype )

set_image

Purpose: Set the associated image.

void set_image( const Image& im )

set_info_raw

Purpose: Set the central event information.

void set_info_raw( const Morf& mf )

set_message

Purpose: Set the message pointer.

void set_message( Ptr msg )

set_name

Purpose: Set the event name.

void set_name( CDU nm )

set_objclass

Purpose: Set the object class.

void set_objclass( CDU cl )

set_objname

Purpose: Set the object name.

void set_objname( CDU nm )

set_oid

Purpose: Set the event OID.

void set_oid( Oid& o )

set_time

Purpose: Set the time of the event.

void set_time( CDU tm )

something_to_do

Purpose: Queue up something to be done when do_something is called.

void something_to_do ( CCB cb, Ptr cdata )

Ordinarily the something_to_do method is called by the PMI before a callback is called, but you could use it to queue up additional operations to occur after the PMI calls do_something. It's usually easier, however, to call do_something yourself within the callback and then do whatever else needs doing.

3.16 Error Class

Inheritance: class Error

#include pmi/error.hh

The class Error stores details of errors related to an object instance of a derived-from-Error class, such as Image.

Example: If im1 is declared and used as follows:

Image im1 ;
im1.f1() ;

...then if f1() fails, the error string and type can be retrieved with:

im1.get_error_string() ;
im1.get_error_type() ;

For any function f1() of a class such as Image, if f1() is a static function, then no object is associated with that function. In such a case, you can use the variable error for error handling, where error is declared as:

Error error ;

Example: f2() is a static function, in the class Image, called as follows:

Image::f2() ;

If f2() fails you can query errors as follows:

error.get_error_type() ;
error.get_error_string() ;

3.16.1 Constructor

The syntax for the constructor for the Error class is:

Error(ErrorType etype=PMI_SUCCESS)

3.16.2 Error Operator Overloading

Assignment Operator

const Error &operator = ( const Error &err )

This assignment operator works like the copy constructor.

3.16.3 Error Public Data Member

The Error class has the following public data member:

static void (*error_entry_callback)(
Error *)

The pointed-to callback function, if set, is called after entering a function of a class that is derived from Error. If that object instance is already in error, it might be because a previous function call had failed.

3.16.4 Error Member Functions

This section describes the member functions of the Error class.

error_to_string

Purpose: Return the default error string for a type.

static const char *error_to_string( ErrorType etype);

get_error_string

char   *get_error_string(void) const

When performing operations that interact with several objects in the MIS, be aware that the operations are "best effort" operations (where access control allows, the operation will succeed) and get_error_string may return a message which is confusing. For example, if a user is not allowed access to at least one object in an album, the user will receive the message, "Can't do this operation: access denied" (assuming the access control behavior is denyWithResponse), even though the given operation will succeed for all objects to which the user has access.

get_error_type

ErrorType get_error_type(void) const

set_error_string

void   set_error_string(char *)

set_error_type

void   set_error_type(ErrorType)

set_error

void   set_error(ErrorType,char *)

reset_error

void   reset_error(void)


Note – All high level PMI calls must make use of the reset_error function to ensure that successive calls of the same type can succeed. For example, consider an Image::send_event() call which fails. If reset_error was not used in the call, successive send_event calls will fail with the same error message as the first, even if they would otherwise have succeeded.

set_error_entry_callback

static  void set_error_entry_callback(void (*eec)(Error 
*)=0)

3.16.5 Error Types and Strings

TABLE 3-11 shows the error types and strings returned by get_error_type() and get_error_string().

TABLE 3-11   Error Types 
Type Comment
MIS_ACCESS_NO_CONNECT_PRIVILEGE
Missing application connect privilege
MIS_ACCESS_USER_DOES_NOT_EXIST
Missing user profile
MIS_ACCESS_USER_NOT_MEMBER_OF_ANY_GROUP
User is not a member of any access control group
MIS_APP_INST_CREATE_FAILED
< /td>
Failed to create application instance
MIS_CONNECTION_PDU_PARSING_FAILED
< /font>
Failure during ape connect
MIS_CREATE_CALLBACK_FAILED
< /td>
Failure of ape instance to create callback
MIS_ERROR
Error in MIS (unexpected?)
MIS_INVALID_PASSWORD
Invalid password on MIS host
MIS_RESOURCE_LIMIT
Ran out of memory
MIS_USER_DOES_NOT_EXIST
User does not exist on MIS host
PMI_CONNECTION_REPLY_PARSING_FAILED
Data passed by an application is not in an expected format
PMI_DATA_OBJECT_OP_FAILURE
< /td>
Operation on associated data object failed
PMI_EM_LOGIN_DEAMON_PROBLEM
Check em_login daemon on MIS host
PMI_ENCODE_FAILED
Encoding of attribute failed
PMI_ERROR
Error
PMI_ILLEGAL_OPERATION
This operation cannot be performed on attribute
PMI_INVALID_ARGUMENT
Argument is not valid in this context
PMI_MESSAGE_SENDS_FAILED
Sending of message failed
PMI_NEW_FAILED
New memory allocation failed
PMI_NO_DATA_OBJECT
Data object associated with this object is NULL
PMI_NOT_IMPLEMENTED
This feature is not implemented
PMI_NULL_ARGUMENT
Argument passed OR attribute used is NULL
PMI_OPERATION_FAILED
Some operation failed
PMI_SUCCESS
Success
PMI_UNKNOWN_PLATFORM
Platform is unrecognized
PMI_USER_ABORTED_CONNECTION
Canceled password dialog


3.17 Image Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

An image is the local representation of a potential or actual framework object. If it represents an actual object, the image is capable of either manual or automatic synchronization. In many respects you can think of the image as the object itself, even though the actual object is off in the MIS, or even further away. Images give access to the object's methods and attributes.

The image provides a model in which data is primarily textual, but also allows raw data to be passed in the form of Morfs. Images also provide attribute-like access to object and attribute schema information.

TABLE 3-12   Image Method Types 
Member Function Method Type
first_album
is_in_album
num_albums
Determine album membership
find_by_nickname
find_by_objname
find_by_oi
Global lookup
boot
shutdown
start_boot
start_shutdown
Image Activation
get_prop
set_prop
Control Properties
get_userdata
set_userdata
User-defined information
set_nickname
set_objclass
Set object information
exists
get_objclass
get_nickname
get_objname
get_state
get_oi
get_oc
get_encoded_oi
Get object information
attr_changed
attr_exists
get_attr_names
get_attr_prop
get_attr_trackmode
set_attr_prop
Attribute information
get_attr_numerrors
get_attr_last_error
Get attribute error information
set
set_dbl
set_from_ref
set_gint
set_long
set_raw
set_str
Set imaginary attribute values
get
get_dbl
get_gint
get_long
get_raw
get_str
Get attribute values since last attribute value change event notification from the managed object
get_set
get_set_dbl
get_set_gint
get_set_long
get_set_raw
get_set_str
Get imaginary attribute values (before they've been stored)
revert
start_store
store
Realize or discard imaginary attribute values
create
start_create
Object creation, known name
create_within
start_create_within
Object creation, known container
destroy
start_destroy
Object destruction
call
call_raw
start
start_raw
Miscellaneous object method activation
get_param_syntax
get_result_syntax
Method data formats
get_when_syntax
when
Notification


3.17.1 Image Constructor

The Image class is designed as a wrapper for a set of related classes. Invoking any of the constructors for the Image class creates an instance of this wrapper class. Note that no methods should be applied to this new image object until the boot method is applied, that is, the Image is booted. After booting, the image object is initialized and methods can be applied to it.

Default Constructor

Image()

The default constructor creates an image instance that refers to no actual image object. The value tests FALSE until you assign it a real image value.
Copy Constructor

Image(const Image& im)

This constructor is an ordinary copy constructor. After the copy, both copies still refer to the same image object.
General Constructor

Image ( CDU objname,
	 CDU objclass = duNO_VALUE,
	 Platform& plat = 
Platform::default_platform() )

This constructor creates an image instance for a particular kind of MIS. Because an image is really a wrapper for a set of related classes, this function actually works a bit like a virtual constructor.
The objclass is required to create an object, if the object does not exist. If such an object is creatable, then boot() succeeds. If the object is not creatable, then boot() fails. Refer to the description of boot().
If the object pointed to by objname already exists, the objclass parameter is not required. The objclass is populated in the object whenever a get/set/delete response is received from the MIS.

3.17.2 Image Operator Overloading

Assignment Operator

Image& operator = 
(const Image& other)

The assignment operator, above, works like the copy constructor.

Cast Operator

operator void*()

The cast operator, above, is for use in conditionals. It returns TRUE if this image refers to an actual image object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

Not Operator

int operator !()

The not operator, above, is provided so that you can say "if (!image)..."

3.17.3 Image Member Functions

This section describes the member functions of the Image class.

attr_changed

Purpose: Determine whether an attribute has changed.

Boolean attr_changed( CDU name )

This method returns TRUE if the real value of the named attribute was modified.

Calling Sequence:

...
Image thing = Image(dn, clsnm);
CDU atnm = "abcXYZ" ; // Some valid attribute name for 
this class
...
if ( !thing.attr_changed( atnm 
) ) {
	 cout << "The attribute was modified.\n" ;
}

This notification refers only to a change reported in the last received notification from the MIS that an attribute was changed. The notification might be either an expected response to a store request of your own, or a somewhat-less-expected attribute change notification caused by someone else's store request. In the latter case, if you have asked for the ATTR_CHANGED notification, the image's real attributes do not change until the CurrentEvent::do_something function is called, either by you within the callback, or by the PMI after your callback returns. This allows you to get at the attribute values both before and after the change takes effect.

attr_exists

Purpose: Determine whether an attribute exists.

Boolean attr_exists( CDU name)

This function can return FALSE on an existing attribute if the value of EXISTS at that point is MAYBE.

Calling Sequence:

...
Image thing = Image(dn, clsnm);
CDU atnm = "abcXYZ" ; // Some valid attribute name for 
this class
...
if ( !thing.attr_exists( atnm 
) ) {
	 cout << "The attribute does not exist.\n" ;
}

boot

Purpose: Activate an image and determine whether the object exists.

Result boot( Array (DU) attrlist,
       Timeout to = DEFAULT_TIMEOUT)

Alternatively,

 Result boot(const Timeout to = DEFAULT_TIMEOUT);

If the object does exist, any attributes not marked IGNORE become available for the various get functions. (If it does not exist, you can set attributes, then make a create or create_within function call.) If TRACKMODE was set to TRACK, the image also begins tracking changes to its object. When the boot is complete, the STATE of the image is set to UP.

If you pass boot without an attribute list argument, all attributes will be returned. If, however, you pass boot with an empty attribute list argument (an argument which contains an empty set of attributes), it will send a get request to the MIS to determine if the object exists, but no attribute values will be returned in the get response. In this way, you can check for the existence of an object without incurring the overhead of retrieving attribute values.

Calling Sequence:

...
Image im(fdn);
if( !im.boot() ) {  // Boot 
an image without an attribute list.
            printf("Error in boot\n");
            return 2;
}

For a complete example, refer to the sample/image_boot.cc file.

For an existing object, if the class specified at the time of object construction is incorrect, this is an error, and boot() fails. Refer to the description of the Image constructors.

call

Purpose: Call a method for an image, with parameter as textual representation.

DU call( CDU name,
         CDU param = duNONE,
         const TIMEOUT to = DEFAULT_TIMEOUT)

Call a miscellaneous method for the managed object represented by this image. Both parameter and result are passed as textual data language.

In the syntax above, name is the name of the action. param is the parameter associated with the action. If param is not provided (or if it is set to duNONE), there is no parameter associated with this action specified in the GDMO.

The syntax of the parameter can be found using the get_param_syntax function. The syntax of the result is found using the get_result_syntax function. Action requests sent as a result of call are always sent with the confirmed bit set. To send unconfirmed action requests, please refer to Image::start(). This function (Image::start()) also sends unconfirmed action requests message when callback is NO_CALLBACK.

call_raw

Purpose: Call a method for an image, with parameter encoded.

Call a miscellaneous method for the managed object represented by this image. The parameter must be in encoded form.

Morf call_raw( CDU name,
               Morf param = Morf(),
               const TIMEOUT to = DEFAULT_TIMEOUT)

In the example above, name is the name of the action. param is the parameter associated with the action. If param is not provided (or if it is set to duNONE, there is no parameter associated with this action.

The syntax of the parameter can be found using get_param_syntax. The syntax of the result can be found using get_result_syntax. Action requests sent as a result of call are always sent with the confirmed bit set. To send unconfirmed action requests, please refer to Image::start().

create

Purpose: Create a managed object represented by a given image.

Result create( Image& refobj = Image(),
               const Timeout to = DEFAULT_TIMEOUT)

Calling Sequence:

Image thing = Image(dn,oc);
    before the next 
call, thing 
must be a valid image for an object. See 
create.cc
if ( !thing.create() ) {
                cout << "create failed" << 
endl;
                return 1;
        } else {
                cout << "create succeeded" 
<< endl;
        }

You cannot create an object that already exists; however, you can check if an object already exists before creating it .

For a complete example, refer to the sample/create.cc file.

The attributes of the new object are a combination of the attributes supplied in the imaginary object, plus any additional attributes supplied by the reference object (if one was supplied), plus any other attributes the MIS feels like creating.

The create function requires the following:

After the create, the OBJNAME property has been set to the actual complete object name, even if it was not specified completely before the create.

create_within

Purpose: Create an object in a container.

Within a specified container object, create, the managed object represented by the specified image.

Result create_within( CDU container_objname,
                   Image& refobj = Image(),
                   const Timeout to = 
DEFAULT_TIMEOUT)

For create_within(), first construct the image using the duNone constant as the instance name (instead of the fdn) as follows:

im = Image(duNone, object_class);
im.create_within(args ...);

Calling Sequence:

...
Image thing = Image(duNone,oc);
if ( !thing.create_within() ) 
{
                cout << "create_within failed" 
<< endl;
                return 1;
      }

Typically you would use this when you want the MIS to make up a name for your object, and you only want to specify the object's location. You cannot create an object that already exists, or you receive an Invalid exception. The attributes of the new object are a combination of the attributes supplied in the imaginary object, plus any additional attributes supplied by the reference object (if one was supplied), plus any other attributes the MIS feels like creating.

The create_within function requires the following:

After the create, the OBJNAME property is set to the actual complete object name, even though it was not specified before the create.

destroy

Purpose: Destroy the managed object represented by this image.

Depending on the semantics of the MIS at that point, this might also delete any children of the object in question, or it might refuse to delete anything if there are any children.

Result destroy(const Timeout to = DEFAULT_TIMEOUT)

Calling Sequence:

...
Image thing = Image(dn,oc); // Valid image of an object.
. . .
if ( !thing.destroy() ) {
           cout << "destroy failed" << endl;
           return 1;
    } else
           cout << "destroy succeeded" << 
endl;
}

exists

Purpose: Determine whether an object exists.

Given a booted image, determine whether a managed object exists.

Boolean exists()

Calling Sequence:

...
Image thing = Image(dn, clsnm);
...
thing.boot(); // Before you call exists(), must boot the 
image.
if ( !thing.exists() ) {
	 cout << "The object does not exist.\n" ;
}

This function can return FALSE on an existing object before the first boot, since at that point the value of EXISTS is MAYBE.

The following function call is equivalent to the above function call:

if ( !thing.get_prop("EXISTS") == "YES" ) {

find_by_nickname

Purpose: Find an image by its nickname.

Returns the value Image() if not found, which in a conditional evaluates to FALSE. All image nicknames are kept in a global registry.

static Image find_by_nickname( CDU name,
     Platform& plat = 
Platform::def_platform)

Calling Sequence:

...
CDU nicnam = "Server" ; 
Image thing = Image::find_by_nickname( nicnam ) ;
if ( !thing ) {
	 cout << "object not found" << endl;
	 return 1 ;
}

find_by_oi

Purpose: Returns an image for the object identified by the argument oi - the object instance.

static Image find_by_oi(CDU oi, Platform$p1)

This static function is equivalent to the following member functions of the Platform class:

Image find_image_by_oi(oi)

If the object exists, it will be returned as a result of the function invocation. If the object does not exist the value Image() will be returned.

find_by_objname

Purpose: Find an image by its object name.

Returns the value Image() if not found, which in a conditional evaluates to FALSE. All image object names are kept in a global registry.

static Image find_by_objname( CDU name,
     Platform& plat = 
Platform::def_platform)

Calling Sequence:

...
CDU objnam = "Server" ; 
Image thing = Image::find_by_objname( objnam ) ;
if ( !thing ) {
	 cout << "object not found" << endl;
	 return 1 ;
}

To guarantee that the image is created if not found, use the Image(objname) constructor.

first_album

Purpose: Return the first album containing the image.

The return value is in the form of an AlbumImage iterator.

AlbumImage first_album()

The AlbumImage::next_album function returns a next album until there are no more.

get

Purpose: Return the value of the attribute,

The attribute is formatted in data language, according to the implicit syntax of the attribute.

DU get( CDU name, FBits fb = 0) const

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
CDU atval = thing.get( atnam 
) ;

The syntax can specify either a list or a scalar. If the attribute is not present, a value of DU() is returned.

get_attr_names

Purpose: Get attribute names.

Return an array containing the names the attributes for this image. The image must be valid and booted before calling get_attr_names().

Array DU 
get_attr_names(Boolean all = 
FALSE )

If all is:

You can examine the EXISTS attribute property to see if the attribute exists in this image.

Calling Sequence:

thing.boot(); // thing must be a booted image before 
this next 
call.
Array(DU) attr_names = thing.get_attr_names();

For a complete example, see the sample/album.cc file.

get_attr_prop

Purpose: Get an attribute property.

Return a property key value of an attribute of the current image.

DU get_attr_prop( CDU attrname, CDU key)

Where, the attrname is an attribute name, the key is a property key, and the Return value is a property key value.

For instance, the property key TRACKMODE can have any one of the property key values IGNORE, SNAP, or TRACK. If key does not specify an existing property, a null DataUnit is returned, which tests FALSE in a conditional.

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnm = "abcXYZ" ;         // Some valid, existing 
attribute name
CDU propkey = "TRACKMODE" ;      // Or: CDU propkey = 
duTRACKMODE 
DU propval = get_attr_prop( atnm, 
propkey ) ;

Some common property keys and values are listed in TABLE 3-13.

TABLE 3-13   Properties Supported by Most Image Attributes
Property Key Values Description
TRACKMODE
IGNORE,
SNAP,
TRACK
This tells the PMI how to track an attribute. Track attributes are maintained by monitoring attribute change events from the MIS. IGNORE attributes are assumed to be uninteresting and never fetched. Attempts to fetch an ignored attribute result in an invalid exception.
In track mode, a PMI image is kept current based on Attribute Value Change notifications (AVCs). However, when tracking is off, AVCs are still issued but the image itself does not change
MOD_PENDING
IGNORE,
REPLACE,
INCLUDE,
EXCLUDE,
DEFAULT
This tells the PMI how to modify this attribute at the next store or start_store.
IGNORE is the initial value, indicating that this attribute is not to be modified.
REPLACE is the default set operation, and requests the MIS to do simple assignment using the supplied value.
INCLUDE and EXCLUDE request the MIS to perform set inclusion or exclusion on a multi-valued attribute. (On a single-valued attribute, produces an invalid exception.)
DEFAULT requests the MIS to set the attribute to its default value.
IGNORE_ALLOWED
REPLACE_ALLOWED
INCLUDE_ALLOWED
EXCLUDE_ALLOWED
DEFAULT_ALLOWED
YES,
NO
These read-only properties say whether you can perform the corresponding modification to this attribute. They are meaningful only if the MIS supplies the corresponding information. It's possible for an attribute to claim to be modifiable and yet the MIS refuses to modify it.
MODIFIABLE
YES,
NO
This read-only property is TRUE if any of REPLACE, INCLUDE, EXCLUDE, or DEFAULT are allowed.
EXISTS
YES,
NO,
MAYBE
This read-only property says whether this attribute is known to exist in the managed object represented by the image. Attributes with a TRACKMODE of IGNORE can remain in MAYBE state even though other attributes have been fetched.


get_attr_trackmode

Purpose: Get the attribute TRACKMODE.

Return the TRACKMODE property value for an attribute of the current image.

DU get_attr_trackmode( CDU attrname )

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted
CDU atnm = "abcXYZ" ;         // Some valid, existing 
attribute name
DU trkmd = thing.get_attr_trackmode( 
atnm ) ;

The following function call is equivalent to the one above:

DU trkmd = thing.get_attr_prop(atnm, "TRACKMODE") ;

get_attr_numerrors

Purpose: Get the number of attributes with outstanding errors.

Returns the number of attributes that have outstanding error messages resulting from the latest attempt to store.

U32 get_attr_numerrors()

Calling Sequence:

Image im ;
U32 n ;
 ...
n = im.get_attr_numerrors() 
// The im image must be booted.

get_attr_last_error

Purpose: Get last error message for this attribute.

Returns the error message associated with the last exception thrown by this attribute, or returned by the MIS.

DU get_attr_last_error(CDU attrname)

Calling Sequence:

Image im ;
CDU atnm = "abcXYZ" ; // Some valid attribute name
DU lem ;
lem = im.get_attr_last_error( atnm 
) ; // im must be booted.

get_dbl

Purpose: Get the attribute as a double.

Returns the value of the attribute formatted as a double. The Syntax must be a scalar and be consistent with a double representation. If the attribute is not present, a value of 0.0 is returned.

double get_dbl( CDU attrname )

Calling Sequence:

Image im ;
CDU atnm = "abcXYZ" ; // Some valid attribute name
double attrvalu = im.get_dbl( atnm 
) ; // im must be booted.

get_gint

Purpose: Get the attribute as a GenInt.

Returns the value of the attribute formatted as a GenInt (arbitrarily long integer). The Syntax must be a scalar and must be consistent with a GenInt representation. If the attribute is not present, a value of GenInt is returned.

GenInt get_gint( CDU attrname )

Calling Sequence:

Image im ;
CDU atnm = "abcXYZ" ; // Some valid attribute name
GenInt attrvalu = im.get_gint( atnm 
) ; // im must be booted.

get_long

Get the attribute as a long.

Returns the value of the attribute formatted as a long. The Syntax must be a scalar and be consistent with a long representation. If the attribute is not present, a value of 0 is returned.

long get_long( CDU attrname )

Calling Sequence:

Image im ;
CDU atnm = "abcXYZ" ; // Some valid attribute name
long attrvalu = im.get_long( atnm 
) ; // im must be booted.

get_nickname

Purpose: Get nickname of image.

Returns the nickname of the current image.

DU get_nickname()

The following function call is equivalent to the one above:

DU get_prop("NICKNAME") ;

Calling Sequence:

Image im ;
CDU ninm = im.get_nickname() 
; // im must be booted.

get_objclass

Purpose: Get class of object.

Returns the name of the class of the managed object represented by this image.

DU get_objclass()

The following function call is equivalent to the one above:

DU get_prop("OBJCLASS") ;

Calling Sequence:

Image im ;
DU obcl = im.get_objclass() ; 
// im must be booted.

get_objname

Purpose: Get object name.

Returns the full name of the managed object represented by this image in local distinguished name (LDN) format.

DU get_objname()

The following is equivalent to the above expression:

DU get_prop("OBJNAME") ;

Calling Sequence:

Image im ;
DU obnm = im.get_objname() ; 
// im must be booted.

get_oi

Purpose: Get the Managed Object Instance, in encoded ASN1 value format, for the instance of the managed object represented by the Image.

Asn1Value get_oi()

get_encoded_oi

Purpose: Get the Managed Object Instance, in human readable format, for the instance of the managed object represented by the Image.

DU get_encoded_oi()

get_oc

Purpose: Get the Managed Object Class of the Managed Object Instance represented by the instance of the Image.

DU get_set( CDU attrname, FBits fb = 0)

get_param_syntax

Purpose: Get the syntax for a method parameter.

Syntax get_param_syntax( CDU name)

For more information, refer to call and start under the description of Image.

Calling Sequence:

For the (arbitrarily chosen) object MDR and method getOidName:

Image im ("metaname=\"MDR\"") ;
im.boot() ;                       // im must be complete 
and booted.
Syntax sntx ;
sntx = im.get_param_syntax( DU 
("getOidName") ) ;

get_prop

Purpose: Get a property of the current image.

DU get_prop( CDU key)

Where, the key is a property key and Return value is a property key value

For instance, If you specify the property TRACKMODE, and there is such a property, then the function returns one of the values IGNORE, SNAP, or TRACK.

If you specify a key that does not match an existing property, then the function returns a null DataUnit, which tests FALSE in a conditional.

Calling Sequence:

Image thing ;
 ...
thing.boot() ;                 // thing must be complete 
and booted.
CDU propkey = "TRACKMODE" ;    // You can use 
duTRACKMODE 
DU propval = thing.get_prop( propkey 
) ;

Most images support at least the following properties:

TABLE 3-14   Properties Supported by Most Images 
Properties Description
OBJNAME
The full name of the managed object represented by this image. To find an existing object, you must set either this property or the NICKNAME.
OBJCLASS
The name of the class of the managed object represented by this image. You must set this property in order to create an object.
NICKNAME
The nickname of this image.
TRACKMODE
(SNAP,
TRACK)
How the PMI keeps track of the attribute value.
SNAP images are fetched when the image is booted, and then left alone. TRACK images are maintained by monitoring events from the MIS.


In track mode, a PMI image is kept current based on Attribute Value Change (AVC) notifications. However, when tracking is off, AVCs are still issued but the image itself does not change.
STATE
(DOWN,
BOOT,
UP,
SHUTDOWN)
The current state of the image. Read only. Initially, an image is DOWN. When you call boot or start_boot, the image enters BOOT state until the boot is done. The image then remains in the UP state until a shutdown or a start_shutdown is done. It remains in SHUTDOWN state until the shutdown is complete, at which time it is DOWN again.
EXISTS
(YES,
NO,
MAYBE)
Whether the object as a whole is real or imaginary. Before the first boot, the state is indeterminate. Real objects cannot be created (unless you enjoy getting the Conflict exception). Imaginary objects can only be created or used as a reference object for a set_from_ref. Attempting to get a real attribute value from an imaginary object results in the noshed exception.


get_raw

Purpose: Get the attribute value, encoded form.

Returns the attribute value in an MIS-specific encoded form.

Morf get_raw( CDU attrname)

Calling Sequence:

Image thing ;
 ...
thing.boot() ;                 // thing must be complete 
and booted.
CDU attrnam = "abcXYZ" ;       // Some valid attribute 
name 
Morf attrval = thing.get_raw( 
attrnam ) ;

get_result_syntax

Purpose: Get the syntax for a method result.

Syntax get_result_syntax( CDU name)

Calling Sequence:

Image thing ;
 ...
thing.boot() ;                 // thing must be complete 
and booted.
CDU methnam = "abcXyz" ;       // Some valid method name 
Syntax sntx = thing.get_result_syntax( methnam ) ;

For more information, refer to call and start under the description of Image.

get_set

Purpose: Gets imaginary value from last set rather than real value.

The get_set function is like get, but it returns the imaginary value from the last set rather than the real attribute value.

DU get_set( CDU attrname, FBits fb = 0)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
DU atval = thing.get_set( atnam 
) ;

get_set_dbl

Purpose: Get imaginary double value from last set.

The get_set_dbl function is like get_dbl, but it returns the imaginary value from the last set rather than the real attribute value.

double get_set_dbl( CDU attrname)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
dbl atval = thing.get_set_dbl( atnam 
) ;

get_set_gint

Purpose: Like get_gint, but returns the imaginary value.

The get_set_gint function is like get_gint, but it returns the imaginary value from the last set rather than the real attribute value.

GenInt get_set_gint( CDU name)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
GenInt atval = thing.get_set_gint( 
atnam ) ;

get_set_long

Purpose: Like get_long, but returns the imaginary value.

The get_set_long function is like get_long, but it returns the imaginary value from the last set rather than the real attribute value.

long get_set_long( CDU name)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
long atval = thing.get_set_long( 
atnam ) ;

get_set_raw

Purpose: Like get_raw, but returns the imaginary value from the last set.

The get_set_raw function call is like get_raw, but returns the imaginary value from the last set rather than the real attribute value.

Morf get_set_raw( CDU name)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
Morf atval = thing.get_set_raw( 
atnam ) ;

get_set_str

Purpose: Like get_str, but returns the imaginary value from the last set.

The get_set_str function is like an ordinary get_str, but returns the imaginary value from the last set rather than the real attribute value.

DU get_set_str( CDU name, FBits fb = 0)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
DU atval = thing.get_set_str( atnam 
) ;

get_str

Purpose: Get attribute as a string.

Returns the value of the attribute formatted as a string without quotes.

DU get_str( CDU attrname, FBits fb = 0)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
DU atval = thing.get_str( atnam 
) ;

The Syntax must be a scalar and be consistent with a string representation. It is legal to get a numeric value as a string, it is converted for you. In fact, it's legal to get_str anything. If get_str doesn't know anything special to do with the data, it calls get for you.

The default format bits (0) sometimes produce strings containing newline characters. You might want to suppress this by passing an fb argument of OMIT_NEWLINES.

By default, the choice specifier is not returned as part of the string for the get_str() function. USE_EXPLICIT_CHOICE should be used as the second argument of this function if you want the choice specifier in the returned value.

If you have registered a Coder for this attribute (or in the absence of that, for the Syntax of this attribute), then that Coder is used to decode the attribute in preference to the standard decoder (the value need not be a scalar value in this case).

get_userdata

Purpose: Get data the application stored under the key specified.

Returns any data the application might have stored under the key specified. There are no predefined values.

DU get_userdata( CDU key)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU atnam = "abcXYZ" ;            // Some existing 
attribute name
DU atval = thing.get_userdata( atnam 
) ;

If there is no data under that key for this instance, the return value (a null DataUnit) evaluates to FALSE.

get_when_syntax

Purpose: Get the syntax of a given event type.

Syntax get_when_syntax( CDU eventname)

Calling Sequence:

Image thing ;
 ..
thing.boot() ;                    // thing must be 
complete & booted.
CDU evnam = "abcXYZ" ;            // Some existing event 
name
Syntax sntx = thing.get_when_syntax( 
evnam ) ;

For a list of events, refer to the description of when, under the description of the Image class.

is_in_album

Purpose: Determine whether the image is in the album.

Returns TRUE if the image is contained in the album.

Boolean is_in_album( Album& album)

Calling Sequence:

Image thing ;
Album myalbum ;
 ...      // Before the next call, derive myalbum.
DU atval = thing.is_in_album( 
myalbum ) ;

U32 num_albums

Purpose: Get the number of albums that contain this image.

U32 num_albums()

Calling Sequence:

Image thing ;
thing.boot() ;
 ...
U32 na = thing.num_albums() ;

revert

Purpose: Cancel any pending sets.

Cancels any pending sets that have not yet been stored.

Result revert()

Calling Sequence:

Image thing ;
thing.boot() ;
 ...
thing.revert() ;

send_event

Purpose: Send event notifications to the MIS.

The image used in the send_event() call is the representation of the managed object that is generating the event notification (such as an alarm). This notification is sent to the MIS, from where it is forwarded to applications that are interested in events of this type.

The image instance (of which send_event() is a member) is the generator of the event. In using send_event(), a PMI application is acting in an agent role, since only agents generate events.

Before calling send_event(), keep in mind that:

When the value of tt is zero, the event is sent with the timestamp of "Now". Timestamp fields follow standard UNIX conventions:

Timestamp sent =
(tt->tm_year + 1900, tt->tm_mon + 1, tt->mday, 
tt->tm_hour, 
 tt->tm_min, tt->tm_sec);

set

Purpose: Set attributes.

The set function encodes the textual data you pass and modifies the value of the attribute using the encoded value.

Result set( CDU name, CDU val, CDU op = 
duREPLACE,
	 FBIts fb = 0)

Actually, it changes the imaginary value of the attribute. The real value is not changed until the next store. The data language is interpreted according to the syntax already implicit in the attribute. If the data cannot be so interpreted, an invalid exception is thrown. The syntax can specify either a list or a scalar. A series of set operations can be undone before the store by calling revert. Refer to the MOD_PENDING attribute property in TABLE 3-13 for a description of legal operations.

set_attr_prop

Purpose: Set a property of an attribute.

Sets a property of an attribute of the current image.

Result& set_attr_prop( CDU name, CDU key, CDU value)

Requirements:

If set_attr_prop cannot do what you ask, it throws an invalid exception. Refer to get_attr_prop, under the description of Image, for some typical properties.

set_dbl

Purpose: Modify an attribute using a double.

Encodes the double you pass and modifies the value portion of the attribute using the encoded value.

Actually, it changes the imaginary value of the attribute. The real value is not changed until the next store. The syntax of the attribute must be a scalar and permit a double representation, or an invalid exception is thrown.

Result set_dbl( CDU name,
	 double val,
	 CDU op 
= duREPLACE)

Refer to the MOD_PENDING attribute property in TABLE 3-13 for a description of legal operations.

set_from_ref

Purpose: Copy attribute values from an object to its current image.

Copies the attribute values from the reference object into the current image.

Result set_from_ref( Image& refobj)

The state of the reference object must be UP, but the reference object need not exist. If the reference object exists, then its real attributes are copied. Otherwise its imaginary attributes are copied. Attributes that receive existing values are automatically given a MOD_PENDING property of REPLACE. Attributes that receive nonexistent values are given a MOD_PENDING property of IGNORE.

set_gint

Purpose: Modify an attribute using a GenInt.

Encodes the arbitrarily long integer you pass and modifies the value portion of the attribute using the encoded value. Actually, it changes the imaginary value of the attribute. The real value is not changed until the next store.

Result set_gint( CDU name,  
	 GenInt& 
val,
	 CDU op 
= duREPLACE)

The syntax of the attribute must be a scalar and permit a GenInt representation, or an invalid exception is thrown. Refer to the MOD_PENDING attribute property in TABLE 3-13 for a description of legal operations.

set_long

Purpose: Modify an attribute using a long.

Encodes the long you pass and modifies the value portion of the attribute using the encoded value. Actually, it changes the imaginary value of the attribute. The real value is not changed until the next store.

Result set_long( CDU name,
	 long 
val,
	 CDU op 
= duREPLACE)

The syntax of the attribute must be a scalar and permit a long representation, or an invalid exception is thrown.

Refer to the MOD_PENDING attribute property in TABLE 3-13 for a description of legal operations.

set_nickname

Purpose: Set the nickname for an image.

Result set_nickname( CDU nickname)

The following is equivalent to the above:

Result set_prop("NICKNAME",nickname) ;

set_objclass

Purpose: Set the object class for an image.

Result set_objclass( CDU name)

The following is equivalent to the above:

Result set_prop("OBJCLASS",name) ;

set_prop

Purpose: Set a property of the current image.

Requirements:

If set_prop cannot do what you ask, it throws an invalid exception. Refer to get_prop under the description of the Album class, for some typical properties.

set_raw

Purpose: Load data into the imaginary value of an attribute.

The set_raw function loads a MIS-specific, encoded data value into the imaginary value of the attribute. If you later do a store, that updates the real value of the attribute.

Result set_raw( CDU attrname,
	 Morf& val,
	 CDU op 
= duREPLACE)

Refer to the MOD_PENDING attribute property in TABLE 3-13 for a description of legal operations.

set_str

Purpose: Encode a string and modify the attribute.

The set_str function encodes the string you pass and modifies the value portion of the attribute using the encoded value.

Actually, it changes the imaginary value of the attribute. The real value is not changed until the next store. The syntax of the attribute must be a scalar and permit a string representation, or an invalid exception is thrown. For choice type attributes, a choice specifier should be used.

Result set_str( CDU attrname,
	 CDU 
val,
	 CDU op 
= duREPLACE, FBits fb = 0)

Calling Sequence:

Image im ;
im.boot() ;
char dn[300]            = "logId=\"AlarmLog\"";
char class_name[300]    = "log";
char attribute_name[300]= "maxLogSize";
char set_val[300]       = "666666";
 ...
if(!im.set_str(attribute_name, 
set_val)) {
...

The difference between set_str and set is that the data language used by set requires quotes as part of the string, while set_str assumes them if necessary. (They're not always necessary; you can also pass numeric values as strings, and they are converted for you.) Refer to the MOD_PENDING attribute property in TABLE 3-13 for a description of legal operations.

If you have registered a Coder for this attribute (or in the absence of that, for the Syntax of this attribute), then that Coder is used to encode the attribute in preference to the standard encoder--the value need not be a scalar value in this case.

set_userdata

Purpose: Store data supplied by the application.

The set_userdata function stores arbitrary data supplied by the application, under the key specified.

Result set_userdata( CDU key, CDU value)

There are no predefined values. If there was already data under that key for this instance, it is replaced without comment. Essentially, this is an associative array belonging to the album that the application can use any way it pleases.

shutdown

Purpose: Deactivate an image.

The shutdown function deactivates an image and invalidates all locally cached attribute values.

...
Image im(fdn);
if( !im.boot() ) {  // Boot 
an image without an attribute list.
            printf("Error in boot\n");
            return 2;
}

A tracking image stops tracking. When complete, the image's STATE is set to DOWN.

start

Purpose: Provide an asynchronous version of call.

The start function is the asynchronous version of call. It sends an unconfirmed action request message when callback is NO_CALLBACK (the default).

Waiter start( CDU name, CDU param = duNONE, CCB 
cb = NO_CALLBACK)

start_boot

Purpose: Provide an asynchronous version of boot.

Waiter start_boot( CCB cb = NO_CALLBACK)

start_create

Purpose: Provide an asynchronous version of create.

Waiter start_create( Image& refobj = Image(),
CCB cb = 
NO_CALLBACK);

virtual Result start_create( Image& refobj = 
Image(), CCB cb 
= 
NO_CALLBACK)

start_create_within

Purpose: Provide an asynchronous version of create_within.

Waiter start_create_within( CDU container_objname,
	 Image& refobj = Image(),
	 CCB cb 
= NO_CALLBACK)

start_destroy

Purpose: Provide an asynchronous version of destroy.

Result start_destroy( CCB cb = NO_CALLBACK)

start_raw

Purpose: Provide an asynchronous version of call_raw.

Waiter start_raw( CDU name,
	 Morf param = Morf(),
	 CCB cb = NO_CALLBACK)

start_shutdown

Purpose: Provide an asynchronous version of shutdown.

Waiter start_shutdown( CCB cb = NO_CALLBACK);

start_store

Purpose: Provide an asynchronous version of store.

Waiter start_store( CCB &cb = NO_CALLBACK)

All start_store set requests are sent in unconfirmed mode when CCB is equal to NO_CALLBACK (the default).

store

Purpose: Update actual attributes using imaginary attributes.

The store function updates the actual object's attributes using any imaginary attributes that have been created by set and any others.

Result store( const Timeout to = DEFAULT_TIMEOUT)

See also start_store().

when

Purpose: Establish a callback routine.

The when function establishes a callback routine to handle an image-specific asynchronous event.

Result when( CDU eventname,
	 CCB cb 
= NO_CALLBACK)

The Platform object receives all events at which time all callbacks registered for by the Platform objects are executed. Next, all of the callbacks registered for by image objects are executed, then all of the callbacks registered for by album objects are executed.

For example, you might want to know if an attribute of the image changed. You might say:

when("ATTR_CHANGED", Callback(attr_change_cb, 0)) ;


Caution – For the same image, multiple callbacks for the same event type are not supported.

Image Events include:

TABLE 3-15   Image-specific Asynchronous Events
Events Description
OBJECT_CREATED
The object represented by this image was successfully created (not necessarily by us!).
OBJECT_DESTROYED
The object represented by this image was successfully destroyed (not necessarily by us!).
ATTR_CHANGED
An attribute of the object represented by this image has changed in value.
RAW_EVENT
Any object-related event can be examined as a raw event before ordinary event processing by the PMI.


3.17.4 Related Global Functions

fdn2formal

Purpose: Take a fully distinguished name in "/" notation and convert it into "{...}" notation.

When passed a fully distinguished name with fdn,the fdn2formal function returns the "{...}" notation value of the FDN.

extern DU fdn2formal(CDU fdn);

fdn2oi

Purpose: Return the ASN1 encoded value for a fully distinguished name.

The fdn2oi function returns the encoded FDN if successful, otherwise NULL.

extern Asn1Value fdn2oi(CDU fdn);

name2oc

Purpose: Return the ASN1 encoded form of an object class, given the name in textual form.

The name2oc function returns the encoded object class if successful, otherwise NULL.

extern Asn1Value name2oc(DU oc);

oc2name

Purpose: Return the name of an object class.

If successful, the oc2name function returns the object class name.

extern DU oc2name(const Asn1Value& av);

oi2fdn

Purpose: Return the decoded FDN string, given the encoded FDN.

If successful, the oi2fdn function returns the decoded FDN string in "/" format.

extern DU oi2fdn(Asn1Value av);

3.18 Morf Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

A Morf is a reference-counting wrapper around an abstract base class--MorfData. Each framework derives a new class from the base class and provides the implementation for manipulating that type of data in the context of the framework. Each instance of the derived class contains an opaque, encoded value along with the information necessary for the PMI to decode it.

In the context of Asn1 encoded values, an instance of a Morf class contains an Asn.1 encoded value that can be retrieved as an Asn1Value instance through the Morf methods (e.g. get_value). The Morf class also contains an instance of the Syntax class, which specifies the type associated with the value.

As noted in their individual descriptions, some of this class's methods require a list argument, some a scalar, and some accept both.

TABLE 3-16   Morf Method Types 
Method Name Data Domain Method Type
void*
=
==
!=


Operator Overloading
get_platform
get_syntax
get_type
has_value
ref
Defined type or list
Get information about an existing morf
is_any
is_choice
is_list
is_set
is_sequence
Defined type or list
Distinguish syntax types
extract
get_member_names
num_elements
split_array
split_queue
List only
Pull apart list morfs
set
Defined type or list
Set the data value of an existing morf
set_any
set_dbl
set_gint
set_long
set_str
set_value
Defined type only






Defined type or list
Set the data value of an existing morf
get()
get_bit_string_identifiers()
get_dbl
get_gint
get_long
get_str
get_size_constraint()
get_value
Defined type only






Defined type or list
Get the data value from an existing morf
get_memname
set_memname
Choice only



3.18.1 Constructors

Morf()

The default constructor creates a Morf instance that refers to no actual morf. The value tests FALSE until you assign it a real morf value.

Morf(Syntax& syn)

The preceding constructor constructs a Morf instance for a particular kind of syntax. Since a Morf is reall a wrapper for a set of related classes, this function actually works like a virtual constructor. The newly constructed Morf will have an associated Syntax (passed as the argument), but no associated value.

Morf(const Morf& other)

The preceding constructor is a copy constructor. After the copy, both copies still refer to the same underlying MorfData object. The reference count on the morf object is incremented.

Morf(Syntax& syn, DU data)

The preceding constructor constructs a Morf instance for a particular kind of syntax, which implies a particular kind of MIS. Because a morf is really a wrapper for a set of related classes, this function actually works something like a virtual constructor. The textual data supplied as the second argument is parsed according to the syntax supplied, so you can create either defined type or list morfs with this function.

Morf(Syntax& syn, ArrayMorf& ma)

The preceding constructor constructs a Morf instance for a particular kind of syntax. Because a Morf is really a wrapper for a set of related classes, this function actually works rather like a virtual constructor. The newly constructed Morf will be associated with the specific Syntax that was passed as the first argument. Because an array of Morf is supplied as the second argument, only list Morf can be created with this function. The value associated with the newly constructed Morf will be constructed from the values of the Morf array elements, passed as the second argument.

Morf(Syntax& syn, class QueueMorfElem& mq)

The preceding constructor constructs a Morf instance for a particular kind of syntax. Because a Morf is really a wrapper for a set of related classes, this function actually works like a virtual constructor. The newly constructed Morf will be associated with the specific Syntax that was passed as the first argument. Because a queue of MorfElems is supplied as the second argument, only list Morf can be created with this function. The value associated with the newly constructed Morf will be constructed from the values of the MorfElems, passed as the second argument.

Morf( CDU attrname, 
Platform& plat = 
Platform::def_platform)

The preceding constructor constructs a Morf instance for a particular kind of attribute, which implies a particular syntax. The attrname passed as the first argument does not imply any specific instance of that attribute. Another way to accomplish this is to create an image for an object of the type containing the attribute in question, and then extracting the Morf corresponding to that attribute. This constructor, however, can be used even when the attribute passed as the first argument is not associated with any specific class.

Morf( Ptr ptrdata, Boolean reuse = FALSE)

The preceding constructor constructs a Morf instance from a void* pointer created by the ref method. It is primarily for internal PMI use within callbacks, when the callback can occur after the original morf has gone out of scope, and would ordinarily have been deleted. Each call to ref increments a reference count, and each construction of a morf using this constructor eventually causes the reference count to be decremented again when the morf is destructed at the end of the callback. If multiple callbacks are to use the same pointer, then pass a reuse parameter of TRUE on all but the last callback (or call ref again within the callback) to keep the reference alive till the next callback.

3.18.2 Destructor

~Morf()

The destructor will decrement the reference count on the MorfData object, associated with the Morf object. If the reference count reaches 0, the destructor on the associated MorfData object is invoked.

3.18.3 Morf Operator Overloading

Morf& operator = (const Morf& other)

The assignment operator works like the copy constructor.

operator void*()

The preceding cast operator is for use in conditionals. It returns TRUE if this Morf refers to an actual morf object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

int operator !()

The preceding function is provided so that you can say "if (!morf)..."

int operator == (const Morf& other)

The preceding comparison operator returns TRUE if the two compared morfs are equivalent in value. The definition of "equivalent" depends on the MIS system type. Some values might be impossible to compare. The operator will test for equivalency of the values associated with the two compared morfs, if both values are interpreted to be of the specific type associated with the Morf.


Note – The type is implicitly associated with the Morf through the contained Syntax object.

int operator != ( const Morf& other)


The preceding comparison operator returns TRUE if the two compared morfs are not equivalent in value.

3.18.4 Morf Member Functions

This section describes the member functions of the Morf class.

extract

Morf extract( DU navigation)

The extract function extracts a morf from a tree of morfs. The navigation parameter is a string containing a dot-separated list of field names or position numbers. A position number (with the exception of 0) is an integer that represents the offset of a morf, or element, in a list of morfs. The position number 0 returns the number of elements in the list at that level of the tree. In the case of Asn.1 encoded morfs, the following conventions are followed:

For example, consider a morf, itself containing four morfs. If you call extract on the morf with the navigation parameter set to 0, the function will return a morf which can be checked over for the number of elements in the list.

Consider next a morf, itself containing five morfs, the third of which contains some arbitrary number of morfs, one of which happens to be called "attributevalue". To extract the morf "attributevalue", simply call extract on the original morf with the navigation parameter set to the string "3.attributevalue".

By manipulating the navigation parameter in this way, it is possible to refer to any morf in a tree of morfs. The string "3.6.2.attributevalue", for example, would refer to a morf called "attributevalue" that was four levels down in a tree of morfs.

The extract function is valid only for a morf that describes a list of values (or a choice). If called on a defined type morf it throws an invalid exception. When called on a choice value with a null navigation string, it returns a morf of the current inner type rather than the outer choice type.

Example: Use extract to find a component in a complex morf.

// If the object instance exists,
// get the value for attribute topoNodeMOSet,
// and construct a Morf.
Morf m = im.get_raw("topoNodeMOSet");
if (m.get_error_type() != PMI_SUCCESS) {
                cout << "Reason: ";
                cout << m.get_error_string() 
<< endl;
                exit(5);
}
 
Morf newm =     m.extract("1");
cout << "Using 1" << endl;
cout << newm.get_str().chp() << endl;
// Print out the attribute value
// before using Morf to split.
 
cout << "Using 1.distinguished " << endl;
newm =  m.extract("1.distinguishedName");
cout << newm.get_str().chp() << endl;
 
cout << "Using 1.distinguishedName.1" << 
endl;
newm =  m.extract("1.distinguishedName.1");
cout << newm.get_str().chp() << endl;
 
cout << "Using 1.distinguishedName.1.1" << 
endl;
newm =  m.extract("1.distinguishedName.1.1");
cout << newm.get_str().chp() << endl;
 
cout << "Using 
1.distinguishedName.1.1.attributeValue" << endl;
newm =  
m.extract("1.distinguishedName.1.1.attributeValue");
cout << newm.get_str().chp() << endl;

get

DU get(FBits fb = 0) const

The preceding function call returns the value of the morf formatted in data language according to the implicit Syntax of the morf. The Syntax can describe either a list or a defined type. Various format bits can be OR'ed together to influence the form of output. If the morf has no value, DU() is returned.

get()

Asn1Type get()

If applied on a Morf object that has the underlying syntax of an ENUMERATED type, this function returns the identifier string associated with the ENUMERATED value.

The same applies to the Morf::get_str() function.

CODE EXAMPLE 3-7 returns the identifier string associated with the enumerated value as defined in the asn1 document.

CODE EXAMPLE 3-7   Morf::get() Example
Morf mrf; 
// Assuming that morf is initialized to an ENUMERATED type attribute
cout << "The value of the morf is " << mrf.get().chp() << endl;

get_bit_string_identifiers()

virtual Result all(Result 
(*f)( Image 
&im, 
void* data),
     void* data = 0)

This method returns a reference to an array of type Asn1NamedNumber, which holds the identifiers and associated position for the ASN.1 BIT STRING type. If this method fails, it returns NOT_OK; otherwise, returns OK.

A sample program describing the use of the get_bit_string_identifiers method is in CODE EXAMPLE 3-8

CODE EXAMPLE 3-8   Morf::get_bit_string_identifiers() Example 
void show_idents(Array(Asn1NamedNumber) &idents) {
	 Asn1TypeInt             int_type(AK_INTEGER);
 	 DU ident;
	 GenInt  numbvalue;
	 U32 i, orig_size;
	  Asn1Value asn1number;
	 Asn1ParsedValue number;
	 orig_size = idents.size;
	 cout << "Number of identifiers is " << orig_size << " ;" << endl;
	  for (i = 0; i<orig_size; i++) {
	 	 	 number = idents[i].num;
	 	 	  ident = idents[i].name;
	 	 	  if (number) {
	 	 	 	 asn1number = number.get_real_val(int_type);
	 	 	 	 asn1number.decode_int(numbvalue);
	 	 	 }
	 	 	 cout << "Identifier # =>" << i << " Name is => ";
	 	 	 cout << ident.chp() << " ;";
	 	 	 cout << " Identifier position is => ";
	 	 	 if (number) {
	 	 	 	 cout << I32(numbvalue);
	 	 	 } else {
	 	 	 	 cout << "NULL";
	 	 	 }
	 	 	 cout << " ;" << endl;
	 }
}
void show_bit_string_identifiers(Asn1Type rrrtype1) {
	 Result rslt;
	 Array(Asn1NamedNumber) newidents;
	 rslt = rrrtype1.get_bit_string_identifiers(newidents);
	 if (rslt == OK) {
	 	 	 show_idents(newidents);
	 } else {
	 	 	 cout << "get_bit_string_identifiers returned NOT_OK!" << endl;
	 }
}

get_dbl

double get_dbl()

The preceding function call returns the value of the morf formatted as a double. The Syntax must describe a defined type and be consistent with a double representation. Otherwise an invalid exception is thrown. If the morf has no value, 0.0 is returned.

get_gint

GenInt get_gint()

The preceding function call the value of the morf formatted as a GenInt (arbitrarily long integer). The Syntax must describe a defined type and be consistent with a GenInt representation. Otherwise an invalid exception is thrown. If the morf has no value, GenInt() is returned.

get_long

long get_long()

The preceding function call returns the value of the morf formatted as a long. The Syntax must describe a defined type and be consistent with a long representation. Otherwise an invalid exception is thrown. If the morf has no value, 0 is returned.

get_member_names

ArrayDU 
get_member_names()

The preceding function call returns the member names (field names) for a list value. For a choice value, it returns the member names of an inner list, presuming that the current value of the choice is a list value. To get the choice names themselves, you must use get_syntax and get_member_names instead.

get_memname

DU get_memname()

The preceding function call returns the name of the member (field) currently held by the morf. Valid only for members of lists and choices. (The morf itself need not be a list or choice.)

get_platform

Platform get_platform()

The preceding function call returns the Platform of the Syntax that is implicitly bound into the morf. Valid either for a morf that describes a defined type value or a list of values.

get_size_constraint()

Result get_size_constraint(Asn1ParsedValue &lower,
                   Boolean           &lower_open,
                   Asn1ParsedValue   &upper,
                   Boolean           &upper_open
) const;

If this method is applied on an Asn1Type object that represents an ASN.1 type different from BIT STRING, OCTET STRING, SEQUENCE OF or SET OF, the method returns NOT_OK. If the invocation is successful, the method returns OK. In addition, this method returns, by reference, the lower and upper size constraints defined on a subtype of a BIT STRING, OCTET STRING, SEQUENCE OF, or SET OF base type as variables of type Asn1ParsedValue, and the lower_open and upper_open Boolean variables that specify whether the corresponding size constraint is open or closed. If the size constraint is open, the lower_open and upper_open variables are set to TRUE; otherwise, these two variables are set to FALSE.

The X.208 standard defines size constraints on BIT STRING, OCTET STRING, SEQUENCE OF, and SET OF types. In addition, the X.208 standard uses MIN and MAX to specify lower and upper constraints respectively.

MIN specifies the lower constraint defined for the parent type. MAX specifies the upper constraint defined for the parent type The PMI library encodes MIN and MAX as NULL Asn1ParsedValue values. Therefore, after invoking the get_size_constraint method, you must check whether the returned values for the upper and lower size constraints are NULL, before attempting to decode them (see CODE EXAMPLE 3-9).
CODE EXAMPLE 3-9 decodes and prints size constraints for BIT STRING, OCTET STRING, SEQUENCE OF, or SET OF types.

CODE EXAMPLE 3-9   Morf::get_size_constraint() Example 
void show_size_constraint(Asn1Type type1) {
	 char  buf1[5000], buf2[5000],
	 	 	 *buf1p = buf1, *buf2p = buf2;
	 U32   buf1len = 5000, buf2len = 5000;
	 Asn1TypeInt             int_type(AK_INTEGER);
	 Result rslt;
	 U32         i;
	 Asn1Value  asn1lower, asn1upper;
	 Asn1ParsedValue  lower, upper;
	 GenInt low, up;
	 Boolean lower_open, upper_open;
	 rslt = type1.get_size_constraint(lower, lower_open, upper, upper_open);
	 if (rslt == OK) {
	 	 	 cout << "get_size_constraint was successfull!" << endl;
	  } else {
	 	 	 cout << "get_size_constraint failed - NOT_OK!" << endl;
 	 	 	 return;
	 }
	 {
	 	 	 if (lower) {
	 	 	 	 asn1lower  = lower.get_real_val(int_type);
	 	 	 	 asn1lower.decode_int(low);
	 	 	 	 buf2len = 5000;
	 	 	 	 buf2p = buf2;
	 	 	 	 int_type.format_value(asn1lower, buf2p, buf2len,
	 	 	 	 	 	 0, TAG_EXPLICIT,DataUnit(),
 	 	 	 	 	 	 0);
 	 	 	 	 cout << "value of lower is "<<buf2<<" !"<<endl;
	 	 	 	 //  cout << "value of low is "<<I32(low)<<" !"<<endl;
	 	 	 	 if (lower_open == TRUE) {
	 	 	 	 	 	 cout << "lower range is open !" << endl;
	 	 	 	  } else {
	 	 	 	 	 	 cout << "lower range is closed !" << endl;
	 	 	 	 }
	 	 	 } else {
	 	  	 cout << "value of lower is MIN !" << endl;
	 	 	 }
	 }
	 {
	 	 	 if (upper) {
	 	 	 	 asn1upper  = upper.get_real_val(int_type);
	 	 	 	 asn1upper.decode_int(up);
	 	 	 	 buf2len = 5000;
	 	 	 	 buf2p = buf2;
	 	 	 	 int_type.format_value(asn1upper, buf2p, buf2len,
	 	 	 	 	 	 0, TAG_EXPLICIT,DataUnit(),
	 	 	 	 	 	 0);
	 	 	 	 cout << "value of upper is "<<buf2<<" !"<<endl;
	 	 	 	 //  cout << "value of up is "<<I32(up)<<" !"<<endl;
	 	 	 	 if (upper_open == TRUE) {
	 	 	 	 	 	 cout 
<< "upper range is open !" << endl;
	 	 	  } else {
	 	 	 	 	 	 cout << "upper range is closed !" << endl;
	 	 	 	 }
	     	 } else {
	   	 	 	 cout << "value of upper is MAX !" << endl;
	 	 	 }
	 }
}

get_str

DU get_str( FBits fb = 0)

The preceding function call returns the value of the morf formatted as a string (without quotes). The Syntax must describe a defined type and be consistent with a string representation. It is legal to get a numeric value as a string; it is automatically converted for you. In fact, any value is legal. If the type is unrecognized, get_str calls get for you. If the morf has no value, DU() is returned.

The default format bits (0) sometimes produce strings containing newline characters. You might want to suppress this by passing an fb argument of OMIT_NEWLINES.

If you have registered a Coder for this morf's attribute (or in the absence of that, for the Syntax of this morf), then that Coder is used to decode the value in preference to the standard decoder. (The value need not be a defined type value in this case.) For more information, refer to set_attr_coder under the description of the Platform class, and set_coder, under the description of the Syntax class.

get_syntax

Syntax get_syntax()

The preceding function call returns the Syntax that is implicitly bound into the Morf. Valid either for a morf that describes a defined type value or a list of values.

get_type()

Asn1Type get_type()

This method returns the underlying Asn1Type object associated with a Morf object. If the Morf object is not initialized, the method returns a NULL Asn1Type (see CODE EXAMPLE 3-10)

CODE EXAMPLE 3-10   Morf::get_type() Example
Morf tstmrf = Morf();
Asn1Type tsttype = tstmrf.get_type();
if (tsttype) {
    cout << "The Asn1Type is initialized!" << endl;
} else {
    cout << "The Asn1Type is not initialized!" << endl;
}

get_value

Asn1Value get_value()

The preceding function call returns the encoded value stored in the morf, if any. No attempt is made, at this point, to validate the value against the type associated with the morf.

has_value

void* has_value()

The preceding function call returns a pointer to the internal, MIS-specific value, if any. Otherwise, returns 0. Note that this differs from operator void*(), which can return TRUE even when the morf contains only a Syntax with no value.

is_any

Boolean is_any()

This function returns TRUE if the type of the data is of the type "ANY DEFINED BY" from the GDMO definition of the object.

is_choice

Boolean is_choice()

The preceding function call returns TRUE if the Syntax of the morf describes a choice value. A choice value can have any one of a number of types of value. (The get_memname function tells you which kind of value the current morf is holding.) Valid either for a morf that describes a defined type value or a list of values.

is_list

Boolean is_list()

The preceding function call returns TRUE if the Syntax of the morf describes a compound data value, and FALSE if it describes a defined type value. Valid either for a morf that describes a defined type value or a list of values. Note that a list with only one element, or zero elements, is still a list and not a defined type.

is_sequence

Boolean is_sequence()

The preceding function call returns TRUE if the type of the data describes a compound data value that contains an ordered list of zero or more members.

is_set

Boolean is_set()

The preceding function call returns TRUE if the type of the data describes a compound data value that contains an unordered list of zero or more members.

num_elements

U32 num_elements()

The preceding function call returns the number of elements in the morf's list. Valid only for a morf that describes a list of values.

ref

Ptr ref()

The preceding function call returns a reference-counted (refcnt) void* pointer to this morf, from which you must, at some future time, reconstruct the morf using the Morf(Ptr, Boolean) constructor. Refer to that constructor description earlier in this section for further information.

set

Morf set( CDU data, Fbits fb = 0)

The preceding function encodes the textual data you pass and replaces the value portion of the morf with the encoded value. The data language is interpreted according to the Syntax already implicit in the morf. If the data cannot be so interpreted, an invalid exception is thrown. The Syntax can describe either a list or defined type.

set_any

Morf set_any( Morf& data)

This function returns TRUE if the type of the data contained in the morf is of the type "ANY DEFINED BY" from the GDMO definition of the object. The morf data is provided in data.

set_dbl

Morf set_dbl( double data)

The preceding function call encodes the double you pass and replaces the value portion of the morf with the encoded value. The Syntax of the morf must be a defined type and should permit a double representation, or an invalid exception is thrown.

set_gint

Morf set_gint(GenInt& data)

The preceding function call encodes the GenInt you pass and replaces the value portion of the morf with the encoded value. (A GenInt is an arbitrarily long integer.) The Syntax of the morf must be a defined type and permit a GenInt representation, or an invalid exception is thrown.

set_long

Morf set_long(long data)

The preceding function call encodes the long you pass and replaces the value portion of the Morf with the encoded value. The Syntax of the morf must be a defined type and should permit a long representation, or an invalid exception is thrown.

set_memname

Result set_memname(CDU name)

The preceding function call sets the name of the member (field) currently held by the morf. Valid only for members of a choice type. The old value of the morf is discarded.

set_str

Morf set_str( CDU data, FBits fb = 0)

The preceding function call encodes the string you pass and replaces the value portion of the morf with the encoded value. The Syntax of the morf must be a defined type and permit a string representation, or an invalid exception is thrown.

The difference between set_str and set is that the data language used by set requires quotes as part of the string, while set_str assumes them if necessary. (They're not always necessary; you might also pass numeric values as strings, and they are converted for you.)

If you have registered a Coder for this morf's attribute (or in the absence of that, for the Syntax of this morf), then that Coder is used to encode the value in preference to the standard encoder. (The value need not be a defined type value in this case.) For more information, refer to set_attr_coder under the description of the Platform class, and set_coder, under the description of the Syntax class.

set_value

void set_value(Asn1Value& data)

The preceding function call sets the encoded value into the morf. Checking is not performed on the value (so that it is not validated, at this point, against the type associated with the morf).

split_array

Array Morf 
split_array()

The preceding function call returns the elements of a list morf in Array form, such that they can be indexed numerically.

Valid only for a morf that describes a list of values. If called on a defined type morf, it throws an invalid exception.

split_queue

class :/Queue 
MorfElem split_queue()

The preceding function call returns the elements of a list morf in Queue form, such that they can be processed with ordinary Queue commands. Valid only for a morf that describes a list of values. If called on a defined type morf it throws an invalid exception.

3.19 MorfBuilder Class

Inheritance: None

#include extpmi/exthi.hh

Data Members: No public data members are declared in this class.

The MorfBuilder class is a utility wrapper built on top of the Morf class. MorfBuilder provides more flexibility in dealing with Morf objects that represent constructed types (SET, SET OF, SEQUENCE, and SEQUENCE OF) and minimizes the amount of coding you have to do.

For example, using MorfBuilder objects, you can create empty Morf objects for a constructed type and incrementally update the fields of the underlying Morf object. This functionality is not supported at the Morf object level.

3.19.1 Constructors

MorfBuilder ( Morf& morf )

The preceding constructor creates a MorfBuilder instance that contains a Morf object and implicitly refers to that Morf object in most MorfBuilder methods. Initially, the Morf object contained in the new MorfBuilder instance has the same syntax and Asn1Value as morf. The syntax of the underlying Morf object does not change throughout the life of the MorfBuilder object. The underlying Morf object's Asn1Value, however, can be modified using the MorfBuilder object's methods.

MorfBuilder (Syntax& syn )

This constructor creates a MorfBuilder instance that contains a Morf object and implicitly refers to this Morf object in most MorfBuilder methods. Initially, the Morf contained in the new MorfBuilder instance has the same syntax as syn and an empty Asn1value.

The syntax of the underlying Morf object does not change throughout the life of the MorfBuilder object. The underlying Morf object's Asn1Value, however, can be modified using the MorfBuilder object's methods.

Morf& set_str( Morf& mf, CDU data, FBits fb )

The preceding constructor is a copy constructor. After the copy operation is completed, the newly created MorfBuilder implicitly refers to a morf, that has the same Syntax and Asn1Value as the morf associated with the MorfBuilder instance being copied. Both instances of the MorfBuilder class are independent copies, and both refer to two separate instances of the Morf class. Updates to the Asn1Value of one of the MorfBuilder instances do not affect the Asn1Value of the other MorfBuilder instance.

MorfBuilder (CDU attrname, 
Platform& plat = 
Platform::def_platform)

The preceding constructor creates a MorfBuilder instance for the given kind of attribute which implies a particular syntax.

3.19.2 Destructor

~MorfBuilder ()

This destructor releases all the resources associated with the MorfBuilder.

3.19.3 MorfBuilder Operator Overloading

MorfBuilder& operator = (const MorfBuilder& 
other)

The assignment operator works like the copy constructor.

operator void*()

The preceding cast operator is to be used in conditionals. It returns TRUE if the MorfBuilder refers to an actual Morf object.


Caution – Do not attempt to use the returned pointer value because it points to private data.

int operator !()

The preceding function is a logical negation that can be used in an "if (!morfbuilder)..." context.

3.19.4 MorfBuilder Member Functions

This section describes the member functions of the MorfBuilder class.

get_raw

Morf get_raw (int do_assemble = TRUE);

If do_assemble is TRUE, this function updates the cached overall internal Asn1Value/Syntax relation by assembling the Asn1Value/Syntax member values of the underlying morf into a new morf.

Updating the cached overall internal Asn1Value/Syntax relation is needed when MorfBuilder is associated with a constructed ASN.1 type such as SEQUENCE, SEQUENCE OF, SET, and SET OF. In such a case, you can update the member values of the underlying morf, but the overall internal Asn1Value /Syntax relation is not updated until you use the get_raw method.

On successful completion, this function returns the newly assembled Morf. Otherwise, the underlying Morf is not updated and an empty Morf is returned.

Therefore, you should check the returned Morf to determine whether it is empty. For example, !morfbuilder.get_raw().

If do_assemble is FALSE, this function returns the underlying Morf without assembling a new Morf. Invoking get_raw(FALSE) does not reset any modifications that might have been done to the MorfBuilder. These modifications are still kept and can be assembled into a modified Morf by calling get_raw(TRUE) at a later time. MorfBuilder always keeps a cached copy of the latest successfully assembled valid Morf, and updates the cached copy with a new Morf only if the new Morf is successfully assembled by invoking get_raw(TRUE).

Morf get_raw (CDU navigation, int do_assemble = TRUE);

Used with a MorfBuilder that is associated with a constructed ASN.1 type, this function recursively navigates to the specified morf in a MorfBuilder using the given navigation string and calls get_raw (do_assemble).

The navigation parameter is a dot-separated list of field names or position numbers. A position number, with the exception of 0, is an integer that represents the offset of a Morf object in a list of Morf objects.

This function returns the Morf object that is associated with the MorfBuilder at the field described by the navigation string. It splits the underlying MorfBuilder into its component parts (for example, a tree of MorfBuilder classes) and recursively invokes the get_raw (newnavigation, do_assemble) function, where the newnavigation argument is the old navigation argument, stripped from the first component of the dot separated list, until one entry is left in the navigation string. This means that the function reached the Morf specified in the navigation string. This function then calls the get_raw (do_assemble) function.

If the MorfBuilder does not represent a constructed type, or the navigation string does not represent a valid field of the asn1 type, this function returns an empty Morf object.

CODE EXAMPLE 3-11 shows how to use get_raw to find a component in a complex morfbuilder.

CODE EXAMPLE 3-11   Using get_raw With a Complex morfbuilder 
/*
SEQUENCE { 
   seqint INTEGER DEFAULT 10,
   seqchar1 OCTET STRING OPTIONAL,
   seqbool1 BOOLEAN,
   seqseqof SEQUENCE OF OCTET STRING
}
If the syntax 
Syntax syn 
is associated with the above described SEQUENCE type,
and the morfbuilder 
MorfBuilder mbd
is associated with the syntax syn
*/
     
     
       Morf m1 = mbd.get_raw("seqint");
       if (!m) {
	 cout << "Failed to get the morf field!" << endl;
       }
// returns the Morf associated with the field seqint
     
       Morf m2 = mbd.get_raw("seqseqof.2");
       if (!m2) {
	 cout << "Failed to get the morf field!" << endl;
       }
// returns the Morf associated with the field seqseqof.2 - i.e.
// the second field of the SEQUENCE OF seqseqof
       Morf m3 = mbd.get_raw(FALSE);
       if (!m3 {
	 cout << "Failed to get the old morf!" << endl;
       }
// returns the Morf associated with the MorfBuilder
// without attempting to reassemble the Morf, if fields of the
// morf were modified
     
       Morf m4 = mbd.get_raw(); // default argument is TRUE
       if (!m4 {
	 cout << "Failed to assemble and get the new morf!" << endl;
       }
// returns the Morf associated with the MorfBuilder
// first attempts to reassemble the Morf, if fields of the
// morf were modified

select_choice

Result select_choice (CDU member_name);

Selects a syntax for the MorfBuilder associated with a CHOICE type specified in the member_name argument.

Returns OK on successful completion; otherwise, returns NOT_OK.


Note – This function should be applied only to MorfBuilder instances that represent CHOICE ASN.1 types. If not, this function returns NOT_OK. Also, if the specific type of a MorfBuilder representing a CHOICE type has been already set, either through a previous invocation of select_choice or through initialization with a Morf object, this function returns NOT_OK.

Result select_choice (CDU navigation, CDU member_name);

Used with a MorfBuilder that is associated with a constructed ASN.1 type, this function recursively navigates to the specified Morf in a MorfBuilder using the given navigation string (navigation) and calls select_choice (member_name).

The navigation parameter is a dot-separated list of field names or position numbers. A position number, with the exception of 0, is an integer that represents the offset of a Morf object in a list of Morf objects.

If the MorfBuilder does not represent a constructed type, or the navigation string does not represent a valid field of the ASN.1 type, the function returns NOT_OK.

set_syntax

 Result set_syntax (Syntax& new_syn);

Selects a syntax for a MorfBuilder associated with a CHOICE type in the new_syn argument.

Returns OK on successful completion; otherwise, returns NOT_OK.

Result set_syntax (CDU navigation, 
Syntax& new_syn);      

Used with a MorfBuilder that is associated with a constructed ASN.1 type, this function recursively navigates to the specified Morf in a MorfBuilder using the given navigation string (navigation) and calls set_syntax (new_syn).

The navigation parameter is a dot-separated list of field names or position numbers. A position number, with the exception of 0, is an integer that represents the offset of a Morf object in a list of Morf objects.

If the MorfBuilder does not represent a constructed type, or the navigation string does not represent a valid field of the ASN.1 type, the function returns NOT_OK.

set_raw

Result set_raw (Morf& morf, FBits fb = 0);

Replaces the MorfBuilder object's underlying Morf object and any contained MorfBuilder objects with morf. This means that if the MorfBuilder represents a constructed type and parts of it have been previously updated, these updates are lost.


Note – To avoid losing previous updates to the member values of a MorfBuilder object that represents a constructed type, use the get_raw function before using the set_raw function.

Returns OK on successful completion; otherwise, returns NOT_OK.

Result set_raw (CDU navigation, Morf& morf, FBits fb 
= 0);

Used with a MorfBuilder that is associated with a constructed ASN.1 type, this function recursively navigates to the specified Morf in a MorfBuilder using the given navigation string (navigation) and calls set_raw (morf, fb).

The navigation parameter is a dot-separated list of field names or position numbers. A position number, with the exception of 0, is an integer that represents the offset of a Morf object in a list of Morf objects.

If the MorfBuilder does not represent a constructed type, or the navigation string does not represent a valid field of the ASN.1 type, the function returns NOT_OK.

set

Result set (CDU value, FBits fb = 0);

This function replaces the MorfBuilder's underlying morf value and any contained MorfBuilder objects with value. This means that if the MorfBuilder represents a constructed type and parts of it have been previously updated, these updates are lost.


Note – To avoid losing previous updates to the member values of a MorfBuilder object that represents a constructed type, use the get_raw function before using the set function.

Returns OK on successful completion; otherwise, returns NOT_OK.

Result set (CDU navigation, CDU value, FBits fb = 0);

Used with a MorfBuilder that is associated with a constructed ASN.1 type, this function recursively navigates to the specified Morf in a MorfBuilder using the given navigation string (navigation) and calls set (morf, fb).

The navigation parameter is a dot-separated list of field names or position numbers. A position number, with the exception of 0, is an integer that represents the offset of a Morf object in a list of Morf objects.

If the MorfBuilder does not represent a constructed type, or the navigation string does not represent a valid field of the ASN.1 type, the function returns NOT_OK.

validate

Result validate (Boolean ignore_tag = FALSE);

Validates the MorfBuilder's underlying Morf object. It does that by invoking internally the function get_raw(TRUE) on the underlying Morf object. If the get_raw(TRUE) operation fails, the validate function returns NOT_OK. Otherwise, the validate function continues. It validates the Asn1Value of the Morf, against the associated ASN.1 type by invoking the method Asn1Type::validate(Asn1Value value, Boolean ignore_tag).

Returns OK on successful completion; otherwise, returns NOT_OK.

Morf validate (CDU navigation, Boolean 
ignore_tag = FALSE);

Used with a MorfBuilder that is associated with a constructed ASN.1 type, this function recursively navigates to the specified Morf in a MorfBuilder using the given navigation string (navigation) and calls validate (ignore_tag).

The navigation parameter is a dot-separated list of field names or position numbers. A position number, with the exception of 0, is an integer that represents the offset of a Morf object in a list of Morf objects.

If the MorfBuilder does not represent a constructed type, or the navigation string does not represent a valid field of the ASN.1 type, the function returns NOT_OK.

get_prop

DU get_prop (CDU key);

The preceding function returns the property addressed by the key key. The properties are local to the MorfBuilder class and are used to control some of its behavior. TABLE 3-17 lists the currently defined properties for the MorfBuilder class.

	 if ( !albumimage ) ...

The access_type property is relevant only to a MorfBuilder class that represents a SEQUENCE type.

When the access_type property is set to by_name, all the MorfBuilder class functions that use the navigation string argument interpret the string as the member name of the SEQUENCE to be accessed.

When the access_type property is set to by_index, all the MorfBuilder functions that use the navigation string argument interpret the string as the position index for the member of the SEQUENCE to be accessed.

For example, suppose a MorfBuilder object represents an object whose type is the SEQUENCE (see CODE EXAMPLE 3-12).

CODE EXAMPLE 3-12   SEQUENCE Type Example
SEQUENCE {                           
   int INTEGER,
   char OCTET STRING
}

If the access_type property of the MorfBuilder object is set to by_name, members of the SEQUENCE type can be accessed by their names (for example, int and char).

If, however, the access_type property of the MorfBuilder object is set to by_index, members of the SEQUENCE type can be accessed by their position indexes (for example, 1 and 2). CODE EXAMPLE 3-13 shows how to use the get_prop() function.

CODE EXAMPLE 3-13   get_prop() Example
Morf morf;
if (mbd.get_prop("access_type") == DU("by_name")) {
    cout << "access_type is by_name !" << endl;
    morf = mbd.get_raw("char");
} else if (mbd.get_prop("access_type") == DU("by_index")) {
           cout << "access_type is by_index !" << endl;
           morf = mbd.get_raw("2");
       } else
          cout << "Invalid access_type is bad !" << endl;

DU get_prop (CDU navigation, CDU key);

Invokes get_prop(CDU key) on the sub-MorfBuilder member addressed by the navigation string.

get_error_type

ErrorType get_error_type(void) const;

This function enables a MorfBuilder object to maintain the error status that results from the invocation of a MorfBuilder function until another function is invoked on the same MorfBuilder. The returned error type can be retrieved through the get_error_type() function.

For example, suppose a MorfBuilder object represents an object whose type is SEQUENCE (see CODE EXAMPLE 3-14).

CODE EXAMPLE 3-14   get_error_type() Example 
SEQUENCE {
   int INTEGER,
   char OCTET STRING
}
   Result rslt = mbd.set("char", "10");
   if (rslt == NOT_OK) {
       ErrorType etype = mbd.get_error_type();
       cout << "Error string ==> " <<  mbd.get_error_string() << endl;
   }

The error type returned by the get_error_type() function can be any of the error types defined as enum ErrorType in include/pmi/error.hh.


Note – The Error type returned by the MorfBuilder::set function is the error type set by the Morf::set function since the MorfBuilder::set function is internally mapped to the Morf::set function.

The ErrorType from a function call must be accessed before a subsequent function call on the same MorfBuilder object because the error status from a previous function call is reset whenever a MorfBuilder function starts executing.

get_error_string

char* get_error_string(void) const;

Enables a MorfBuilder object to maintain the error status that results from the invocation of a MorfBuilder function until another function is invoked on the same MorfBuilder. The returned error string can be retrieved through the get_error_string() function.

For example, suppose a MorfBuilder object represents an object whose type is SEQUENCE (see CODE EXAMPLE 3-15).

CODE EXAMPLE 3-15   get_error_string() Example 
SEQUENCE {
   int INTEGER,
   char OCTET STRING
}
   Result rslt = mbd.set("char", "10");
   if (rslt == NOT_OK) {
       ErrorType etype = mbd.get_error_type();
       cout << "Error string ==> " <<  mbd.get_error_string() << endl;
   }

The error type returned by the get_error_string() function can be any of the error types defined as enum ErrorType in include/pmi/error.hh.


Note – The Error string returned by the MorfBuilder::set function is the error string set by the Morf::set function since the MorfBuilder::set function is internally mapped to the Morf::set function.

The error string from a function call must be accessed before a subsequent function call on the same MorfBuilder object because the error status from a previous function call is reset whenever a MorfBuilder function starts executing.

set_prop

Result set_prop (CDU key, CDU value);

Sets the property addressed by key to value. The properties are local to the MorfBuilder object and are used to control some of its behavior. TABLE 3-17 lists the currently defined properties for the MorfBuilder class. The access_type property is relevant only to a MorfBuilder class that represents a SEQUENCE type.

When the access_type property is set to by_name, all the MorfBuilder class functions that use the navigation string argument interpret the string as the member name of the SEQUENCE to be accessed.

When the access_type property is set to by_index, all the MorfBuilder functions that use the navigation string argument interpret the string as the position index for the member of the SEQUENCE to be accessed. CODE EXAMPLE 3-16 shows how to use the set_prop() function.

CODE EXAMPLE 3-16   set_prop() Example 
Result rslt;
Morf morf;
rslt = mbd.set_prop("access_type", "by_name");
morf = mbd.get_raw("char");
rslt = mbd.set_prop("access_type", "by_index");
morf = mbd.get_raw("2");

Result set_prop (CDU navigation, CDU key, CDU value);

Invokes set_prop(CDU key, CDU value) on the sub-MorfBuilder member addressed by the navigation string.

3.20 PasswordTty Class

Inheritance: none

#include pmi/password_tty.hh

Data Members: No public data members are declared in this class.

This class implements the TTY based password query mechanism. You can derive from this class to implement different password query mechanism (for example, dialog box based for GUI applications). All non-GUI Solstice EM applications automatically get the TTY based password query mechanism. The Platform::connect method determines if user's password is required and accordingly calls a method on this class to get the password. If you don't wish to alter the default TTY based password query mechanism, you don't need to use this class.

At any given time, there can be at most one instance of this class or one of its derived classes. If no instance exists, then the Platform::connect method temporarily creates one and uses that to query the user's password. If you derive from this class and create an instance of it before you call Platform::connect, then that instance will be used to query the password. This is achieved using the virtual methods in C++. You need to implement the PasswordTty::password_function virtual method in your class to replace the default TTY based password query mechanism.

For an example program, please refer to files in $EM_HOME/src/access_passwd which demonstrate how to implement dialog box based password query mechanism in Motif based GUI applications.

3.20.1 Constructors

PasswordTty ()

Creates an instance of the PasswordTty class. This will result in an assertion failure if an instance of this or its derived classes already exists. At any given time, there can be at most one instance of this class or one of its derived classes.

3.20.2 PasswordTty Operator Overloading

No public operators are defined for this class.

3.20.3 PasswordTty Member function

password_function

virtual int password_function (char *user, char *password) const

This function queries the user for login name and password. The login name defaults to the user argument. This method returns a non-zero value if password query succeeds. If you derive from the PasswordTty class, you should implement this method to provide your own password query mechanism.

3.21 Platform Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

An instance of the Platform class represents a potential or actual connection to a particular MIS, along with all the implied semantics of the framework implemented by the MIS.

The Platform is a reference-counting wrapper around an inner abstract base class; each framework derives a new class from the base class to implement framework-specific semantics. (The base class does provide a generic attribute-like mechanism that specific frameworks can use for specifying things like access tickets or default time-outs.).

TABLE 3-18   Platform Method Types
Method Name Method Type
default_platform
set_default_platform
MIS default
get_prop
set_prop
replace_discriminator
replace_discriminator_classes
Property control
connect
start_connect
disconnect
start_disconnect
get_connection_fd
cleanup_def_platform
MIS connection
find_album_by_nickname
find_image_by_nickname
find_image_by_objname
find_image_by_oi
get_fdn
get_fullname
get_shortname
Name translation
get_when_syntax
when
Function callback
get_plat_id
get_raw_sap
Utility routines
get_attr_coder
set_attr_coder
String encoding/decoding hooks
get_authorized_features
get_authorized_applications
Access control


3.21.1 Constructors

Platform()

The default constructor creates a Platform instance that refers to no actual MIS. The value tests FALSE until you assign it a real Platform value.

Platform( const Platform& other)

The preceding is an ordinary copy constructor. After the copy, both copies still refer to the same MIS object. The reference count on the MIS object is incremented.

Platform( CDU plattype, CDU nickname = 
duNO_VALUE() )

The preceding constructor constructs a Platform instance for a particular kind of MIS. Because a Platform is really a wrapper for a set of related classes, this function actually works a bit like a virtual constructor.

3.21.2 Destructor

~Platform()

Decrements the reference count and deletes the Platform if reference count is zero.

3.21.3 Platform Operator Overloading

Platform& operator = (const Platform& other)

The assignment operator, above, works like the copy constructor

operator void*()

The preceding cast operator is for use in conditionals. It returns TRUE if this Platform refers to an actual MIS object (regardless of whether that MIS is connected yet). Do not attempt to use the returned value as a pointer to anything, since it points to private data.

int operator !()

The preceding operator definition is provided so that you can state:

"if (!platform)..."

3.21.4 Platform Member Functions

This section describes the member functions of the Platform class.

cleanup_def_platform

static void cleanup_def_platform(void);

This method resets the default platform and clears the caches associated with the default platform. The cleanup_def_platform method should be invoked after disconnecting an existing platform and before attempting to establish a new platform connection.

The cleanup_def_platform method does not by itself force an established platform connection down. Rather it is used to clean up a connection after a disconnect (e.g. a disconnect event was received). The cleanup_def_platform method is usually used in the disconnect callback, registered for the platform.


Note – The attempt to reconnect to the platform must not occur in the disconnect callback. The disconnect callback only post a timer to invoke a reconnect callback sometimes later, after the disconnect callback has exited.

CODE EXAMPLE 3-17 is an example of this function's use:

CODE EXAMPLE 3-17   Platform::cleanup_def_platform Method 
void disc_cb( Ptr, Ptr);
void mis_retry_handler (Ptr, Ptr);
Platform *plat = 0;
char *host;
int main (int argc, char **argv)
{ 
 	 host = getenv("EM_SERVER");
    if (!host) {
        host = new char[MAXHOSTNAMELEN+1];
        sysinfo(SI_HOSTNAME, host, 255);
    }
 	 while (1) {
        plat = new Platform(duEM);
        cout << "Connecting to ... " << host << endl;
        if (!plat->connect(host, "em_sample", 20.0)) { 
	 	 	 	 // Connect to the MIS
 	 	 	 	 cout << "Failed to connect to " << host << endl;
            cout << plat->get_error_string() << endl;
            Platform::cleanup_def_platform();
            delete plat;
            plat = 0;
 	 	 	 }
        else {
            break;
        }
	 } /* while */
 
    if (!plat->when("DISCONNECTED", Callback(disc_cb, 0))) {
        cout << plat->get_error_string() << endl;
        exit(3);
    }
...............
 
    while (TRUE) {
        dispatch_recursive(TRUE);       
	 	 	 // Enter the infinite listen loop.
    }
    exit(0);
}
 
...............
// Define a function to do something if disconnected.
 
void
disc_cb(Ptr, Ptr) {
 	 cout << "****** DISCONNECTED event received 
******" << endl;
    Platform::cleanup_def_platform();
    delete plat;
    plat = 0;
    post_timer(Timer((10 * 1000), 0, mis_retry_handler, 
0));
    return;
}
...............
 
void
 	 mis_retry_handler (Ptr   user_data,  Ptr 
passed_data) {
    plat = new Platform(duEM);
    cout << "Connecting to ... " << host 
<< endl;
    if (!plat->connect(host, "em_sample", 20.0)) {
 	 	 	 cout << "Failed to connect to 
" << host << endl;
        cout << plat->get_error_string() 
<< endl;
        Platform::cleanup_def_platform();
        if (plat != 0) {
	 	 	 	 delete plat;
            plat = 0;
        }
 	 	 	 post_timer(Timer((10 * 1000), 0, 
mis_retry_handler, 0));
        return;
    }
 	 if (!plat->when("DISCONNECTED", Callback(disc_cb, 
0))) {
        cout << plat->get_error_string() 
<< endl;
        exit(3);
    }
 	 return;
}

After a platform is disconnected, and the cleanup_def_platform is invoked, all the PMI objects used in the previous connection are invalid. New instances (Image and Album, for example) must be created and booted.


Note – Attempts to access PMI objects from the previous platform connection can result in segmentation violation, since the PMI program will attempt to access memory that has already been freed up. The PMI library does not support multiple concurrent platform connections within the same process (the same PMI program). After one platform is disconnected, the PMI program can invoke the cleanup_def_platform method to clear the platform caches and to reset the default platform, and then it can post a timer, that will invoke a reconnect callback and attempt to set up a new platform connection in that reconnect callback.

connect

Result connect(CDU location,
               CDU application_name,
const Timeout to = 
DEFAULT_TIMEOUT)

This function call attempts to connect to the MIS. The value of location is implementation dependent, but might be something as simple as a host name.

This method determines if the user is subject to password authentication. If the user is, then this method queries the login name and password. By default, a tty-based password query mechanism is used. An application can redefine the password query mechanism by deriving from the PasswordTty class and providing its own definition of the PasswordTty::password_function virtual method.

The argument application_name is used by the Access Control Module to determine if the user has permission to use the application. If the user does not have permission to use the application this method fails to connect to the MIS and returns NOT_OK. The Platform::get_error_string function can be used to determine the reason for the failure.

default_platform

static Platform default_platform()

This function call returns the default MIS. The Image and Album constructors use this value if you invoke them without supplying an argument to specify an MIS. To set the default MIS, use set_default_platform.

disconnect

Result disconnect(const Timeout to = DEFAULT_TIMEOUT)

This method forces a disconnect from the platform, resets the default platform, and clears the caches associated with the default platform. Do not assume that the event callbacks are executed before the connection to the MIS is closed (so that it cannot be assumed that if a callback was registered for the DISCONNECTED event, that the callback will be invoked).

The invocation of disconnect() must happen in an event callback function, called indirectly through dispatch_recursive(). CODE EXAMPLE 3-18 sets a timer callback that will be invoked when the timer expires and will call disconnect(). A new timer can be set, within this callback, to execute a reconnect callback later.

CODE EXAMPLE 3-18   Platform::disconnect Method 
void disc_cb( Ptr, Ptr);
void mis_retry_handler (Ptr, Ptr);
void disconnect_handler(Ptr,  Ptr);
 
Platform *plat = 0;
char *host;
int main (int argc, char **argv)
{                                                                              
    host = getenv("EM_SERVER");
    if (!host) {
	 host = new char[MAXHOSTNAMELEN+1];
        sysinfo(SI_HOSTNAME, host, 255);
    }
	 while (1) {
        plat = new Platform(duEM);
        cout << "Connecting to ... " << host << endl;
        if (!plat->connect(host, "em_sample", 20.0)) { 
	 	 	 // Connect to the MIS.
	 	 	 	 	 cout << "Failed to connect to " << host << endl;
            cout << plat->get_error_string() << endl;
            Platform::cleanup_def_platform();
            delete plat;
            plat = 0;
	 	 	 }
        else {
            break;
        }
	 	  } /* while */
 
    if (!plat->when("DISCONNECTED", Callback(disc_cb, 0))) {
        cout << plat->get_error_string() << endl;
        exit(3);
    }
 
    post_timer(Timer((10 * 1000), 0, disconnect_handler, 0));
...............
 
    while (TRUE) {
        dispatch_recursive(TRUE);        
	  	  	  // Enter the infinite listen loop.
    }
 	 exit(0);
}
 
...............
// Define a function to do something if disconnected.
 
void
disc_cb(Ptr, Ptr) {
    cout << "****** DISCONNECTED event received ******" << endl;
    Platform::cleanup_def_platform();
    delete plat;
    plat = 0;
    post_timer(Timer((10 * 1000), 0, mis_retry_handler, 0));
    return;
}
...............
 
void
	 mis_retry_handler (Ptr   user_data,  Ptr passed_data) {
    plat = new Platform(duEM);
    cout << "Connecting to ... " << host << endl;
	 if (!plat->connect(host, "em_sample", 20.0)) {
        cout << "Failed to connect to " << host << endl;
        cout << plat->get_error_string() << endl;
        Platform::cleanup_def_platform();
        if (plat != 0) {
            delete plat;
            plat = 0;
        }
	  post_timer(Timer((10 * 1000), 0, mis_retry_handler, 0));
        return;
    }
 
    if (!plat->when("DISCONNECTED", Callback(disc_cb, 0))) {
        cout << plat->get_error_string() << endl;
        exit(3);
    }
    return;
}
void
    disconnect_handler(Ptr   user_data,  Ptr passed_data) {
    char ch;
 
    cout << " disconnecting !" << endl;
    if (plat) {
        plat->disconnect();
        delete plat;
        plat = 0;
        post_timer(Timer((10 * 1000), 0, mis_retry_handler, 0));
    }
}

After a platform is disconnected, and the cleanup_def_platform is invoked, all the PMI objects used in the previous connection are invalid. New instances (Image and Album, for example) must be created and booted.


Note – Attempts to access PMI objects from the previous platform connection can result in segmentation violation, since the PMI program will attempt to access memory that has already been freed up. The attempt to reconnect to the platform must not happen in the disconnect callback. The disconnect callback must only post a timer to invoke a reconnect callback sometimes later, after the disconnect callback has exited.

find_album_by_nickname

Album find_album_by_nickname( CDU name)

The preceding function call locates the album that has registered itself with the specified name. The null value Album() is returned if no such album is found.

find_image_by_nickname

Image find_image_by_nickname( CDU name)

The preceding function call locates the image that has registered itself with the specified name. The null value Image() is returned if no such image is found.

find_image_by_objname

Image find_image_by_objname( CDU name)

The preceding function call locates the image that has registered itself with the specified name. The null value Image() is returned if no such image is found. Note that the Image constructor can also do lookups for you, should you want the image to be created when not found
find_image_by_oi

Image find_image_by_oi( CDU oi)

This function returns the image that has registered itself with the specified oi. The null value Image() is returned if no such image is found.

get_attr_coder

Coder get_attr_coder( CDU attrname)

The preceding method returns the encoder/decoder for a given attribute.

get_authorized_applications

Result get_authorized_applications(AuthApps &apps, 
const char *user = 0 );

This method is used to get the list of authorized applications for the given user. In most cases, you should use the default value of the user argument, which will default to the currently logged in user. The user logged in to MIS may be different than the user running the application since the user name can be changed during the password query.

This method should be called after Platform::connect has been successful. This method returns OK if there is no unexpected PMI error and if the user is authorized to use at least one application. You can query if an application is authorized or not by using the AuthApps::is_authorized() method on the authApps argument.

Please notice, this method uses the AuthApps class, whereas, the method Platform::get_authorized_features uses the AuthFeatures class. If all applications are authorized, any argument to the AuthApps::is_authorized() will return OK even if the application has not yet been registered in the MIS.

The following is an example of this function's use:

include pmi/auth_apps.hh
// After Platform::connect has been successful ...

AuthApps authApps;
if (platform.get_authorized_applications(authApps) == OK) {
if (!authApps.is_authorized("em_discover")) {
// em_discover is not authorized
}
// Check other apps ...
}
else {
// handle unexpected PMI error
}

get_authorized_features

Result get_authorized_features (AuthFeatures &features,
const char *user = 0, const 
char *appname = 0 );

This method is used get the list of authorized features for the given user and the application. In most cases, you should use the default value of the user and the application argument, which will default to the currently logged in user and the current application being run. The user logged in to MIS may be different than the user running the application since the user name can be changed during the password query.

This method should be called after Platform::connect has been successful. This method returns OK if there is no unexpected PMI error and if the user is authorized to use at least one feature for the given application. You can query if a feature is authorized or not by using the AuthFeatures::is_authorized() method on the features argument.

Please notice, this method uses the AuthFeatures class, whereas, the method Platform::get_authorized_applications uses the AuthApps class. If all features are authorized, any argument to the AuthFeatures::is_authorized() will return OK even if the feature has not yet been registered in the MIS.

The following is an example of this function's use:

#include pmi/auth_features.hh
// After Platform::connect has been successful ...

AuthFeatures features;
if (platform.get_authorized_features(features) == OK) {
// For the sake of this example, it is assumed,
// there are two features, "Create" and "Delete", in
// this application. It is also assumed that by default these
// features are enabled. The following code
// checks if a feature is not authorized and disables the feature.

if (!features.is_authorized("Create")) {
// Disable "Create" feature
}
if (!features.is_authorized("Delete")) {
// Disable "Delete" feature
}
}
else {
// handle unexpected PMI error
}

get_connection

int get_connection_fd()

The preceding method returns the file descriptor corresponding to the connection to an MIS. It is useful in a GUI program for waiting in a select() (3C) for platform events.

get_fdn

DU get_fdn (DU &dn)

The preceding method returns the ldn or fdn to the specified dn.

get_fullname

DU get_fullname( CDU shortname)

The preceding function call translates a short attribute name to its fully qualified name. Refer also to the Platform::when method description for more information.

get_plat_id

PlatformId get_plat_id()

The preceding function call returns the MIS ID number, which is not very useful outside the PMI.

get_prop

DU get_prop( CDU key)

The preceding function call returns a property of the current MIS. If key does not specify an existing property, returns a null DataUnit, which tests FALSE in a conditional. Most MISs support, at a minimum, the properties in TABLE 3-19.

TABLE 3-19   MIS Properties Supported 
Properties Description
PLATFORM_TYPE
As specified to the "virtual" constructor.
(Read Only)
PLATFORM_OBJNAME
Absolute object name of the MIS itself.
(Read Only)
APPLICATION_OBJNAME
Object instance name of the object (within the MIS) that represents the current application's connection and/or process. (Read Only)
PLATFORM_NICKNAME
The nickname for the MIS that you specified to the "virtual" constructor.
APPLICATION_TYPE
The kind of application specified to connect. (Read Only)
LOCATION
The location of the MIS specified to connect. (Read Only)
STATE
The state of the connection (Read Only):
DOWN - Unconnected
BOOT - Connecting
UP - Connected
SHUTDOWN - Disconnecting
DEFAULT_TIMEOUT
The default time-out for this MIS, in seconds, with fractions allowed.


If you want to construct an event sieve by hand, you need to know the application instance name to tell the sieve where to forward events. The PMI constructs most sieves for you automatically, so you generally need not be concerned with this.

The PMI makes no use of the nickname property; it is there merely as a convenience.

The synchronous version of any function that has both a synchronous and an asynchronous version uses the default time-out. If you set the default time-out to 0, only the asynchronous version works (unless of course you specify an explicit time-out on the synchronous call itself).

See the description of the replace_discriminator() and replace_discriminator_classes() methods, below. These methods allow you, to construct an event seive, without a call to get_prop()in some programs.

replace_discriminator

Result replace_discriminator (DU discriminatorConstruct
)

The preceeding function call takes a discriminator construct, for example, (and:{item:equality...}). In certain cases using this function can allow you to avoid a call to get_prop(). Using this function reduces network traffic and unnecessary processing time. This function is more generalized and more difficult to use than the replace_discriminator_classes function.

replace_discriminator_classes

Result replace_discriminator_classes (Array (DU) object_classes, 
Array (DU) event_types = DEF_ARRAY_DU)

The preceding function call takes an array of managed object classes, such as the topo managed object class, and an array of events, such as object create. This function works on an application instance object. In certain cases, using this function can allow you to avoid a call to get_prop( ). Using this function reduces network traffic and unnecessary processing time.

get_raw_sap

void* get_raw_sap()

The preceding function call returns the message SAP of the internal connection to the MIS. This is useful for programs that need to use both the low- and high-levels of the PMI, when both need to share the same connection.

get_shortname

DU get_shortname( CDU fullname)

The preceding function call translates a fully qualified attribute name to its corresponding short name. Typically this involves stripping a document name from it.

get_when_syntax

Syntax get_when_syntax( CDU eventname)

The preceding function call returns the syntax of the information that is passed to the callback function. Primarily for internal use.

set_attr_coder

void set_attr_coder( CDU attrname, Coder cd)

The preceding function call sets the encoder/decoder for a given attribute. The Coder is used by the get_str and set_str functions in both Morfs and Images. See also set_coder, under the description of the Syntax class.

set_default_platform

static void set_default_platform( Platform& plat)

The preceding function call sets the default MIS. The Image and Album constructors use this value when you omit the platform argument. You do not usually need to call this function, since the first time you connect to a MIS it is invoked for you, and most applications talk to only one MIS.

set_prop

Result set_prop( CDU key, CDU value)

The preceding function call sets a property of the current MIS, provided that the key specifies a supported property and the value specifies a legal value. If set_prop cannot do what you ask, it throws an invalid exception. Refer to TABLE 3-19 for some typical properties.

start_connect

Waiter start_connect( CDU platform,
                      CDU application_name,
                      CCB cb = NO_CALLBACK)

The preceding function call is the asynchronous version of connect.

start_disconnect

Waiter start_disconnect( CCB cb = NO_CALLBACK)

The preceding function call is the asynchronous version of disconnect.

when

Result when( CDU eventname, CCB cb = NO_CALLBACK)

The Platform object receives all events at which time all callbacks registered for by the Platform objects are executed. Next, all of the callbacks registered for by image objects are executed, then all of the callbacks registered for by album objects are executed.

The name of the event specified in the above call needs to be the fully specified name defined in the GDMO definition unless it is a standard event supported by the Platform such as OBJECT_CREATED, ATTR_CHANGED etc. Refer also to the Platform::get_fullname method description.

The following function call establishes a callback routine to handle a class of MIS-specific asynchronous events.

For example, the following could be used to find out when an MIS disconnects:

when( "DISCONNECTED", Callback( disconnect_cb, 0));

TABLE 3-20 shows the supported Platform events.

TABLE 3-20   MIS Events Supported 
Event Description
ATTR_CHANGED
An attribute of an object in the MIS changed.
DISCONNECTED
The MIS dropped its end of the connection for some reason.
OBJECT_CREATED
An object was created in the MIS.
OBJECT_DESTROYED
An object was destroyed in the MIS.
RAW_EVENT
A raw event came in from the MIS. You can examine it before the PMI does anything else with it. But note that CurrentEvent::do_something never does anything with a raw event. You have to register a callback for the event under the proper name, such as ATTR_CHANGED, and do_something in that callback.
WAIT
The PMI is entering a wait state. CurrentEvent::get_name returns a string describing the wait state. The callback is called again when leaving the wait state, but with a null name.


3.21.5 GETENV Macro

#include pmi/installation.hh
GETENV(key);

The GETENV macro returns a null terminated string with the value of the environment variable pointed to by key, or NULL when there is no such environment variable. The parameter key is of type char *.

3.22 Syntax Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

A Syntax is the representation of a type. All framework-encoded data, whether part of an object or not, has a type. This type specifies, among other things, how to produce and understand human-readable representations of the data. In general, the application programmer need not deal with Syntaxes directly except when building Morfs from scratch.

TABLE 3-21   Syntax Method Types
Method Name Method Type
expansion
get
get_raw
get_type
Access to the type representation
get_platform
is_any
is_choice
is_list
is_sequence
is_set
Collateral information
get_member_names
get_memname
get_members
member
List handling
get_coder
set_coder
String encoding/decoding hooks


3.22.1 Constructors

Syntax()

The default constructor creates a Syntax instance that refers to no actual Syntax. The value tests FALSE until you assign it a real Syntax value.

Syntax( const Syntax& other)

The preceding constructor is an ordinary copy constructor. After the copy, both copies still refer to the same Syntax object. The reference count on the Syntax object is incremented.

Syntax( Platform& plat, DU text)

The preceding constructor constructs a Syntax instance for a particular kind of MIS. Because a Syntax is really a wrapper for a set of related classes, this function actually works somewhat like a virtual constructor.

Syntax( Morf& morf)

The preceding constructor constructs a Syntax instance for a particular kind of MIS, which is an implicit part of the Morf. The data portion of the Morf is interpreted as a description of the correct Syntax. (The Syntax implicit to the Morf describes the syntax of the description, not the Syntax to be created by the constructor.) Because a Syntax is really a wrapper for a set of related classes, this function actually works a little like a virtual constructor.

Syntax(CDU attrname, 
Platform& plat = 
Platform::def_platform)

The preceding constructor constructs a Syntax instance for a particular kind of attribute. You could conceivably accomplish the same end by creating an image for an object of the type containing the attribute in question, extracting the Morf corresponding to that attribute, and then extracting the Syntax from that Morf. However, this is far more cumbersome than simply instantiating a Syntax instance.

3.22.2 Syntax Operator Overloading

Syntax& operator = (const Syntax& other)

The assignment operator works like the copy constructor.

operator void*()

The preceding cast operator is for use in conditionals. It returns TRUE (that is, a nonzero value) if this Syntax refers to an actual syntax object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

int operator !()

The preceding function call is provided so that you can use
"if (!syntax)...".

3.22.3 Syntax Member Functions

This section describes the member functions of the Syntax class.

expansion

Syntax expansion()

The purpose of the Syntax::expansion() is to return the syntax, without respect to tagging or selection, from the current syntax.

get

DU get(FBits fb = 0) 

Returns a textual expansion of the syntax

get_coder

Coder get_coder()

The preceding function call returns the encoder/decoder for this type.

get_member_names

Array(DU) get_member_names()

The preceding function call returns the list of member names (field names) for list types that have such names.

get_members

Array(syntax) get_members()

The preceding function call returns a list of syntax for the corresponding member name (field name).

get_memname

DU get_memname()

The preceding function call returns the member name (field name) of this syntax, if it happens to be a member of a list that has member names.

get_platform

Platform get_platform()

The preceding function call returns the MIS implicit in every Syntax.

get_raw

Morf get_raw()

The preceding function call returns the Syntax in encoded, MIS-specific form.

get_type()

Asn1Type get_type()

This method returns the underlying Asn1Type object associated with a Syntax object. If the Syntax object is not initialized, the method returns a NULL Asn1Type (CODE EXAMPLE 3-19).

CODE EXAMPLE 3-19   Syntax::get_type() Example 
Syntax tstsyn = tstmrf.get_syntax();
Asn1Type tsttype2 = tstsyn.get_type();
if (tsttype2) {
    cout << "The Asn1Type is initialized!" << endl;
} else {
    cout << "The Asn1Type is not initialized!" << endl;
}

is_any

Boolean is_any()

The preceding function call returns TRUE if the syntax describes a type that is any.

is_choice

Boolean is_choice()

The preceding function call returns TRUE if the Syntax describes a type that lets you pick one of a set of other types.

is_list

Boolean is_list()

The preceding function call returns TRUE if the Syntax describes a compound data value, and FALSE if it describes a scalar value.

is_sequence

Boolean is_sequence()

The preceding function call returns TRUE if the syntax describes a compound data value that contains an ordered list of zero or more members.

is_set

Boolean is_set()

The preceding function call returns TRUE if the syntax describes a compound data value that contains an unordered list of zero or more members.

member

Syntax member( DU name = duNO_VALUE )

The preceding function call returns the Syntax for a type that is a member of the current type. Obviously, this is valid only for Syntaxes that have members, namely choices and lists. If a list type has unnamed members (or is a list of identical elements, such as a "SET OF" or "SEQUENCE OF" ASN-1 type) the first anonymous member type can be extracted by passing a null name argument. (Subsequent anonymous types are inaccessible.)

set_coder

void set_coder( Coder coder)

The preceding function call sets the encoder/decoder for this type. The Coder is used by the get_str and set_str functions in both Morfs and Images. See also set_attr_coder under the description of the Platform class.

3.23 Waiter Class

Inheritance: public Error

#include pmi/hi.hh

Data Members: No public data members are declared in this class.

A Waiter is the representation of an ongoing asynchronous operation. The Waiter provides methods for cancelling and awaiting completion of the operation.

The Waiter can also serve as the basis for asynchronous operations of your own construction.

TABLE 3-22   Waiter Method Types  
Method Name Method Type
wait
Normal Wait
when_canceled
when_done
when_resp
when_tick
Schedule additional notifications
cancel
get_except
num_clobbered
time_remaining
waitmore
was_completed
Managing a Waiter you didn't create
clobber
complete
dec
get_current_event
get_data
inc
send_resp
ref
Managing a Waiter you created


3.23.1 Constructors

Waiter()

The default constructor creates a Waiter instance that refers to no actual Waiter. The value tests FALSE until you assign it a real Waiter value.

Waiter( const Waiter& other)

The preceding constructor is an ordinary copy constructor. After the copy, both copies still refer to the same Waiter object. The reference count on the Waiter object is incremented.

Waiter( Ptr ptrdata, 
CCB callback,
Timeout defto = REAL_DEFAULT_TIMEOUT )

The preceding constructor constructs a Waiter instance that calls back to the specified callback when the Waiter completes. The ptrdata is a convenient place to store arbitrary data.

Waiter( Ptr ptrdata, Boolean reuse = FALSE )

The preceding constructor constructs a Waiter instance from a void* pointer created by the ref method. It is primarily for internal PMI use within callbacks, when the callback can occur after the original Waiter has gone out of scope, and would ordinarily have been deleted. Each call to ref increments a reference count, and each construction of a Waiter using this constructor eventually causes the reference count to be decremented again when the Waiter is destructed at the end of the callback. If multiple callbacks are to use the same pointer, then pass a reuse parameter of TRUE on all but the last callback (or call ref again within the callback) to keep the reference alive till the next callback.

Waiter::complete

After the preceding constructor is constructed from a void* pointer by the ref() method, make sure the waiter::complete() function is called. An example is shown below.

CODE EXAMPLE 3-20   waiter::complete() Function 
   Callback cb_all(all_done, 0);
   Waiter all_waiter(0, cb_all);
   cout << "Image(" << obj1 << ") to be booted" << endl;
   Image im1 = Image(obj1);
   Callback cb1(f1, all_waiter.ref());
   Waiter waiter1 = im1.start_boot(cb1);
   cout << "Image(" << obj2 << ") to be booted" << endl;
   Image im2 = Image(obj2);
   Callback cb2(f2, all_waiter.ref());
   Waiter waiter2 = im2.start_boot(cb2);
   cout << "Waiting for callback event" << endl;
   while ( !done_flag ) {
       dispatch_recursive(TRUE);
   }
void
f1(Ptr user_data, Ptr)
{
        cout << "job1 is done" << endl;
        Waiter waiter1(user_data, FALSE);
        if (waiter1)
        {
                //Mark job1 is done
                waiter1.complete();
        }
}
void
f2(Ptr user_data, Ptr)
{
        cout << "job2 is done" << endl;
        Waiter waiter2(user_data, FALSE);
        if (waiter2)
        {
                //Mark job2 is done
                waiter2.complete();
        }
}
void
all_done(Ptr, Ptr)
{
        cout << "All Jobs are done" << endl;
        done_flag = 1;
}

3.23.2 Waiter Operator Overloading

Waiter& operator = ( const Waiter& other)

The assignment operator, above, works like the copy constructor.

operator void*()

The preceding cast operator is for use in conditionals. It returns TRUE if this Waiter refers to an actual Waiter object. Do not attempt to use the returned value as a pointer to anything, since it points to private data.

int operator !()

The preceding function call is provided so that you can say
"if (!waiter)..."

3.23.3 Waiter Member Functions

This section describes the member functions of the Waiter class.

cancel

Result cancel()

The preceding function call causes the asynchronous operation to time out immediately. Essentially it's a waitmore(0.0). Any existing callbacks are not removed.

clobber

void clobber( const ExceptionType* err = 0)

The preceding function call causes the Waiter to be marked as deficient in some respect or other. This function is primarily for internal use; the PMI uses it to pass error information back to the application when, for instance, an unexpected error response is received from the MIS. The function can be called multiple times, but only the first error is remembered. This function does not complete the Waiter.

complete

void complete()

The preceding function call marks the Waiter as complete. This function is primarily for internal use; the PMI uses it to notify the Waiter so that it can call any waiting external callbacks, and can let the wait function return to the application (if the wait function was in fact called). Waiter.complete() should be called regularly. Calls to this function are ignored if there are still pending internal callbacks.

dec

U32 dec()

The preceding function call decrements the Waiter's count of the number of internal callbacks it is waiting for. The Waiter cannot complete while there are pending internal callbacks. This function is primarily for internal use; it returns the number of callbacks pending after the decrement.

get_current_event

CurrentEvent get_current_event()

The preceding function call returns the CurrentEvent that is contained within the Waiter. This is the event that is passed to all external callbacks when the Waiter completes. The "message pointer" in this event is actually a pointer back to the Waiter containing it.

get_data

Ptr get_data()

The preceding function call returns the ptrdata originally passed to the Waiter constructor. This function is primarily for internal use.

get_except

const ExceptionType* get_except()

The preceding function call returns the exception that the Waiter was clobbered with, if any.

inc

U32 inc()

The preceding function call increments the Waiter's count of the number of internal callbacks it is waiting for. The Waiter cannot complete while there are still pending internal callbacks. This function is primarily for internal use. It returns the number pending before the increment.


Note – It can be disastrous to lose track of the number of pending callbacks. You can either hang forever or dump core.

num_clobbered

U32 num_clobbered()

The preceding function call returns the number of times the Waiter was clobbered.

ref

Ptr ref()

The preceding function call returns a reference-counted (refcnt) void* pointer to this Waiter, from which you must, at some future time, reconstruct the Waiter using the Waiter(Ptr,  Boolean) constructor. Refer to the description of that constructor earlier in this section for further information.


Note – If Waiter::ref() is used to pass waiters in callbacks, then the asynchronous operation never completes. This is because the ref() function may do more than increase the ref count on the Waiter. It also increases the pending count on the Waiter.

send_resp

void send_resp(Ptr Calldata)

When invoked on a Waiter, this method posts the callback, stored during a previous call to the when_resp() method, in the scheduler queue with the associated Calldata. Calldata is a pointer that can be converted to a CurrentEvent object which can be manipulated by the application that receives it.

time_remaining

Timeout time_remaining()

The preceding function call returns the time remaining before the Waiter would expire due to a time-out. In combination with the when_tick function, this let's you give the user a countdown till the time the application blows up. Note that a Timeout value is a (possibly fractional) number of seconds. Any rounding is up to you.

wait

CurrentEvent wait( const Timeout to = 
DEFAULT_TIMEOUT)

The preceding function call blocks for up to the specified period, waiting for the asynchronous operation to complete. It returns a CurrentEvent. It it also capable of throwing an exception if the Waiter was clobbered with a nonzero ExceptionType pointer.

waitmore

Result waitmore( const Timeout to = DEFAULT_TIMEOUT)

The preceding function call is available for callbacks to reset the time-out clock to a longer (or shorter) interval because some intermediate event occurred. For instance, if receiving multiple messages, you might want to extend the time-out each time a message comes in, and only time out if the gap between two subsequent messages exceeds some threshold.

was_completed

Boolean was_completed()

The preceding function call returns TRUE if the Waiter: :complete function has been called when there were no more pending internal callbacks.

when_canceled

Result when_canceled( CCB cb = NO_CALLBACK)

The preceding function call specifies a callback to call if the operation is cancelled or times out or is otherwise clobbered. Multiple callbacks can be added per waiter.


Note – All of the callbacks will be called if multiple callbacks are issued on the Waiter. Multiple callbacks are supported so that more than one area of the program code can be notified of the completion of an asynchronous operation.

If the callback is not specified, all callbacks are removed, including the original callback passed to the constructor.

when_done

Result when_done( CCB cb = NO_CALLBACK)

The preceding function call specifies a callback to call if the operation completes successfully. Multiple callbacks can be added per waiter.


Note – All of the callbacks will be called if multiple callbacks are issued on the Waiter. Multiple callbacks are supported so that more than one area of the program code can be notified of the completion of an asynchronous operation.

If the callback is not specified, all callbacks are removed, including the original callback passed to the constructor.

when_resp

Result when_resp(CCB cb = NO_CALLBACK)

When invoked on a Waiter returned from one of the Album methods, this function allows the given callback cb to be called each time a reply related to the sent request is available.

The callback's second argument, which is a pointer of type void, cannot be ignored and the callback must build a CurrentEvent with the second argument.

CODE EXAMPLE 3-21 is an example of appropriate callback use.

CODE EXAMPLE 3-21   Appropriate Callback Use Example
void cb(Ptr userdata, Ptr calldata)
{
// do whatever
if(calldata)
	 	 {
	 	 CurrentEvent ce(calldata);
	 	 // 	 Do whatever and use and access the 
information 
	 //	 	 within the CurrentEvent ce
	 	 }
// do whatever
}

CODE EXAMPLE 3-22 is an example of inappropriate callback use.

CODE EXAMPLE 3-22   Inappropriate Callback Use Example
void cb(Ptr userdata,Ptr calldata)
{
// do whatever but never use calldata to 
}
// or
void cb(Ptr userdata)
{
// do whatever and ignore the second argument
}

The relevant information in the CurrentEvent depends on the request sent in the case of CMIS M_GET, M_SET, or M_DELETE.

The following methods are available on the CurrentEvent object instance:

The get_message() method returns the message that caused the callback function to be called. And in the case of CMIS M_ACTION, two additional methods are added to the CurrentEvent object instance:

when_tick

Result when_tick( CCB cb = NO_CALLBACK, 
const Timeout to = 1.0)

The preceding function call specifies a callback to call repeatedly as long as the operation has not yet completed successfully. By default the callback is called once per second, but you can specify a different Timeout parameter to modify that. Only one such callback can be added per waiter. If the callback is not specified, the callback is removed.


Sun Microsystems, Inc.
Copyright information. All rights reserved.
Doc Set  |   Contents   |   Previous   |   Next   |   Index