    // ------------------------------- //
    // -------- Start of File -------- //
    // ------------------------------- //
    // ----------------------------------------------------------- //
    // C++ Source Code File Name: testprog.cpp
    // C++ Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
    // Produced By: DataReel Software Development Team
    // File Creation Date: 02/19/1996
    // Date Last Modified: 06/17/2016
    // Copyright (c) 2001-2024 DataReel Software Development
    // ----------------------------------------------------------- //
    // ------------- Program Description and Details ------------- //
    // ----------------------------------------------------------- //
    /*
    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.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
    USA

    This is a test program for the gxConfig class.
    */
    // ----------------------------------------------------------- //
    #include "gxdlcode.h"

    #if defined (__USE_ANSI_CPP__) // Use the ANSI Standard C++ library
    #include <iostream>
    using namespace std; // Use unqualified names for Standard C++ library
    #else // Use the old iostream library by default
    #include <iostream.h>
    #endif // __USE_ANSI_CPP__

    #include <stdio.h>
    #include "gxconfig.h"

    #ifdef __MSVC_DEBUG__
    #include "leaktest.h"
    #endif

    // Data structure use to store program gxConfiguration values
    struct ProgramgxConfig
    {
      ProgramgxConfig() { // Set the default values
        s_val1 = "YES";
        s_val2 = "NO";
        s_val3 = "TRUE";
        s_val4 = "FALSE";
        i_val = 32768;
        l_val = 2147483647;
        d_val = 1.12345;
      }
      ProgramgxConfig(const ProgramgxConfig &ob) {
        s_val1 = ob.s_val1;
        s_val2 = ob.s_val2;
        s_val3 = ob.s_val3;
        s_val4 = ob.s_val4;
        i_val = ob.i_val; l_val = ob.l_val; d_val = ob.d_val;
      }

      gxString s_val1;
      gxString s_val2;
      gxString s_val3;
      gxString s_val4;
      int i_val;
      long l_val;
      double d_val;
    };

    void PausePrg()
    {
      cin.get();
      cout << "Press enter to continue..." << "\n";
      cout << "\n";
    }

    void DisplayConfig(gxConfig *CfgData, ProgramgxConfig *cfg)
    // Display the program gxConfiguration and load gxConfig values
    {
      char *s1 = CfgData->GetStrValue("String1");
      if(!s1) {
        cout << "String1 section missing from gxConfig file" << "\n";
      }
      else {
        cout << "String1 section of gxConfig file = " << s1 << "\n";
        cfg->s_val1 = s1;
      }

      char *s2 = CfgData->GetStrValue("String2");
      if(!s2) {
        cout << "String2 section missing from gxConfig file" << "\n";
      }
      else {
        cout << "String2 section of gxConfig file = " << s2 << "\n";
        cfg->s_val2 = s2;
      }

      char *s3 = CfgData->GetStrValue("String3");
      if(!s3) {
        cout << "String3 section missing from gxConfig file" << "\n";
      }
      else {
        cout << "String3 section of gxConfig file = " << s3 << "\n";
        cfg->s_val3 = s3;
      }

      char *s4 = CfgData->GetStrValue("String4");
      if(!s4) {
        cout << "String4 section missing from gxConfig file" << "\n";
      }
      else {
        cout << "String4 section of gxConfig file = " << s4 << "\n";
        cfg->s_val4 = s4;
      }

      int i1 = CfgData->GetIntValue("Int");
      if(!i1) {
        cout << "Int section missing from gxConfig file" << "\n";
      }
      else {
        cout << "Integer section of gxConfig file = " << i1 << "\n";
        cfg->i_val = i1;
      }

      double d1 = CfgData->GetFloatValue("Float");
      if(!d1) {
        cout << "Float section missing from gxConfig file" << "\n";
      }
      else {
        cout << "Floating Point number section of gxConfig file = "
    	 << d1 << "\n";
        cfg->d_val = d1;
      }

      long l1 = CfgData->GetLongValue("Long");
      if(!l1) {
        cout << "Long int section missing from gxConfig file" << "\n";
      }
      else {
        cout << "Long int section of gxConfig file = " << l1 << "\n";
        cfg->l_val = l1;
      }

      cout << "\n";
    }

    void MultipleRead(gxConfig *CfgData)
    {
      char *ServerName = CfgData->GetStrValue("ServerName");
      if(!ServerName) {
        cout << "ServerName value is not set in the gxConfig file" << "\n";
        return;
      }
      else
        cout << "Server name = " << ServerName << "\n";

      char *FullPathName = CfgData->GetStrValue("FullPathName0");
      if(!FullPathName) {
        cout << "No path names are set in the gxConfig file" << "\n";
        return;
      }

      char cfgValue[255];
      long file_num = -1;

      while(1) {
        file_num++;
        sprintf(cfgValue, "FullPathName%d", (int)file_num);
        char *buf = CfgData->GetStrValue(cfgValue);
        if(!buf) break;

        gxString sbuf(buf);
        int offset = 0;
        int index = 0;
        while(1) {
        offset = sbuf.Find("/", offset);
        if(offset != -1) index = offset;
        if(offset == -1) break;
        offset++;
        }
        if(index > 0) sbuf.DeleteAt(0, ++index);

        if(sbuf.length() == 0) {
          cout << "Invalid file name for " << cfgValue << "\n";
          return;
        }

        cout << "Reading: " << buf << "\n";
        cout << "Copying to: " << sbuf.c_str() << "\n";

        buf = 0;
        for(int i = 0; i < 255; i++) cfgValue[i] = 0;
      }
      cout << "\n";
    }

    void NewParmID(gxConfig *CfgData)
    {
      CfgData->UnLoad();
      CfgData->SetParmID("://");
      gxString parmName("http");
      CfgData->ReadComments();
      CfgData->ReLoad();

      gxConfigListNode *ptr = (gxConfigListNode *)CfgData->GetHead();
      while(ptr) { // Scan until end of list
        int offset = 0;
        offset = ptr->node_data.Find(parmName);
        if(offset != -1) {
          gxConfigListNode *sptr = (gxConfigListNode *)ptr->next;
          gxString ServerName(sptr->node_data);
          gxString FullPathName(sptr->node_data);
          offset = ServerName.Find("/");
          if(offset != -1) {
    	ServerName.DeleteAt(offset, (ServerName.length() - offset));
    	FullPathName.DeleteAt(0, offset);
    	cout << "Server: " << ServerName.c_str() << " Path: "
    	     << FullPathName.c_str() << "\n";
          }
        }
        ptr = (gxConfigListNode *)ptr->next;
      }
    }

    int main()
    {
    #ifdef __MSVC_DEBUG__
      InitLeakTest();
    #endif

      gxConfig *CfgData = new gxConfig;
      ProgramgxConfig *cfg = new ProgramgxConfig;
      int Status;

      // Test for all three overloads
      const char *fname = "gxconfig.ini";

      cout << "Loading gxConfig File..." << "\n";
      Status = CfgData->Load(fname);
      if(!Status) {
        cout << "gxConfig file not found!" << "\n";
        delete CfgData;
        delete cfg;
        return 0;
      }
      else
        cout << "Processing file: " << CfgData->GetFileName() << "\n";

      DisplayConfig(CfgData, cfg);
      ProgramgxConfig org_gxConfig(*cfg); // Record the original values

      cout << "Testing reload function" << "\n";
      PausePrg();
      CfgData->ReLoad(fname);
      DisplayConfig(CfgData, cfg);

      cout << "Writing new values to the file" << "\n";
      PausePrg();
      CfgData->ChangeConfigValue("String1", "no");
      CfgData->ChangeConfigValue("String2", "yes");
      CfgData->ChangeConfigValue("String3", "false");
      CfgData->ChangeConfigValue("String4", "true");

      CfgData->ChangeConfigValue("Float", 1.98712);
      CfgData->ChangeConfigValue("Int", 12345);
      CfgData->ChangeConfigValue("Long", 23889);
      DisplayConfig(CfgData, cfg);

      cout << "Restoring original values" << "\n";
      PausePrg();
      CfgData->ChangeConfigValue("String1", org_gxConfig.s_val1);
      CfgData->ChangeConfigValue("String2", org_gxConfig.s_val2);
      CfgData->ChangeConfigValue("String3", org_gxConfig.s_val3);
      CfgData->ChangeConfigValue("String4", org_gxConfig.s_val4);
      CfgData->ChangeConfigValue("Int", org_gxConfig.i_val);
      CfgData->ChangeConfigValue("Float", org_gxConfig.d_val);
      CfgData->ChangeConfigValue("Long", org_gxConfig.l_val);
      DisplayConfig(CfgData, cfg);

      cout << "Performing a multiple read and parsing operation" << "\n";
      PausePrg();
      MultipleRead(CfgData);

      cout << "Reloading the file with a new parameter ID string" << "\n";
      PausePrg();
      NewParmID(CfgData);

      CfgData->UnLoad();

      delete CfgData;
      delete cfg;
      return 0;
    }
    // ----------------------------------------------------------- //
    // ------------------------------- //
    // --------- End of File --------- //
    // ------------------------------- //