yuchuli пре 2 година
родитељ
комит
7f4dadbde2

+ 15 - 1
src/test/carmakerexecwork/carmakerexecwork.cpp

@@ -18,6 +18,7 @@ int ExecCarmakerWork(int64_t workid,std::string strInputName, std::string strOut
                      std::shared_ptr<char> pinput_ptr,int ninputsize,
                      std::shared_ptr<char> & poutput_ptr,int & noutputsize)
 {
+
     QFile xFile;
     xFile.setFileName(strInputName.data());
     if(xFile.open(QIODevice::ReadWrite))
@@ -54,7 +55,8 @@ int ExecCarmakerWork(int64_t workid,std::string strInputName, std::string strOut
         noutputsize = ba.size();
         std::cout<<" file size: "<<noutputsize<<std::endl;
         poutput_ptr =  std::shared_ptr<char>(new char[static_cast<unsigned long>(noutputsize) ]);
-        memcpy(poutput_ptr.get(),ba.data(),noutputsize);
+        memcpy(poutput_ptr.get(),ba.data(),static_cast<size_t>(noutputsize) );
+        xFileout.close();
     }
     else
     {
@@ -62,5 +64,17 @@ int ExecCarmakerWork(int64_t workid,std::string strInputName, std::string strOut
         return -1;
     }
 
+    QFileInfo fileinfo1(strInputName.data());
+    if(fileinfo1.isFile())
+    {
+        QFile::remove(strInputName.data());
+    }
+
+    QFileInfo fileinfo2(strOutputName.data());
+    if(fileinfo2.isFile())
+    {
+        QFile::remove(strOutputName.data());
+    }
+
     return 1;
 }

+ 889 - 0
src/test/testipgroad/infoc.h

@@ -0,0 +1,889 @@
+/******************************************************************************/
+/*  Infofile-API.							      */
+/*  ------------------------------------------------------------------------  */
+/*  (c) IPG Automotive GmbH    www.ipg-automotive.com   Fon: +49.721.98520-0  */
+/*  Bannwaldallee 60    D-76185 Karlsruhe     Germany   Fax: +49.721.98520-99 */
+/******************************************************************************/
+
+#ifndef __INFOC_H__
+#define __INFOC_H__
+
+#include <stddef.h>
+
+#if defined(__GNUC__)
+# ifndef INFO_PRINTF
+#  if __GNUC__ >= 5 || __GNUC__ >= 4 && __GNUC_MINOR__ >= 4
+#   define INFO_PRINTF gnu_printf
+#  else
+#   define INFO_PRINTF printf
+#  endif
+# endif
+#else
+# ifndef __attribute__
+#   define __attribute__(x) /*nothing*/
+# endif
+#endif
+
+#ifdef __cplusplus
+# define __INFOC_CPP_BEGIN	extern "C" {
+# define __INFOC_CPP_END	}
+__INFOC_CPP_BEGIN
+#endif
+
+extern const char InfoVersion[];
+extern const int  InfoNumVersion;
+extern const char InfoArch[];
+extern const char InfoCompFlags[];
+
+
+/** Format einer Info-Datei  **************************************************/
+
+
+/*
+**    o Leerzeilen sind erlaubt. Leerzeichen und Tabs an Zeilenanfang bzw.
+**	-ende, hinter Schluesseln bzw. vor dem eigentlichen Wert werden
+**	ignoriert (bis auf Tab in der ersten Spalte, s.u.).
+**
+**    o Kommentarzeilen enthalten ein '#' als erstes Nicht-Leerzeichen.
+**
+**    o Signifikante Leerzeichen und Tabs koennen durch Einfassen des Textes
+**      in "" beibehalten werden, dadurch wird auch die Interpretation von
+**	Trennzeichen (d.h. []=:) verhindert. Einzelne Zeichen koennen auch
+**	durch Voranstellen von '\' von jeglicher Interpretation ausgenommen
+**	werden (so erhaelt man z.B. " innerhalb von "..." durch "...\"...").
+**
+**    o Zu lange Zeilen duerfen aufgetrennt werden. Ein '\' als LETZTES Zeichen
+**	in der Zeile zeigt an, dass der Zeileninhalt in der naechsten Zeile
+**	fortgesetzt wird. Beispiel:
+**	    Fahrzeug.Reifen.Hersteller:		Michelin, Continental, \
+**						Brigdestone, Fulda
+**
+**   o Es gibt zwei Arten von Werten zu Schluesseln.
+**	- String-Werte in Form einer einzelnen Zeichenkette. Schluessel und
+**	  Wert sind dann durch '=' getrennt. Beispiel:
+**	    Fahrzeug =			Porsche
+**	    Fahrzeug.Farbe =		rot
+**	- Text-Werte in Form mehrerer Textzeilen. Der Schluessel steht dann
+**	  allein in einer Zeile, terminiert durch ':'. Die einzenen Textzeilen
+**	  sind mit einem Tabulator-Zeichen eingerueckt. Beispiel:
+**	    Fahrzeug.Kommentar:
+**		    Farbe ist nett. Faehrt sich gut,
+**	    	    Allerdings sind die Sitze etwas weich
+**		    und die Lenkung ein wenig unpraezise in der Mittellage.
+**	- Gross-/Kleinschreibung eines Schluessels ist signifikant.
+**
+**    o Die Schluessel koennen hierarchisch untergliedert werden, sind dann
+**	in sog. Subschluessel unterteilt. Die Subschluessel werden durch '.'
+**	voneinander getrennt. Beispiele:
+**	    Fahrzeug
+**	    Fahrzeug.Farbe
+**	    Fahrzeug.Reifen.Groesse
+**	    Fahrzeug.Reifen.Hersteller
+**	    Fahrzeug.Kommentar
+**      Fahrzeug, Farbe, Reifen, Groesse usw. sind Subschlessel.
+**
+**   o Schluessel koennen auf zwei Arten angegeben werden.
+**	- Absolut wie im obigen Beispiel.
+**	- Relativ zu einem Praefix. Beispiel:
+**	    [Fahrzeug]
+**	    .Farbe
+**	    .Reifen.Groesse
+**	    .Reifen.Hersteller
+**	  Achtung, Praefixe duerfen nicht an anderer Stelle als Schluessel
+**	  mit einem Wert versehen werden. Im obigen Beispiel:
+**	  "Fahrzeug = VW Kaefer" an einer anderen Stelle in der Info-Datei
+**	  wuerde zu einem Fehler "Duplicate key." beim Einlesen fuehren.
+**	- Absolute und relative Schluesselangaben duerfen gemischt werden.
+**	  Die relativen Schluessel beziehen sich dabei immer auf das zuletzt
+**	  mit [...] definierte Praefix.
+**
+**    o Tritt ein und derselbe Schluessel mehrfach auf, hat nur das zuletzt
+**	gelesene Schluessel-Wert-Paar Signifikanz. (Die vorigen werden beim
+**	Zugriff ueber den Schluessel "nicht mehr gefunden".)
+**
+**    o Grenzen:
+**	Maximale Zeilenlaenge inklusive aller Fortsetzungszeilen: 4096 Zeichen.
+**	Maximale Anzahl Zeichen pro Subschluessel: 32 (inkl. '\0')
+**	Maximale Anzahl Subschluessel pro Schluessel: 16
+*/
+
+
+
+/** Datentypen fuer den Umgang mit Infos  *************************************/
+
+typedef struct tInfos tInfos;
+typedef struct tInfoIter tInfoIter;
+
+typedef struct tErrorMsg {
+    char *Msg;			/* Klartext-Fehlerbeschreibung. */
+    int LineNo;			/* Zeilennummer, in der der Fehler auftrat.
+				   Falls < 0: Allgemeiner Fehler. */
+    char *Line;			/* Zeile, in der der Fehler auftrat. */
+    struct tErrorMsg *Next;	/* Naechste Fehlermeldung in der Kette. */
+} tErrorMsg;
+
+
+
+/** Anlegen, Lesen, Schreiben, Loeschen von Infos  ****************************/
+
+
+/*
+** Erzeuge bzw. loesche eine Info-Datenstruktur.
+**
+** Rueckgabe:
+** 	Funktionswert	Handle fuer zukuenftigen Zugriff auf Infos.
+**		NULL bei Fehler.
+*/
+tInfos *InfoNew (void);
+int InfoDelete (tInfos *inf);
+
+
+/*
+** Kopiere alle Schluessel einer Info-Datenstruktur.
+** Es werden nur Schluessel kopiert, fuer die die angegebene Filterfunktion
+** einen Wert ungleich 0 liefert, dies also quasi mit "true" genehmigt.
+** Leer- und Kommentarzeilen, Schluesselreihenfolge etc. werden
+** beim Kopieren _nicht_ uebernommen.
+** Anstatt einer Filterfunktion ist auch NULL als Wert fuer skip_key
+** erlaubt, dann werden alle Schluessel ohne Ausnahme kopiert.
+*/
+void InfoMerge (tInfos *dstinf, const tInfos *srcinf,
+		int (*skip_key) (void *data, const char *key), void *data);
+
+
+/*
+** Lies alle Infos aus der angegebenen Datei.
+**
+** Rueckgabe:
+**	Funktionswert	Betrag |.| liefert Zahl der Fehlermeldungen in *perrors.
+**			< 0 bei Dateizugriffsfehler (harter Fehler).
+**			= 0 falls alles ok.
+**			> 0 bei Syntaxfehlern (weicher Fehler, Warnung)
+**	*perrors	Liste mit Fehlermeldungen, die beim Lesen auftraten.
+*/
+int InfoRead (tErrorMsg **perrors, tInfos *inf, const char *filename);
+int InfoReadMem (tErrorMsg **perrors, tInfos *inf,
+		 char *bufStart, /*Puffer wird modifiziert*/
+		 int bufSize);
+
+
+/*
+** Schreibe alle Infos in die angegebene Datei.
+**
+** Rueckgabe:
+**	Funktionswert	!= 0 bei Fehler, == 0 sonst.
+**			(siehe InfoErrno bzw. InfoStrError() in diesem Fall).
+*/
+int InfoWrite (tInfos *inf, const char *filename);
+char *InfoWriteMem (tInfos *inf, int *size);
+
+
+
+/*
+** Liefere den Namen der zuletzt mit dem angegebenen Handle gelesenen
+** Datei (bzw. NULL, falls die Information nicht verfuegbar ist).
+*/
+const char *InfoGetFilename (const tInfos *inf);
+
+
+/*
+** ...
+*/
+char **InfoGetDataPools (void);
+void InfoSetDataPools  (char *const *dirs);
+void InfoSetDataPoolsV (const char *firstdir, ...);
+int  InfoGetDataPoolsMaxLen (void);
+
+/*
+** ...
+** NULL, falls Datei nicht gefunden.
+** Das Freigeben des gelieferten Pfades ist Aufgabe des Anwenders.
+*/
+char *InfoLocateFile (const char *path, int ignoreinfofilesuffixes);
+
+
+/** Einzelzugriff auf Infos  **************************************************/
+
+
+/*
+** Liefere eine Liste von Schluesseln des angegebenen Typs.
+** Argument 'prefix' muss einen vollstaendigen Schluessel enthalten (kein
+** Muster mit '*' o.ae. oder einen Teil-String, und endet auch nie auf '.').
+**
+** Rueckgabe:
+**    Funktionswert	Zeiger auf ein NULL-terminiertes Stringfeld mit den
+**			Schluesseln. Der Aufrufer ist fuer das Freigeben des
+**			Feldes samt Inhalt verantwortlich.
+**			NULL bei Fehler.
+*/
+typedef enum {
+    Keys,		/* Alle Schluessel genau ein Subschluessel-Level
+			   unterhalb eines Schluessel-Praefix. */
+    Subkeys,		/* Alle Subschluessel (d.h. Schluesselkomponenten)
+			   genau ein Subschluessel-Level unterhalb eines
+			   Schluessel-Praefix. */
+    Unread_Keys,	/* Alle Schluessel unterhalb eines Subschluessel-Level,
+			   die bislang noch keinen Zugriff (lesend oder
+			   schreibend) erfahren haben. */
+    All_Keys,		/* Alle Schluessel
+			   unterhalb eines Schluessel-Praefix. */
+    Next_Level_Keys = Keys					/* Kompat. */
+} tIterKind;
+
+char **InfoListKeys (const tInfos *inf, const char *prefix, tIterKind kind);
+
+
+/*
+** Liefere den Typ des unter einem Schluessel gespeicherten Wertes.
+*/
+typedef enum {
+    No_Key,			/* Schluessel existiert nicht (bzw. ohne Wert). */
+    String_Key,			/* Schluessel zu einem String-Wert. */
+    Text_Key			/* Schluessel zu einem Text-Wert. */
+#define Empty_Key  50000	/* KOMPAT, wird nicht mehr verwendet */
+#define Prefix_Key 50001	/* KOMPAT, wird nicht mehr verwendet */
+} tKeyKind;
+
+tKeyKind InfoKeyKind (const tInfos *inf, const char *key);
+
+
+/*
+** Loesche das zum Schluessel gehoerende Info.
+**
+** Rueckgabe:
+**   Funktionswert	-1 bei Fehler, 0 sonst.
+*/
+int  InfoDelKey (tInfos *inf, const char *key);
+
+
+/*
+** Suche den zum Schluessel gehoerenden Wert.
+**
+** Rueckgabe:
+**   Funktionswert	-1 bei Fehler, 0 sonst.
+**   *pval		Der Wert. Der im Falle von InfoGetStr() gelieferte
+**			String verweist auf Speicher, der NICHT vom Anwender
+**			freizugeben ist (d.h. free(pval) ist nicht erlaubt.)
+**			Das Freigeben der von InfoGetTxt() gelieferten Liste
+**			von Strings ist Aufgabe des Anwenders (d.h. free(pval)
+**			erlaubt und in seiner Verantwortung), nicht aber das
+**			Freigeben der Strings, auf die die Liste verweist
+**			(d.h. beispielsweise free(pval[0]) ist nicht erlaubt).
+**			Das Freigeben der von InfoGetBin() gelieferten Daten
+**			mittels free() ist Aufgabe des Anwenders.
+*/
+int  InfoGetStr	 (char     **pval, const tInfos *inf, const char *key);
+int  InfoGetLLong(long long *pval, const tInfos *inf, const char *key);
+int  InfoGetLong (long      *pval, const tInfos *inf, const char *key);
+int  InfoGetInt  (int       *pval, const tInfos *inf, const char *key);
+int  InfoGetDbl	 (double    *pval, const tInfos *inf, const char *key);
+int  InfoGetFlt	 (float     *pval, const tInfos *inf, const char *key);
+int  InfoGetBin  (char     **pval, int *pvalsize, tInfos *inf, const char *key);
+int  InfoGetTxt	 (char    ***pval, const tInfos *inf, const char *key);
+
+
+/*
+**  Suche den zum Schluessel gehoerenden Wert.
+**  Falls kein Info mit diesem Schluessel existiert, liefere den angegebenen
+**  Defaultwert.
+**
+**  Rueckgabe:
+**    Funktionswert	-1 bei Fehler, 1 bei nicht gefundenem Schluessel,
+**			0 sonst.
+**	*pval		Der Wert. Zur Speicherfreigabe des in pval gelieferten
+**			Ergebnisses siehe InfoGetStr(), InfoGetLong(), usw.
+*/
+int InfoGetStrDef  (char     **pval, const tInfos *inf, const char *key, char     *def);
+int InfoGetLLongDef(long long *pval, const tInfos *inf, const char *key, long long def);
+int InfoGetLongDef (long      *pval, const tInfos *inf, const char *key, long      def);
+int InfoGetIntDef  (int       *pval, const tInfos *inf, const char *key, int       def);
+int InfoGetDblDef  (double    *pval, const tInfos *inf, const char *key, double    def);
+int InfoGetFltDef  (float     *pval, const tInfos *inf, const char *key, float     def);
+int InfoGetBinDef  (char     **pval, int *pvalsize, tInfos *inf, const char *key, char *def, int defsize);
+int InfoGetTxtDef  (char    ***pval, const tInfos *inf, const char *key, char    **def);
+
+
+/*
+** Suche den zum Schluessel gehoerenden Wert.
+** Falls kein Info mit diesem Schluessel existiert, liefere einen
+** "leeren" Wert (Leer-String oder Txt-Array mit 0 Zeilen).
+** Die Funktionen arbeiten unabhaengig vom Schluesseltyp, d.h. zwischen
+** Str und Txt wird automatisch konvertiert. Zur der Bedeutung von
+** sepchar siehe InfoTxt2Str().
+** Der gelieferte Wert ist vom Aufrufenden freizugeben.
+*/
+char  *InfoFetchStr (const tInfos *inf, const char *key, int sepchar);
+char **InfoFetchTxt (const tInfos *inf, const char *key);
+
+
+/*
+** Suche die zum Schluessel gehoerende Tabelle.
+** Der Schluesseltyp (txt oder str) spielt dabei keine Rolle.
+** Die Anzahl der gefundenen Tabellenelemente muss ungleich 0 sein und
+** sich ohne Rest durch die geforderte Anzahl Spalten teilen lassen,
+** andernfalls wird ein Fehler gemeldet.
+** Tabellen beliebiger Groesse lassen sich mit |ncolumns|=1 lesen,
+** Ablage im Speicher dann zeilenweise und die Anzahl der gefundenen
+** Elemente steht anschliessend in mrows.
+**
+** Die Tabelle darf Kommentare beginnend mit # enthalten; diese gelten bis
+** zum Zeilenende und werden ueberlesen.
+**
+** Beispieltabellen (alle aequivalent):
+**	My.Table = 10 20 30 40 50 60
+**	Your.Table:
+**		10  20		# x
+**		30  40		# y
+**		50  60		# z
+**	Their.Table:
+**		#  a   b
+**		  10  20	# x
+**		  30  40	# y
+**		  50  60	# z
+**
+** Rueckgabe:
+**   Funktionswert	NULL bei Fehler (und Fehlercode in InfoErrno), gueltige
+**			Liste mit mrows*|ncolumns| vielen Elementen zeilenweise
+**			(ncols<0) bzw. spalten spaltenweise (ncols>0) zusammen-
+**			gefasst. Freigeben dieser Liste ist Aufgabe des Anwenders.
+**			Die InfoGetTableS*()-Varianten liefern die Tabellen-
+**			elemente als NULL-terminierte Liste von Strings, die
+**			ebenso einzeln freigegeben werden muessen (z.B. via
+**			InfoFreeTxt()).
+**			Bzgl. Freigabe aber Vorsicht, falls der Default-Wert
+**			zurueckgeliefert wird - er wird ohne Aenderung durchge-
+**			reicht, liegt also evt. statisch im Speicher oder ist
+**			im Fall von InfoGetTableS*() nicht NULL-terminiert.
+**   *mrows		Die Anzahl der gefundenen Tabellenzeilen.
+*/
+double *InfoGetTable  (const tInfos *inf, const char *key, int ncols, int *mrows);
+char  **InfoGetTableS (const tInfos *inf, const char *key, int ncols, int *mrows);
+
+/*
+** Analog InfoGetStrDef() usw.
+** Falls der gesuchte Schluessel nicht existiert oder keine Tabellendaten
+** enthaelt, liefere den angegebenen Default-Wert. Ansonsten siehe InfoGetTable().
+*/
+double *InfoGetTableDef2 (const tInfos *inf, const char *key,
+			  int ncols, int *mrows, double *def, int mrowsdef);
+char **InfoGetTableSDef2 (const tInfos *inf, const char *key,
+			  int ncols, int *mrows, char **def, int mrowsdef);
+
+/*
+** Analog InfoGetTable() bzw. InfoGetTableDef(),
+** nur dass die Anzahl der erwarteten Tabellenzeilen vorgegeben wird.
+*/
+double *InfoGetFixedTable    (const tInfos *inf, const char *key,
+			      int ncols, int mrows);
+char  **InfoGetFixedTableS   (const tInfos *inf, const char *key,
+			      int ncols, int mrows);
+double *InfoGetFixedTableDef2 (const tInfos *inf, const char *key,
+			       int ncols, int  mrows, double *def);
+char  **InfoGetFixedTableSDef2 (const tInfos *inf, const char *key,
+				int ncols, int  mrows, char **def);
+
+/*
+** Speichere einen Wert unter dem angegebenen Schluessel.
+** Falls kein Info mit diesem Schluessel existiert, lege ein neues Info an.
+**
+** Rueckgabe:
+**     Funktionswert	-1 bei Fehler, 0 sonst.
+*/
+int InfoSetStr	(tInfos *inf, const char *key, const char *val);
+int InfoSetStrF	(tInfos *inf, const char *key, const char *format, ...)
+    __attribute__((format(INFO_PRINTF,3,4)));
+int InfoSetLLong(tInfos *inf, const char *key, long long val);
+int InfoSetLong	(tInfos *inf, const char *key, long val);
+int InfoSetInt	(tInfos *inf, const char *key, int val);
+int InfoSetDbl	(tInfos *inf, const char *key, double val);
+int InfoSetFlt	(tInfos *inf, const char *key, float val);
+int InfoSetBin  (tInfos *inf, const char *key, const char *val, int valsize);
+int InfoSetZBin (tInfos *inf, const char *key, const char *val, int valsize);
+int InfoSetTxt	(tInfos *inf, const char *key,        char *const *val);
+int InfoSetTxtN (tInfos *inf, const char *key, int n, char *const *val);
+int InfoSetTxtV	(tInfos *inf, const char *key, const char *first, ...);
+int InfoTxtAppendF (tInfos *inf, const char *key, const char *format, ...)
+    __attribute__((format(INFO_PRINTF,3,4)));
+int InfoTxtAppendN (tInfos *inf, const char *key, int n, char *const *val);
+int InfoTxtAppendV (tInfos *inf, const char *key, const char *first, ...);
+
+
+/*
+** Verschiebe einen Schluessel vor/hinter den angegebenen Zielschluessel.
+**
+** Sonderfaelle:
+**   InfoMoveKeyBefore (*, NULL, *)	Einfuegen vor der allerersten Zeile.
+**   InfoMoveKeyBehind (*, NULL, *)	Einfuegen hinter der allerletzten Zeile.
+**
+** Rueckgabe:
+**   Funktionswert	-1 bei Fehler (ungueltiger/nicht existenter Schluessel),
+**                      0 sonst.
+*/
+int InfoMoveKeyBefore (tInfos *inf, const char *destkey, const char *key);
+int InfoMoveKeyBehind (tInfos *inf, const char *destkey, const char *key);
+
+
+/*
+** Fuege eine Leer- bzw. Kommentarzeile vor/hinter dem angegebenen
+** Zielschluessel ein.
+**
+** Sonderfaelle:
+**   InfoAddLineBefore (*, NULL, *)	Einfuegen vor der allerersten Zeile.
+**   InfoAddLineBehind (*, NULL, *)	Einfuegen hinter der allerletzten Zeile.
+**
+** Rueckgabe:
+**   Funktionswert	-1 bei Fehler, 0 sonst.
+*/
+int InfoAddLineBefore (tInfos *inf, const char *destkey, const char *val);
+int InfoAddLineBehind (tInfos *inf, const char *destkey, const char *val);
+
+
+
+/** Iterierender Zugriff auf Infos  *******************************************/
+
+/*
+ * !!! Use of the InfoIXXX() functions is deprecated, use InfoListKeys() instead.
+ * !!! In future versions of the Infofile library the functions will no longer
+ * !!! be available.
+ */
+
+/*
+** Erzeuge bzw. loesche einen Iterator.
+**
+** Rueckgabe:
+**	Funktionswert	Handle zur zukuenftigen Verwendung des Iterators.
+**			NULL bei Fehler.
+*/
+tInfoIter *	InfoINew (void);
+int		InfoIDelete (tInfoIter *iter);
+
+
+/*
+** Initialisiere einen Iterator. Iteriert wird ab einem Praefix ueber alle
+** Schluessel des angegebenen Typs (siehe InfoListKeys()).
+**
+** Rueckgabe:
+**   Funktionswert	Anzahl der gefundenen passenden Schluessel
+**			bzw. -1 bei Fehler.
+*/
+int	InfoIStart (tInfoIter *iter, tInfos *inf,
+		    const char *prefix, tIterKind kind);
+int	InfoIReset (tInfoIter *iter);
+
+
+/*
+** Iteriere ueber das aktuelle Info. Lies Schluessel bzw. Wert des Infos
+** und ruecke anschliessend automatisch zum naechsten gefundenen Info vor.
+**
+** Rueckgabe:
+**	Funktionswert	Wahrheitswert, ob noch ein Info gefunden wurde;
+**			-1 bei Fehler.
+**	*pkey		Der Schluessel des gefundenen Infos.
+**	*pval		Der Wert des gefundenen Infos.
+**			Speicherfreigabe siehe entsprechende InfoGetXXX-Fkt.
+**	*iter		Iterator-Handle, zeigt auf das naechste gefundene Info.
+*/
+int InfoIGetKey  (char **pkey,                    tInfoIter *iter);
+int InfoIGetStr  (char **pkey, char       **pval, tInfoIter *iter);
+int InfoIGetLLong(char **pkey, long long   *pval, tInfoIter *iter);
+int InfoIGetLong (char **pkey, long        *pval, tInfoIter *iter);
+int InfoIGetInt  (char **pkey, int         *pval, tInfoIter *iter);
+int InfoIGetDbl  (char **pkey, double      *pval, tInfoIter *iter);
+int InfoIGetFlt  (char **pkey, float       *pval, tInfoIter *iter);
+int InfoIGetBin  (char **pkey, char       **pval, int *pvalsize, tInfoIter *iter);
+int InfoIGetTxt  (char **pkey, char      ***pval, tInfoIter *iter);
+
+
+
+/** Hilfsfunktionen  **********************************************************/
+
+/*
+** Erzeuge ein NULL-terminiertes Txt-Array aus Einzel-Strings.
+** Als letztes Argument der Funktion muss NULL angegeben werden.
+**
+** Parameter:
+**    linkonly == 0	Erzeuge Kopien der angebenen Einzel-Strings.
+**			Die Wiederfreigabe eines erzeugten Txt-Arrays t kann
+**			anschliessend z.B. mit InfoFreeTxt(t) erfolgen.
+**    linkonly != 0	Verweise direkt auf die angegebenen Einzel-Strings.
+**			Die Wiederfreigabe eines erzeugten Txt-Arrays t muss
+**			anschliessend mit free(t) erfolgen.
+*/
+char **InfoMakeTxt (int linkonly, const char *first, ...);
+
+
+/*
+** Gib den Speicher eines NULL-terminierten Txt-Arrays frei,
+** dessen Txt-Zeilen einzeln allokiert wurden.
+** Achtung: Der belegte Speicher muss komplett der Anwendung gehoeren
+** und darf nicht von der Infofile-Bibliothek verwaltet werden,
+** d.h. der Rueckgabewert von InfoGetTxt() darf _nicht_ mit dieser
+** Funktion frei gegeben werden, da die referenzierten Txt-Zeilen
+** weiterhin der Verwaltung der Infofile-Bibliothek unterliegen.
+*/
+void InfoFreeTxt (char **txt);
+
+
+/*
+ * Dupliziere ein Txt-Array.
+ */
+char **InfoDupTxt (char *const *orig);
+
+
+/*
+** Zaehle die Anzahl Zeilen in einem Txt-Array.
+*/
+int InfoTxtLength (char *const *txt);
+
+
+/*
+** String s in Txt-Array txt enthalten?
+*/
+int InfoTxtContains (char *const *txt, const char *s);
+
+
+/*
+** Zeichenweiser Vergleich zweier Txt-Arrays analog strcmp().
+*/
+int InfoTxtCompare (char *const *ta, char *const *tb);
+
+
+/*
+** Fuege alle Txt-Zeilen zu einem grossen String zusammen.
+** Zwischen den einzelnen Zeilen wird jeweils ein Trennzeichen sepchar
+** eingefuegt. Default-Trennzeichen (mit sepchar == 0) ist '\n'.
+*/
+char *InfoJoinTxt (char *const *txt, int sepchar);
+
+
+/*
+** Zerlege einen String in einzelne Txt-Zeilen.
+** Trennzeichen innerhalb von str ist sepchar.
+** Default-Trennzeichen (mit sepchar == 0) ist '\n'.
+*/
+char **InfoSplitStr (const char *str, int sepchar);
+
+
+/*
+** Fuege mehrere Subschluessel zu einem gueltigen Schluessel zusammen.
+** Gegenstueck zu InfoKeySplit(). Entspricht InfoJoinTxt(subkeys, '.').
+**
+** Ersatzfunktion ohne Laengenlimits fuer InfoMakeKey().
+*/
+char *InfoKeyJoin (char *subkeys[]);
+
+
+/*
+** Zerlege einen Schluessel in seine Subschluessel.
+** Gegenstueck zu InfoKeyJoin(). Entspricht InfoSplitTxt(key, '.').
+**
+** Ersatzfunktion ohne Laengenlimits fuer InfoSplitKey().
+*/
+char **InfoKeySplit (const char *key);
+
+
+/** Fehlercodes  **************************************************************/
+
+
+typedef enum {
+    INFO_EOK = 0,		/* Schliesse 0 als moeglichen Fehlercode aus. */
+
+    INFO_EINTERNAL = 1,		/* Bibliotheksinterner Fehler. */
+
+    INFO_EBADFNAME = 2,		/* Ungueltiger Dateiname. */
+    INFO_EBADFTYPE = 3,		/* Ungueltiger Dateityp (Verzeichnis usw.). */
+    INFO_ECONTENT = 4,		/* Datei ist kein Infofile. */
+    INFO_EVERSION = 5,		/* Noch nicht unterstuetztes Dateiformat. */
+    INFO_EREAD = 6,			/* Fehler beim Dateilesen, siehe errno. */
+    INFO_EWRITE = 7,		/* Fehler beim Dateischreiben, siehe errno. */
+
+    INFO_EBADKEY = 8,		/* Ungueltiger Schluessel. */
+    INFO_EBADSUBKEY = 9,	/* Ungueltiger Subschluessel. */
+    INFO_ETOOMANY = 10,		/* Max. Anz. Subschluessel ueberschritten. */
+    INFO_ENOINFO = 11,		/* Info mit diesem Schluessel existiert nicht;
+				   keine weiteren iterierbaren Infos da. */
+    INFO_EBADTYPE = 12,		/* Type-Mismatch beim Zugriff auf Info. */
+
+
+    INFO_EMATBADTYPE = 13,	/* Ungueltiger Matrizentyp. */
+    INFO_EMATVERSION = 14,	/* Noch nicht unterstuetztes Matrix-Format. */
+    INFO_EMATBADHEADER = 15,	/* Kein bzw. ungueltiger Matrix-Header. */
+    INFO_EMATSYNTAX = 16,	/* Syntaxfehler in den Matrix-Daten. */
+    INFO_EMATBADSIZE = 17,	/* Ungueltige Anzahl Tabellenelemente. */
+
+    INFO_ECRYPTCORRUPT = 18,	/* Verschluesselte Daten sind beschaedigt. */
+    INFO_ECRYPTWRONGSECRET = 19,/* Falsches Geheimwort. */
+    INFO_ECRYPTALGODATED = 20,	/* Nicht mehr unterstuetzte Verschluesselung. */
+    INFO_ECRYPTALGO = 21,	/* Noch nicht unterstuetzte Verschluesselung. */
+    INFO_ECRYPTEXPIRED = 22,	/* Verfallsdatum ueberschritten. */
+    INFO_ECRYPTACCESS = 23,	/* Zugriff verweigert. */
+    INFO_ECRYPTNOPASSWD = 24,	/* Falscher Schluessel. */
+    INFO_ECRYPTNOABSTRACT = 25,	/* Kurzfassung unvollstaendig/nicht gefunden. */
+    INFO_ECRYPTCONFIG = 26,	/* Fehlerhafte Konfiguration. */
+    INFO_ECRYPTCONFIGILLEGAL = 27,	/* Unerlaubte Konfiguration. */
+
+    INFO_EBINCORRUPT = 28,	/* Binaere Daten sind beschaedigt. */
+    INFO_EBINFORMAT = 29,	/* Binaere Daten in unbekanntem Format. */
+
+    INFO_ECRYPTDATECONFUSION = 30	/* Manipulationsversuch. */
+} tInfoError;
+
+extern tInfoError InfoErrno;	/* Fehlercode des letzten Funktionsaufrufs. */
+extern int InfoSysErrno;	/* Wert von errno nach Dateifehler. */
+
+
+/*
+** Liefere die Klartext-Fehlermeldung zum letzten, aufgetretenen Fehler.
+**
+** Rueckgabe:
+**   Funktionswert	Zeiger auf die Fehlermeldung (statisch angelegt).
+*/
+const char *InfoStrError (void);
+
+
+/** Matrix-API ****************************************************************/
+
+typedef enum tInfoMatType {
+    INFOMAT_UNKNOWN = 0,
+    INFOMAT_DOUBLE,
+    INFOMAT_SINGLE,
+    INFOMAT_UINT32, INFOMAT_INT32,
+    INFOMAT_UINT16, INFOMAT_INT16,
+    INFOMAT_UINT8,  INFOMAT_INT8,
+    INFOMAT_LOGICAL
+} tInfoMatType;
+
+
+typedef struct tInfoMat {
+    tInfoMatType	Type;
+    int			isComplex;
+    int			nDims;		/* nDims>=2 */
+    size_t		*Dims;		/* Dims[0]=mRows, Dims[1]=nCols */
+    int			nElems;
+    void		*RealData;	/* Data in column major order */
+    void		*ImagData;	/* ImagData==NULL if not complex */
+    int			isLinkedData;	/* RealData/ImagData externally allocated? */
+} tInfoMat;
+
+
+tInfoMat   *InfoGetMat    (const tInfos *inf, const char *key,
+			   tInfoMatType fallbacktype, int fallbackncols);
+tInfoMat   *InfoGetMatDef (const tInfos *inf, const char *key,
+			   tInfoMatType fallbacktype, int fallbackncols,
+			   tInfoMat *def);
+int         InfoSetMat    (tInfos *inf, const char *key,
+			   const tInfoMat *mat, const char *format);
+
+
+tInfoMat   *InfoMakeMat (tInfoMatType type, int iscomplex,
+			 int ndims, size_t *dims,
+			 int nelems, void *realdata, void *imagdata, int islinkeddata);
+void        InfoFreeMat   (tInfoMat *mat);
+
+
+tInfoMat   *InfoMatMakeScalar    (tInfoMatType type, int iscomplex,
+				  double re, double im);
+tInfoMat   *InfoMatMakeRowVector (tInfoMatType type, int nelems,
+				  const void *realdata, const void *imagdata);
+tInfoMat   *InfoMatMakeColVector (tInfoMatType type, int nelems,
+				  const void *realdata, const void *imagdata);
+
+
+/** Crypto-API ****************************************************************/
+
+/*
+** Suche Informationen ueber eine Infofile-Datei.
+** Der Anfang der angegebenen Datei wird gelesen, um daraus Rueckschluesse
+** auf den Inhalt zu machen. Syntax-Fehler beim Einlesen werden ignoriert.
+**
+** Parameter:
+**    inf		Handle, in den das Teilstueck eingelesen wird.
+**			sein.
+**    filename		Name der zu lesenden Datei.
+**    size		Groesse des Teilstuecks, das gelesen werden soll
+**			(<= 0 bewirkt Default-Groesse, z.Zt. 2048).
+**
+** Rueckgabe:
+**    Funktionswert	== 0 falls alles ok.
+**			!= 0 bei Fehler
+**			(siehe InfoErrno bzw. InfoStrError() in diesem Fall).
+*/
+int InfoReadPart (tInfos *inf, const char *filename, int size);
+
+
+/*
+** Ermittle, ob die zu einem Infohandle gehoerenden Daten verschluesselt
+** sind bzw. waren.
+**
+** Rueckgabe:
+**    Funktionswert	Wahr (!= 0), falls verschluesselt, Falsch (== 0) sonst.
+*/
+int InfoIsEncrypted (const tInfos *inf);
+int InfoWasEncrypted (const tInfos *inf);
+
+
+/*
+** Entpacke die zu einem verschluesselten Infofile gehorende
+** Kurzfassung.
+**
+** Parameter:
+**    restrictions	Handle, in dem nach erfolgreichem Entpacken die
+**			Kurzfassung enthalten ist. Der alte Inhalt wird ersetzt.
+** Rueckgabe:
+**    Funktionswert	== 0 falls alles ok.
+**			!= 0 bei Fehler
+**			(siehe InfoErrno bzw. InfoStrError() in diesem Fall).
+*/
+int InfoExpandAbstract (const tInfos *inf, tInfos *abstract);
+
+
+/*
+** Vorab-Check zum Entschluesseln eines Infohandles.
+** Geprueft werden, soweit zutreffend und benoetigt, u.a. Verfallsdatum und
+** Korrektheit des Passworts.
+**
+** Parameter:
+**    inf		Handle der verschluesselten Daten.
+**
+** Rueckgabe:
+**    Funktionswert	== 0 bei erfolgreichem Vorab-Check.
+**			!= 0, falls nicht entschluesselt werden konnte
+**			(siehe InfoErrno bzw. InfoStrError() in diesem Fall).
+*/
+int InfoDecryptCheck (tInfos *inf);
+
+
+/*
+** Entschluessele die zu einem Infohandle gehoerenden Daten.
+**
+** Parameter:
+**    inf		Handle der verschluesselten Daten.
+**    config		Handle, in dem nach erfolgreichem Entschluesseln die
+**			Verschluesselungskonfiguration enthalten ist
+**			(NULL erlaubt, falls kein Interesse daran).
+**
+** Rueckgabe:
+**    Funktionswert	== 0 bei erfolgreicher Entschluesselung.
+**			!= 0, falls nicht entschluesselt werden konnte
+**			(siehe InfoErrno bzw. InfoStrError() in diesem Fall).
+*/
+int InfoDecrypt (tInfos *inf, tInfos *config);
+
+
+/*
+** Schreibe alle Infos verschluesselt in die angegebene Datei.
+** Zuvor entschluesselte Daten duerfen nur mit exakt der gleichen
+** Kryptokonfiguration wieder verschluesselt werden.
+**
+** Parameter:
+**    inf		Handle der zu schreibenden Daten.
+**    filename		Name der Datei, in die geschrieben werden soll.
+**    config		Handle mit Verschluesselungskonfiguration.
+**
+** Rueckgabe:
+**    Funktionswert	== 0 bei erfolgreicher Verschluesselung.
+**			!= 0 bei Fehler
+**			(siehe InfoErrno bzw. InfoStrError() in diesem Fall).
+*/
+int  InfoWriteEncrypted (tInfos *inf, const char *filename,
+			 tInfos *config);
+
+
+void InfoClearMem (const tInfos *inf);
+void InfoClearMemAll (void);
+
+void InfoEmptyPool (void);
+void InfoAddToPool (const char *passwd);
+
+void InfoSetFileSuffixes (char *const *suffixes);
+char **InfoGetFileSuffixes (void);
+int  InfoGetFileSuffixesMaxLen (void);
+
+
+/** Variable-API (Named Values) ***********************************************/
+
+int  InfoGetValueSubstMode (void);
+void InfoSetValueSubstMode (int enabled);
+
+void InfoSetValue (const char *name, const char *value);
+
+void InfoUnsetValue (const char *name);
+void InfoUnsetAllValues (void);
+
+int  InfoGetValueCount (void);
+int  InfoGetValueInfo (int i, const char **pname, const char **pvalue);
+
+int  InfoGetUnresolvedFileCount (void);
+const char *InfoGetUnresolvedFile (int index);
+char **InfoGetUnresolvedNames (int index, int *count);
+void InfoClearUnresolved (void);
+
+char **InfoGetUnreferencedValues (int *count);
+void InfoResetAllValueCounters (void);
+
+char **InfoListValueNames (const tInfos *inf);
+
+// InfoKeyHasValueRef(): Returns boolean.
+// Wildcards "*" (all keys) and "a.b*" (a.b and all keys below a.b.c) are supported.
+int  InfoKeyHasValueRef (const tInfos *inf, const char *key);
+
+void InfoAddToCategory (tInfos *inf, const char *category);
+void InfoRemoveFromCategory (tInfos *inf, const char *category);
+
+void InfoSetKeyValueStr  (const char *path, const char *value);
+void InfoSetKeyValueTxt  (const char *path, char *const *value);
+void InfoSetKeyValueTxtV (const char *path, const char *first, ...);
+
+void InfoUnsetKeyValue (const char *path);
+void InfoUnsetAllKeyValues (void);
+
+int  InfoGetKeyValueCount (void);
+int  InfoGetKeyValueInfo  (int i, const char **ppath, const char **pvalue);
+int  InfoGetKeyValueInfo2 (int i, const char **ppath,
+			   const char **pvalue, char ***ptxtvalue /*free(txtvalue)!*/);
+
+
+/** Tcl Stuff *****************************************************************/
+
+/* Tcl-related stuff below can be activated by #including <tcl.h> */
+#ifdef TCL_VERSION
+
+/* Initialize statically linked Tcl module. */
+int Ifile_Init (Tcl_Interp *interp);
+
+/* Retrieve tInfos handle from command name created with [ifile new]. */
+tInfos *InfoGetHandleFromCmd (Tcl_Interp *interp, const char *cmdname);
+
+#endif
+
+
+/** Debugging/Internal Stuff **************************************************/
+
+extern int InfoInitialized;	/* Flag, ob InfoSetup() bereits aufgerufen. */
+
+/* Initialisiere Infofile-Bibliothek. Wird automatisch aufgerufen. */
+void InfoSetup (void);
+
+/* Freigabe allen internen Speichers der Infofile-Bibliothek.
+   Aufruf ist nur bei Programmende sinnvoll. */
+void InfoCleanup (void);
+
+/* Debug-Ausgabe (stdout), Infos ueber in Benutzung befindliche Handles. */
+void InfoShowHandles (void);
+
+/* Wie InfoDelete(), aber fuer alle in Benutzung befindlichen Handles. */
+int  InfoDeleteAll (void);	/* Rueckgabe: Anzahl geloeschter Handles. */
+
+/* Wie InfoWrite(), aber fuer altes INFOFILE1-Format.
+   Funktioniert nicht mit eingelesenen Daten! "Internal, don't use!" */
+int InfoWrite_v1 (tInfos *inf, const char *filename);
+
+
+/******************************************************************************/
+
+#ifdef __cplusplus
+__INFOC_CPP_END
+#endif
+
+#endif /* !defined(__INFOC_H__) */
+

+ 243 - 0
src/test/testipgroad/infofile.h

@@ -0,0 +1,243 @@
+/******************************************************************************/
+/*  Infofile-API C++							      */
+/*  ------------------------------------------------------------------------  */
+/*  (c) IPG Automotive GmbH    www.ipg-automotive.com   Fon: +49.721.98520-0  */
+/*  Bannwaldallee 60    D-76185 Karlsruhe     Germany   Fax: +49.721.98520-99 */
+/******************************************************************************/
+
+/*
+**  C++-Wrapper-Klasse fuer das entsprechende C-Modul.
+**  Naeheres siehe dort.
+**
+**  Achtung: Kopieren/Zuweisen einer Instanz erzeugt eine FLACHE KOPIE,
+**  d.h. danach arbeiten beide Instanzen auf denselben Infos und es kracht
+**  beim zweiten Aufruf eines Destruktors einer dieser Instanzen.
+**  $$$ Abhilfe evt. per Referenzzaehler o.ae.
+*/
+
+#ifndef __INFOFILE_H__
+#define __INFOFILE_H__
+
+#include "infoc.h"
+
+class cInfoFile {
+  friend class cInfoIter;
+
+  protected:
+    tInfos		*inf;
+
+  public:
+    cInfoFile (void);
+    ~cInfoFile (void);
+
+    int			Read (tErrorMsg **perrors, const char *filename);
+    int			Write (const char *filename);
+
+    char **		ListKeys (const char *prefix, tIterKind kind);
+    tKeyKind		KeyKind (const char *key);
+    int			DelKey (const char *key);
+    int			AddLineBefore (const char *key, const char *value);
+    int			AddLineBehind (const char *key, const char *value);
+
+    int			Get (char **pval,	const char *key);
+    int			Get (long *pval,	const char *key);
+    int			Get (int *pval,		const char *key);
+    int			Get (double *pval,	const char *key);
+    int			Get (float *pval,	const char *key);
+    int			Get (char ***pval,	const char *key);
+
+    int			GetDef (char **pval,	const char *key, char *def);
+    int			GetDef (long *pval,	const char *key, long def);
+    int			GetDef (int *pval,	const char *key, int def);
+    int			GetDef (double *pval,	const char *key, double def);
+    int			GetDef (float *pval,	const char *key, float def);
+    int			GetDef (char ***pval,	const char *key, char **def);
+
+    int			Set (const char *key, const char *value);
+    int			Set (const char *key, long value);
+    int			Set (const char *key, int value);
+    int			Set (const char *key, double value);
+    int			Set (const char *key, float value);
+    int			Set (const char *key, char **value);
+
+    static char *	KeyJoin (char *subKeys[]);
+    static char **	KeySplit (const char *key);
+};
+
+
+class cInfoIter {
+  private:
+    tInfoIter		*iter;
+
+  public:
+    cInfoIter (void);
+    ~cInfoIter (void);
+
+    int			Start (cInfoFile& cinf, const char *key,
+			       tIterKind kind);
+    int			Reset (void);
+
+    int			GetKey (char **pkey);
+    int			Get (char **pkey, char **pval);
+    int			Get (char **pkey, long *pval);
+    int			Get (char **pkey, int *pval);
+    int			Get (char **pkey, double *pval);
+    int			Get (char **pkey, char ***pval);
+};
+
+
+/******************************************************************************/
+
+inline
+cInfoFile::cInfoFile (void)
+    { inf = InfoNew(); }
+
+inline
+cInfoFile::~cInfoFile (void)
+    { InfoDelete(inf); }
+
+inline int
+cInfoFile::Read (tErrorMsg **perrors, const char *filename)
+    { return InfoRead(perrors, inf, filename); }
+
+inline int
+cInfoFile::Write (const char* filename)
+    { return InfoWrite(inf, filename); }
+
+inline char **
+cInfoFile::ListKeys (const char *prefix, tIterKind kind)
+    { return InfoListKeys(inf, prefix, kind); }
+
+inline tKeyKind
+cInfoFile::KeyKind (const char *key)
+    { return InfoKeyKind(inf, key); }
+
+inline int
+cInfoFile::DelKey (const char *key)
+    { return InfoDelKey(inf, key); }
+
+inline int
+cInfoFile::AddLineBefore (const char *key, const char *value)
+    { return InfoAddLineBefore(inf, key, value); }
+
+inline int
+cInfoFile::AddLineBehind (const char *key, const char *value)
+    { return InfoAddLineBehind(inf, key, value); }
+
+inline int
+cInfoFile::Get (char **pval, const char *key)
+    { return InfoGetStr(pval, inf, key); }
+
+inline int
+cInfoFile::Get (long *pval, const char *key)
+    { return InfoGetLong(pval, inf, key); }
+
+inline int
+cInfoFile::Get (int *pval, const char *key)
+    { return InfoGetInt(pval, inf, key); }
+
+inline int
+cInfoFile::Get (double *pval, const char *key)
+    { return InfoGetDbl(pval, inf, key); }
+
+inline int
+cInfoFile::Get (float *pval, const char *key)
+    { return InfoGetFlt(pval, inf, key); }
+
+inline int
+cInfoFile::Get (char ***pval, const char *key)
+    { return InfoGetTxt(pval, inf, key); }
+
+inline int
+cInfoFile::GetDef (char **pval, const char *key, char *def)
+    { return InfoGetStrDef(pval, inf, key, def); }
+
+inline int
+cInfoFile::GetDef (long *pval, const char *key, long def)
+    { return InfoGetLongDef(pval, inf, key, def); } 
+
+inline int
+cInfoFile::GetDef (int *pval, const char *key, int def)
+    { return InfoGetIntDef(pval, inf, key, def); } 
+
+inline int
+cInfoFile::GetDef (double *pval, const char *key, double def)
+    { return InfoGetDblDef(pval, inf, key, def); }
+
+inline int
+cInfoFile::GetDef (float *pval, const char *key, float def)
+    { return InfoGetFltDef(pval, inf, key, def); }
+
+inline int
+cInfoFile::GetDef (char ***pval, const char *key, char **def)
+    { return InfoGetTxtDef(pval, inf, key, def); }
+
+inline int
+cInfoFile::Set (const char *key, const char *value)
+    { return InfoSetStr(inf, key, value); }
+
+inline int
+cInfoFile::Set (const char *key, long value)
+    { return InfoSetLong(inf, key, value); }
+
+inline int
+cInfoFile::Set (const char *key, int value)
+    { return InfoSetInt(inf, key, value); }
+
+inline int
+cInfoFile::Set (const char *key, double value)
+    { return InfoSetDbl(inf, key, value); }
+
+inline int
+cInfoFile::Set (const char *key, float value)
+    { return InfoSetFlt(inf, key, value); }
+
+inline int
+cInfoFile::Set (const char *key, char **value)
+    { return InfoSetTxt(inf, key, value); }
+
+/******************************************************************************/
+
+inline
+cInfoIter::cInfoIter (void)
+    { iter = InfoINew(); }
+
+inline
+cInfoIter::~cInfoIter (void)
+    { InfoIDelete (iter); }
+
+inline int
+cInfoIter::Start (cInfoFile& cinf, const char *key, tIterKind kind)
+    { return InfoIStart(iter, cinf.inf, key, kind); }
+
+inline int
+cInfoIter::Reset (void)
+    { return InfoIReset(iter); }
+
+inline int
+cInfoIter::GetKey (char **pkey)
+    { return InfoIGetKey(pkey, iter); }
+
+inline int
+cInfoIter::Get (char **pkey, char **pval)
+    { return InfoIGetStr(pkey, pval, iter); }
+
+inline int
+cInfoIter::Get (char **pkey, long *pval)
+    { return InfoIGetLong(pkey, pval, iter); }
+
+inline int
+cInfoIter::Get (char **pkey, int *pval)
+    { return InfoIGetInt(pkey, pval, iter); }
+
+inline int
+cInfoIter::Get (char **pkey, double *pval)
+    { return InfoIGetDbl(pkey, pval, iter); }
+
+inline int
+cInfoIter::Get (char **pkey, char ***pval)
+    { return InfoIGetTxt(pkey, pval, iter); }
+
+
+#endif /* __INFOFILE_H__ */
+

+ 10 - 1
src/test/testipgroad/main.cpp

@@ -62,7 +62,7 @@ int  GetOptLong(int argc, char *argv[]) {
             optional_argument(即2),表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
      */
     static struct option long_options[] = {
-        {"input", required_argument, NULL, 'v'},
+        {"input", required_argument, NULL, 'i'},
         {"output", required_argument, NULL, 'o'},
         {"fromroad", required_argument, NULL, 'a'},
         {"fromlane", required_argument, NULL, 'b'},
@@ -479,10 +479,19 @@ createRoadFile (tRoad *road, char* fname)
 
 #include <QFileInfo>
 
+#include "infofile.h"
+
 int main(int argc, char *argv[])
 {
     QCoreApplication a(argc, argv);
 
+//    cInfoFile xInfo;
+//    tErrorMsg *error;
+//    xInfo.Read(&error,"D://ConstructionSite");
+
+//    char * pval;
+//    xInfo.Get(&pval,"Vehicle");
+
 
     snprintf(gstr_fromroad,256,"1");
     snprintf(gstr_toroad,256,"3");

+ 40 - 0
src/test/testipgroad/rd5route.pro

@@ -0,0 +1,40 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        rd5routemain.cpp \
+        rd5route.cpp
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+HEADERS += \
+    infoc.h \
+    infofile.h \
+    rd5route.h \
+    road.h \
+    roadbuilder.h
+
+#file:///C:/Users/yuchu/Downloads/libinfofile.a
+
+#DEFINES += TESTC
+
+
+LIBS += -L$$PWD/./ -lipgroadbuilder -linfofile   -lm -lws2_32 -lpsapi -lwinspool -lmxml
+
+

+ 251 - 0
src/test/testipgroad/rd5routemain.cpp

@@ -0,0 +1,251 @@
+#include <QCoreApplication>
+
+#include <QProcess>
+
+#include "stdarg.h"
+
+#include "road.h"
+#include "roadbuilder.h"
+
+#include <iostream>
+
+#include <getopt.h>
+
+#include <iostream>
+
+#include "rd5route.h"
+
+
+static char gstr_inputpath[256];
+static char gstr_outputpath[256];
+
+static char gstr_fromroad[256];
+static char gstr_fromlane[256];
+
+static char gstr_toroad[256];
+static char gstr_tolane[256];
+
+/**
+ * @brief print_useage
+ */
+void print_useage()
+{
+    std::cout<<" -i --input $xodrfile : set  input file path. eq.  -i d:/lk.rd5"<<std::endl;
+    std::cout<<" -o --output $outputfile : set output file. eq.  -o d:/lk2.rd5"<<std::endl;
+    std::cout<<" -a --fromroad  eq.  -a 1"<<std::endl;
+    std::cout<<" -b --fromlane  eq.  -b -1"<<std::endl;
+    std::cout<<" -c --toroad  eq.  -c 3"<<std::endl;
+    std::cout<<" -d --tolane  eq.  -d -1"<<std::endl;
+    std::cout<<" -h --help print help"<<std::endl;
+}
+
+int  GetOptLong(int argc, char *argv[]) {
+    int nRtn = 0;
+    int opt; // getopt_long() 的返回值
+    int digit_optind = 0; // 设置短参数类型及是否需要参数
+    (void)digit_optind;
+
+    // 如果option_index非空,它指向的变量将记录当前找到参数符合long_opts里的
+    // 第几个元素的描述,即是long_opts的下标值
+    int option_index = 0;
+    // 设置短参数类型及是否需要参数
+    const char *optstring = "i:o:a:b:c:d:h";
+
+    // 设置长参数类型及其简写,比如 --reqarg <==>-r
+    /*
+    struct option {
+             const char * name;  // 参数的名称
+             int has_arg; // 是否带参数值,有三种:no_argument, required_argument,optional_argument
+             int * flag; // 为空时,函数直接将 val 的数值从getopt_long的返回值返回出去,
+                     // 当非空时,val的值会被赋到 flag 指向的整型数中,而函数返回值为0
+             int val; // 用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值
+        };
+    其中:
+        no_argument(即0),表明这个长参数不带参数(即不带数值,如:--name)
+            required_argument(即1),表明这个长参数必须带参数(即必须带数值,如:--name Bob)
+            optional_argument(即2),表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
+     */
+    static struct option long_options[] = {
+        {"input", required_argument, NULL, 'i'},
+        {"output", required_argument, NULL, 'o'},
+        {"fromroad", required_argument, NULL, 'a'},
+        {"fromlane", required_argument, NULL, 'b'},
+        {"toroad", required_argument, NULL, 'c'},
+        {"tolane", required_argument, NULL, 'd'},
+        {"help",  no_argument,       NULL, 'h'},
+ //       {"optarg", optional_argument, NULL, 'o'},
+        {0, 0, 0, 0}  // 添加 {0, 0, 0, 0} 是为了防止输入空值
+    };
+
+    while ( (opt = getopt_long(argc,
+                               argv,
+                               optstring,
+                               long_options,
+                               &option_index)) != -1) {
+//        printf("opt = %c\n", opt); // 命令参数,亦即 -a -b -n -r
+//        printf("optarg = %s\n", optarg); // 参数内容
+//        printf("optind = %d\n", optind); // 下一个被处理的下标值
+//        printf("argv[optind - 1] = %s\n",  argv[optind - 1]); // 参数内容
+//        printf("option_index = %d\n", option_index);  // 当前打印参数的下标值
+//        printf("\n");
+        switch(opt)
+        {
+        case 'i':
+            strncpy(gstr_inputpath,optarg,255);
+            break;
+        case 'o':
+            strncpy(gstr_outputpath,optarg,255);
+            break;
+        case 'a':
+            strncpy(gstr_fromroad,optarg,255);
+            break;
+        case 'b':
+            strncpy(gstr_fromlane,optarg,255);
+            break;
+        case 'c':
+            strncpy(gstr_toroad,optarg,255);
+            break;
+        case 'd':
+            strncpy(gstr_tolane,optarg,255);
+            break;
+        case 'h':
+            print_useage();
+            nRtn = 1; //because use -h
+            break;
+        default:
+            break;
+        }
+
+    }
+
+    return nRtn;
+}
+
+
+
+
+int
+ipgErrorExit(tRoad *road)
+{
+    int nErrMsg;
+    tRoadMessageList msgList;
+
+    nErrMsg = RoadGetMessageList(road, RMT_Error, &msgList);
+    while (--nErrMsg>=0)  fprintf(stderr, "%s\n", msgList.msg[nErrMsg].msg);
+    RoadDeleteMessageList(road,&msgList);
+    RoadClearMessageBuffer(road, RMT_Error);
+
+    return ROAD_Error;
+}
+
+void
+ipgWarnMsg(tRoad *road)
+{
+    int nWarn;
+    tRoadMessageList msgList;
+
+    nWarn = RoadGetMessageList(road, RMT_Warn, &msgList);
+    while (--nWarn>=0)  fprintf(stderr, "%s\n", msgList.msg[nWarn].msg);
+    RoadDeleteMessageList(road,&msgList);
+    RoadClearMessageBuffer(road, RMT_Warn);
+}
+
+
+#include <QFileInfo>
+
+#include "infofile.h"
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+//    cInfoFile xInfo;
+//    tErrorMsg *error;
+//    xInfo.Read(&error,"D://ConstructionSite");
+
+//    char * pval;
+//    xInfo.Get(&pval,"Vehicle");
+
+
+    snprintf(gstr_fromroad,256,"1");
+    snprintf(gstr_toroad,256,"3");
+    snprintf(gstr_fromlane,256,"-1");
+    snprintf(gstr_tolane,256,"-1");
+
+    int nRtn = GetOptLong(argc,argv);
+    if(nRtn == 1)  //show help,so exit.
+    {
+        return 0;
+    }
+
+
+#ifdef TESTC
+    snprintf(gstr_inputpath,255,"D:/lk.rd5");
+    snprintf(gstr_outputpath,255,"D:/lkr.rd5");
+#endif
+
+    if(strncmp(gstr_inputpath , "",255) == 0)
+    {
+        std::cout<<"Please use -i set input file path."<<std::endl;
+        print_useage();
+        return 0;
+    }
+
+    char strout[1000];
+    snprintf(strout,1000,"Input File Path: %s",gstr_inputpath);
+    std::cout<<strout<<std::endl;
+
+    if(strncmp(gstr_outputpath , "",255) == 0)
+    {
+        std::cout<<"Please use -o set output file path."<<std::endl;
+        print_useage();
+        return 0;
+    }
+
+    snprintf(strout,1000,"Output File Path: %s",gstr_outputpath);
+    std::cout<<strout<<std::endl;
+
+
+    tRoad * pRoad;
+
+    pRoad = RoadNew();
+
+    if(pRoad == NULL)
+    {
+        std::cout<<" Road New Fail."<<std::endl;
+        return -1;
+    }
+    else
+    {
+        std::cout<<" Road New Successfully."<<std::endl;
+    }
+
+
+//    createRoadFile(pRoad,"D:/z.rd5");
+
+    int nrtn =  RoadReadInfoFile(pRoad,gstr_inputpath); //RoadReadOpenDRIVE(pRoad,stroutxodrname);
+
+    if(nrtn<0)
+    {
+        ipgErrorExit(pRoad);
+        return -1;
+    }
+
+
+    rd5route * proute = new rd5route(pRoad);
+//    proute->route();
+
+    int nfromroad = atoi(gstr_fromroad);
+    int ntoroad = atoi(gstr_toroad);
+    int nfromlane = atoi(gstr_fromlane);
+    int ntolane = atoi(gstr_tolane);
+    proute->route(nfromroad,nfromlane,ntoroad,ntolane);
+ //   proute->route(1,-3,2,3);
+ //   proute->route(1,-1,1,-1);
+    delete proute;
+
+    RoadWriteFile(pRoad,gstr_outputpath,NULL);
+
+    return 0;
+//    return a.exec();
+}

+ 2 - 0
src/test/testipgroad/testipgroad.pro

@@ -24,6 +24,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
 !isEmpty(target.path): INSTALLS += target
 
 HEADERS += \
+    infoc.h \
+    infofile.h \
     rd5route.h \
     road.h \
     roadbuilder.h

+ 40 - 0
src/test/testipgroad/xodr2rd5.pro

@@ -0,0 +1,40 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        xodr2rd5main.cpp \
+        rd5route.cpp
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+HEADERS += \
+    infoc.h \
+    infofile.h \
+    rd5route.h \
+    road.h \
+    roadbuilder.h
+
+#file:///C:/Users/yuchu/Downloads/libinfofile.a
+
+#DEFINES += TESTC
+
+
+LIBS += -L$$PWD/./ -lipgroadbuilder -linfofile   -lm -lws2_32 -lpsapi -lwinspool -lmxml
+
+

+ 223 - 0
src/test/testipgroad/xodr2rd5main.cpp

@@ -0,0 +1,223 @@
+#include <QCoreApplication>
+
+#include <QProcess>
+
+#include "stdarg.h"
+
+#include "road.h"
+#include "roadbuilder.h"
+
+#include <iostream>
+
+#include <getopt.h>
+
+#include <iostream>
+
+#include "rd5route.h"
+
+
+static char gstr_inputpath[256];
+static char gstr_outputpath[256];
+
+static char gstr_fromroad[256];
+static char gstr_fromlane[256];
+
+static char gstr_toroad[256];
+static char gstr_tolane[256];
+
+/**
+ * @brief print_useage
+ */
+void print_useage()
+{
+    std::cout<<" -i --input $xodrfile : set  input file path. eq.  -i d:/lk.xodr"<<std::endl;
+    std::cout<<" -o --output $outputfile : set output file. eq.  -o d:/test.rd5"<<std::endl;
+    std::cout<<" -h --help print help"<<std::endl;
+}
+
+int  GetOptLong(int argc, char *argv[]) {
+    int nRtn = 0;
+    int opt; // getopt_long() 的返回值
+    int digit_optind = 0; // 设置短参数类型及是否需要参数
+    (void)digit_optind;
+
+    // 如果option_index非空,它指向的变量将记录当前找到参数符合long_opts里的
+    // 第几个元素的描述,即是long_opts的下标值
+    int option_index = 0;
+    // 设置短参数类型及是否需要参数
+    const char *optstring = "i:o:h";
+
+    // 设置长参数类型及其简写,比如 --reqarg <==>-r
+    /*
+    struct option {
+             const char * name;  // 参数的名称
+             int has_arg; // 是否带参数值,有三种:no_argument, required_argument,optional_argument
+             int * flag; // 为空时,函数直接将 val 的数值从getopt_long的返回值返回出去,
+                     // 当非空时,val的值会被赋到 flag 指向的整型数中,而函数返回值为0
+             int val; // 用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值
+        };
+    其中:
+        no_argument(即0),表明这个长参数不带参数(即不带数值,如:--name)
+            required_argument(即1),表明这个长参数必须带参数(即必须带数值,如:--name Bob)
+            optional_argument(即2),表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
+     */
+    static struct option long_options[] = {
+        {"input", required_argument, NULL, 'i'},
+        {"output", required_argument, NULL, 'o'},
+        {"help",  no_argument,       NULL, 'h'},
+ //       {"optarg", optional_argument, NULL, 'o'},
+        {0, 0, 0, 0}  // 添加 {0, 0, 0, 0} 是为了防止输入空值
+    };
+
+    while ( (opt = getopt_long(argc,
+                               argv,
+                               optstring,
+                               long_options,
+                               &option_index)) != -1) {
+//        printf("opt = %c\n", opt); // 命令参数,亦即 -a -b -n -r
+//        printf("optarg = %s\n", optarg); // 参数内容
+//        printf("optind = %d\n", optind); // 下一个被处理的下标值
+//        printf("argv[optind - 1] = %s\n",  argv[optind - 1]); // 参数内容
+//        printf("option_index = %d\n", option_index);  // 当前打印参数的下标值
+//        printf("\n");
+        switch(opt)
+        {
+        case 'i':
+            strncpy(gstr_inputpath,optarg,255);
+            break;
+        case 'o':
+            strncpy(gstr_outputpath,optarg,255);
+            break;
+        case 'h':
+            print_useage();
+            nRtn = 1; //because use -h
+            break;
+        default:
+            break;
+        }
+
+    }
+
+    return nRtn;
+}
+
+
+
+
+int
+ipgErrorExit(tRoad *road)
+{
+    int nErrMsg;
+    tRoadMessageList msgList;
+
+    nErrMsg = RoadGetMessageList(road, RMT_Error, &msgList);
+    while (--nErrMsg>=0)  fprintf(stderr, "%s\n", msgList.msg[nErrMsg].msg);
+    RoadDeleteMessageList(road,&msgList);
+    RoadClearMessageBuffer(road, RMT_Error);
+
+    return ROAD_Error;
+}
+
+void
+ipgWarnMsg(tRoad *road)
+{
+    int nWarn;
+    tRoadMessageList msgList;
+
+    nWarn = RoadGetMessageList(road, RMT_Warn, &msgList);
+    while (--nWarn>=0)  fprintf(stderr, "%s\n", msgList.msg[nWarn].msg);
+    RoadDeleteMessageList(road,&msgList);
+    RoadClearMessageBuffer(road, RMT_Warn);
+}
+
+
+#include <QFileInfo>
+
+#include "infofile.h"
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+//    cInfoFile xInfo;
+//    tErrorMsg *error;
+//    xInfo.Read(&error,"D://ConstructionSite");
+
+//    char * pval;
+//    xInfo.Get(&pval,"Vehicle");
+
+
+    snprintf(gstr_fromroad,256,"1");
+    snprintf(gstr_toroad,256,"3");
+    snprintf(gstr_fromlane,256,"-1");
+    snprintf(gstr_tolane,256,"-1");
+
+    int nRtn = GetOptLong(argc,argv);
+    if(nRtn == 1)  //show help,so exit.
+    {
+        return 0;
+    }
+
+
+#ifdef TESTC
+    snprintf(gstr_inputpath,255,"D:/lk.xlsx");
+    snprintf(gstr_outputpath,255,"D:/lk.rd5");
+#endif
+
+    if(strncmp(gstr_inputpath , "",255) == 0)
+    {
+        std::cout<<"Please use -i set input file path."<<std::endl;
+        print_useage();
+        return 0;
+    }
+
+    char strout[1000];
+    snprintf(strout,1000,"Input File Path: %s",gstr_inputpath);
+    std::cout<<strout<<std::endl;
+
+    if(strncmp(gstr_outputpath , "",255) == 0)
+    {
+        std::cout<<"Please use -o set output file path."<<std::endl;
+        print_useage();
+        return 0;
+    }
+
+    snprintf(strout,1000,"Output File Path: %s",gstr_outputpath);
+    std::cout<<strout<<std::endl;
+
+
+
+
+
+    tRoad * pRoad;
+
+    pRoad = RoadNew();
+
+    if(pRoad == NULL)
+    {
+        std::cout<<" Road New Fail."<<std::endl;
+        return -1;
+    }
+    else
+    {
+        std::cout<<" Road New Successfully."<<std::endl;
+    }
+
+
+//    createRoadFile(pRoad,"D:/z.rd5");
+
+    int nrtn = RoadReadOpenDRIVE(pRoad,gstr_inputpath);
+
+    if(nrtn<0)
+    {
+        ipgErrorExit(pRoad);
+        return -1;
+    }
+
+
+    RoadWriteFile(pRoad,gstr_outputpath,NULL);
+
+
+    return 0;
+    return a.exec();
+}