E57 Foundation API v1.1.312  Aug. 10, 2011
Functions
examples/NodeFunctions.cpp File Reference

example: get info about generic Nodes More...

Include dependency graph for NodeFunctions.cpp:

Functions

void printGenericInfo (Node n)
 Print generic Node info.
void printSpecificInfo (Node n)
 Decode Node type and print type specific info.
int main (int, char **)
 Example use of generic and specific Node functions.

Detailed Description

example: get info about generic Nodes

Also see listing at end of this page for source without line numbers (to cut&paste from).

00001 /*** NodeFunctions.cpp example: get info about generic Nodes */
00004 #include <iostream>
00005 #include "E57Foundation.h"
00006 using namespace e57;
00007 using namespace std;
00008 
00010 void printGenericInfo(Node n)
00011 {
00012     cout << "  elementName    = " << n.elementName()              << endl;
00013     cout << "  pathName       = " << n.pathName()                 << endl;
00014     cout << "  parent name    = " << n.parent().pathName()        << endl;
00015     cout << "  isRoot         = " << n.isRoot()                   << endl;
00016     cout << "  isAttached     = " << n.isAttached()               << endl;
00017     cout << "  destImageFile  = " << n.destImageFile().fileName() << endl;
00018     cout << "  type           = " << n.type()                     << endl;
00019 }
00020 
00022 void printSpecificInfo(Node n)
00023 {
00024     switch (n.type()) {
00025         case E57_STRUCTURE: {
00026             StructureNode s = static_cast<StructureNode>(n);
00027             StructureNode s2(n);
00028             StructureNode s3 = StructureNode(n);
00029             StructureNode s4 = (StructureNode)n;
00030             cout << "  StructureNode with " << s.childCount() << " children" << endl;
00031             printGenericInfo(s);
00032         }
00033         break;
00034         case E57_VECTOR: {
00035             VectorNode v = static_cast<VectorNode>(n);
00036             cout << "  VectorNode with " << v.childCount() << " children" << endl;
00037             printGenericInfo(v);
00038         }
00039         break;
00040         case E57_COMPRESSED_VECTOR: {
00041             CompressedVectorNode cv = static_cast<CompressedVectorNode>(n);
00042             cout << "  CompressedVectorNode with " << cv.childCount() << " children" << endl;
00043             printGenericInfo(cv);
00044         }
00045         break;
00046         case E57_INTEGER: {
00047             IntegerNode i = static_cast<IntegerNode>(n);
00048             cout << "  IntegerNode with value = " << i.value() << endl;
00049             printGenericInfo(i);
00050         }
00051         break;
00052         case E57_SCALED_INTEGER: {
00053             ScaledIntegerNode si = static_cast<ScaledIntegerNode>(n);
00054             cout << "  ScaledIntegerNode with rawValue = " << si.rawValue() << endl;
00055             printGenericInfo(si);
00056         }
00057         break;
00058         case E57_FLOAT: {
00059             FloatNode f = static_cast<FloatNode>(n);
00060             cout << "  FloatNode with value = " << f.value() << endl;
00061             printGenericInfo(f);
00062         }
00063         break;
00064         case E57_STRING: {
00065             StringNode s = static_cast<StringNode>(n);
00066             cout << "  StringNode with value = " << s.value() << endl;
00067             printGenericInfo(s);
00068         }
00069         break;
00070         case E57_BLOB: {
00071             BlobNode b = static_cast<BlobNode>(n);
00072             cout << "  BlobNode with length = " << b.byteCount() << endl;
00073             printGenericInfo(b);
00074         }
00075         break;
00076     }
00077 }
00078 
00080 int main(int /*argc*/, char** /*argv*/) {
00081     try {
00082         ImageFile imf("temp._e57", "w");
00083         StructureNode root = imf.root();
00084 
00085         // Add a String element in /child/grandchild
00086         StructureNode child   = StructureNode(imf);
00087         StringNode grandchild = StringNode(imf, "I'm a grandchild");
00088         root.set("child", child);
00089         child.set("grandchild", grandchild);
00090 
00091         cout << "root node:" << endl;
00092         printSpecificInfo(root);
00093 
00094         cout << "child node:" << endl;
00095         printSpecificInfo(child);
00096 
00097         cout << "grandchild node:" << endl;
00098         printSpecificInfo(grandchild);
00099 
00100         StructureNode unattached = StructureNode(imf);
00101         StringNode unattachedChild = StringNode(imf, "I'm a child of an unattached node");
00102         unattached.set("unattachedChild", unattachedChild);
00103 
00104         cout << "unattached node:" << endl;
00105         printSpecificInfo(unattached);
00106 
00107         cout << "unattached child node:" << endl;
00108         printSpecificInfo(unattachedChild);
00109 
00110         imf.close(); // don't forget to explicitly close the ImageFile
00111     } catch(E57Exception& ex) {
00112         ex.report(__FILE__, __LINE__, __FUNCTION__);
00113         return(-1);
00114     }
00115     return(0);
00116 }

This example program illustrates the manipulation and interrogation of generic Nodes. A tree three levels deep is created and printed. See the HelloWorld.cpp example for discussion of the use of include files, constructing an ImageFile, and the try/catch block to handle exceptions.

In source lines 82-83, an new E57 file is opened for writing, and the predefined root node is fetched. On source line 86, a StructureNode is created, and a handle to it is saved in child. On source line 87, a StringNode is created, and a handle to it is saved in grandchild. The StructureNode is then attached to the root of the ImageFile, on source line 88, with a resulting absolute path name of "/child". Then, in source line 89, the StringNode is attached into the ImageFile tree with a resulting absolute path name of "/child/grandchild".

