wxJSON Tutorial – Part II – Сonfiguration File

Preface

Here is a second part of wxJSON tutorial provided by Luciano Cattani, author and maintainer of wxJSON library.

Creating a Configuration File with wxJSON

We start by using JSON for an application’s configuration file. There are many formats for storing application’s configuration data. I remember when there was MS-DOS: each application used its own, unreadable and proprietary format (it was a nightmare). Next came Windows 3: it had a better way for storing application’s configuration data; they were kept in an .INI file which contains simple ASCII text. This was a good thing because it was easier for humans to fine-tuning application’s behaviour.

In this example we use JSON to store the configuration data of a simple web server application. If you take a look at the Apache config file you will notice that our example looks very similar (but much more human readable).

Our server is a neverending application and it is not interactive: it reads its configuration at startup and when a signal is sent to it. Using JSON for the configuration data is a good choice because it is easy for humans to write the JSON text document. Below we find our webserver’s configuration file:

{
   // global configuration
   "Global" :  {
     "DocumentRoot"  : "/var/www/html",
     "MaxClients"    : 250,
     "ServerPort"    : 80,
     "ServerAddress" : 0.0.0.00
     "MaxRequestsPerClient"  : 1000
   }

   // an array of objects that describes the modules that has to
   // be loaded at startup
   "Modules" : [
      {
        "Name"    : "auth_basic",
        "File"    : "modules/mod_auth_basic.so",
        "OnStart" : true
      },
      {
        "Name"    : "auth_digest",
        "File"    : "modules/mod_auth_digest.so",
        "OnStart" : true
      },
      {
        "Name"    : "auth_file",
        "File"    : "modules/mod_auth_file.so",
        "OnStart" : false
      },
   ]

   // Main server configuration
   "Server" :       {
      "Admin" : "root@localhost.localdomain"
      "Name"  : "www.example.com"
   },

   // The description of directories and their access permissions
   "Diretory"  : [
      {
         "Path"       : "/var/www/html",
         "AllowFrom"  : "ALL",
         "DenyFrom"   : null,
         "Options" :     {
            "Multiviews"    : false,
            "Indexes"       : true,
            "FollowSymLink" : false
         }
      }
   ]
 }

I think that the file is self-explanatory. I do not want to write the code of the whole web-server application: I only want to show you how to read the configuration data.

When the application starts, it calls a function that reads the configuration file and returns ZERO if there was no error or an exit status code if the file is not correct. The function may be similar to the following one:

int ReadConfig( wxInputStream& jsonStream )
{
// comment lines are recognized by the wxJSON library and
// can also be stored in the JSON value objects they refer to
// but this is not needed by our application because the
// config file is written by hand by the website admin
// so we use the default ctor of the parser which recognizes
// comment lines but do not store them
wxJSONReader reader;
wxJSONvalue root;
int numErrors = reader.Parse( jsonStream, root );
if ( numErrors > 0 ) {
// if there are errors in the JSON document, print the
// errors and return a non-ZERO value
const wxArrayString& errors = reader.GetErrors();
for ( int i = 0; i < numErrors; i++ ) { cout << errors[i] << endl; } return 1; } // if the config file is syntactically correct, we retrieve // the values and store them in application's variables gs_docRoot = root["Global"]["DocumentRoot"].AsString(); // we use the Get() memberfunction to get the port on which // the server listens. If the parameter does not exist in the // JSON value, the default port 80 is returned wxJSONvalue defaultPort = 80; gs_serverPort = root["Global"].Get( "ServerPort", defaultPort ).AsInt(); // the array of modules is processed in a different way: for // every module we print its name and the 'OnStart' flag. // if the flag is TRUE, we load it. wxJSONValue modules = root["Modules"]; // check that the 'Modules' value is of type ARRAY if ( !modules.IsArray() ) { cout << "ERROR: \'modules\' must be a JSON array" << endl; return 1; } for ( int i = 0; i < modules.Size(); i++ ) { cout << "Processing module: " << modules[i]["Name"].AsString() << endl; bool load = modules[i]["OnStart"].AsBool(); cout << "Load module? " << ( load ? "YES" : "NO" ) << endl; if ( load ) { LoadModule( modules[i]["File"].Asstring()); } } // return a ZERO value: it means success. return 0; } [/sourcecode]

Leave a Reply

Your email address will not be published. Required fields are marked *

Please leave these two fields as-is: