reZo Labs

INI Parser

Well, I’ve recently been working on a INI parser, which I’m using in a C++, SDL API game. The class enables you to parse any given ini file, and use it’s settings within a C++ application. Note, this code is subject to change.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
 * INI Parser
 *
 * Parse and replace (set) settings within settings.ini
 * Syntax of settings.ini, command = value, ; comment
 *
 * @author  Gareth Stones <gareth@rezolabs.com>
 * @license GNU GPL (latest version)
 */


class Settings {
   
   private:
      // settings map to store command / value
      std::map<std::string, std::string> settings;
      // input file descriptor
      std::ifstream iSettings;
      // output file descriptor
      std::ofstream oSettings;
      // filename
      std::string filename;
      void parse (std::string line);
   
   public:
      void load (std::string file);
      void set (std::string command, std::string value);
      std::string get (std::string command);
} Settings;

/**
 * Open file for parsing
 *
 * @param std::string file filename to open
 */


void Settings::load (std::string file) {
   
   std::string line;
   filename = file;
   
   iSettings.open (filename.data(), std::ios::in);
   
   if (!iSettings.is_open())
      return;
   
   while (!iSettings.eof()) {
      getline (iSettings, line);
      parse (line);
   }
   
   iSettings.close();
}

/**
 * Get value from settings map<std::string, std::string>
 *
 * @param  std::string commmand name of command of which value to return
 * @return std::string value
 */


std::string Settings::get (std::string command) {
   
   return settings[command];
}

/**
 * Use iterator object from map object to compare command index std::string
 *
 * @param std::string command holds command to change value of
 * @param std::string value   value command will be replaced with
 */


void Settings::set (std::string command, std::string value) {
   
   oSettings.open (filename.data(), std::ios::out);
   
   std::map<std::string, std::string>::iterator line;
   
   for (line = settings.begin(); line != settings.end(); line++) {
      if (((*line).first).compare(command) == 0)
         oSettings << command  << " = " << value;
      else
         oSettings << (*line).first << " = " << (*line).second << "\n";
   }
   
   settings[command] = value;
   
   oSettings.close();
}

/**
 * Parse command and value from @param std::string line into settings map<std::string,
 * std::string>
 *
 * @param std::string line the line to parse
 *
 * Uses ; for comment
 */


void Settings::parse (std::string line) {
   
   if (line.substr(0, 1).compare(";") == 0 || line.compare("") == 0)
      return;
   
   std::string command, value;
   std::string::size_type location;
   
   location = line.find (" = ", 0);
   
   if (location != std::string::npos) {
      command = line.substr(0, location);
      value = line.substr(location + 3, line.length());
   }
   
   settings[command] = value;
}

Basic example of usage:

1
2
3
4
5
6
7
8
...
void usage () {
   
    settings.load("file.ini");
    std::cout << "Screen resolution width: " << atoi(settings.get("resolution.width").c_str()) << std::endl;
    settings.set("example", "value");
}
...
Posted in Desktop Programming | Leave a comment

Combining Web 2.0 with 1.0

It’s all very nice and dandy to have a website built within 2.0 standards. However, what if the website hasn’t been built for non-JavaScript browsers, or for people with JavaScript disabled?

There is an easy work around for this, by simply returning true or false within a inline JavaScript event. If JavaScript is disabled, the browser will proceed to load the href target. While if JavaScript is enabled, the onclick event will return false; letting the browser know not to load the href target link, instead, we can do some AJAX, or DOM (in this case) HTML manipulation.

For instance,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script language="javascript">
function example () {
   
    // Simple DOM JS
    document.getElementById('alter').innerHTML = 'Ajax like event triggered.';
    document.getElementById('alter').innerHTML += '<br />';
    document.getElementById('alter').innerHTML += '<img src="screenshot.png" title="Screenshot" alt="Screenshot" />';
   
    // return false; so the browser knows not to continue, if JavaScript is enabled.
    return false;
}
</script>
<p id="alter"></p>
<a href="/screenshot.html" onclick="return example();">link</a>
Posted in Web Development | Leave a comment

Using Memcache with PHP

It’s been at the back of my mind for a while, using objects from cache, without destructing them, and only initializing them once.

Many thanks to Memcache this is now possible. Memcached (daemon) stores arrays, objects and variables in memory available for clients to access them at any time. This speeds up the process of a web application a lot. Instead of having to create a new object each time the page is loaded, you can simply retrieve the desired object from Memcache and operate on it normally.

Memcache was fairly easy to get up and running to. Since I’m on Debian (lenny/sid), I was able to get it from the repository (apt-get install memcache). Or you can always compile it from source. Once that was setup, I then installed the memcache PHP extension, php5-mod-memcache, to allow PHP to interact with the Memcache daemon (memcached CLI).

There are some really nice features about Memcache, for instance, it allows you to use a pool of computers, perhaps a rack of hard drives, and to run a copy of Memcache on each of these. Therefore, using Memcache on the network across multiple machines.

Since this is just a testing server and development laptop, I was happy with the default memory allocation setting for Memcache, which is 64mb. Not that I’ll use it all! (Maybe for extreme cases for stress testing / benchmarking). The maximum recommended size for each instance of Memcache is 2gb of allocated memory, which is really only useful for a production server, within a data center or the like.

Memcache also has a limit of 1mb for any given array, object or variable. Which is very useful, as this would most likely help prevent memory leaks and what not.

The Memcache daemon is fairly easy to get up and running too, with the -h parameter on a Unix box, you get the CLI argument options. I went pretty much default on this, with the extra -v and -vv for full verbose mode. This allowed me to see if everything was working correctly, which it was.

Overall, Memcache is an excellent new addition to my web development environment, and will hopefully use it for a long time!

Posted in Operating Systems, Web Development | Leave a comment

CLI Arguments

I’m sure you all know what CLI arguments are, if not then head to Wikipedia for a great article on them. Well, as far as programming goes. It’s very useful to have code which you can use multiple times, without having to edit (or slight edits), in order to use in another program.

I thought I would share my CLI arguments C code which I’m currently using in multiple programs. A few things to note however, that this code will most certainly change from time to time, as I optimize and make improvments to it. Another note, the code is currently for *nix CLI, however, it can easily be altered to work on Windows as well, as Windows CLI tends to use the “/key value” notion of passing arguments. You could possibly use #ifdef win32 macro to check if we’re parsing *nix or win32 style CLI arguments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
 * CLI Argument Parser
 *
 * @author Gareth Stones <gareth@rezolabs.com>
 * @license GNU General Public License
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
 * Function prototype's
 */


void argumentShort (char *key, char *value);
void argumentLong (char *key, char *value);
char *argumentGetKey (char *key);
char *argumentGetValue (char *key);

/**
 * Send argv[i] && argv[i+1] off to there correct parser's
 */


int main (int argc, char *argv[]) {
   
   if (argc == 1) {
      fprintf(stderr, "usage: %s (arguments)\n", argv[0]);
      return -1;
   }
   
   int i;
   
   for (i = 1; i < argc; i++) {
      char *current = (char*) malloc(sizeof(char*) * strlen(argv[i]));
      snprintf(current, strlen(argv[i]), "%s", argv[i]);
      if (*(current) == '-' && *(current+1) == '-')
         argumentLong(argv[i], argv[i+1]);
      else if (*(current) == '-' && *(current+1) != '-')
         argumentShort(argv[i], argv[i+1]);
      free(current);
   }
   
   return 0;
}

/**
 * Parse short CLI argument's
 *
 * @accept -k
 *         -k value
 *         -k=value
 */


void argumentShort (char *key, char *value) {
   
   if (strlen(key) <= 1) {
      fprintf(stderr, "Invalid CLI argument length (short).\n");
      exit(-1);
   }
   
   /**
    * Settings that do not require usage of value argument
    */

   
   if (strncmp(key, "-e", 2) == 0 && strlen(key) == 2 && value == NULL)
      printf("%s argument with no value, setting to default\n", key);
   
   /**
    * Check if we're dealing with -k=value if value is NULL
    */

   
   if (value == NULL) {
      if (strchr(key, '=') != NULL) {
         value = argumentGetValue(key);
         key = argumentGetKey(key);
      }
      else
         return;
   }
   
   if (strncmp(key, "-e", 2) == 0 && strlen(key) == 2)
      printf("%s %s\n", key, value);
}