Source line 92 calls a routine printSpecificInfo that prints out information that is specific to the type of the node. However the format argument to the function is of type Node, and the type of actual argument provided is type StructureNode in source line 92. This type mis-match is resolved by the compiler by using the upcast function of StructureNode that can convert the handle into a generic Node. This conversion is silently by the compiler, as it is always type-safe. Once inside printSpecificInfo, the true type of n is temporarily lost. A Node handle does not have the member function to get how many children the underlying StructureNode object has. On source line 24, the true type of n is fetched, and used in a switch statement to protect against attempting to convert a generic Node handle to a handle of the incorrect underlying type (this attempt would fail with an exception). The generic Node handle is convert back to the correct underlying type (e.g. in source line 26) by calling a handle downcast function. Note that in source lines 27-29, three alternate syntaxes are given for calling the exact same downcast function. The specific handle is used to print out some information that can't be gotten using the generic handle. Then printGenericInfo is called to print out the state of seven generic Node attributes that are common to all Node types.

Some state of the three nodes ("/", "/child", and "/child/grandchild") are listed in the output lines 1-27. The two more nodes are created, but not attached to the root node, and some of their state is printed out in output lines 28-45. Note that the isAttached attribute is false for both nodes. When the try block ends in source line 111, all the constructed objects will be deleted. The two unattached nodes will not be saved in the E57 file, because the were not attached directly or indirectly to the ImageFile root node. This is reflected in the XML listing, where only three elements show up, instead of five. Also note that the two unattached nodes remember (see output lines 35 and 44) which destination ImageFile was declared during their creation, even though they never get attached to that file. It is not an error to fail to attach a node to the declared ImageFile (it's just wasteful).

The following console output is produced:

The XML section of the temp._e57 E57 file produced by this example program is as follows:

Here is the source code without line numbers to cut&paste from:

/*** NodeFunctions.cpp example: get info about generic Nodes */
#include <iostream>
#include "E57Foundation.h"
using namespace e57;
using namespace std;

void printGenericInfo(Node n)
{
    cout << "  elementName    = " << n.elementName()              << endl;
    cout << "  pathName       = " << n.pathName()                 << endl;
    cout << "  parent name    = " << n.parent().pathName()        << endl;
    cout << "  isRoot         = " << n.isRoot()                   << endl;
    cout << "  isAttached     = " << n.isAttached()               << endl;
    cout << "  destImageFile  = " << n.destImageFile().fileName() << endl;
    cout << "  type           = " << n.type()                     << endl;
}

void printSpecificInfo(Node n)
{
    switch (n.type()) {
        case E57_STRUCTURE: {
            StructureNode s = static_cast<StructureNode>(n);
            StructureNode s2(n);
            StructureNode s3 = StructureNode(n);
            StructureNode s4 = (StructureNode)n;
            cout << "  StructureNode with " << s.childCount() << " children" << endl;
            printGenericInfo(s);
        }
        break;
        case E57_VECTOR: {
            VectorNode v = static_cast<VectorNode>(n);
            cout << "  VectorNode with " << v.childCount() << " children" << endl;
            printGenericInfo(v);
        }
        break;
        case E57_COMPRESSED_VECTOR: {
            CompressedVectorNode cv = static_cast<CompressedVectorNode>(n);
            cout << "  CompressedVectorNode with " << cv.childCount() << " children" << endl;
            printGenericInfo(cv);
        }
        break;
        case E57_INTEGER: {
            IntegerNode i = static_cast<IntegerNode>(n);
            cout << "  IntegerNode with value = " << i.value() << endl;
            printGenericInfo(i);
        }
        break;
        case E57_SCALED_INTEGER: {
            ScaledIntegerNode si = static_cast<ScaledIntegerNode>(n);
            cout << "  ScaledIntegerNode with rawValue = " << si.rawValue() << endl;
            printGenericInfo(si);
        }
        break;
        case E57_FLOAT: {
            FloatNode f = static_cast<FloatNode>(n);
            cout << "  FloatNode with value = " << f.value() << endl;
            printGenericInfo(f);
        }
        break;
        case E57_STRING: {
            StringNode s = static_cast<StringNode>(n);
            cout << "  StringNode with value = " << s.value() << endl;
            printGenericInfo(s);
        }
        break;
        case E57_BLOB: {
            BlobNode b = static_cast<BlobNode>(n);
            cout << "  BlobNode with length = " << b.byteCount() << endl;
            printGenericInfo(b);
        }
        break;
    }
}

int main(int /*argc*/, char** /*argv*/) {
    try {
        ImageFile imf("temp._e57", "w");
        StructureNode root = imf.root();

        // Add a String element in /child/grandchild
        StructureNode child   = StructureNode(imf);
        StringNode grandchild = StringNode(imf, "I'm a grandchild");
        root.set("child", child);
        child.set("grandchild", grandchild);

        cout << "root node:" << endl;
        printSpecificInfo(root);

        cout << "child node:" << endl;
        printSpecificInfo(child);

        cout << "grandchild node:" << endl;
        printSpecificInfo(grandchild);

        StructureNode unattached = StructureNode(imf);
        StringNode unattachedChild = StringNode(imf, "I'm a child of an unattached node");
        unattached.set("unattachedChild", unattachedChild);

        cout << "unattached node:" << endl;
        printSpecificInfo(unattached);

        cout << "unattached child node:" << endl;
        printSpecificInfo(unattachedChild);

        imf.close(); // don't forget to explicitly close the ImageFile
    } catch(E57Exception& ex) {
        ex.report(__FILE__, __LINE__, __FUNCTION__);
        return(-1);
    }
    return(0);
}
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines