summaryrefslogtreecommitdiff
path: root/Skin++
diff options
context:
space:
mode:
Diffstat (limited to 'Skin++')
-rwxr-xr-xSkin++/Makefile35
-rwxr-xr-xSkin++/data/_Geo3D.txt230
-rwxr-xr-xSkin++/data/fact.c2m19
-rwxr-xr-xSkin++/data/grep.c2m15
-rwxr-xr-xSkin++/data/pwr2010.c2m19
-rwxr-xr-xSkin++/rskin130
-rwxr-xr-xSkin++/src/Clcm.cxx1308
-rwxr-xr-xSkin++/src/Clcm.hxx706
-rwxr-xr-xSkin++/src/Cle2000.cxx104
-rwxr-xr-xSkin++/src/Cle2000.hxx96
-rwxr-xr-xSkin++/src/Cle2000Exception.cxx22
-rwxr-xr-xSkin++/src/Cle2000Exception.hxx22
-rwxr-xr-xSkin++/src/LCMexception.cxx22
-rwxr-xr-xSkin++/src/LCMexception.hxx22
-rwxr-xr-xSkin++/src/Lifo.cxx691
-rwxr-xr-xSkin++/src/Lifo.hxx373
-rwxr-xr-xSkin++/src/LifoException.cxx22
-rwxr-xr-xSkin++/src/LifoException.hxx22
-rwxr-xr-xSkin++/src/Makefile182
-rwxr-xr-xSkin++/src/Skin++.cxx80
20 files changed, 4120 insertions, 0 deletions
diff --git a/Skin++/Makefile b/Skin++/Makefile
new file mode 100755
index 0000000..5ca3e2a
--- /dev/null
+++ b/Skin++/Makefile
@@ -0,0 +1,35 @@
+#---------------------------------------------------------------------------
+#
+# Makefile for executing the Skin++ non-regression test
+# Author : A. Hebert (2018-5-10)
+#
+#---------------------------------------------------------------------------
+#
+OS = $(shell uname -s | cut -d"_" -f1)
+ifneq (,$(filter $(OS),SunOS AIX))
+ MAKE = gmake
+endif
+ifeq ($(openmp),1)
+ nomp = 16
+else
+ nomp = 0
+endif
+ifeq ($(intel),1)
+ fcompilerSuite = intel
+else
+ ifeq ($(nvidia),1)
+ fcompilerSuite = nvidia
+ else
+ ifeq ($(llvm),1)
+ fcompilerSuite = llvm
+ else
+ fcompilerSuite = custom
+ endif
+ endif
+endif
+all :
+ $(MAKE) -C src
+clean :
+ $(MAKE) clean -C src
+tests :
+ ./rskin -c $(fcompilerSuite) -p $(nomp) -q
diff --git a/Skin++/data/_Geo3D.txt b/Skin++/data/_Geo3D.txt
new file mode 100755
index 0000000..a9b892d
--- /dev/null
+++ b/Skin++/data/_Geo3D.txt
@@ -0,0 +1,230 @@
+-> 1 12 1 4 <-
+MIX
+ -1 -2 -3 -4
+-> 1 12 0 -1 <-
+FC1B
+-> 2 12 2 5 <-
+MESHY
+ -1.42875004E+01 -7.28750038E+00 0.00000000E+00 7.28750038E+00 1.42875004E+01
+-> 2 12 2 2 <-
+MESHZ
+ -2.47649994E+01 -7.00000000E+00
+-> 2 12 2 3 <-
+OFFCENTER
+ 3.50000000E+00 0.00000000E+00 0.00000000E+00
+-> 2 12 2 6 <-
+RADIUS
+ 0.00000000E+00 7.22163022E-01 2.16032505E+00 3.60068202E+00 5.16887522E+00
+ 6.58748198E+00
+-> 2 12 1 72 <-
+MIX
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+-> 2 12 3 3 <-
+SIGNATURE
+ 4 4 4
+L_GEOM
+-> 2 12 1 40 <-
+STATE-VECTOR
+ 23 5 3 4 1 72 11 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+-> 2 12 1 6 <-
+NCODE
+ 0 0 0 0 0 0
+-> 2 12 2 6 <-
+ZCODE
+ 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00
+ 0.00000000E+00
+-> 2 12 1 6 <-
+ICODE
+ 0 0 0 0 0 0
+-> 2 12 2 4 <-
+MESHX
+ -2.85750008E+01 -2.15750008E+01 -1.42875004E+01 -7.00000000E+00
+-> -2 0 0 0 <-
+-> 1 12 0 -1 <-
+MD1B
+-> 2 12 2 5 <-
+MESHY
+ -1.42875004E+01 -7.28750038E+00 0.00000000E+00 7.28750038E+00 1.42875004E+01
+-> 2 12 2 2 <-
+MESHZ
+ -2.47649994E+01 -7.00000000E+00
+-> 2 12 1 8 <-
+MIX
+ 11 11 11 11 11 11 11 11
+-> 2 12 3 3 <-
+SIGNATURE
+ 4 4 4
+L_GEOM
+-> 2 12 1 40 <-
+STATE-VECTOR
+ 7 0 2 4 1 8 11 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+-> 2 12 1 6 <-
+NCODE
+ 0 0 0 0 0 0
+-> 2 12 2 6 <-
+ZCODE
+ 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00
+ 0.00000000E+00
+-> 2 12 1 6 <-
+ICODE
+ 0 0 0 0 0 0
+-> 2 12 2 3 <-
+MESHX
+ -7.00000000E+00 0.00000000E+00 7.00000000E+00
+-> -2 0 0 0 <-
+-> 1 12 0 -1 <-
+FC1T
+-> 2 12 2 5 <-
+MESHY
+ -1.42875004E+01 -7.28750038E+00 0.00000000E+00 7.28750038E+00 1.42875004E+01
+-> 2 12 2 3 <-
+MESHZ
+ -7.00000000E+00 0.00000000E+00 7.00000000E+00
+-> 2 12 2 3 <-
+OFFCENTER
+ 3.50000000E+00 0.00000000E+00 0.00000000E+00
+-> 2 12 2 6 <-
+RADIUS
+ 0.00000000E+00 7.22163022E-01 2.16032505E+00 3.60068202E+00 5.16887522E+00
+ 6.58748198E+00
+-> 2 12 1 144 <-
+MIX
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+ 1 2 3 4 5 11 1 2
+ 3 4 5 11 1 2 3 4
+ 5 11 1 2 3 4 5 11
+-> 2 12 3 3 <-
+SIGNATURE
+ 4 4 4
+L_GEOM
+-> 2 12 1 40 <-
+STATE-VECTOR
+ 23 5 3 4 2 144 11 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+-> 2 12 1 6 <-
+NCODE
+ 0 0 0 0 0 0
+-> 2 12 2 6 <-
+ZCODE
+ 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00
+ 0.00000000E+00
+-> 2 12 1 6 <-
+ICODE
+ 0 0 0 0 0 0
+-> 2 12 2 4 <-
+MESHX
+ -2.85750008E+01 -2.15750008E+01 -1.42875004E+01 -7.00000000E+00
+-> -2 0 0 0 <-
+-> 1 12 0 -1 <-
+AD1T
+-> 2 12 2 5 <-
+MESHY
+ -1.42875004E+01 -7.28750038E+00 0.00000000E+00 7.28750038E+00 1.42875004E+01
+-> 2 12 2 3 <-
+MESHZ
+ -7.00000000E+00 0.00000000E+00 7.00000000E+00
+-> 2 12 2 7 <-
+RADIUS
+ 0.00000000E+00 5.77000022E-01 3.67805004E+00 3.80999994E+00 4.44500017E+00
+ 4.75199986E+00 6.37763977E+00
+-> 2 12 1 112 <-
+MIX
+ 12 13 14 15 16 17 11 12
+ 13 14 15 16 17 11 12 13
+ 14 15 16 17 11 12 13 14
+ 15 16 17 11 12 13 14 15
+ 16 17 11 12 13 14 15 16
+ 17 11 12 13 14 15 16 17
+ 11 12 13 14 15 16 17 11
+ 12 13 14 15 16 17 11 12
+ 13 14 15 16 17 11 12 13
+ 14 15 16 17 11 12 13 14
+ 15 16 17 11 12 13 14 15
+ 16 17 11 12 13 14 15 16
+ 17 11 12 13 14 15 16 17
+ 11 12 13 14 15 16 17 11
+-> 2 12 3 3 <-
+SIGNATURE
+ 4 4 4
+L_GEOM
+-> 2 12 1 40 <-
+STATE-VECTOR
+ 22 6 2 4 2 112 17 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+-> 2 12 1 6 <-
+NCODE
+ 0 0 0 0 0 0
+-> 2 12 2 6 <-
+ZCODE
+ 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00
+ 0.00000000E+00
+-> 2 12 1 6 <-
+ICODE
+ 0 0 0 0 0 0
+-> 2 12 2 3 <-
+MESHX
+ -7.00000000E+00 0.00000000E+00 7.00000000E+00
+-> -2 0 0 0 <-
+-> 1 12 3 3 <-
+SIGNATURE
+ 4 4 4
+L_GEOM
+-> 1 12 1 40 <-
+STATE-VECTOR
+ 7 0 2 1 2 4 17 1
+ 4 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0
+-> 1 12 1 6 <-
+NCODE
+ 2 5 2 5 2 5
+-> 1 12 2 6 <-
+ZCODE
+ 1.00000000E+00 0.00000000E+00 1.00000000E+00 0.00000000E+00 1.00000000E+00
+ 0.00000000E+00
+-> 1 12 1 6 <-
+ICODE
+ 0 0 0 0 0 0
+-> 1 12 3 12 <-
+CELL
+ 4 4 4 4 4 4 4 4
+ 4 4 4 4
+FC1B MD1B FC1T AD1T
+-> -1 0 0 0 <-
diff --git a/Skin++/data/fact.c2m b/Skin++/data/fact.c2m
new file mode 100755
index 0000000..45a6dfd
--- /dev/null
+++ b/Skin++/data/fact.c2m
@@ -0,0 +1,19 @@
+ !
+ ! Example of a recursive procedure.
+ !
+ ! input to "fact": *n*
+ ! output from "fact": *n_fact*
+ !
+ INTEGER n n_fact prev_fact ;
+ :: >>n<< ;
+ IF n 1 = THEN
+ EVALUATE n_fact := 1 ;
+ ELSE
+ EVALUATE n := n 1 - ;
+ ! Here, "fact" calls itself
+ PROCEDURE fact ;
+ fact :: <<n>> >>prev_fact<< ;
+ EVALUATE n_fact := n 1 + prev_fact * ;
+ ENDIF ;
+ :: <<n_fact>> ;
+ QUIT " Recursive procedure *fact* XREF " .
diff --git a/Skin++/data/grep.c2m b/Skin++/data/grep.c2m
new file mode 100755
index 0000000..f79ad30
--- /dev/null
+++ b/Skin++/data/grep.c2m
@@ -0,0 +1,15 @@
+ !
+ ! Grep a value in the state-vector of a LCM object
+ !
+ ! input to "grep": *lcm object*
+ ! output from "grep": *nb_mix*
+ !
+ PARAMETER GEOM ::
+ ::: LINKED_LIST GEOM ; ;
+ MODULE GREP: END: ;
+ INTEGER nb_mix ;
+
+ GREP: GEOM :: GETVAL 'STATE-VECTOR' 7 >>nb_mix<< ;
+ :: <<nb_mix>> ;
+ END: ;
+ QUIT .
diff --git a/Skin++/data/pwr2010.c2m b/Skin++/data/pwr2010.c2m
new file mode 100755
index 0000000..14d5042
--- /dev/null
+++ b/Skin++/data/pwr2010.c2m
@@ -0,0 +1,19 @@
+ !
+ ! Dummy pwr2010 computational scheme
+ !
+ PARAMETER saphyb ::
+ ::: XSM_FILE saphyb ; ;
+ MODULE UTL: END: ;
+ STRING draglib type fuel rod homoge ;
+ :: >>draglib<< >>type<< >>fuel<< >>rod<< >>homoge<< ;
+ REAL u235 burnup ;
+ :: >>u235<< >>burnup<< ;
+ INTEGER ngroup ;
+ :: >>ngroup<< ;
+
+ saphyb := UTL: :: CREA 'SIGNATURE' 3 = 'L_SA' 'PHYB' ' ' ;
+ ECHO "draglib=" draglib " type=" type " fuel=" fuel ;
+ ECHO "rod=" rod " homoge=" homoge " u235=" u235 ;
+ ECHO "burnup=" burnup " ngroup=" ngroup ;
+
+ QUIT " Computational scheme *pwr2010* XREF " .
diff --git a/Skin++/rskin b/Skin++/rskin
new file mode 100755
index 0000000..268785f
--- /dev/null
+++ b/Skin++/rskin
@@ -0,0 +1,130 @@
+#!/bin/sh
+#
+# author : A. Hebert
+# use : rskin [-c:|-q|-w|-p:]
+# -c name of compiler
+# -q quiet execution for regression testing
+# -w to execute in console (for debug purpose)
+# -p number of parallel threads (=1 by default)
+#
+System=`uname -s`
+Sysx="`echo $System | cut -b -6`"
+if [ $Sysx = "CYGWIN" ]; then
+ MACH=`uname -o`
+elif [ $Sysx = "AIX" ]; then
+ MACH=`uname -s`
+else
+ MACH=`uname -sm | sed 's/[ ]/_/'`
+fi
+
+typ='custom'
+quiet=0
+term=0
+nomp=0
+
+while getopts ":c:qwp:" opt; do
+ case $opt in
+ c) typ="$OPTARG"
+ ;;
+ q) quiet=1
+ ;;
+ w) term=1
+ ;;
+ p) nomp=$OPTARG
+ ;;
+ \?) echo "Invalid option $opt -$OPTARG" >&2
+ exit 1
+ ;;
+ esac
+
+ case $OPTARG in
+ -*) echo "Option $opt needs a valid argument"
+ exit 1
+ ;;
+ esac
+done
+
+Code=`basename "$PWD"`
+if [ $quiet = 0 ]; then
+ echo 'execute with' $Code 'on system' $MACH 'with' $typ 'compiler'
+fi
+
+if [ -d "$MACH" ]; then
+ if [ $quiet = 0 ]; then
+ echo 'use the existing directory' $MACH
+ fi
+else
+ echo 'creation of directory' $MACH
+ mkdir "$MACH"
+fi
+CodeDir=$PWD
+
+if [ $Sysx = "AIX" ]; then
+ Tmpdir=/usr/tmp
+elif [ $Sysx = "SunOS" ]; then
+ Tmpdir=/var/tmp
+else
+ Tmpdir=/tmp
+fi
+inum=1
+while [ -d $Tmpdir/rundir$inum ]
+ do
+ inum=`expr $inum + 1 `
+done
+Rundir=$Tmpdir/rundir$inum
+mkdir $Rundir
+if [ $quiet = 0 ]; then
+ echo "RunDirectory:" $Rundir
+fi
+cd $Rundir
+
+if [ $typ = 'custom' ]; then
+ cp "$CodeDir"/bin/"$MACH"/Skin++ ./code
+else
+ cp "$CodeDir"/bin/"$MACH"'_'$typ/Skin++ ./code
+fi
+
+ln -s "$CodeDir"/data/* .
+
+before=$(date +%s)
+if [ $nomp != 0 ]; then
+ echo 'number of OpenMP threads=' $nomp
+ export OMP_NUM_THREADS=$nomp
+ if command -v numactl >&2; then
+ numactl --cpunodebind=0 --membind=0 2>/dev/null
+ echo "use NUMA memory policy"
+ fi
+else
+ export OMP_NUM_THREADS=1
+fi
+if [ $term = 0 ]; then
+ ./code >result
+else
+ ./code
+fi
+if [ $quiet = 0 ]; then
+ time=$(( $(date +%s) - before))
+ printf 'End of execution. Total execution time: %dh %dmin %ds\n' \
+ $(($time/3600)) $(($time%3600/60)) $(($time%60))
+fi
+mv result "$CodeDir"/"$MACH"
+if [ $quiet = 0 ]; then
+ echo 'the listing is located on ./'$MACH
+fi
+
+cd "$CodeDir"/"$MACH"
+if [ $quiet = 0 ] && [ $term = 0 ]; then
+ tail -25 result
+elif [ $term = 0 ]; then
+ RED='\033[0;31m'
+ GREEN='\033[0;32m'
+ NC='\033[0m' # No Color
+ if tail result | grep -q "normal end" ; then
+ printf "${GREEN}[OK]${NC}\n"
+ else
+ printf "${RED}[FAILED]${NC}\n"
+ fi
+fi
+chmod -R 777 $Rundir
+/bin/rm -r -f $Rundir
+cd ..
diff --git a/Skin++/src/Clcm.cxx b/Skin++/src/Clcm.cxx
new file mode 100755
index 0000000..4ea27ca
--- /dev/null
+++ b/Skin++/src/Clcm.cxx
@@ -0,0 +1,1308 @@
+
+/*****************************************/
+/* C++ LCM OBJECT WRAPPER */
+/* AUTHOR: A. HEBERT ; 2024/08/04 */
+/*****************************************/
+
+/*
+Copyright (C) 2010 Ecole Polytechnique de Montreal
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+*/
+
+#include "Clcm.hxx"
+
+using namespace std;
+using namespace ganlib;
+static ostringstream hsmg;
+
+/* abort condition setting */
+void xabort_c(char *msg){
+ cout << "Clcm xabort called: " << string(msg) << endl;
+ throw LCMexception(msg);
+}
+
+ganlib::Clcm::Clcm(const string stype, const string myName, const string myPath) {
+ cout << "New Clcm object called '" << myName << "'" << endl;
+ this->root = this;
+ this->global_list = new vector<AnyPtr>;
+ this->isroot = true;
+ this->version = 4;
+ bool l_import = false;
+ bool l_exists = false;
+ int_32 imode=0;
+ if (stype == "LCM") {
+ this->objtype = 1;
+ } else if (stype == "XSM") {
+ DIR *dp;
+ struct dirent *dirp;
+ this->objtype = 2;
+ vector<string> names = vector<string>();
+ if((dp = opendir(myPath.c_str())) == NULL) {
+ hsmg << "no XSM file found (missing directory name: '" << myPath << ")'" << endl;
+ throw LCMexception(hsmg.str());
+ }
+ while ((dirp = readdir(dp)) != NULL) {
+ names.push_back(string(dirp->d_name));
+ }
+ closedir(dp);
+ for (size_t i=0; i<names.size(); i++) {
+ if (names[i] == myName) l_exists = true;
+ }
+ } else if (stype == "BINARY") {
+ this->objtype = 3;
+ } else if (stype == "ASCII") {
+ this->objtype = 4;
+ } else if (stype == "DA") {
+ this->objtype = 5;
+ } else if (stype == "LCM_IMP_BINARY") {
+ imode = 1;
+ this->objtype = 1;
+ l_import = true;
+ } else if (stype == "XSM_IMP_BINARY") {
+ imode = 1;
+ this->objtype = 2;
+ l_import = true;
+ } else if (stype == "LCM_IMP_ASCII") {
+ imode = 2;
+ this->objtype = 1;
+ l_import = true;
+ } else if (stype == "XSM_IMP_ASCII") {
+ imode = 2;
+ this->objtype = 2;
+ l_import = true;
+ } else if (stype == "LCM_IMP_ASCII_V3") {
+ imode = 2;
+ this->objtype = 1;
+ this->version = 3;
+ l_import = true;
+ } else {
+ throw LCMexception("invalid type: '" + stype + "'");
+ }
+ this->access = 0;
+ this->name = myName;
+ this->path = myPath;
+ this->addr = NULL;
+ this->lrda = 128;
+ try {
+ if (l_exists) {
+ this->addr = NULL;
+ cout << "XSM file " << path << myName << " already exists\n";
+ this->open("READ-ONLY");
+ this->access = 2;
+ } else {
+ this->open("NEW");
+ this->access = 1;
+ }
+ } catch(...) {
+ throw LCMexception("Exception catched by new(1)");
+ }
+ if (this->objtype <= 2) {
+ this->nammy = "/";
+ this->empty = true;
+ this->ilong = -1;
+ }
+ if (l_import) {
+ this->empty = false;
+ this->untoutched = false;
+ try {
+ DIR *dp;
+ struct dirent *dirp;
+ vector<string> names = vector<string>();
+ if((dp = opendir(myPath.c_str())) == NULL) {
+ hsmg << "no ASCII file found (missing directory name: '" << myPath << ")'" << endl;
+ throw LCMexception(hsmg.str());
+ }
+ while ((dirp = readdir(dp)) != NULL) {
+ names.push_back(string(dirp->d_name));
+ }
+ closedir(dp);
+ for (size_t i=0; i<names.size(); i++) {
+ string::size_type loc = names[i].find("_");
+ if( loc != string::npos ) {
+ string fileName = names[i].substr(loc, string::npos);
+ if (fileName == "_"+this->name) {
+ FILE *file;
+ file = fopen((myPath+names[i]).c_str(), "r");
+ if (this->version == 4) {
+ lcmexp_c(&(this->addr), 0, file, imode, 2);
+ }
+ else {
+ lcmexpv3_c(&(this->addr), 0, file, imode, 2);
+ }
+ fclose(file);
+ return;
+ }
+ }
+ }
+ // Modified R. Chambon 09/2011
+ for (size_t i=0; i<names.size(); i++) {
+ if (myName.compare(names[i]) == 0) {
+ FILE *file;
+ file = fopen((myPath+names[i]).c_str(), "r");
+ if (this->version == 4) {
+ lcmexp_c(&(this->addr), 0, file, imode, 2);
+ }
+ else {
+ lcmexpv3_c(&(this->addr), 0, file, imode, 2);
+ }
+ fclose(file);
+ return;
+ }
+ }
+ //
+ hsmg << "File '" << "_" << this->name << "' not found in '" << myPath <<"'";
+ throw LCMexception(hsmg.str());
+ } catch(...) {
+ throw LCMexception("Exception catched by new(2)");
+ }
+ }
+}
+
+ganlib::Clcm::Clcm(lcm *daughter, Clcm *root, const int_32 type, const string name, const int_32 ilong, const string key) {
+ this->global_list = root->global_list;
+ this->root = root;
+ this->addr = daughter;
+ this->access = 1;
+ this->name = name;
+ this->path = "./";
+ this->nammy = key;
+ this->empty = true;
+ this->ilong = ilong;
+ this->objtype = type;
+ this->untoutched = false;
+ this->isroot = false;
+ this->version = root->version;
+}
+
+ganlib::Clcm::Clcm(lcm *myLcm, const int_32 type, const int_32 access, const string OSname) {
+ this->root = this;
+ this->global_list = new vector<AnyPtr>;
+ this->isroot = false;
+ this->version = 4;
+ this->addr = myLcm;
+ this->access = access;
+ this->ilong = -1;
+ this->objtype = type-2;
+ this->empty = false;
+ this->name = OSname;
+ this->nammy = "/";
+ this->path = "";
+ this->untoutched = true;
+}
+
+ganlib::Clcm::Clcm(const string stype, ClcmPtr myClcm) {
+ if (myClcm->objtype > 2) throw LCMexception("copy constructor not available for file objects");
+ if (stype == "LCM") {
+ this->objtype = 1;
+ } else if (stype == "XSM") {
+ this->objtype = 2;
+ }
+ bool lopen = true;
+ if (myClcm->access == 0) {
+ lopen = false;
+ myClcm->open("READ-ONLY");
+ }
+ this->version = root->version;
+ this->name = myClcm->name + ".bis";
+ cout << "New Clcm object (clone) called '" << this->name << "'" << endl;
+ this->open("NEW");
+ this->access = 1;
+ lcm *myLcm = myClcm->addr;
+ lcmequ_c(&myLcm, &(this->addr));
+ this->root = this;
+ this->global_list = new vector<AnyPtr>;
+ this->isroot = true;
+ this->path = myClcm->path;
+ this->lrda = myClcm->lrda;
+ if (!lopen) {
+ myClcm->close("KEEP");
+ this->close("KEEP");
+ }
+}
+
+ganlib::Clcm::~Clcm() {
+ if (this->isroot) {
+ cout << "Clcm root destructor called. LCM object=" << this->name << endl;
+ if ((this->addr != NULL) & (this->access == 1)) {
+ cout << "Destroy object " << this->name << endl;
+ this->close("DESTROY");
+ } else if ((this->addr != NULL) & (this->access == 2)) {
+ cout << "Keep object " << this->name << endl;
+ this->close("KEEP");
+ }
+ if (this->global_list != NULL) delete this->global_list;
+ }
+}
+
+ostream & ganlib::operator<<(ostream &s, ClcmPtr myClcm) {
+ if (myClcm->objtype > 2) throw LCMexception("operator<< not available for file objects");
+ FILE *file = fopen("_dummy.txt", "w");
+ if (file == NULL) {
+ throw LCMexception("fopen failure in operator<<. file=_dummy.txt");
+ }
+ lcmexp_c(&(myClcm->addr), 0, file, 2, 1);
+ fclose(file);
+ ifstream ifs ( "_dummy.txt" , ifstream::in );
+ while (ifs.good()) s << (char) ifs.get();
+ ifs.close();
+ if( remove("_dummy.txt") != 0 ) {
+ throw LCMexception("Error deleting file after <<: _dummy.txt");
+ }
+ return s;
+}
+
+void ganlib::Clcm::expor(const string stype) {
+ this->expor(stype, "_"+this->name);
+}
+
+void ganlib::Clcm::expor(const string stype, const string new_name) {
+ if (this->objtype > 2) throw LCMexception("expor not available for file objects");
+ int_32 imode;
+ if (stype == "BINARY") {
+ imode = 1;
+ } else if (stype == "ASCII") {
+ imode = 2;
+ } else {
+ throw LCMexception("invalid type: '" + stype + "'");
+ }
+ size_t found=new_name.find("_");
+ if (found == string::npos) {
+ throw LCMexception("Export file name ("+new_name+") must contains _");
+ }
+ FILE *file = fopen(new_name.c_str(), "w");
+ if (file == NULL) {
+ throw LCMexception("fopen failure in expor(). file="+new_name);
+ }
+ lcmexp_c(&(this->addr), 0, file, imode, 1);
+ fclose(file);
+}
+
+void ganlib::Clcm::except() {
+ throw LCMexception("Programmer-triggered exception");
+}
+
+string ganlib::Clcm::getName() throw() {
+ return this->name;
+}
+
+string ganlib::Clcm::getPath() throw() {
+ return this->path;
+}
+
+int_32 ganlib::Clcm::getType() throw() {
+ return this->objtype;
+}
+
+int_32 ganlib::Clcm::getLength() {
+ char namlcm[73], nammy[13];
+ int_32 empty, ilong, lcml, access;
+ if (this->objtype > 2) throw LCMexception("getLength not available for file objects");
+ lcminf_c(&(this->addr), namlcm, nammy, &empty, &ilong, &lcml, &access);
+ return ilong;
+}
+
+string ganlib::Clcm::getDirectory() {
+ char namlcm[73], nammy[13];
+ int_32 empty, ilong, lcml, access;
+ if (this->objtype > 2) throw LCMexception("getDirectory not available for file objects");
+ lcminf_c(&(this->addr), namlcm, nammy, &empty, &ilong, &lcml, &access);
+ return nammy;
+}
+
+int_32 ganlib::Clcm::getAccess() {
+ char namlcm[73], nammy[13];
+ int_32 empty, ilong, lcml;
+ if (this->objtype <= 2) {
+ lcminf_c(&(this->addr), namlcm, nammy, &empty, &ilong, &lcml, &(this->access));
+ }
+ return this->access;
+}
+
+int_32 ganlib::Clcm::getLrda() throw() {
+ return this->lrda;
+}
+
+int_32 ganlib::Clcm::getVersion() throw() {
+ return this->version;
+}
+
+bool ganlib::Clcm::isEmpty() {
+ char namlcm[73], nammy[13];
+ int_32 empty, ilong, lcml, access;
+ if (this->objtype > 2) throw LCMexception("isEmpty not available for file objects");
+ lcminf_c(&(this->addr), namlcm, nammy, &empty, &ilong, &lcml, &access);
+ return empty;
+}
+
+bool ganlib::Clcm::isNew() throw() {
+ return this->untoutched;
+}
+
+void ganlib::Clcm::open(const string saccess) {
+ if (this->access != 0) {
+ throw LCMexception("the object " + this->name + " is already open");
+ }
+ if (saccess == "NEW") {
+ this->untoutched = true;
+ } else if (saccess == "READ/WRITE") {
+ if ((this->addr == NULL)&(this->objtype == 1)) {
+ throw LCMexception("the object " + this->name + " is destroyed(1)");
+ }
+ this->access = 1;
+ this->untoutched = false;
+ } else if (saccess == "READ-ONLY") {
+ if ((this->addr == NULL)&(this->objtype == 1)) {
+ throw LCMexception("the object " + this->name + " is destroyed(2)");
+ }
+ this->access = 2;
+ this->untoutched = false;
+ } else {
+ throw LCMexception("invalid access: '" + saccess + "'");
+ }
+ if (this->objtype == 1) {
+ try {
+ lcmop_c(&(this->addr), (char *)(this->name).c_str(), this->access, this->objtype, 99);
+ } catch(...) {
+ throw LCMexception("Exception catched by open (1)");
+ }
+ } else if (this->objtype == 2) {
+ try {
+ lcmop_c(&(this->addr), (char *)(this->path+this->name).c_str(), this->access, this->objtype, 0);
+ } catch(...) {
+ throw LCMexception("Exception catched by open (1)");
+ }
+ } else if (this->objtype <= 5) {
+ this->addr = NULL;
+ bool exs = false;
+ DIR *dp;
+ struct dirent *dirp;
+ vector<string> names = vector<string>();
+ if((dp = opendir(this->path.c_str())) == NULL) {
+ hsmg << "no file found (missing directory name: '" << this->path << ")'" << endl;
+ throw LCMexception(hsmg.str());
+ }
+ while ((dirp = readdir(dp)) != NULL) {
+ names.push_back(string(dirp->d_name));
+ }
+ closedir(dp);
+ for (size_t i=0; i<names.size(); i++) {
+ if (names[i] == this->name) exs = true;
+ }
+ if (this->access == 0) {
+ if (exs) {
+ hsmg << "New file " << this->path << this->name << " exists";;
+ throw LCMexception(hsmg.str());
+ }
+ } else if (this->access == 1) {
+ if (!exs) {
+ hsmg << "Old file " << this->path << this->name << " does not exist(1)";;
+ throw LCMexception(hsmg.str());
+ }
+ } else if (this->access == 2) {
+ if (!exs) {
+ hsmg << "Old file " << this->path << this->name << " does not exist(2)";;
+ throw LCMexception(hsmg.str());
+ }
+ }
+ } else {
+ hsmg << "invalid type in open (" << this->objtype << ")";
+ throw LCMexception(hsmg.str());
+ }
+}
+
+void ganlib::Clcm::close(const string saccess) {
+ int iact;
+ if (saccess == "KEEP") {
+ iact = 1;
+ } else if (saccess == "DESTROY") {
+ iact = 2;
+ } else if (saccess == "ERASE") {
+ iact = 3;
+ } else {
+ throw LCMexception("invalid condition: '" + saccess + "'");
+ }
+ if (this->access != 0) {
+ if (this->objtype <= 2) {
+ try {
+ lcmcl_c(&(this->addr), iact);
+ } catch(...) {
+ throw LCMexception("Exception catched by close(1)");
+ }
+ } else if (this->objtype <= 5) {
+ if (iact >= 2) {
+ try {
+ this->aFile.close();
+ if( remove((this->path+this->name).c_str()) != 0 ) {
+ throw LCMexception("Error deleting file: " + this->path + this->name);
+ }
+ cout << "File deleted:" << this->path << this->name << endl;
+ } catch(...) {
+ throw LCMexception("Exception catched by close(2)");
+ }
+ }
+ }
+ } else {
+ throw LCMexception("the object " + this->name + " is already closed");
+ }
+ if (iact == 2) {
+ this->addr = NULL;
+ }
+ this->access = 0;
+}
+
+int_32 ganlib::Clcm::length(const std::string key) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("length not available for file objects");
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (itylcm == 3) mylength=4*mylength;
+ return mylength;
+}
+
+int_32 ganlib::Clcm::length(const int_32 iset) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("length not available for file objects");
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (itylcm == 3) mylength=4*mylength;
+ return mylength;
+}
+
+int_32 ganlib::Clcm::type(const std::string key) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("type not available for file objects");
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (itylcm == 99) {
+ hsmg << "length: no block named '" << key << "'";
+ throw LCMexception(hsmg.str());
+ }
+ return itylcm;
+}
+
+int_32 ganlib::Clcm::type(const int_32 iset) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("type not available for file objects");
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (itylcm == 99) {
+ hsmg << "length: no block at position " << iset << ".";
+ throw LCMexception(hsmg.str());
+ }
+ return itylcm;
+}
+
+void ganlib::Clcm::lib() {
+ if (this->objtype > 2) throw LCMexception("lib not available for file objects");
+ lcmlib_c(&(this->addr));
+}
+
+void ganlib::Clcm::val() {
+ if (this->objtype > 2) throw LCMexception("val not available for file objects");
+ lcmval_c(&(this->addr), " ");
+}
+
+//----------------------------------------------------------------------
+//-- set --
+//----------------------------------------------------------------------
+
+ClcmPtr ganlib::Clcm::setDictionary(const std::string key) {
+ if (this->objtype > 2) throw LCMexception("setDictionary not available for file objects");
+ lcm *daughter = lcmdid_c(&(this->addr), (char *)key.c_str());
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, -1, key));
+}
+
+ClcmPtr ganlib::Clcm::setDictionary(const int_32 iset) {
+ if (this->objtype > 2) throw LCMexception("setDictionary not available for file objects");
+ lcm *daughter = lcmdil_c(&(this->addr), iset);
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, -1, " "));
+}
+
+ClcmPtr ganlib::Clcm::setList(const std::string key, const int_32 ilong) {
+ if (this->objtype > 2) throw LCMexception("setList not available for file objects");
+ lcm *daughter = lcmlid_c(&(this->addr), (char *)key.c_str(), ilong);
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, 0, key));
+}
+
+ClcmPtr ganlib::Clcm::setList(const int_32 iset, const int_32 ilong) {
+ if (this->objtype > 2) throw LCMexception("setList not available for file objects");
+ lcm *daughter = lcmlil_c(&(this->addr), iset, ilong);
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, 0, " "));
+}
+
+//----------------------------------------------------------------------
+//-- get --
+//----------------------------------------------------------------------
+
+ClcmPtr ganlib::Clcm::getClcm(const std::string key) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getClcm not available for file objects");
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getClcm(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ }
+ if (itylcm == 0) {
+ lcm *daughter = lcmgid_c(&(this->addr), (char *)key.c_str());
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, -1, key));
+ } else if (itylcm == 10) {
+ lcm *daughter = lcmgid_c(&(this->addr), (char *)key.c_str());
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, 0, key));
+ } else {
+ hsmg << "getClcm(" << key << ") expecting a Clcm object(1)";
+ throw LCMexception(hsmg.str());
+ }
+}
+
+ClcmPtr ganlib::Clcm::getClcm(const int_32 iset) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getClcm not available for file objects");
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getClcm(" << iset << ") entry is missing(2)";
+ throw LCMexception(hsmg.str());
+ }
+ if (itylcm == 0) {
+ lcm *daughter = lcmgil_c(&(this->addr), iset);
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, -1, " "));
+ } else if (itylcm == 10) {
+ lcm *daughter = lcmgil_c(&(this->addr), iset);
+ return ClcmPtr(new Clcm(daughter, this->root, this->objtype, this->name, 0, " "));
+ } else {
+ hsmg << "getClcm(" << iset << ") expecting a Clcm object(2)";
+ throw LCMexception(hsmg.str());
+ }
+}
+
+/// @cond DEV
+// Use this destructor to avoid deleting LCM array pointed by the shared_array object
+template<typename T>
+struct my_deleter
+{
+ void operator()(T* p) { }
+};
+/// @endcond
+
+IntPtrConst ganlib::Clcm::getInt(const std::string key) {
+ int_32 mylength, itylcm;
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getInt(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 1) {
+ hsmg << "getInt(" << key << ") expecting an integer array(1)";
+ throw LCMexception(hsmg.str());
+ }
+ if (this->objtype == 1) {
+ // Use a reference without copy (pinning).
+ int_32 *array;
+ lcmgpd_c(&(this->addr), (char *)key.c_str(), &array);
+ IntPtrConst iarray(array, my_deleter<const int_32>());
+ return iarray;
+ } else if (this->objtype == 2) {
+ // Use a reference with copy.
+ IntPtrConst iarray(new int_32[mylength]);
+ lcmget_c(&(this->addr), (char *)key.c_str(), (int_32 *)iarray.get());
+ return iarray;
+ } else {
+ throw LCMexception("getInt not available for file objects");
+ }
+}
+
+IntPtrConst ganlib::Clcm::getInt(const int_32 iset) {
+ int_32 mylength, itylcm;
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getInt(" << iset << ") entry is missing(2)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 1) {
+ hsmg << "getInt(" << iset << ") expecting an integer array(2)";
+ throw LCMexception(hsmg.str());
+ }
+ if (this->objtype == 1) {
+ // Use a reference without copy (pinning).
+ int_32 *array;
+ lcmgpl_c(&(this->addr), iset, &array);
+ IntPtrConst iarray(array, my_deleter<const int_32>());
+ return iarray;
+ } else if (this->objtype == 2) {
+ // Use a reference with copy.
+ IntPtrConst iarray(new int_32[mylength]);
+ lcmgdl_c(&(this->addr), iset, (int_32 *)iarray.get());
+ return iarray;
+ } else {
+ throw LCMexception("getInt not available for file objects");
+ }
+}
+
+FloatPtrConst ganlib::Clcm::getFloat(const std::string key) {
+ int_32 mylength, itylcm;
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getFloat(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 2) {
+ hsmg << "getFloat(" << key << ") expecting a single precision real array(1)";
+ throw LCMexception(hsmg.str());
+ }
+ if (this->objtype == 1) {
+ // Use a reference without copy (pinning).
+ float_32 *array;
+ lcmgpd_c(&(this->addr), (char *)key.c_str(), (int_32 **)&array);
+ FloatPtrConst iarray(array, my_deleter<const float_32>());
+ return iarray;
+ } else if (this->objtype == 2) {
+ // Use a reference with copy.
+ FloatPtrConst iarray(new float_32[mylength]);
+ lcmget_c(&(this->addr), (char *)key.c_str(), (int_32 *)iarray.get());
+ return iarray;
+ } else {
+ throw LCMexception("getFloat not available for file objects");
+ }
+}
+
+FloatPtrConst ganlib::Clcm::getFloat(const int_32 iset) {
+ int_32 mylength, itylcm;
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getFloat(" << iset << ") entry is missing(2)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 2) {
+ hsmg << "getFloat(" << iset << ") expecting a single precision real array(2)";
+ throw LCMexception(hsmg.str());
+ }
+ if (this->objtype == 1) {
+ // Use a reference without copy (pinning).
+ float_32 *array;
+ lcmgpl_c(&(this->addr), iset, (int_32 **)&array);
+ FloatPtrConst iarray(array, my_deleter<const float_32>());
+ return iarray;
+ } else if (this->objtype == 2) {
+ // Use a reference with copy.
+ FloatPtrConst iarray(new float_32[mylength]);
+ lcmgdl_c(&(this->addr), iset, (int_32 *)iarray.get());
+ return iarray;
+ } else {
+ throw LCMexception("getFloat not available for file objects");
+ }
+}
+
+StringPtrConst ganlib::Clcm::getString(const std::string key) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getString not available for file objects");
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getString(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 3) {
+ hsmg << "getString(" << key << ") expecting a character array(1)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpd_c(&(this->addr), (char *)key.c_str(), &iarray);
+ return StringPtrConst(new string((char*)iarray, 4*mylength));
+}
+
+StringPtrConst ganlib::Clcm::getString(const int_32 iset) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getString not available for file objects");
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getString(" << iset << ") entry is missing(2)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 3) {
+ hsmg << "getString(" << iset << ") expecting a character array(2)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpl_c(&(this->addr), iset, &iarray);
+ return StringPtrConst(new string((char*)iarray, 4*mylength));
+}
+
+StringVecPtr ganlib::Clcm::getVecString(const std::string key, const int_32 size) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getVecString not available for file objects");
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getVecString(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 3) {
+ hsmg << "getVecString(" << key << ") expecting a character array(1)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpd_c(&(this->addr), (char *)key.c_str(), &iarray);
+ StringVecPtr ivecPtr = StringVecPtr(new vector<string>);
+ for (int i=0; i<size; i++) {
+ int_32 nbchar = ( mylength*4 + size - 1) / size;
+ int_32 istart = nbchar*i;
+ if (i == size-1) nbchar = mylength*4 - nbchar*i;
+ if (nbchar != 0) {
+ string myString = string((char *)iarray, istart, nbchar);
+ ivecPtr->push_back(myString.substr(0, myString.find_last_not_of(" ")+1));
+ }
+ }
+ return ivecPtr;
+}
+
+StringVecPtr ganlib::Clcm::getVecString(const int_32 iset, const int_32 size) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getVecString not available for file objects");
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getVecString(" << iset << ") entry is missing(2)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 3) {
+ hsmg << "getVecString(" << iset << ") expecting a character array(2)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpl_c(&(this->addr), iset, &iarray);
+ StringVecPtr ivecPtr = StringVecPtr(new vector<string>);
+ for (int i=0; i<size; i++) {
+ int_32 nbchar = ( mylength*4 + size - 1) / size;
+ int_32 istart = nbchar*i;
+ if (i == size-1) nbchar = mylength*4 - nbchar*i;
+ if (nbchar != 0) {
+ string myString = string((char *)iarray, istart, nbchar);
+ ivecPtr->push_back(myString.substr(0, myString.find_last_not_of(" ") + 1));
+ }
+ }
+ return ivecPtr;
+}
+
+DoublePtrConst ganlib::Clcm::getDouble(const std::string key) {
+ int_32 mylength, itylcm;
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getDouble(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 4) {
+ hsmg << "getDouble(" << key << ") expecting a double precision real array(1)";
+ throw LCMexception(hsmg.str());
+ }
+ if (this->objtype == 1) {
+ // Use a reference without copy (pinning).
+ double_64 *array;
+ lcmgpd_c(&(this->addr), (char *)key.c_str(), (int_32 **)&array);
+ DoublePtrConst iarray(array, my_deleter<const double_64>());
+ return iarray;
+ } else if (this->objtype == 2) {
+ // Use a reference with copy.
+ DoublePtrConst iarray(new double_64[mylength]);
+ lcmget_c(&(this->addr), (char *)key.c_str(), (int_32 *)iarray.get());
+ return iarray;
+ } else {
+ throw LCMexception("getDouble not available for file objects");
+ }
+}
+
+DoublePtrConst ganlib::Clcm::getDouble(const int_32 iset) {
+ int_32 mylength, itylcm;
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getDouble(" << iset << ") entry is missing(2)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 4) {
+ hsmg << "getDouble(" << iset << ") expecting a double precision real array(2)";
+ throw LCMexception(hsmg.str());
+ }
+ if (this->objtype == 1) {
+ // Use a reference without copy (pinning).
+ double_64 *array;
+ lcmgpl_c(&(this->addr), iset, (int_32 **)&array);
+ DoublePtrConst iarray(array, my_deleter<const double_64>());
+ return iarray;
+ } else if (this->objtype == 2) {
+ // Use a reference with copy.
+ DoublePtrConst iarray(new double_64[mylength]);
+ lcmgdl_c(&(this->addr), iset, (int_32 *)iarray.get());
+ return iarray;
+ } else {
+ throw LCMexception("getDouble not available for file objects");
+ }
+}
+
+BoolPtrConst ganlib::Clcm::getBool(const std::string key) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getBool not available for file objects");
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getBool(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 5) {
+ hsmg << "getBool(" << key << ") expecting a boolean array(1)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpd_c(&(this->addr), (char *)key.c_str(), &iarray);
+ BoolPtrConst ibool(new bool[mylength]);
+ bool *myBool = (bool *)ibool.get();
+ for (int i=0; i<mylength; i++) myBool[i] = (iarray[i] == 1);
+ return ibool;
+}
+
+BoolPtrConst ganlib::Clcm::getBool(const int_32 iset) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getBool not available for file objects");
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getBool(" << iset << ") entry is missing(2)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 5) {
+ hsmg << "getBool(" << iset << ") expecting a boolean array(2)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpl_c(&(this->addr), iset, &iarray);
+ BoolPtrConst ibool(new bool[mylength]);
+ bool *myBool = (bool *)ibool.get();
+ for (int i=0; i<mylength; i++) myBool[i] = (iarray[i] == 1);
+ return ibool;
+}
+
+ComplexPtrConst ganlib::Clcm::getComplex(const std::string key) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getComplex not available for file objects");
+ lcmlen_c(&(this->addr), (char *)key.c_str() ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getComplex(" << key << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 6) {
+ hsmg << "getComplex(" << key << ") expecting a Complex array(1)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpd_c(&(this->addr), (char *)key.c_str(), &iarray);
+ complex<float_32> *icomplex = new complex<float_32>[mylength];
+ for (int i=0; i<mylength; i++) {
+ icomplex[i] = complex<float_32>((float_32)iarray[2*i],(float_32)iarray[1+2*i]);
+ }
+ return ComplexPtrConst(icomplex);
+}
+
+ComplexPtrConst ganlib::Clcm::getComplex(const int_32 iset) {
+ int_32 mylength, itylcm;
+ if (this->objtype > 2) throw LCMexception("getComplex not available for file objects");
+ lcmlel_c(&(this->addr), iset ,&mylength, &itylcm);
+ if (mylength == 0) {
+ hsmg << "getComplex(" << iset << ") entry is missing(1)";
+ throw LCMexception(hsmg.str());
+ } else if (itylcm != 6) {
+ hsmg << "getComplex(" << iset << ") expecting a Complex array(2)";
+ throw LCMexception(hsmg.str());
+ }
+ // Use a reference with copy.
+ int_32 *iarray;
+ lcmgpl_c(&(this->addr), iset, &iarray);
+ complex<float_32> *icomplex = new complex<float_32>[mylength];
+ for (int i=0; i<mylength; i++) {
+ icomplex[i] = complex<float_32>((float_32)iarray[2*i],(float_32)iarray[1+2*i]);
+ }
+ return ComplexPtrConst(icomplex);
+}
+
+//----------------------------------------------------------------------
+//-- keys --
+//----------------------------------------------------------------------
+
+StringVecPtr ganlib::Clcm::keys() {
+ if (this->objtype > 2) throw LCMexception("keys not available for file objects");
+ if (this->getLength() != -1) throw LCMexception("keys only available for dictionaries");
+ StringVecPtr ivecPtr = StringVecPtr(new vector<string>);
+ char first[13], key[13];
+ strcpy(first, " ");
+ lcmnxt_c(&(this->addr), first);
+ strcpy(key, first);
+ while (true) {
+ lcmnxt_c(&(this->addr), key);
+ ivecPtr->push_back(string(key));
+ if (strcmp(key, first) == 0) break;
+ }
+ return ivecPtr;
+}
+
+//----------------------------------------------------------------------
+//-- put --
+//----------------------------------------------------------------------
+
+void ganlib::Clcm::put(const std::string key, IntPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << key << ") has zero length(1)";
+ throw LCMexception(hsmg.str());
+ }
+ int_32 *myArrayPointer = (int_32 *)myArray.get();
+ if ((this->objtype == 1) && (this->global_list != NULL)) {
+ // Use a reference without copy (pinning) for memory-resident lcm objects.
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 1, myArrayPointer);
+ refpush(&(this->addr), myArrayPointer);
+ (this->global_list)->push_back(myArray);
+ } else if (this->objtype == 1) {
+ // Use a reference with copy for memory-resident lcm objects (the lcm object is
+ // coming from outside C++).
+ int_32 *iarray = setara_c(myLength);
+ for (int i=0; i<myLength; i++) iarray[i] = myArrayPointer[i];
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 1, iarray);
+ } else if (this->objtype == 2) {
+ // Use a reference with copy for xsm file objects.
+ xsm *ipxsm = (xsm *)(this->addr);
+ xsmput_c(&ipxsm, (char *)key.c_str(), myLength, 1, myArrayPointer);
+ }
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, IntPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << iset << ") has zero length(2)";
+ throw LCMexception(hsmg.str());
+ }
+ int_32 *myArrayPointer = (int_32 *)myArray.get();
+ if ((this->objtype == 1) && (this->global_list != NULL)) {
+ // Use a reference without copy (pinning) for memory-resident lcm objects.
+ lcmppl_c(&(this->addr), iset, myLength, 1, myArrayPointer);
+ refpush(&(this->addr), myArrayPointer);
+ (this->global_list)->push_back(myArray);
+ } else if (this->objtype == 1) {
+ // Use a reference with copy for memory-resident lcm objects (the lcm object is
+ // coming from outside C++).
+ int_32 *iarray = setara_c(myLength);
+ for (int i=0; i<myLength; i++) iarray[i] = myArrayPointer[i];
+ lcmppl_c(&(this->addr), iset, myLength, 1, iarray);
+ } else if (this->objtype == 2) {
+ // Use a reference with copy for xsm file objects.
+ xsm *ipxsm = (xsm *)(this->addr) + iset;
+ xsmput_c(&ipxsm, " ", myLength, 1, myArrayPointer);
+ }
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const std::string key, FloatPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << key << ") has zero length(1)";
+ throw LCMexception(hsmg.str());
+ }
+ float_32 *myArrayPointer = (float_32 *)myArray.get();
+ if ((this->objtype == 1) && (this->global_list != NULL)) {
+ // Use a reference without copy (pinning) for memory-resident lcm objects.
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 2, (int_32 *)myArrayPointer);
+ refpush(&(this->addr), (int_32 *)myArrayPointer);
+ (this->global_list)->push_back(myArray);
+ } else if (this->objtype == 1) {
+ // Use a reference with copy for memory-resident lcm objects (the lcm object is
+ // coming from outside C++).
+ int_32 *iarray = setara_c(myLength);
+ for (int i=0; i<myLength; i++) iarray[i] = (int_32)myArrayPointer[i];
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 2, iarray);
+ } else if (this->objtype == 2) {
+ // Use a reference with copy for xsm file objects.
+ xsm *ipxsm = (xsm *)(this->addr);
+ xsmput_c(&ipxsm, (char *)key.c_str(), myLength, 2, (int_32 *)myArrayPointer);
+ }
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, FloatPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << iset << ") has zero length(2)";
+ throw LCMexception(hsmg.str());
+ }
+ float_32 *myArrayPointer = (float_32 *)myArray.get();
+ if ((this->objtype == 1) && (this->global_list != NULL)) {
+ // Use a reference without copy (pinning) for memory-resident lcm objects.
+ lcmppl_c(&(this->addr), iset, myLength, 2, (int_32 *)myArrayPointer);
+ refpush(&(this->addr), (int_32 *)myArrayPointer);
+ (this->global_list)->push_back(myArray);
+ } else if (this->objtype == 1) {
+ // Use a reference with copy for memory-resident lcm objects (the lcm object is
+ // coming from outside C++).
+ int_32 *iarray = setara_c(myLength);
+ for (int i=0; i<myLength; i++) iarray[i] = (int_32)myArrayPointer[i];
+ lcmppl_c(&(this->addr), iset, myLength, 2, iarray);
+ } else if (this->objtype == 2) {
+ // Use a reference with copy for xsm file objects.
+ xsm *ipxsm = (xsm *)(this->addr) + iset;
+ xsmput_c(&ipxsm, " ", myLength, 2, (int_32 *)myArrayPointer);
+ }
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const std::string key, StringPtr myArray) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ } else if ((myArray.get())->length() <= 0) {
+ hsmg << "put(" << key << ") has zero length(1)";
+ throw LCMexception(hsmg.str());
+ }
+ int_32 ilen = ((myArray.get())->length()+3)/4;
+ int_32 *iarray = (int_32 *)setara_c(ilen);
+ for (int i=0; i<ilen; i++) memcpy((char *)&iarray[i], " ", 4);
+ string myString = *myArray.get();
+ strncpy((char *)iarray, myString.c_str(), myString.length());
+ lcmppd_c(&(this->addr), (char *)key.c_str(), ilen, 3, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, StringPtr myArray) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ } else if ((myArray.get())->length() <= 0) {
+ hsmg << "put(" << iset << ") has zero length(2)";
+ throw LCMexception(hsmg.str());
+ }
+ int_32 ilen = ((myArray.get())->length()+3)/4;
+ int_32 *iarray = (int_32 *)setara_c(ilen);
+ for (int i=0; i<ilen; i++) memcpy((char *)&iarray[i], " ", 4);
+ string myString = *myArray.get();
+ strncpy((char *)iarray, myString.c_str(), myString.length());
+ lcmppl_c(&(this->addr), iset, ilen, 3, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const std::string key, StringVecPtr myArray) {
+ const vector<string> *ivec = (vector<string>*)myArray.get();
+ const int_32 mySize = ivec->size();
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ } else if (mySize <= 0) {
+ hsmg << "put(" << key << ") has zero size(1)";
+ throw LCMexception(hsmg.str());
+ }
+ int_32 maxLength = 0;
+ for (int i=0; i<mySize; i++) {
+ maxLength = max(maxLength, (int_32)(*ivec)[i].length());
+ }
+ if (maxLength == 0) {
+ hsmg << "put(" << key << ") has zero length(1)";
+ throw LCMexception(hsmg.str());
+ }
+ maxLength = (maxLength+3)/4;
+ int_32 *iarray = (int_32 *)setara_c(maxLength*mySize);
+ for (int i=0; i<maxLength*mySize; i++) memcpy((char *)&iarray[i], " ", 4);
+ for (int i=0; i<mySize; i++) {
+ string myString = (*ivec)[i];
+ strncpy((char *)&iarray[maxLength*i], myString.c_str(), myString.length());
+ }
+ lcmppd_c(&(this->addr), (char *)key.c_str(), maxLength*mySize, 3, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, StringVecPtr myArray) {
+ const vector<string> *ivec = (vector<string>*)myArray.get();
+ const int_32 mySize = ivec->size();
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ } else if (mySize <= 0) {
+ hsmg << "put(" << iset << ") has zero size(2)";
+ throw LCMexception(hsmg.str());
+ }
+ int_32 maxLength = 0;
+ for (int i=0; i<mySize; i++) {
+ maxLength = max(maxLength, (int_32)(*ivec)[i].length());
+ }
+ if (maxLength == 0) {
+ hsmg << "put(" << iset << ") has zero length(2)";
+ throw LCMexception(hsmg.str());
+ }
+ maxLength = (maxLength+3)/4;
+ int_32 *iarray = (int_32 *)setara_c(maxLength*mySize);
+ for (int i=0; i<maxLength*mySize; i++) memcpy((char *)(&iarray[i]), " ", 4);
+ for (int i=0; i<mySize; i++) {
+ string myString = (*ivec)[i];
+ strncpy((char *)(&iarray[maxLength*i]), myString.c_str(), myString.length());
+ }
+ lcmppl_c(&(this->addr), iset, maxLength*mySize, 3, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const std::string key, DoublePtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << key << ") has zero length(1)";
+ throw LCMexception(hsmg.str());
+ }
+ double_64 *myArrayPointer = (double_64 *)myArray.get();
+ if ((this->objtype == 1) && (this->global_list != NULL)) {
+ // Use a reference without copy (pinning) for memory-resident lcm objects.
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 4, (int_32 *)myArrayPointer);
+ refpush(&(this->addr), (int_32 *)myArrayPointer);
+ (this->global_list)->push_back(myArray);
+ } else if (this->objtype == 1) {
+ // Use a reference with copy for memory-resident lcm objects (the lcm object is
+ // coming from outside C++).
+ int_32 *iarray = setara_c(2*myLength);
+ for (int i=0; i<2*myLength; i++) iarray[i] = ((int_32 *)myArrayPointer)[i];
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 4, iarray);
+ } else if (this->objtype == 2) {
+ // Use a reference with copy for xsm file objects.
+ xsm *ipxsm = (xsm *)(this->addr);
+ xsmput_c(&ipxsm, (char *)key.c_str(), myLength, 4, (int_32 *)myArrayPointer);
+ }
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, DoublePtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << iset << ") has zero length(2)";
+ throw LCMexception(hsmg.str());
+ }
+ double_64 *myArrayPointer = (double_64 *)myArray.get();
+ if ((this->objtype == 1) && (this->global_list != NULL)) {
+ // Use a reference without copy (pinning) for memory-resident lcm objects.
+ lcmppl_c(&(this->addr), iset, myLength, 4, (int_32 *)myArrayPointer);
+ refpush(&(this->addr), (int_32 *)myArrayPointer);
+ (this->global_list)->push_back(myArray);
+ } else if (this->objtype == 1) {
+ // Use a reference with copy for memory-resident lcm objects (the lcm object is
+ // coming from outside C++).
+ int_32 *iarray = setara_c(2*myLength);
+ for (int i=0; i<2*myLength; i++) iarray[i] = ((int_32 *)myArrayPointer)[i];
+ lcmppl_c(&(this->addr), iset, myLength, 4, iarray);
+ } else if (this->objtype == 2) {
+ // Use a reference with copy for xsm file objects.
+ xsm *ipxsm = (xsm *)(this->addr) + iset;
+ xsmput_c(&ipxsm, " ", myLength, 4, (int_32 *)myArrayPointer);
+ }
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const std::string key, BoolPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << key << ") has zero length(1)";
+ throw LCMexception(hsmg.str());
+ }
+ bool *myArrayPointer = (bool *)myArray.get();
+ // Use a reference with copy.
+ int_32 *iarray = setara_c(myLength);
+ for (int i=0; i<myLength; i++) {
+ myArrayPointer[i] ? iarray[2*i] = 1 : iarray[2*i] = 0;
+ }
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 5, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, BoolPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << iset << ") has zero length(2)";
+ throw LCMexception(hsmg.str());
+ }
+ bool *myArrayPointer = (bool *)myArray.get();
+ // Use a reference with copy.
+ int_32 *iarray = setara_c(myLength);
+ for (int i=0; i<myLength; i++) {
+ myArrayPointer[i] ? iarray[2*i] = 1 : iarray[2*i] = 0;
+ }
+ lcmppl_c(&(this->addr), iset, myLength, 5, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const std::string key, ComplexPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << key << ") has zero length(1)";
+ throw LCMexception(hsmg.str());
+ }
+ complex<float_32> *myArrayPointer = (complex<float_32> *)myArray.get();
+ // Use a reference with copy.
+ int_32 *iarray = setara_c(2*myLength);
+ for (int i=0; i<myLength; i++) {
+ iarray[2*i] = (int_32)myArrayPointer[i].real();
+ iarray[1+2*i] = (int_32)myArrayPointer[i].imag();
+ }
+ lcmppd_c(&(this->addr), (char *)key.c_str(), myLength, 6, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, ComplexPtr myArray, const int_32 myLength) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ } else if (myLength <= 0) {
+ hsmg << "put(" << iset << ") has zero length(2)";
+ throw LCMexception(hsmg.str());
+ }
+ complex<float_32> *myArrayPointer = (complex<float_32> *)myArray.get();
+ // Use a reference with copy.
+ int_32 *iarray = setara_c(2*myLength);
+ for (int i=0; i<myLength; i++) {
+ iarray[2*i] = (int_32)myArrayPointer[i].real();
+ iarray[1+2*i] = (int_32)myArrayPointer[i].imag();
+ }
+ lcmppl_c(&(this->addr), iset, myLength, 6, iarray);
+ myArray.reset();
+ return;
+}
+
+void ganlib::Clcm::put(const std::string key, ClcmPtr myClcm) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << key << ") forbidden if the object is not open in modification mode(1)";
+ throw LCMexception(hsmg.str());
+ }
+ lcm *daughter = lcmgid_c(&(this->addr), (char *)key.c_str());
+ lcm *myLcm = myClcm->addr;
+ lcmequ_c(&myLcm, &daughter);
+ return;
+}
+
+void ganlib::Clcm::put(const int_32 iset, ClcmPtr myClcm) {
+ if (this->getAccess() != 1) {
+ hsmg << "put(" << iset << ") forbidden if the object is not open in modification mode(2)";
+ throw LCMexception(hsmg.str());
+ }
+ lcm *daughter = lcmgil_c(&(this->addr), iset);
+ lcm *myLcm = myClcm->addr;
+ lcmequ_c(&myLcm, &daughter);
+ return;
+}
+
+lcm *ganlib::Clcm::extract() {
+ return this->addr;
+}
diff --git a/Skin++/src/Clcm.hxx b/Skin++/src/Clcm.hxx
new file mode 100755
index 0000000..86a12b7
--- /dev/null
+++ b/Skin++/src/Clcm.hxx
@@ -0,0 +1,706 @@
+/**
+ * This class is an implementation of the C++ bindings for LCM.
+ * LCM capabilities are available for a program written in C++
+ * by using methods belonging to the Clcm class.
+ * <P> A Clcm object in C++ can encapsulate a native LCM object
+ * which can be memory-resident or persistent (using the XSM C API)
+ * or a file. A LCM or XSM native object can contains dictionaries
+ * (aka associative tables or hash tables) and lists.
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2024)
+ */
+#ifndef Clcm_HXX
+#define Clcm_HXX
+
+#include <cstddef> // for __GLIBCXX__
+
+#ifdef __GLIBCXX__ // for memory management with shared_ptr
+# include <tr1/memory>
+#else
+# ifdef __IBMCPP__
+# define __IBMCPP_TR1__
+# endif
+# include <memory>
+#endif
+
+#include <cerrno>
+#include <cstdio>
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <fstream>
+#include <complex>
+#include <memory>
+#include <variant>
+#include "LCMexception.hxx"
+extern "C" {
+#include <dirent.h>
+#include "lcm.h"
+}
+
+#define IntPtr std::shared_ptr<int_32[]>
+#define FloatPtr std::shared_ptr<float_32[]>
+#define StringPtr std::shared_ptr<std::string>
+#define DoublePtr std::shared_ptr<double_64[]>
+#define BoolPtr std::shared_ptr<bool[]>
+#define ComplexPtr std::shared_ptr< std::complex<float_32>[] >
+#define StringVecPtr std::shared_ptr< std::vector<std::string> >
+#define ClcmPtr std::shared_ptr<Clcm>
+
+// support for pinning.
+#define AnyPtr std::variant<IntPtr, FloatPtr, StringPtr, DoublePtr, BoolPtr, ComplexPtr>
+#define IntPtrConst std::shared_ptr<const int_32>
+#define FloatPtrConst std::shared_ptr<const float_32>
+#define StringPtrConst std::shared_ptr<const std::string>
+#define DoublePtrConst std::shared_ptr<const double_64>
+#define BoolPtrConst std::shared_ptr<const bool>
+#define ComplexPtrConst std::shared_ptr<const std::complex<float_32> >
+
+namespace ganlib {
+
+/**
+ * This class is an implementation of the C++/shared_ptr bindings for LCM.
+ * LCM capabilities are available for a program written in C++
+ * by using methods belonging to the Clcm class. These methods
+ * encapsulate the LCM C API calls used as "extern"C" functions.
+ * <P> A Clcm object in C++ can encapsulate a native LCM object
+ * which can be memory-resident or persistent (using the XSM C API)
+ * or a file. A LCM or XSM native object can contains dictionaries
+ * (aka associative tables or hash tables) and lists.
+ * <P>
+ * The Clcm class uses predefined declarations for some datatypes:
+ * <table border="0">
+ * <tr> <td><tt>#define IntPtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr<int_32[]></tt></td> </tr>
+ * <tr> <td><tt>#define FloatPtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr<float_32[]></tt></td> </tr>
+ * <tr> <td><tt>#define StringPtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr<std::string></tt></td> </tr>
+ * <tr> <td><tt>#define DoublePtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr<double_64[]></tt></td> </tr>
+ * <tr> <td><tt>#define BoolPtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr<bool[]></tt></td> </tr>
+ * <tr> <td><tt>#define ComplexPtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr< complex<float_32>[] ></tt></td> </tr>
+ * <tr> <td><tt>#define StringVecPtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr< std::vector<std::string> ></tt></td> </tr>
+ * <tr> <td><tt>#define ClcmPtr</tt>:</td> &nbsp; <td><tt>std::shared_ptr<Clcm></tt></td> </tr>
+ * </table>
+ * <P>
+ * Moreover, get methods are constructing shared arrays that <i>cannot</i> be modified in the calling C++
+ * code. To prevent this, they are declared <tt>const</tt> using the following predefined declarations:
+ * <table border="0">
+ * <tr> <td><tt>#define IntPtrConst</tt>:</td> &nbsp; <td><tt>std::shared_ptr<const int_32[]></tt></td> </tr>
+ * <tr> <td><tt>#define FloatPtrConst</tt>:</td> &nbsp; <td><tt>std::shared_ptr<const float_32[]></tt></td> </tr>
+ * <tr> <td><tt>#define StringPtrConst</tt>:</td> &nbsp; <td><tt>std::shared_ptr<const std::string></tt></td> </tr>
+ * <tr> <td><tt>#define DoublePtrConst</tt>:</td> &nbsp; <td><tt>std::shared_ptr<const double_64[]></tt></td> </tr>
+ * <tr> <td><tt>#define BoolPtrConst</tt>:</td> &nbsp; <td><tt>std::shared_ptr<const bool[]></tt></td> </tr>
+ * <tr> <td><tt>#define ComplexPtrConst</tt>:</td> &nbsp; <td><tt>std::shared_ptr<const complex<float_32>[] ></tt></td> </tr>
+ * </table>
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2010)
+ */
+
+class Clcm {
+public:
+ /**
+ * Use this constructor to create a Clcm object of a specified type.
+ * The new LCM object is open in modification mode and is in a state
+ * such that the <tt>isNew()</tt> method will return <tt>true</tt>.
+ * If a XSM file <tt>name</tt> exists, the Clcm object is pointing to
+ * this file open in <tt>"READ-ONLY"</tt> mode and is in a state
+ * such that the <tt>isNew()</tt> method will return <tt>false</tt>.
+ * If the type is <tt>"LCM_IMP"</tt> or <tt>"XSM_IMP"</tt>, the new
+ * LCM object is open in modification mode and the <tt>isNew()</tt>
+ * method will return <tt>false</tt>.
+ * <p>
+ * A Clcm object is created using a construct similar to the following one:
+ * <pre>
+ * ClcmPtr myNewClcm = ClcmPtr(new Clcm("XSM_IMP_ASCII", "Multicompo", "./"));
+ * </pre>
+ * where a XSM file is imported from ASCII file <tt>./Multicompo</tt>.
+ *
+ * @param stype type of the new Clcm object. This variable is chosen among
+ * the following values:
+ * <ul><dl>
+ * <dt> <tt>"LCM"</tt> <dd> memory-resident LCM object
+ * <dt> <tt>"XSM"</tt> <dd> XSM object (or persistent LCM object)
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * <dt> <tt>"DA"</tt> <dd> binary direct-access file (with 128-word records)
+ * <dt> <tt>"LCM_IMP_BINARY"</tt> <dd> memory-resident LCM object constructed by
+ * importing from a binary sequential file named <tt>"_"</tt>+name
+ * <dt> <tt>"XSM_IMP_BINARY"</tt> <dd> XSM object constructed by importing
+ * from a binary sequential file named <tt>"_"</tt>+name
+ * <dt> <tt>"LCM_IMP_ASCII"</tt> <dd> memory-resident LCM object constructed by
+ * importing from an ASCII sequential file named <tt>"_"</tt>+name
+ * <dt> <tt>"XSM_IMP_ASCII"</tt> <dd> XSM object constructed by importing
+ * from an ASCII sequential file named <tt>"_"</tt>+name
+ * </dl></ul>
+ * @param myName creation name of the new Clcm object
+ * @param myPath path to access the associated file. This can be a sequential import
+ * file (with <tt>"_"</tt> prefix), an <tt>"XSM"</tt>, <tt>"BINARY"</tt>,
+ * <tt>"ASCII"</tt> or <tt>"DA"</tt> file. Set to <tt>"./"</tt> to work
+ * in the current directory.
+ */
+ Clcm(const std::string stype, const std::string myName, const std::string myPath);
+
+ /// @cond DEV
+ Clcm(lcm *, Clcm *, const int_32, const std::string, const int_32, const std::string);
+ /// @endcond
+
+ /**
+ * Use this constructor to create a clone of an existing Clcm object. This is a deep-copy
+ * operation. A clone is created using the following construct:
+ * <pre>
+ * ClcmPtr myClcmClone = ClcmPtr(new Clcm("LCM", myClcm));
+ * </pre>
+ * @param stype type of the new Clcm object. This variable is chosen among
+ * the following values:
+ * <ul><dl>
+ * <dt> <tt>"LCM"</tt> <dd> memory-resident LCM object
+ * <dt> <tt>"XSM"</tt> <dd> XSM object (or persistent LCM object)
+ * </dl></ul>
+ * @param myClcm existing ClcmPtr object accessed in read-only mode. This object must me of
+ * LCM or XSM type.
+ */
+ Clcm(const std::string stype, ClcmPtr myClcm);
+
+ /**
+ * Use this constructor to encapsulate an open LCM or XSM object into a Clcm object. The
+ * existing LCM or XSM object is not garbage collected (it may belong to another Clcm object).
+ * @param mylcm existing LCM or XSM object.
+ * @param type type of object (=1: LCM; =2:XSM).
+ * @param access access mode of object (=1: ; =2:).
+ * @param OSname operating system name of object.
+ */
+ Clcm(lcm *mylcm, const int_32 type, const int_32 access, const std::string OSname);
+
+ /** Close and destroy a Clcm object if in modification mode; close and
+ * keep a Clcm object if in read-only mode.
+ */
+ ~Clcm();
+
+ /** Export a Clcm object into an ostream (ascii stream). This method is not available for
+ * file-type Clcm objects. A Clcm object can be dumped to the standard output using:
+ * <pre>
+ * cout << myClcm;
+ * </pre>
+ * @param s initial std::ostream objet.
+ * @param myClcm ClcmPtr object to export.
+ * @return final std::ostream objet including the ClcmPtr object.
+ */
+ friend std::ostream & operator<<(std::ostream &s, ClcmPtr myClcm);
+
+ /** Serialize and save the object content on a sequential file. This method is not
+ * available for file-type Clcm objects. The name of the sequential file is
+ * the catenation of <tt>"_"</tt> with the name of the Clcm object.
+ * @param stype type of the export file. This variable is chosen among
+ * the following values:
+ * <ul><dl>
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * </dl></ul>
+ */
+ void expor(const std::string stype);
+
+ /** Serialize and save the object content on a sequential file. This method is not
+ * available for file-type Clcm objects.
+ * @param stype type of the export file. This variable is chosen among
+ * the following values:
+ * <ul><dl>
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * </dl></ul>
+ * @param new_name name of the sequential file. This name must begin by
+ * character <tt>"_"</tt>.
+ */
+ void expor(const std::string stype, const std::string new_name);
+
+ /** Cause an exception (used to debug XABORT in C++).
+ */
+ void except();
+
+ /** Return the name of the Clcm object.
+ */
+ std::string getName() throw();
+
+ /** Return the path to access the associated file.
+ */
+ std::string getPath() throw();
+
+ /** Return the type of the Clcm object.
+ * @return =1: memory-resident LCM object; =2: persistent LCM object;
+ * =3: binary sequential file; =4: ASCII sequential file; =5 binary
+ * direct-access file.
+ */
+ int_32 getType() throw();
+
+ /** Return the length of a list-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * @return =-1: dictionary; >=1: length of the list-type Clcm object.
+ */
+ int_32 getLength();
+
+ /** Return the name of the accessible directory of a dictionary-type
+ * Clcm object. This method is not available for file-type Clcm objects.
+ * @return =<tt>"/"</tt> for a dictionary on root or name of the accessible
+ * directory.
+ */
+ std::string getDirectory();
+
+ /** Return the access type of a Clcm object.
+ * @return =0: the object is closed; =1: the object is open in modification
+ * mode; =2: the object is open in read-only mode.
+ */
+ int_32 getAccess();
+
+ /** Return the number of words in a record of a direct access-type Clcm object.
+ */
+ int_32 getLrda() throw();
+
+ /** Return the original version of the imported object.
+ */
+ int_32 getVersion() throw();
+
+ /** Return true if the a dictionary-type Clcm object is empty. This method
+ * is not available for file-type Clcm objects.
+ */
+ bool isEmpty();
+
+ /** Return true if the dictionary-type Clcm object is new. This method
+ * is not available for file-type Clcm objects.
+ */
+ bool isNew() throw();
+
+ /** Open a new Clcm object or reopen an existing Clcm object already closed by
+ * the close(<tt>"KEEP"</tt>) method. In this case, the Clcm object is reopen
+ * in a state such as the <tt>isNew()</tt> method will return false.
+ * @param saccess type of open. This variable is chosen among the following
+ * values:
+ * <ul><dl>
+ * <dt> <tt>"NEW"</tt> <dd> open a new Clcm object.
+ * <dt> <tt>"READ/WRITE"</tt> <dd> open in modification mode.
+ * <dt> <tt>"READ-ONLY"</tt> <dd> open in read-only mode.
+ * </dl></ul>
+ */
+ void open(const std::string saccess);
+
+ /** Close a Clcm object.
+ * @param saccess =<tt>"KEEP"</tt>: close without destruction of the object
+ * content; =<tt>"DESTROY"</tt>: close with destruction of the object content.
+ */
+ void close(const std::string saccess);
+
+ /**
+ * Return the length of a block of information in a dictionary-type
+ * Clcm object. This method is not available for file-type Clcm objects.
+ * @param key key identification of the block in the dictionary
+ * @return the number of components for an elementary block; -1 for
+ * a daughter dictionary; 0: the block does't exist; length of the list
+ * for a daughter list; length in characters for a string array.
+ */
+ int_32 length(const std::string key);
+
+ /**
+ * Return the length of a block of information in a list-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ * @param iset index of the block in the list. The first list element is
+ * stored at index 0.
+ * @return the number of components for an elementary block; -1 for
+ * a daughter dictionary; 0: the block does't exist; length of the list
+ * for a daughter list; length in characters for a string array.
+ */
+ int_32 length(const int_32 iset);
+
+ /**
+ * Return the type of a block of information in a dictionary-type
+ * Clcm object. This method is not available for file-type Clcm objects.
+ * @param key key identification of the block in the dictionary
+ * @return =0: dictionary; =1: integer (int_32); =2: real number (float);
+ * =3: string; =4: real number (double); =5: boolean; =6: Complex object;
+ * =10: list.
+ */
+ int_32 type(const std::string key);
+
+ /**
+ * Return the type of a block of information in a list-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ * @param iset index of the block in the list. The first list element is
+ * stored at index 0.
+ * @return =0: dictionary; =1: integer (int_32); =2: real number (float);
+ * =3: string; =4: real number (double); =5: boolean; =6: Complex object;
+ * =10: list.
+ */
+ int_32 type(const int_32 iset);
+
+ /** Print the table of contents of a dictionary- or list-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ */
+ void lib();
+
+ /** Validate a dictionary- or list-type Clcm object. Detect possible memory
+ * corruption.
+ * This method is not available for file-type Clcm objects.
+ */
+ void val();
+
+ /** Set a daughter dictionary-type Clcm object from a dictionary-type Clcm
+ * object. This method is not available for file-type Clcm objects.
+ * @param key key identification of the daughter Clcm object in the dictionary
+ * @return daughter ClcmPtr object of dictionary or list type.
+ */
+ ClcmPtr setDictionary(const std::string key);
+
+ /** Set a daughter dictionary-type Clcm object from a list-type Clcm
+ * object. This method is not available for file-type Clcm objects.
+ * @param iset index of the daughter Clcm object in the list. The first list
+ * element is stored at index 0.
+ * @return daughter ClcmPtr object of dictionary or list type.
+ */
+ ClcmPtr setDictionary(const int_32 iset);
+
+ /** Set a daughter list-type Clcm object from a dictionary-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ * @param key key identification of the daughter Clcm object in the dictionary
+ * @param ilong initial length of the heterogeneous list
+ * @return daughter ClcmPtr object of dictionary or list type.
+ */
+ ClcmPtr setList(const std::string key, const int_32 ilong);
+
+ /** Set a daughter list-type Clcm object from a list-type Clcm object
+ * This method is not available for file-type Clcm objects.
+ * @param iset index of the daughter Clcm object in the list. The first list
+ * element is stored at index 0.
+ * @param ilong initial length of the heterogeneous list
+ * @return daughter ClcmPtr object of dictionary or list type.
+ */
+ ClcmPtr setList(const int_32 iset, const int_32 ilong);
+
+ /** Recover a daughter Clcm object from an existing dictionary-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ * @param key key identification of the daughter Clcm object in the dictionary
+ * @return daughter ClcmPtr object of dictionary or list type.
+ */
+ ClcmPtr getClcm(const std::string key);
+
+ /** Recover a daughter Clcm object from an existing list-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ * @param iset index of the daughter Clcm object in the list. The first list
+ * element is stored at index 0.
+ * @return daughter ClcmPtr object of dictionary or list type.
+ */
+ ClcmPtr getClcm(const int_32 iset);
+
+ /** Recover an integer array from a dictionary-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getInt</tt>. This method is not available for file-type Clcm objects.
+ * <p>
+ * <b>Example</b>: An integer array named <tt>"myArray"</tt> is read from
+ * Clcm object named <tt>multicompo</tt> using
+ * <pre>
+ * IntPtrConst ia = multicompo->getInt("myArray");
+ * for(int i = 0; i < multicompo->length("myArray"); ++i)
+ * cout << "ia(" << i << ")=" << ia[i] << endl;
+ * </pre>
+ * @param key key identification of the integer array in the dictionary
+ * @return array of integer values stored as <tt>IntPtr</tt> object.
+ */
+ IntPtrConst getInt(const std::string key);
+
+ /** Recover an integer array from a list-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getInt</tt>. This method is not available for file-type Clcm objects.
+ * @param iset index of the integer array in the list. The first list element
+ * is stored at index 0.
+ * @return array of integer values stored as <tt>IntPtr</tt> object.
+ */
+ IntPtrConst getInt(const int_32 iset);
+
+ /** Recover a single precision real array from a dictionary-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getFloat</tt>. This method is not available for file-type Clcm objects.
+ * @param key key identification of the real array in the dictionary
+ * @return array of single precision real values stored as <tt>FloatPtr</tt> object.
+ */
+ FloatPtrConst getFloat(const std::string key);
+
+ /** Recover a single precision real array from a list-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getFloat</tt>. This method is not available for file-type Clcm objects.
+ * @param iset index of the real array in the list. The first list element
+ * is stored at index 0.
+ * @return array of single precision real values stored as <tt>FloatPtr</tt> object.
+ */
+ FloatPtrConst getFloat(const int_32 iset);
+
+ /** Recover a string pointer from a dictionary-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the string returned
+ * by <tt>getString</tt>. This method is not available for file-type Clcm objects.
+ * @param key key identification of the character array in the dictionary
+ * @return character information stored as <tt>StringPtr</tt> object.
+ */
+ StringPtrConst getString(const std::string key);
+
+ /** Recover a string pointer from a list-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the string returned
+ * by <tt>getString</tt>. This method is not available for file-type Clcm objects.
+ * @param iset index of the integer array in the list. The first list element
+ * is stored at index 0.
+ * @return character information stored as <tt>StringPtr</tt> object.
+ */
+ StringPtrConst getString(const int_32 iset);
+
+ /** Recover a vector-of-string pointer from a dictionary-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the vector-of-string returned
+ * by <tt>getVecString</tt>. This method is not available for file-type Clcm objects.
+ * @param key key identification of the character array in the dictionary
+ * @param size number of components in the vector-of-string
+ * @return vector-of-string containing the character information stored as
+ * <tt>StringVecPtr</tt> object.
+ */
+ StringVecPtr getVecString(const std::string key, const int_32 size);
+
+ /** Recover a vector-of-string pointer from a list-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the vector-of-string returned
+ * by <tt>getVecString</tt>. This method is not available for file-type Clcm objects.
+ * @param iset index of the integer array in the list. The first list element
+ * is stored at index 0.
+ * @param size number of components in the vector-of-string
+ * @return vector-of-string containing the character information stored as
+ * <tt>StringVecPtr</tt> object.
+ */
+ StringVecPtr getVecString(const int_32 iset, const int_32 size);
+
+ /** Recover a double precision real array from a dictionary-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getDouble</tt>. This method is not available for file-type Clcm objects.
+ * @param key key identification of the double precision array in the dictionary
+ * @return array of double precision real values stored as <tt>DoublePtr</tt> object.
+ */
+ DoublePtrConst getDouble(const std::string key);
+
+ /** Recover a double precision real array from a list-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getDouble</tt>. This method is not available for file-type Clcm objects.
+ * @param iset index of the double precision array in the list. The first list element
+ * is stored at index 0.
+ * @return array of double precision real values stored as <tt>DoublePtr</tt> object.
+ */
+ DoublePtrConst getDouble(const int_32 iset);
+
+ /** Recover a boolean array from a dictionary-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getBool</tt>. This method is not available for file-type Clcm objects.
+ * @param key key identification of the boolean array in the dictionary
+ * @return array of boolean values stored as <tt>BoolPtr</tt> object.
+ */
+ BoolPtrConst getBool(const std::string key);
+
+ /** Recover a boolean array from a list-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getBool</tt>. This method is not available for file-type Clcm objects.
+ * @param iset index of the boolean array in the list. The first list element
+ * is stored at index 0.
+ * @return array of boolean values stored as <tt>BoolPtr</tt> object.
+ */
+ BoolPtrConst getBool(const int_32 iset);
+
+ /** Recover a complex array from a dictionary-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getComplex</tt>. This method is not available for file-type Clcm objects.
+ * @param key key identification of the complex array in the dictionary
+ * @return array of complex values stored as <tt>ComplexPtr</tt> object.
+ */
+ ComplexPtrConst getComplex(const std::string key);
+
+ /** Recover a complex array from a list-type Clcm object.
+ * <b>General rule:</b> Never try to modify, deallocate or free the object returned
+ * by <tt>getComplex</tt>. This method is not available for file-type Clcm objects.
+ * @param iset index of the complex array in the list. The first list element
+ * is stored at index 0.
+ * @return array of complex values stored as <tt>ComplexPtr</tt> object.
+ */
+ ComplexPtrConst getComplex(const int_32 iset);
+
+ /** Recover a vector-of-string pointer containing the keys of a dictionary-type Clcm
+ * object. <b>General rule:</b> Never try to modify, deallocate or free the vector-of-string
+ * returned by <tt>keys</tt>. This method is not available for file-type or list-type
+ * Clcm objects.
+ * @return <tt>StringVecPtr</tt> of a vector-of-string containing the dictionary keys
+ */
+ StringVecPtr keys();
+
+ /** Store an integer array in a dictionary-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * <p>
+ * <b>Example</b>: An integer array named <tt>"myIntArray"</tt> is inserted in
+ * Clcm object named <tt>multicompo</tt> using
+ * <pre>
+ * static int_32 myStaticArray[] = {33, 22, 11, 89};
+ * IntPtr myIntPtr = IntPtr(new int_32[4]);
+ * for(int i = 0; i < 4; ++i) myIntPtr[i] = myStaticArray[i];
+ * multicompo->put("myIntArray", myIntPtr, 4);
+ * </pre>
+ * @param key key identification of the block in the dictionary
+ * @param myArray integer array stored as <tt>IntPtr</tt> object.
+ * @param myLength number of components in integer array.
+ */
+ void put(const std::string key, IntPtr myArray, const int_32 myLength);
+
+ /** Store an integer array in a list-type Clcm object. This method is not available
+ * for file-type Clcm objects.
+ * @param iset index of the integer array in the list. The first list element
+ * is stored at index 0.
+ * @param myArray integer array stored as <tt>IntPtr</tt> object.
+ * @param myLength number of components in integer array.
+ */
+ void put(const int_32 iset, IntPtr myArray, const int_32 myLength);
+
+ /** Store a single precision real array in a dictionary-type Clcm object. This method
+ * is not available for file-type Clcm objects.
+ * @param key key identification of the block in the dictionary
+ * @param myArray single precision real array stored as <tt>FloatPtr</tt> object.
+ * @param myLength number of components in real array.
+ */
+ void put(const std::string key, FloatPtr myArray, const int_32 myLength);
+
+ /** Store a single precision real array in a list-type Clcm object. This method is
+ * not available for file-type Clcm objects.
+ * @param iset index of the real array in the list. The first list element
+ * is stored at index 0.
+ * @param myArray single precision real array stored as <tt>FloatPtr</tt> object.
+ * @param myLength number of components in real array.
+ */
+ void put(const int_32 iset, FloatPtr myArray, const int_32 myLength);
+
+ /** Store a string pointer in a dictionary-type Clcm object. This method is not available
+ * for file-type Clcm objects.
+ * @param key key identification of the character array in the dictionary
+ * @param myArray character information stored as <tt>StringPtr</tt> object.
+ */
+ void put(const std::string key, StringPtr myArray);
+
+ /** Store a string pointer in a list-type Clcm object. This method is not available for
+ * file-type Clcm objects.
+ * @param iset index of the string in the list. The first list element is stored at index 0.
+ * @param myArray character information stored as <tt>StringPtr</tt> object.
+ */
+ void put(const int_32 iset, StringPtr myArray);
+
+ /** Store a vector-of-string pointer in a dictionary-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ * @param key key identification of the character array in the dictionary
+ * @param myArray vector-of-string containing the character information stored as
+ * <tt>StringVecPtr</tt> object.
+ */
+ void put(const std::string key, StringVecPtr myArray);
+
+ /** Store a vector-of-string pointer in a list-type Clcm object.
+ * This method is not available for file-type Clcm objects.
+ * @param iset index of the character array in the list. The first list element
+ * is stored at index 0.
+ * @param myArray vector-of-string containing the character information stored as
+ * <tt>StringVecPtr</tt> object.
+ */
+ void put(const int_32 iset, StringVecPtr myArray);
+
+ /** Store a double precision real array in a dictionary-type Clcm object. This method is
+ * not available for file-type Clcm objects.
+ * @param key key identification of the double precision array in the dictionary
+ * @param myArray double precision array stored as <tt>DoublePtr</tt> object.
+ * @param myLength number of components in double precision array.
+ */
+ void put(const std::string key, DoublePtr myArray, const int_32 myLength);
+
+ /** Store a double precision real array in a list-type Clcm object. This method is
+ * not available for file-type Clcm objects.
+ * @param iset index of the double precision array in the list. The first list element
+ * is stored at index 0.
+ * @param myArray double precision array stored as <tt>DoublePtr</tt> object.
+ * @param myLength number of components in double precision array.
+ */
+ void put(const int_32 iset, DoublePtr myArray, const int_32 myLength);
+
+ /** Store a boolean array in a dictionary-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * @param key key identification of the block in the dictionary
+ * @param myArray boolean array stored as <tt>BoolPtr</tt> object.
+ * @param myLength number of components in boolean array.
+ */
+ void put(const std::string key, BoolPtr myArray, const int_32 myLength);
+
+ /** Store a boolean array in a list-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * @param iset index of the boolean array in the list. The first list element
+ * is stored at index 0.
+ * @param myArray boolean array stored as <tt>BoolPtr</tt> object.
+ * @param myLength number of components in boolean array.
+ */
+ void put(const int_32 iset, BoolPtr myArray, const int_32 myLength);
+
+ /** Store a complex array in a dictionary-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * <p>
+ * <b>Example</b>: A complex array named <tt>"myComplArray"</tt> is inserted in
+ * Clcm object named <tt>multicompo</tt> using
+ * <pre>
+ * ComplexPtr myComplexPtr = ComplexPtr(new complex<float_32>[2]);
+ * myComplexPtr[0] = complex<float_32>(3.3, 8.9);
+ * myComplexPtr[1] = complex<float_32>(-3.3, 7.9);
+ * multicompo->put("myComplArray", myComplexPtr, 2);
+ * </pre>
+ * @param key key identification of the block in the dictionary
+ * @param myArray complex array stored as <tt>ComplexPtr</tt> object.
+ * @param myLength number of components in complex array.
+ */
+ void put(const std::string key, ComplexPtr myArray, const int_32 myLength);
+
+ /** Store a complex array in a list-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * @param iset index of the complex array in the list. The first list element
+ * is stored at index 0.
+ * @param myArray complex array stored as <tt>ComplexPtr</tt> object.
+ * @param myLength number of components in complex array.
+ */
+ void put(const int_32 iset, ComplexPtr myArray, const int_32 myLength);
+
+ /** Store a daughter Clcm object in a dictionary-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * @param key key identification of the block in the dictionary
+ * @param myClcm daughter Clcm object.
+ */
+ void put(const std::string key, ClcmPtr myClcm);
+
+ /** Store a daughter Clcm object in a list-type Clcm object. This method is not
+ * available for file-type Clcm objects.
+ * @param iset index of the complex array in the list. The first list element
+ * is stored at index 0.
+ * @param myClcm daughter Clcm object.
+ */
+ void put(const int_32 iset, ClcmPtr myClcm);
+
+ /** Extract the LCM structure.
+ * @return ANSI C pointer of the embedded LCM structure.
+ */
+ lcm *extract();
+
+private:
+ std::vector<AnyPtr> *global_list; // container for the global references
+ lcm *addr; // address of the LCM object
+ Clcm *root; // address of Clcm root object
+ std::ofstream aFile; // embedded file if type >= 3
+ int_32 lrda; // used with direct access files only
+ std::string name; // object name
+ std::string path; // path to access the Clcm file to import
+ std::string nammy; // directory name inside LCM object
+ bool empty; // empty flag
+ int_32 ilong; // -1 (dictionary) or list length
+ int_32 objtype; // type of the object =1: LCM; =2: XSM; =3: binary Fortran file
+ // =4: ASCII Fortran file; =5: direct access Fortran file
+ int_32 access; // =0: closed object; =1: object in read/write mode
+ // =2: object in read-only mode
+ int_32 version; // original ganlib version of object
+ bool untoutched; // brand new object flag
+ bool isroot; // true if addr is pointing on the root object
+}; // class Clcm
+ std::ostream & operator<<(std::ostream &, ClcmPtr);
+
+} // namespace ganlib
+#endif
diff --git a/Skin++/src/Cle2000.cxx b/Skin++/src/Cle2000.cxx
new file mode 100755
index 0000000..c49b721
--- /dev/null
+++ b/Skin++/src/Cle2000.cxx
@@ -0,0 +1,104 @@
+
+/*****************************************/
+/* C++ CLE-2000 OBJECT WRAPPER */
+/* AUTHOR: A. HEBERT ; 2012/10/07 */
+/*****************************************/
+
+/*
+Copyright (C) 2012 Ecole Polytechnique de Montreal
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+*/
+
+#include "Cle2000.hxx"
+
+using namespace std;
+using namespace ganlib;
+static ostringstream hsmg;
+
+ganlib::Cle2000::Cle2000(string sname) {
+ this->edit = 0;
+ this->procName = sname;
+ this->stack.reset();
+}
+ganlib::Cle2000::Cle2000(string sname, int_32 edit) {
+ this->edit = edit;
+ this->procName = sname;
+ this->stack.reset();
+}
+ganlib::Cle2000::Cle2000(string sname, LifoPtr jstack) {
+ this->edit = 0;
+ this->procName = sname;
+ this->stack = jstack;
+}
+ganlib::Cle2000::Cle2000(string sname, int_32 edit, LifoPtr jstack) {
+ this->edit = edit;
+ this->procName = sname;
+ this->stack = jstack;
+}
+
+ganlib::Cle2000::~Cle2000() {
+ cout << "Cle2000 destructor called." << endl;
+}
+
+void ganlib::Cle2000::setLifo(LifoPtr myLifo) {
+ this->stack = myLifo;
+}
+
+void ganlib::Cle2000::exec() {
+ int_32 ier, ilevel = 1;
+
+// close the LCM objects
+ for (int_32 ipos=0; ipos<this->stack->getMax(); ++ipos) {
+ int_32 myTypeNode = this->stack->typeNode(ipos);
+ if ((myTypeNode == 3) || (myTypeNode == 4)) {
+ if (this->stack->accessNode(ipos) > 0) {
+ ClcmPtr myClcm; this->stack->node(ipos, myClcm);
+ try {
+ lcm *myLcmStructure = myClcm->extract();
+ lifo *myLifo = this->stack->extract();
+ lifo_node *myNode = clepos(&myLifo, ipos);
+ strcpy(myNode->OSname, myLcmStructure->hname);
+ lcmcl_c(&myLcmStructure, 1);
+ } catch(...) {
+ throw Cle2000Exception("Exception catched by lcmcl_c");
+ }
+ }
+ }
+ }
+
+// call the parametrized procedure
+ try {
+ ier = cle2000_c(ilevel, &donmod, (char *)this->procName.c_str(), this->edit,
+ (lifo*)this->stack->extract());
+
+ } catch(...) {
+ throw Cle2000Exception("Exception catched by cle2000_c");
+ }
+ if (ier != 0) {
+ hsmg << "Cle2000: cle2000 failure (" << this->procName << ".c2m). ier=" << ier;
+ throw Cle2000Exception(hsmg.str());
+ }
+
+// reopen the LCM objects
+ for (int ipos=0; ipos<this->stack->getMax(); ++ipos) {
+ int_32 myTypeNode = this->stack->typeNode(ipos);
+ if ((myTypeNode == 3) || (myTypeNode == 4)) {
+ int_32 access = this->stack->accessNode(ipos);
+ if (access == 0) access=1;
+ ClcmPtr myClcm; this->stack->node(ipos, myClcm);
+ try {
+ lcm *myLcmStructure = myClcm->extract();
+ int_32 myTypeNode = this->stack->typeNode(ipos);
+ string myOSname_str = this->stack->OSName(ipos);
+ char *myOSname = (char *)myOSname_str.c_str();
+ lcmop_c(&myLcmStructure, myOSname, access, myTypeNode-2, 0);
+ } catch(...) {
+ throw Cle2000Exception("Exception catched by lcmop_c");
+ }
+ }
+ }
+}
diff --git a/Skin++/src/Cle2000.hxx b/Skin++/src/Cle2000.hxx
new file mode 100755
index 0000000..af869dd
--- /dev/null
+++ b/Skin++/src/Cle2000.hxx
@@ -0,0 +1,96 @@
+/**
+ * Call a parametrized Cle2000 procedure. A Lifo object is used to manage
+ * input/output parameters for this CLE-2000 procedure.
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2012)
+ */
+#ifndef Cle2000_HXX
+#define Cle2000_HXX
+
+#include <cstddef> // for __GLIBCXX__
+
+#ifdef __GLIBCXX__ // for memory management with shared_ptr
+# include <tr1/memory>
+#else
+# ifdef __IBMCPP__
+# define __IBMCPP_TR1__
+# endif
+# include <memory>
+#endif
+
+#include "Cle2000Exception.hxx"
+#include "Lifo.hxx"
+extern "C" {
+#include <dirent.h>
+int_32 donmod(char *cmodul, int_32 nentry, char (*hentry)[13], int_32 *ientry,
+ int_32 *jentry, lcm **kentry, char (*hparam)[73]);
+}
+#define Cle2000Ptr std::shared_ptr<Cle2000>
+
+namespace ganlib {
+
+/**
+ * Call a parametrized CLE-2000 procedure. A CLE-2000 procedure is implemented
+ * as a 80-column ascii file. The name of that file must have a <tt>".c2m"</tt>
+ * suffix. A Lifo object is used to manage input/output parameters for this
+ * CLE-2000 procedure.
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2012)
+ */
+class Cle2000 {
+public:
+ /** use this constructor to create a new CLE-2000 object
+ * @param sname string containing the name of the ascii file containing the CLE-2000
+ * procedure (without the <tt>".c2m"</tt> suffix)
+ */
+ Cle2000(std::string sname);
+
+ /** use this constructor to create a new Cle2000 object
+ * @param sname string containing the name of the ascii file containing the CLE-2000
+ * procedure (without the <tt>".c2m"</tt> suffix)
+ * @param edit user-defined edition index. Increasing value of <tt>edit</tt> will
+ * cause increasing amount of listing information. Set <tt>edit</tt> to zero to avoid
+ * listing information.
+ */
+ Cle2000(std::string sname, int_32 edit);
+
+ /** use this constructor to create a new Cle2000 object with an embedded Lifo stack
+ * @param sname string containing the name of the ascii file containing the CLE-2000
+ * procedure (without the <tt>".c2m"</tt> suffix)
+ * @param jstack Lifo stack to include in Cle2000 object
+ */
+ Cle2000(std::string sname, LifoPtr jstack);
+
+ /** use this constructor to create a new Cle2000 object with an embedded Lifo stack
+ * @param sname string containing the name of the ascii file containing the CLE-2000
+ * procedure (without the <tt>".c2m"</tt> suffix)
+ * @param edit user-defined edition index. Increasing value of <tt>edit</tt> will
+ * cause increasing amount of listing information. Set <tt>edit</tt> to zero to avoid
+ * listing information.
+ * @param jstack Lifo stack to include in Cle2000 object
+ */
+ Cle2000(std::string sname, int_32 edit, LifoPtr jstack);
+
+ /** Close and destroy a Cle2000 object.
+ */
+ ~Cle2000();
+
+ /** attach a lifo stack to the Cle2000 object
+ * @param myLifo Lifo stack containing input/output parameters
+ */
+ void setLifo(LifoPtr myLifo);
+
+ /** call the native CLE-2000 procedure
+ */
+ void exec();
+
+private:
+ std::string procName;
+ int_32 edit;
+ LifoPtr stack;
+}; // class Cle2000
+
+} // namespace ganlib
+#endif
diff --git a/Skin++/src/Cle2000Exception.cxx b/Skin++/src/Cle2000Exception.cxx
new file mode 100755
index 0000000..216825f
--- /dev/null
+++ b/Skin++/src/Cle2000Exception.cxx
@@ -0,0 +1,22 @@
+
+/*****************************************/
+/* EXCEPTION CLASS FOR Lifo */
+/* AUTHOR: A. HEBERT ; 2012/10/07 */
+/*****************************************/
+
+/*
+Copyright (C) 2012 Ecole Polytechnique de Montreal
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+*/
+
+#include "Cle2000Exception.hxx"
+using namespace std;
+using namespace ganlib;
+
+ganlib::Cle2000Exception::Cle2000Exception(const string& msg) : runtime_error(msg) {
+ cout << "A Cle2000Exception was thrown with message: " << msg << endl;
+}
diff --git a/Skin++/src/Cle2000Exception.hxx b/Skin++/src/Cle2000Exception.hxx
new file mode 100755
index 0000000..5c9020a
--- /dev/null
+++ b/Skin++/src/Cle2000Exception.hxx
@@ -0,0 +1,22 @@
+/**
+ * Exception class for Cle2000 wrapper uses in C++
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2012)
+ */
+#ifndef Cle2000Exception_HXX
+#define Cle2000Exception_HXX
+
+#include <string>
+#include <iostream>
+#include <stdexcept>
+
+namespace ganlib {
+
+class Cle2000Exception : public std::runtime_error {
+public:
+ Cle2000Exception(const std::string& msg = "");
+}; // class Cle2000Exception */
+
+} // namespace ganlib
+#endif
diff --git a/Skin++/src/LCMexception.cxx b/Skin++/src/LCMexception.cxx
new file mode 100755
index 0000000..08960f3
--- /dev/null
+++ b/Skin++/src/LCMexception.cxx
@@ -0,0 +1,22 @@
+
+/*****************************************/
+/* EXCEPTION CLASS FOR LCM */
+/* AUTHOR: A. HEBERT ; 2010/12/31 */
+/*****************************************/
+
+/*
+Copyright (C) 2010 Ecole Polytechnique de Montreal
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+*/
+
+#include "LCMexception.hxx"
+using namespace std;
+using namespace ganlib;
+
+ganlib::LCMexception::LCMexception(const string& msg) : runtime_error(msg) {
+ cout << "A LCMexception was thrown with message: " << msg << endl;
+}
diff --git a/Skin++/src/LCMexception.hxx b/Skin++/src/LCMexception.hxx
new file mode 100755
index 0000000..041d334
--- /dev/null
+++ b/Skin++/src/LCMexception.hxx
@@ -0,0 +1,22 @@
+/**
+ * Exception class for LCM uses in C++
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2010)
+ */
+#ifndef LCMexception_HXX
+#define LCMexception_HXX
+
+#include <string>
+#include <iostream>
+#include <stdexcept>
+
+namespace ganlib {
+
+class LCMexception : public std::runtime_error {
+public:
+ LCMexception(const std::string& msg = "");
+}; // class LCMexception */
+
+} // namespace ganlib
+#endif
diff --git a/Skin++/src/Lifo.cxx b/Skin++/src/Lifo.cxx
new file mode 100755
index 0000000..4451d90
--- /dev/null
+++ b/Skin++/src/Lifo.cxx
@@ -0,0 +1,691 @@
+
+/*****************************************/
+/* C++ LIFO STACK OBJECT WRAPPER */
+/* AUTHOR: A. HEBERT ; 2012/10/07 */
+/*****************************************/
+
+/*
+Copyright (C) 2012 Ecole Polytechnique de Montreal
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+*/
+
+#include "Lifo.hxx"
+
+using namespace std;
+using namespace ganlib;
+static ostringstream hsmg;
+
+ganlib::Lifo::Lifo() {
+ cout << "New Lifo object constructed.'" << endl;
+ try {
+ cleopn(&(this->addr));
+ } catch(...) {
+ throw LifoException("Exception catched by cleopn");
+ }
+ this->global_list = new vector<ClcmPtr>;
+}
+
+ganlib::Lifo::~Lifo() {
+ cout << "Lifo destructor called (" << this->getMax() << " nodes remaining)." << endl;
+ int_32 nitma = clecls(&(this->addr));
+ if(nitma != 0) {
+ char hsmg[132];
+ snprintf(hsmg,42,"%s\n","Lifo destruction failure: Lifo not empty");
+ xabort_c(hsmg);
+ }
+ delete this->global_list;
+}
+
+//----------------------------------------------------------------------
+//-- pop --
+//----------------------------------------------------------------------
+
+void ganlib::Lifo::pop() {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(0)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(1)");
+ }
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+void ganlib::Lifo::pop(int_32 &myInteger) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(1)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(1)");
+ }
+ if (myNode->type != 11) {
+ hsmg << "pop() expecting an integer value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myInteger = myNode->value.ival;
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+void ganlib::Lifo::pop(float_32 &myFloat) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(2)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(2)");
+ }
+ if (myNode->type != 12) {
+ hsmg << "pop() expecting a real value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myFloat = myNode->value.fval;
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+void ganlib::Lifo::pop(string &myString) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(3)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(3)");
+ }
+ if (myNode->type != 13) {
+ hsmg << "pop() expecting a string value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myString = string(myNode->value.hval);
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+void ganlib::Lifo::pop(double &myDouble) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(4)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(4)");
+ }
+ if (myNode->type != 14) {
+ hsmg << "pop() expecting a double precision value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myDouble = myNode->value.dval;
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+void ganlib::Lifo::pop(bool &myBool) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(5)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(5)");
+ }
+ if (myNode->type != 15) {
+ hsmg << "pop() expecting a boolean value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myBool = (myNode->value.ival == 1);
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+void ganlib::Lifo::pop(ClcmPtr &myClcm) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(6)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(6)");
+ }
+ if ((myNode->type != 3) && (myNode->type != 4)) {
+ hsmg << "pop() expecting a LCM or XSM object (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ lcm *myLcm = myNode->value.mylcm;
+ myClcm = ClcmPtr(new Clcm(myLcm, myNode->type, myNode->access, myNode->OSname));
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+void ganlib::Lifo::pop(string myFile, string stype) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(7)");
+ try {
+ myNode = clepos(&(this->addr), this->addr->nup-1);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(7)");
+ }
+ if (myNode->type == 5) {
+ stype = "BINARY";
+ } else if (myNode->type == 6) {
+ stype = "ASCII";
+ } else if (myNode->type == 7) {
+ stype = "DA";
+ } else {
+ hsmg << "pop(): unknown file type";
+ throw LifoException(hsmg.str());
+ }
+ myFile = string(myNode->value.hval);
+ clepop(&(this->addr));
+ free(myNode);
+}
+
+//----------------------------------------------------------------------
+//-- push --
+//----------------------------------------------------------------------
+
+void ganlib::Lifo::push(string sname, const int_32 myInteger) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str()); myNode->type = 11; myNode->value.ival = myInteger;
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(1)");
+ }
+}
+
+void ganlib::Lifo::push(string sname, const float_32 myFloat) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str()); myNode->type = 12; myNode->value.fval = myFloat;
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(2)");
+ }
+}
+
+void ganlib::Lifo::push(string sname, const string myString) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str()); myNode->type = 13;
+ strcpy(myNode->value.hval, (char *)myString.c_str());
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(3)");
+ }
+}
+
+void ganlib::Lifo::push(string sname, const double myDouble) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str()); myNode->type = 14; myNode->value.dval = myDouble;
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(4)");
+ }
+}
+
+void ganlib::Lifo::push(string sname, bool myBool) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ int_32 ibool = 0; if (myBool) ibool = 1;
+ strcpy(myNode->name, (char *)sname.c_str()); myNode->type = 15; myNode->value.ival = ibool;
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(5)");
+ }
+}
+
+void ganlib::Lifo::push(string sname, ClcmPtr myClcm) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str());
+ myNode->type = myClcm->getType()+2;
+ myNode->access = myClcm->getAccess();
+ lcm *myLcm = myClcm->extract();
+ myNode->value.mylcm = myLcm;
+ strcpy(myNode->OSname, (char *)myClcm->getName().c_str());
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(6)");
+ }
+ (this->global_list)->push_back(myClcm);
+}
+
+void ganlib::Lifo::push(string sname, string myFile, string stype) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str());
+ if (stype == "BINARY") {
+ myNode->type = 5;
+ } else if (stype == "ASCII") {
+ myNode->type = 6;
+ } else if (stype == "DA") {
+ myNode->type = 7;
+ } else {
+ hsmg << "push() unknown file type (" << stype << ")";
+ throw LifoException(hsmg.str());
+ }
+ strcpy(myNode->value.hval, (char *)myFile.c_str());
+ strcpy(myNode->OSname, (char *)myFile.c_str());
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(7)");
+ }
+}
+
+void ganlib::Lifo::push(string sname, string myFile, string stype, string OSname) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str());
+ if (stype == "BINARY") {
+ myNode->type = 5;
+ } else if (stype == "ASCII") {
+ myNode->type = 6;
+ } else if (stype == "DA") {
+ myNode->type = 7;
+ } else {
+ hsmg << "push(): unknown file type (" << stype << ")";
+ throw LifoException(hsmg.str());
+ }
+ strcpy(myNode->value.hval, (char *)myFile.c_str());
+ strcpy(myNode->OSname, (char *)OSname.c_str());
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(8)");
+ }
+}
+
+//----------------------------------------------------------------------
+//-- pushEmpty --
+//----------------------------------------------------------------------
+
+void ganlib::Lifo::pushEmpty(string sname, string nodeType) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str());
+ if (nodeType == "I") {
+ myNode->type = -11 ;
+ } else if (nodeType == "F") {
+ myNode->type = -12 ;
+ } else if (nodeType == "D") {
+ myNode->type = -13 ;
+ } else if (nodeType == "S") {
+ myNode->type = -14 ;
+ } else if (nodeType == "B") {
+ myNode->type = -15 ;
+ } else if (nodeType == "LCM") {
+ myNode->type = -3 ;
+ myNode->access = 0 ;
+ strcpy(myNode->OSname, (char *)sname.c_str());
+ } else if (nodeType == "XSM") {
+ myNode->type = -4 ;
+ myNode->access = 0 ;
+ strcpy(myNode->OSname, (char *)sname.c_str());
+ } else if (nodeType == "BINARY") {
+ myNode->type = -5 ;
+ myNode->access = 0 ;
+ } else if (nodeType == "ASCII") {
+ myNode->type = -6 ;
+ myNode->access = 0 ;
+ } else if (nodeType == "DA") {
+ myNode->type = -7 ;
+ myNode->access = 0 ;
+ } else {
+ hsmg << nodeType << "is an invalid type in pushEmpty";
+ throw LifoException(hsmg.str());
+ }
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(9)");
+ }
+}
+
+void ganlib::Lifo::pushEmpty(string sname, string nodeType, string OSname) {
+ lifo_node * myNode = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(myNode->name, (char *)sname.c_str());
+ if (nodeType == "XSM") {
+ myNode->type = -4 ;
+ myNode->access = 0 ;
+ } else if (nodeType == "BINARY") {
+ myNode->type = -5 ;
+ myNode->access = 0 ;
+ } else if (nodeType == "ASCII") {
+ myNode->type = -6 ;
+ myNode->access = 0 ;
+ } else if (nodeType == "DA") {
+ myNode->type = -7 ;
+ myNode->access = 0 ;
+ } else {
+ hsmg << nodeType << "is an invalid type in pushEmpty";
+ throw LifoException(hsmg.str());
+ }
+ strcpy(myNode->OSname, (char *)OSname.c_str());
+ try {
+ clepush(&(this->addr), myNode);
+ } catch(...) {
+ throw LifoException("Exception catched by clepush(9)");
+ }
+}
+
+//----------------------------------------------------------------------
+//-- node by position --
+//----------------------------------------------------------------------
+
+void ganlib::Lifo::node(int_32 ipos, int_32 &myInteger) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(11)");
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(11)");
+ }
+ if (myNode->type != 11) {
+ hsmg << "node() expecting an integer value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myInteger = myNode->value.ival;
+}
+
+void ganlib::Lifo::node(int_32 ipos, float_32 &myFloat) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(12)");
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(12)");
+ }
+ if (myNode->type != 12) {
+ hsmg << "node() expecting a real value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myFloat = myNode->value.fval;
+}
+
+void ganlib::Lifo::node(int_32 ipos, string &myString) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(13)");
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(13)");
+ }
+ if (myNode->type != 13) {
+ hsmg << "node() expecting a string value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myString = string(myNode->value.hval);
+}
+
+void ganlib::Lifo::node(int_32 ipos, double &myDouble) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(14)");
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(14)");
+ }
+ if (myNode->type != 14) {
+ hsmg << "node() expecting a double precision value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myDouble = myNode->value.dval;
+}
+
+void ganlib::Lifo::node(int_32 ipos, bool &myBool) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(15)");
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(15)");
+ }
+ if (myNode->type != 11) {
+ hsmg << "node() expecting a boolean value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myBool = (myNode->value.ival == 1);
+}
+
+void ganlib::Lifo::node(int_32 ipos, ClcmPtr &myClcm) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(16)");
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(16)");
+ }
+ if ((myNode->type != 3) && (myNode->type != 4)) {
+ hsmg << "node() expecting a LCM or XSM object (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ lcm *myLcm = myNode->value.mylcm;
+ myClcm = ClcmPtr(new Clcm(myLcm, myNode->type, myNode->access, myNode->OSname));
+}
+
+void ganlib::Lifo::node(int_32 ipos, string myFile, string stype) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(17)");
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(17)");
+ }
+ if (myNode->type == 5) {
+ stype = "BINARY";
+ } else if (myNode->type == 6) {
+ stype = "ASCII";
+ } else if (myNode->type == 7) {
+ stype = "DA";
+ } else {
+ hsmg << "node(): unknown file type";
+ throw LifoException(hsmg.str());
+ }
+ myFile = string(myNode->value.hval);
+}
+
+//----------------------------------------------------------------------
+//-- node by name --
+//----------------------------------------------------------------------
+
+void ganlib::Lifo::node(string sname, int_32 &myInteger) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(21)");
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(21)");
+ }
+ if (myNode->type != 11) {
+ hsmg << "node() expecting an integer value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myInteger = myNode->value.ival;
+}
+
+void ganlib::Lifo::node(string sname, float_32 &myFloat) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(22)");
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(22)");
+ }
+ if (myNode->type != 12) {
+ hsmg << "node() expecting a real value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myFloat = myNode->value.fval;
+}
+
+void ganlib::Lifo::node(string sname, string &myString) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(23)");
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(23)");
+ }
+ if (myNode->type != 13) {
+ hsmg << "node() expecting a string value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myString = string(myNode->value.hval);
+}
+
+void ganlib::Lifo::node(string sname, double &myDouble) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(24)");
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(24)");
+ }
+ if (myNode->type != 14) {
+ hsmg << "node() expecting a double precision value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myDouble = myNode->value.dval;
+}
+
+void ganlib::Lifo::node(string sname, bool &myBool) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(25)");
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(25)");
+ }
+ if (myNode->type != 11) {
+ hsmg << "node() expecting a boolean value (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ myBool = (myNode->value.ival == 1);
+}
+
+void ganlib::Lifo::node(string sname, ClcmPtr &myClcm) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to recover from stack(26)");
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(26)");
+ }
+ if ((myNode->type != 3) && (myNode->type != 4)) {
+ hsmg << "node() expecting a LCM or XSM object (" << myNode->type << " found)";
+ throw LifoException(hsmg.str());
+ }
+ lcm *myLcm = myNode->value.mylcm;
+ myClcm = ClcmPtr(new Clcm(myLcm, myNode->type, myNode->access, myNode->OSname));
+}
+
+void ganlib::Lifo::node(string sname, string myFile, string stype) {
+ lifo_node *myNode;
+ if (this->addr->nup == 0) throw LifoException("no nodes to pop from stack(27)");
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(27)");
+ }
+ if (myNode->type == 5) {
+ stype = "BINARY";
+ } else if (myNode->type == 6) {
+ stype = "ASCII";
+ } else if (myNode->type == 7) {
+ stype = "DA";
+ } else {
+ hsmg << "node(): unknown file type";
+ throw LifoException(hsmg.str());
+ }
+ myFile = string(myNode->value.hval);
+}
+
+//----------------------------------------------------------------------
+
+int_32 ganlib::Lifo::getMax() {
+ return this->addr->nup;
+}
+
+int_32 ganlib::Lifo::typeNode(int_32 ipos) {
+ lifo_node *myNode;
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(51)");
+ }
+ return myNode->type;
+}
+
+int_32 ganlib::Lifo::accessNode(int_32 ipos) {
+ lifo_node *myNode;
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(52)");
+ }
+ return myNode->access;
+}
+
+string ganlib::Lifo::OSName(int_32 ipos) {
+ lifo_node *myNode;
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(53)");
+ }
+ return myNode->OSname;
+}
+
+string ganlib::Lifo::Name(int_32 ipos) {
+ lifo_node *myNode;
+ try {
+ myNode = clepos(&(this->addr), ipos);
+ } catch(...) {
+ throw LifoException("Exception catched by clepos(54)");
+ }
+ return myNode->name;
+}
+
+int_32 ganlib::Lifo::typeNode(string sname) {
+ lifo_node *myNode;
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(55)");
+ }
+ return myNode->type;
+}
+
+int_32 ganlib::Lifo::accessNode(string sname) {
+ lifo_node *myNode;
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(56)");
+ }
+ return myNode->access;
+}
+
+string ganlib::Lifo::OSName(string sname) {
+ lifo_node *myNode;
+ try {
+ myNode = clenode(&(this->addr), sname.c_str());
+ } catch(...) {
+ throw LifoException("Exception catched by clenode(57)");
+ }
+ return myNode->OSname;
+}
+
+void ganlib::Lifo::lib() {
+ try {
+ clelib(&(this->addr));
+ } catch(...) {
+ throw LifoException("Exception catched by clelib");
+ }
+}
+
+lifo *ganlib::Lifo::extract() {
+ return this->addr;
+}
diff --git a/Skin++/src/Lifo.hxx b/Skin++/src/Lifo.hxx
new file mode 100755
index 0000000..78a6836
--- /dev/null
+++ b/Skin++/src/Lifo.hxx
@@ -0,0 +1,373 @@
+/**
+ * This class is an implementation of the C++ bindings for a Lifo
+ * stack, as required by the Cle-2000 class.
+ * Lifo capabilities are available for a program written in C++
+ * by using methods belonging to the Lifo class.
+ * <P> A Lifo object in C++ can encapsulate a native Lifo stack
+ * using the GANLIB5 API in ANSI C
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2012)
+ */
+#ifndef Lifo_HXX
+#define Lifo_HXX
+
+#include <cstddef> // for __GLIBCXX__
+
+#ifdef __GLIBCXX__ // for memory management with shared_ptr
+# include <tr1/memory>
+#else
+# ifdef __IBMCPP__
+# define __IBMCPP_TR1__
+# endif
+# include <memory>
+#endif
+
+#include "LifoException.hxx"
+#include "Clcm.hxx"
+extern "C" {
+#include <dirent.h>
+#include "cle2000.h"
+}
+#define LifoPtr std::shared_ptr<Lifo>
+
+namespace ganlib {
+
+/**
+ * This class is an implementation of the C++/shared_ptr bindings for a last-in-first-out
+ * (lifo) stack used with CLE-2000. Lifo management capabilities for a program
+ * written in C++ are available by using methods belonging to the Lifo class.
+ * These methods encapsulate the lifo API calls used as "extern"C" functions.
+ * <P> A Lifo object in C++ can encapsulate a native lifo stack used to
+ * manage CLE-2000 parameters.
+ * <P> A lifo stack can contain defined or undefined (empty) nodes; used to represent
+ * known or unknown parameters, respectively.
+ * <P> <I>Note:</I> There is a constraint_32 in CLE-2000. LCM (or XSM) objects and files
+ * must be pushed before single-value nodes in the stack.
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2012)
+ */
+class Lifo {
+public:
+ /**
+ * Use this constructor to create an empty Lifo object.
+ */
+ Lifo();
+
+ /** Close and destroy a Lifo object.
+ */
+ ~Lifo();
+
+ /** Pop the value on top of the Lifo stack without recovering it. If the node is empty, an
+ * exception is thrown
+ */
+ void pop();
+
+ /** Pop the integer value on top of the Lifo stack. If the node is empty or if the argument type
+ * is wrong, an exception is thrown
+ * @param myInteger integer value node to pop from the lifo stack.
+ */
+ void pop(int_32 &myInteger);
+
+ /** Pop the real value on top of the Lifo stack. If the node is empty or if the argument type
+ * is wrong, an exception is thrown
+ * @param myFloat real value node to pop from the lifo stack.
+ */
+ void pop(float_32 &myFloat);
+
+ /** Pop the character string on top of the Lifo stack. If the node is empty or if the argument type
+ * is wrong, an exception is thrown
+ * @param myString character string node (limited to 72 characters) to pop from the lifo stack.
+ */
+ void pop(std::string &myString);
+
+ /** Pop the double precision value on top of the Lifo stack. If the node is empty or if the argument type
+ * is wrong, an exception is thrown
+ * @param myDouble double precision value node to pop from the lifo stack.
+ */
+ void pop(double &myDouble);
+
+ /** Pop the boolean value on top of the Lifo stack. If the node is empty or if the argument type
+ * is wrong, an exception is thrown
+ * @param myBool boolean value node to pop from the lifo stack.
+ */
+ void pop(bool &myBool);
+
+ /** Pop the ClcmPtr object on top of the Lifo stack. If the node is empty or if the argument type
+ * is wrong, an exception is thrown
+ * @param myClcm LCM object node to pop from the lifo stack.
+ */
+ void pop(ClcmPtr &myClcm);
+
+ /** Pop the file object on top of the Lifo stack. If the node is empty or if the argument type
+ * is wrong, an exception is thrown
+ * @param myFile operating system (OS) name (limited to 72 characters) associated to the file object
+ * node to pop from the lifo stack.
+ * @param stype type of file. This variable is selected by <tt>pop</tt> among the
+ * following values:
+ * <ul><dl>
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * <dt> <tt>"DA"</tt> <dd> binary direct-access file (with 128-word records)</ul>
+ */
+ void pop(std::string myFile, std::string stype);
+
+ /** Return the integer value node with a given position. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @param myInteger integer value node.
+ */
+ void node(int_32 ipos, int_32 &myInteger);
+
+ /** Return the real value node with a given position. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @param myFloat real value node.
+ */
+ void node(int_32 ipos, float_32 &myFloat);
+
+ /** Return the character string node with a given position. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @param myString character string node (limited to 72 characters).
+ */
+ void node(int_32 ipos, std::string &myString);
+
+ /** Return the double precision value node with a given position. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @param myDouble double precision value node.
+ */
+ void node(int_32 ipos, double &myDouble);
+
+ /** Return the boolean value node with a given position. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @param myBool integer value node.
+ */
+ void node(int_32 ipos, bool &myBool);
+
+ /** Return the ClcmPtr object node with a given position. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @param myClcm ClcmPtr object node.
+ */
+ void node(int_32 ipos, ClcmPtr &myClcm);
+
+ /** Return the file object node with a given position. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @param node operating system (OS) name (limited to 72 characters) associated to the file object
+ * node to pop from the lifo stack.
+ * @param stype type of LCM object or file. This variable is selected by <tt>pop</tt> among the
+ * following values:
+ * <ul><dl>
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * <dt> <tt>"DA"</tt> <dd> binary direct-access file (with 128-word records)</ul>
+ */
+ void node(int_32 ipos, std::string node, std::string stype);
+
+ /** Return the integer value node with a given name. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @param myInteger integer value node.
+ */
+ void node(std::string sname, int_32 &myInteger);
+
+ /** Return the real value node with a given name. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @param myFloat real value node.
+ */
+ void node(std::string sname, float_32 &myFloat);
+
+ /** Return the character string node with a given name. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @param myString character string node (limited to 72 characters).
+ */
+ void node(std::string sname, std::string &myString);
+
+ /** Return the double precision value node with a given name. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @param myDouble double precision value node.
+ */
+ void node(std::string sname, double &myDouble);
+
+ /** Return the boolean value node with a given name. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @param myBool integer value node.
+ */
+ void node(std::string sname, bool &myBool);
+
+ /** Return the ClcmPtr object node with a given name. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @param myClcm ClcmPtr object node.
+ */
+ void node(std::string sname, ClcmPtr &myClcm);
+
+ /** Return the file object node with a given name. If the node is empty or if the argument type
+ * is wrong, an exception is thrown. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @param node operating system (OS) name (limited to 72 characters) associated to the file object
+ * node to pop from the lifo stack.
+ * @param stype type of LCM object or file. This variable is selected by <tt>pop</tt> among the
+ * following values:
+ * <ul><dl>
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * <dt> <tt>"DA"</tt> <dd> binary direct-access file (with 128-word records)</ul>
+ */
+ void node(std::string sname, std::string node, std::string stype);
+
+ /** Return the OSname of the node associated with a given name. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @return OSName of the file
+ */
+ std::string OSName(std::string sname);
+
+ /** Return the OSname of the node at a given position. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @return OSName of the file
+ */
+ std::string OSName(int_32 ipos);
+
+ /** Return the name of the node at a given position. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @return name of the node
+ */
+ std::string Name(int_32 ipos);
+
+ /** Return the type of the node associated with a given name. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @return node type (3= LCM object; 4= XSM file; 5= seq binary; 6= seq ascii; 7= DA binary;
+ 11= integer value; 12= real value; 13= character std::string; 14= double precision value;
+ 15= logical value). A negative value indicates an empty node.
+ */
+ int_32 typeNode(std::string sname);
+
+ /** Return the type of the node at a given position. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @return node type (3= LCM object; 4= XSM file; 5= seq binary; 6= seq ascii; 7= DA binary;
+ 11= integer value; 12= real value; 13= character std::string; 14= double precision value;
+ 15= logical value). A negative value indicates an empty node.
+ */
+ int_32 typeNode(int_32 ipos);
+
+ /** Return the access of the node associated with a given name. The lifo stack is not modified
+ * @param sname node name (limited to 12 characters)
+ * @return node access (0= creation; 1:modification; 2=read-only).
+ */
+ int_32 accessNode(std::string sname);
+
+ /** Return the access of the node at a given position. The lifo stack is not modified
+ * @param ipos node position in lifo stack
+ * @return node access (0= creation; 1:modification; 2=read-only).
+ */
+ int_32 accessNode(int_32 ipos);
+
+ /** Push a new integer on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myInteger integer value to push into the lifo stack
+ */
+ void push(std::string sname, const int_32 myInteger);
+
+ /** Push a new real on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myFloat real value to push into the lifo stack
+ */
+ void push(std::string sname, const float myFloat);
+
+ /** Push a new node object on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myString string object to push into the lifo stack.
+ */
+ void push(std::string sname, const std::string myString);
+
+ /** Push a new double precision value on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myDouble double precision value to push into the lifo stack
+ */
+ void push(std::string sname, const double_64 myDouble);
+
+ /** Push a new boolean value on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myBool boolean value to push into the lifo stack
+ */
+ void push(std::string sname, const bool myBool);
+
+ /** Push a new ClcmPtr node object on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myClcm ClcmPtr LCM/XSM object to push into the lifo stack.
+ * result
+ */
+ void push(std::string sname, const ClcmPtr myClcm);
+
+ /** Push a new node object with a type on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myFile file object to push into the lifo stack.
+ * @param stype type of LCM object or file. This variable is chosen among
+ * the following values:
+ * <ul><dl>
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * <dt> <tt>"DA"</tt> <dd> binary direct-access file (with 128-word records)
+ */
+ void push(std::string sname, std::string myFile, std::string stype);
+
+ /** Push a new node object with a type and an <tt>"OSname"</tt> on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param myFile file object to push into the lifo stack.
+ * @param stype type of LCM object or file. This variable is chosen among
+ * the following values:
+ * <ul><dl>
+ * <dt> <tt>"BINARY"</tt> <dd> binary sequential file
+ * <dt> <tt>"ASCII"</tt> <dd> ACSII sequential file
+ * <dt> <tt>"DA"</tt> <dd> binary direct-access file (with 128-word records)</ul>
+ * @param OSname operating system (OS) name associated to the file (limited to 72 characters).
+ */
+ void push(std::string sname, std::string myFile, std::string stype,
+ std::string OSname);
+
+ /** Push an empty node on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param nodeType node type (='I': integer value; 'F': real value; 'D': double precision value;
+ * 'B': boolean value;'S': character string value; ='LCM': memory-resident LCM object; ='XSM': XSM file;
+ * ='BINARY': binary file; ='ASCII': ascii file; ='DA': direct-access file (with 128-word records))
+ */
+ void pushEmpty(std::string sname, std::string nodeType);
+
+ /** Push an empty node on top of the Lifo stack
+ * @param sname node name (limited to 12 characters)
+ * @param nodeType node type (='XSM': XSM file; ='BINARY': binary file; ='ASCII': ascii file;
+ * ='DA': direct-access file (with 128-word records))
+ * @param OSname operating system (OS) name associated to the file (limited to 72 characters).
+ */
+ void pushEmpty(std::string sname, std::string nodeType, std::string OSname);
+
+ /** Gives the number of nodes in the lifo stack
+ * @return number of nodes in lifo stack
+ */
+ int_32 getMax();
+
+ /** Print_32 the table-of-content of a lifo stack
+ */
+ void lib();
+
+ /** Extract the lifo structure.
+ * @return ANSI C pointer of the embedded lifo structure.
+ */
+ lifo *extract();
+
+private:
+ std::vector<ClcmPtr> *global_list; // container for the global references
+ lifo *addr; // address of the Lifo object
+}; // class Lifo
+
+} // namespace ganlib
+#endif
diff --git a/Skin++/src/LifoException.cxx b/Skin++/src/LifoException.cxx
new file mode 100755
index 0000000..ba8c1ad
--- /dev/null
+++ b/Skin++/src/LifoException.cxx
@@ -0,0 +1,22 @@
+
+/*****************************************/
+/* EXCEPTION CLASS FOR Lifo */
+/* AUTHOR: A. HEBERT ; 2012/10/07 */
+/*****************************************/
+
+/*
+Copyright (C) 2012 Ecole Polytechnique de Montreal
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+*/
+
+#include "LifoException.hxx"
+using namespace std;
+using namespace ganlib;
+
+ganlib::LifoException::LifoException(const string& msg) : runtime_error(msg) {
+ cout << "A LifoException was thrown with message: " << msg << endl;
+}
diff --git a/Skin++/src/LifoException.hxx b/Skin++/src/LifoException.hxx
new file mode 100755
index 0000000..79b348a
--- /dev/null
+++ b/Skin++/src/LifoException.hxx
@@ -0,0 +1,22 @@
+/**
+ * Exception class for Lifo stack uses in C++
+ * <P>
+ *
+ * @author Alain Hebert, Ecole Polytechnique de Montreal (2012)
+ */
+#ifndef LifoException_HXX
+#define LifoException_HXX
+
+#include <string>
+#include <iostream>
+#include <stdexcept>
+
+namespace ganlib {
+
+class LifoException : public std::runtime_error {
+public:
+ LifoException(const std::string& msg = "");
+}; // class LifoException */
+
+} // namespace ganlib
+#endif
diff --git a/Skin++/src/Makefile b/Skin++/src/Makefile
new file mode 100755
index 0000000..fe13dae
--- /dev/null
+++ b/Skin++/src/Makefile
@@ -0,0 +1,182 @@
+#---------------------------------------------------------------------------
+#
+# Makefile for building the Skin++ library and load module
+# Author : A. Hebert (2018-5-10)
+#
+#---------------------------------------------------------------------------
+#
+ARCH = $(shell uname -m)
+ifneq (,$(filter $(ARCH),aarch64 arm64))
+ nbit =
+else
+ ifneq (,$(filter $(ARCH),i386 i686))
+ nbit = -m32
+ else
+ nbit = -m64
+ endif
+endif
+
+DIRNAME = $(shell uname -sm | sed 's/[ ]/_/')
+OS = $(shell uname -s | cut -d"_" -f1)
+opt = -O -g
+ifeq ($(openmp),1)
+ COMP = -fopenmp
+ FOMP = -fopenmp -D_OPENMP
+else
+ COMP =
+ FOMP =
+endif
+
+ifeq ($(intel),1)
+ fcompiler = ifort
+ ccompiler = icpc
+else
+ ifeq ($(nvidia),1)
+ fcompiler = nvfortran
+ ccompiler = nvc++
+ else
+ ifeq ($(llvm),1)
+ fcompiler = flang-new
+ ccompiler = clang++
+ else
+ fcompiler = gfortran
+ ccompiler = gcc
+ endif
+ endif
+endif
+
+clib = -lstdc++
+ifeq ($(OS),Darwin)
+ C = $(ccompiler) -std=c++17
+ F90 = $(fcompiler)
+ FLAGS = -DLinux -DUnix
+ CFLAGS = -Wall $(nbit) -fPIC
+ LFLAGS = $(nbit)
+ clib = -lc++
+else
+ifeq ($(OS),Linux)
+ ifeq ($(nvidia),1)
+ C = $(ccompiler) -std=c++14
+ else
+ C = $(ccompiler) -std=c++17
+ endif
+ F90 = $(fcompiler)
+ FLAGS = -DLinux -DUnix
+ CFLAGS = -Wall $(nbit) -fPIC
+ LFLAGS = $(nbit)
+else
+ifeq ($(OS),CYGWIN)
+ C = g++ -std=c++17
+ F90 = $(fcompiler)
+ FLAGS = -DLinux -DUnix
+ CFLAGS = -Wall $(nbit) -fPIC
+ LFLAGS = $(nbit)
+else
+ifeq ($(OS),SunOS)
+ MAKE = gmake
+ F90 = f90
+ C = cc
+ FLAGS = -DSunOS -DUnix
+ CFLAGS = $(nbit)
+ LFLAGS = $(nbit)
+else
+ifeq ($(OS),AIX)
+ opt = -O4
+ MAKE = gmake
+ DIRNAME = AIX
+ F90 = xlf90
+ C = xlc
+ FLAGS = -DAIX -DUnix
+ CFLAGS = -qstrict
+ LFLAGS = -qstrict -bmaxdata:0x80000000 -qipa
+else
+ $(error $(OS) is not a valid OS)
+endif
+endif
+endif
+endif
+endif
+INCLUDE = -I../../Ganlib/src/
+
+ifeq ($(intel),1)
+ FFLAGS = -fPIC
+ FFLAG77 = -fPIC
+ lib = ../lib/$(DIRNAME)_intel
+ bin = ../bin/$(DIRNAME)_intel
+ libUtl = ../../Utilib/lib/$(DIRNAME)_intel
+ libGan = ../../Ganlib/lib/$(DIRNAME)_intel
+ libTri = ../../Trivac/lib/$(DIRNAME)_intel
+ libDra = ../../Dragon/lib/$(DIRNAME)_intel
+ libDon = ../../Donjon/lib/$(DIRNAME)_intel
+else
+ ifeq ($(nvidia),1)
+ lib = ../lib/$(DIRNAME)_nvidia
+ bin = ../bin/$(DIRNAME)_nvidia
+ libUtl = ../../Utilib/lib/$(DIRNAME)_nvidia
+ libGan = ../../Ganlib/lib/$(DIRNAME)_nvidia
+ libTri = ../../Trivac/lib/$(DIRNAME)_nvidia
+ libDra = ../../Dragon/lib/$(DIRNAME)_nvidia
+ libDon = ../../Donjon/lib/$(DIRNAME)_nvidia
+ else
+ ifeq ($(llvm),1)
+ lib = ../lib/$(DIRNAME)_llvm
+ bin = ../bin/$(DIRNAME)_llvm
+ libUtl = ../../Utilib/lib/$(DIRNAME)_llvm
+ libGan = ../../Ganlib/lib/$(DIRNAME)_llvm
+ libTri = ../../Trivac/lib/$(DIRNAME)_llvm
+ libDra = ../../Dragon/lib/$(DIRNAME)_llvm
+ libDon = ../../Donjon/lib/$(DIRNAME)_llvm
+ LFLAGS += -lclang_rt.osx
+ else
+ lib = ../lib/$(DIRNAME)
+ bin = ../bin/$(DIRNAME)
+ libUtl = ../../Utilib/lib/$(DIRNAME)
+ libGan = ../../Ganlib/lib/$(DIRNAME)
+ libTri = ../../Trivac/lib/$(DIRNAME)
+ libDra = ../../Dragon/lib/$(DIRNAME)
+ libDon = ../../Donjon/lib/$(DIRNAME)
+ endif
+ endif
+endif
+
+ifeq ($(hdf5),1)
+ CFLAGS += -DHDF5_LIB -I${HDF5_INC}
+ LFLAGS += -L${HDF5_API} -lhdf5
+endif
+
+SRCC = $(shell ls *.cxx)
+OBJC = $(SRCC:.cxx=.o)
+all : sub-make Skin++
+ifeq ($(openmp),1)
+ @echo 'Skin++: openmp is defined'
+endif
+ifeq ($(intel),1)
+ @echo 'Skin++: intel is defined'
+endif
+ifeq ($(nvidia),1)
+ @echo 'Skin++: nvidia is defined'
+endif
+ifeq ($(llvm),1)
+ @echo 'Skin++: llvm is defined'
+endif
+ifeq ($(hdf5),1)
+ @echo 'Skin++: hdf5 is defined'
+endif
+sub-make:
+ $(MAKE) openmp=$(openmp) intel=$(intel) nvidia=$(nvidia) llvm=$(llvm) hdf5=$(hdf5) -C ../../Donjon/src
+%.o : %.cxx
+ $(C) $(CFLAGS) $(FLAGS) $(opt) $(COMP) $(INCLUDE) -c $< -o $@
+$(lib)/:
+ mkdir -p $(lib)/
+libSkin++.a: $(OBJC) $(lib)/
+ ar r $@ $(OBJC)
+ cp $@ $(lib)/$@
+$(bin)/:
+ mkdir -p $(bin)/
+Skin++: libSkin++.a Skin++.o $(bin)/ sub-make
+ $(F90) $(opt) $(FOMP) Skin++.o $(lib)/libSkin++.a $(libDon)/libDonjon.a $(libDra)/libDragon.a $(libTri)/libTrivac.a \
+ $(libDra)/libDragon.a $(libUtl)/libUtilib.a $(libGan)/libGanlib.a $(clib) $(LFLAGS) -o Skin++
+ cp $@ $(bin)/$@
+clean:
+ $(MAKE) -C ../../Donjon/src clean
+ /bin/rm -f *.o *.a sub-make Skin++
diff --git a/Skin++/src/Skin++.cxx b/Skin++/src/Skin++.cxx
new file mode 100755
index 0000000..150e6d5
--- /dev/null
+++ b/Skin++/src/Skin++.cxx
@@ -0,0 +1,80 @@
+#include "Cle2000.hxx"
+using namespace std; using namespace ganlib;
+
+int main(int argc, char **argv) {
+ // construct the lifo stack
+ LifoPtr ipLifo = LifoPtr(new Lifo());
+ ipLifo->push("input_val",5);
+ ipLifo->pushEmpty("output_val","I");
+
+ // call the procedure with in-out CLE-2000 variables
+ Cle2000Ptr ipCle2000 = Cle2000Ptr(new Cle2000("fact", 0, ipLifo));
+ ipCle2000->exec();
+
+ // recover and erase the lifo stack
+ int_32 output_val; ipLifo->pop(output_val);
+ cout << endl << "factorial(5)=" << output_val << endl << endl;
+ if (output_val != 120) throw Cle2000Exception("Test failure 1");
+
+ // empty the lifo stack
+ while (ipLifo->getMax() > 0) ipLifo->pop();
+
+ // end of case -----------------------------------------------------------
+
+ // construct a new lcm object
+ ClcmPtr iplistgen = ClcmPtr(new Clcm("LCM_IMP_ASCII", "Geo3D.txt", "./"));
+ iplistgen->lib();
+ StringPtrConst myString = iplistgen->getString("SIGNATURE");
+ cout << "signature=" << *myString << "<---" << endl;
+ iplistgen->close("KEEP");
+
+ // construct a new lifo stack
+ LifoPtr ipLifo2 = LifoPtr(new Lifo());
+ ipLifo2->push("Geo3D",iplistgen);
+ ipLifo2->pushEmpty("nb_mix","I");
+ ipLifo2->lib();
+
+ // call the procedure with in-out CLE-2000 variables
+ Cle2000Ptr ipCle2000_bis = Cle2000Ptr(new Cle2000("grep", 0, ipLifo2));
+ ipCle2000_bis->exec();
+
+ // recover and erase the lifo stack
+ int_32 nb_mix; ipLifo2->pop(nb_mix);
+ cout << endl << "number of mixtures = " << nb_mix << endl << endl;
+ if (nb_mix != 17) throw Cle2000Exception("Test failure 2");
+
+ // empty the lifo stack
+ while (ipLifo2->getMax() > 0) ipLifo2->pop();
+
+ // end of case -----------------------------------------------------------
+
+ // construct the lifo stack
+ LifoPtr ipLifo3 = LifoPtr(new Lifo());
+ ipLifo3->pushEmpty("saphyb", "XSM", "./saphyb_UOX_AICN");
+ ipLifo3->push("draglib", string("draglibendfb7r1SHEM295"));
+ ipLifo3->push("type", string("FRA"));
+ ipLifo3->push("combustible", string("UOX"));
+ ipLifo3->push("barres", string("AICN"));
+ ipLifo3->push("homoge", string("HOMOGENE"));
+ ipLifo3->push("u235", float_32(3.7));
+ ipLifo3->push("burnup", float_32(85000.));
+ ipLifo3->push("nrgoup", int_32(2));
+ ipLifo3->lib();
+
+ // call the procedure with in-out CLE-2000 variables
+ Cle2000Ptr ipCle2000_ter = Cle2000Ptr(new Cle2000("pwr2010", 0, ipLifo3));
+ ipCle2000_ter->exec();
+
+ // recover the saphyb
+ ClcmPtr xsm_object; ipLifo3->node("saphyb", xsm_object);
+ xsm_object->open("READ-ONLY");
+ xsm_object->lib();
+ xsm_object->close("KEEP");
+
+ // empty the lifo stack
+ while (ipLifo3->getMax() > 0) ipLifo3->pop();
+
+ // end of case -----------------------------------------------------------
+ cout << "Skin++: normal end of execution" << endl;
+ return 0;
+}