/**
 * Parse long CLI argument's
 *
 * @accept --key
 *         --key value
 *         --key=value
 */


void argumentLong (char *key, char *value) {
   
   if (strlen(key) <= 2) {
      fprintf(stderr, "Invalid CLI argument length (long)\n");
      exit(-1);
   }
   
   /**
    * Settings that do not require usage of value argument
    */

   
   if (strncmp(key, "--example", 9) == 0 && strlen(key) == 9 && value == NULL)
      printf("%s with no value, setting to default\n", key);
   
   /**
    * Check if we're dealing with --key=value if value is NULL
    */

   
   if (value == NULL) {
      if (strchr(key, '=') != NULL) {
         value = argumentGetValue(key);
         key = argumentGetKey(key);
      }
      else
         return;
   }
   
   if (strncmp(key, "--example", 9) == 0 && strlen(key) == 9)
      printf("%s %s\n", key, value);
}

/**
 * Extract key from -k=value or --key=value syntax
 */


char *argumentGetKey (char *key) {
   
   return strtok(key, "=");
}

/**
 * Extract value from -k=value or --key=value syntax
 */


char *argumentGetValue (char *key) {
   
   char *value;
   
   value = strtok(key, "=");
   value = strtok(NULL, "=");
   
   return value;
}

Example of possible usage,

1
2
3
% ./program -k=value --key=value
% ./program -k value
% etc...
Posted in Desktop Programming | Leave a comment

Richard Stallmans Lecture

Last Friday I had the privilege of seeing Richard Stallman give a lecture on “Copyright and Community in the Age of the Computer Networks”. It was a rather interesting lecture, where he raised some informative points, which I agree with.

One of the examples of copyright within the age of computer networks was copyright with books. Yes, his lecture wasn’t entirely computer related, it was more media related, movies, music, books and of course, software. The examples he presented were based on books in general, the fact copyright for books goes on far too long. Plus the fact authors of books tend to extend their copyright when it’s about to expire.

An example he gave was, you don’t see a blacksmith copyright his work and getting his grand children and what not to benefit from the work he produced as a blacksmith, in the way of getting paid for their grandparents work. This is what seems to happen with copyright and media. Authors of books are getting 75 year copyright licenses for their books, in which their grandchildren and such are benefiting from the sales of the books, ie. getting cash they did not earn.

Another interesting case is the DRM (Digital Rights Management) issue. DRM has been implemented upon a few technologies today, such as iPod, iTunes, Windows Media Player (optional) and more. What DRM does, is it restricts the user’s ability to port media from one source, or device to another. Using non-DRM protected media, you are able to view the same media on any device. However, when using DRM protected media, you are only able to view the media on DRM supported devices. Companies such as Microsoft, Apple and possibly others are claiming it’s better for the end user, that they have more freedom in playing music on their DRM devices. It’s not though, it’s restricting the end user to only be able to play their media on DRM devices, which is ridiculous. As Stallman said, people should be allowed to play media on the device of their choice, DRM protected or not. Whither it’s a computer, mp3 player, or a gaming console. If the device supports the media, or you can make a hack for it to support it, you should be able to.

The lecture went on for an hour and a half, which went surprisingly fast. At the end of the lecture, there were stickers (free), GNU teddy bears and badges available for us to buy. I ended up buying a GNU teddy bear ($30 donation to FSF), and a badge ($3 donation). I also got about at least 20 stickers. The stickers were anti-(DRM, iPod, iTunes), Bad Vista, GNU, Free Software Foundation (FSF) stickers and more.

Here’s some small picture’s of a GNU, and FSF sticker’s I got, which I placed on the cover of my laptop. I’ll upload my GNU teddy bear picture once I take a photo of it, currently not sure were my digital camera is.

Free Software Foundation

I’ll be keeping an eye out on YouTube, and news around my university campus for an uploaded version of Stallman’s lecture, as it was recorded. Be sure to check it out!

Posted in Geek Events | Leave a comment