E57 Foundation API v1.1.312
Aug. 10, 2011
|
example: get info about generic Nodes More...
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. |
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); }