E57 Foundation API v1.1.312
Aug. 10, 2011
|
example: creating SourceDestBuffers of Strings More...
Functions | |
int | main (int, char **) |
Example use of ustring SourceDestBuffers. |
example: creating SourceDestBuffers of Strings
Also see listing at end of this page for source without line numbers (to cut&paste from).
00001 /*** SourceDestBufferStringCreate.cpp example: creating SourceDestBuffers of Strings */ 00004 #include <iostream> 00005 #include "E57Foundation.h" 00006 using namespace e57; 00007 using namespace std; 00008 00010 int main(int /*argc*/, char** /*argv*/) { 00011 try { 00012 ImageFile imf("temp._e57", "w"); 00013 StructureNode root = imf.root(); 00014 00015 StructureNode prototype(imf); 00016 prototype.set("s", StringNode(imf)); 00017 00018 VectorNode codecs(imf, true); 00019 00020 CompressedVectorNode cv(imf, prototype, codecs); 00021 root.set("cv1", cv); 00022 00023 const int N = 2; 00024 vector<ustring> strings; 00025 strings.push_back("first string"); 00026 strings.push_back("second string"); 00027 vector<SourceDestBuffer> sbufs; 00028 sbufs.push_back(SourceDestBuffer(imf, "s", &strings)); 00029 00030 { 00031 CompressedVectorWriter writer = cv.writer(sbufs); 00032 writer.write(N); 00033 writer.close(); // don't forget to explicitly close the CompressedVectorWriter 00034 } 00035 00036 imf.close(); // don't forget to explicitly close the ImageFile 00037 } catch(E57Exception& ex) { 00038 ex.report(__FILE__, __LINE__, __FUNCTION__); 00039 return(-1); 00040 } 00041 00042 try { 00043 ImageFile imf("temp._e57", "r"); 00044 StructureNode root = imf.root(); 00045 00046 CompressedVectorNode cv = static_cast<CompressedVectorNode> (root.get("cv1")); 00047 00048 unsigned nChildren = static_cast<unsigned>(cv.childCount()); 00049 vector<ustring> strings(nChildren); 00050 vector<SourceDestBuffer> dbufs; 00051 dbufs.push_back(SourceDestBuffer(imf, "s", &strings)); 00052 00053 { 00054 CompressedVectorReader reader = cv.reader(dbufs); 00055 unsigned nRead = reader.read(); 00056 if (nRead != nChildren) 00057 return(-1); 00058 for (unsigned i = 0; i < nRead; i++) 00059 cout << " string[" << i << "] = " << strings[i] << endl; 00060 reader.close(); // don't forget to explicitly close the CompressedVectorReader 00061 } 00062 00063 imf.close(); // don't forget to explicitly close the ImageFile 00064 } catch(E57Exception& ex) { 00065 ex.report(__FILE__, __LINE__, __FUNCTION__); 00066 return(-1); 00067 } 00068 return(0); 00069 }
This example program illustrates the writing and reading of StringNodes in a CompressedVectorNode. See the HelloWorld.cpp example for discussion of the use of include files, constructing an ImageFile, and the try/catch block to handle exceptions. See CompressedVectorCreate.cpp example for discussion about the writing/reading a CompressedVectorNode. See SourceDestBufferNumericCreate.cpp example for discussion about writing numbers in a CompressedVectorNode.
It is envisioned that for most uses of the E57 format, the fields of a CompressedVectorNode record will be entirely numeric. However it is possible to store Unicode strings in the record of a CompressedVectorNode (i.e. store strings in the compressed section of an E57 file). Writing and reading strings in a CompressedVectorNode are a little different than numbers: their values are not a known fixed width. Rather than using built-in C++ arrays as memory buffers to hold numbers, string use vector<ustring> buffers. The vector<ustring> has a fixed number of entries, just like the C++ arrays from numbers, but the length of each ustring in the vector can be different (i.e. sbuf[0].length() can be different than sbuf[1].length()).
Source lines 12-21 create a CompressedVectorNode that has a record that has a single string element s
. Source lines 24-28 create a SourceDestBuffer that represents a two element vector that holds two ustrings of different lengths. Note that the third argument in the SourceDestBuffer constructor on source line 28, is the address of the vector to use, rather than the vector itself. Source lines 31-33 write the 2 strings to the CompressedVectorNode as a block.
In source lines 43-46, the E57 file is reopened for reading, and the CompressedVectorNode is fetched. An vector of strings is constructed in source line 49 which is large enough to hold all the strings from all the records defined (which is two records in this example), and a corresponding SourceDestBuffer is created in source line 50. The strings are read in one gulp on source line 55. The string values are printed on source lines 58-59. Repeated calls to CompressedVectorReader::read with a fixed length vector would be preferable in working code, as the number of records in a CompressedVectorNode is unbounded. Even with fetching a fixed number of strings on each read call, the amount of memory required is unknown because the strings read can be of any length.
Note that the string values written in the file do not appear in the XML listing, as they are stored in the binary section of the file that is not printed by the utility (E57xmldump.exe) that generated the listing. On XML line 4, you can see the fileOffset
XML attribute that indicates the binary section that holds the CompressedVectorNode values starts at the physical offset of 40 (decimal) in the disk file.
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:
/*** SourceDestBufferStringCreate.cpp example: creating SourceDestBuffers of Strings */ #include <iostream> #include "E57Foundation.h" using namespace e57; using namespace std; int main(int /*argc*/, char** /*argv*/) { try { ImageFile imf("temp._e57", "w"); StructureNode root = imf.root(); StructureNode prototype(imf); prototype.set("s", StringNode(imf)); VectorNode codecs(imf, true); CompressedVectorNode cv(imf, prototype, codecs); root.set("cv1", cv); const int N = 2; vector<ustring> strings; strings.push_back("first string"); strings.push_back("second string"); vector<SourceDestBuffer> sbufs; sbufs.push_back(SourceDestBuffer(imf, "s", &strings)); { CompressedVectorWriter writer = cv.writer(sbufs); writer.write(N); writer.close(); // don't forget to explicitly close the CompressedVectorWriter } imf.close(); // don't forget to explicitly close the ImageFile } catch(E57Exception& ex) { ex.report(__FILE__, __LINE__, __FUNCTION__); return(-1); } try { ImageFile imf("temp._e57", "r"); StructureNode root = imf.root(); CompressedVectorNode cv = static_cast<CompressedVectorNode> (root.get("cv1")); unsigned nChildren = static_cast<unsigned>(cv.childCount()); vector<ustring> strings(nChildren); vector<SourceDestBuffer> dbufs; dbufs.push_back(SourceDestBuffer(imf, "s", &strings)); { CompressedVectorReader reader = cv.reader(dbufs); unsigned nRead = reader.read(); if (nRead != nChildren) return(-1); for (unsigned i = 0; i < nRead; i++) cout << " string[" << i << "] = " << strings[i] << endl; reader.close(); // don't forget to explicitly close the CompressedVectorReader } imf.close(); // don't forget to explicitly close the ImageFile } catch(E57Exception& ex) { ex.report(__FILE__, __LINE__, __FUNCTION__); return(-1); } return(0); }