Function Chaining in C++

Function chaining is a construct in  C++. It constructs a chain of function calls in one statement. Return value of the previous function call is used to call the next function and hence a chain of function calls is created. Following is an example of it:

obj.func1().func2().func3();

obj.fun1() is an expression which evaluates to the return-value of func1(). On this returned-value func2() is called which again evaluates to its return value. Similarly func3().

Function chaining is good as well as bad. It may make the code look compact and nice but excessive use may end up with readability and maintenance issues. The code may be difficult to debug also. One can’t see the intermediate return values of the function calls.

Apart for the readability and debugging issues, it can also result into a serious memory issue. Lately, I faced it while converting from a QString to a char* C string. Here is the code:

// function QString::toLocal8Bit() returns QByteArray
// QByteArray::data() returns pointer to internal data

QString str("manjeet");
const char *c_str = str.toLocal8Bit().data();
// c_str is now a dangling pointer referring to an invalid memory

In the above code c_str points to an invalid memory.

It happens because the function chaining involves unnamed temporary objects. These unnamed temporary objects are returned by the function calls. And these are again used to call the next function call. But in this case the last temporary object is not stored and is deleted after the statement is complete.

This code can be fixed by avoiding the function chaining and storing the intermediate object.

QString str("manjeet");
QByteArray ba = str.toLocal8Bit();
const char *c_str = ba.data();

Here the problem is fixed as the byte array is now being stored the ba variable.

[1] http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr382.htm

[2] http://stackoverflow.com/questions/154864/function-chaining-how-many-is-too-many

Control Mouse Speed from Command Line

I use two different mouse devices with my laptop, one in office and one at home. Mouse devices of different manufactures can have different sensitivity. This results in different speeds of the mouse pointer. To adjust the same, one can change the mouse speed from the Control Panel to achieve same speed or same experience with different mouse devices.

This has become a daily task for me. Twice a day, I have to change the pointer speed from the control panel. I thought of automating the process of changing the mouse speed to save myself from daily manual painful steps.

For part of the solution, I wrote a small utility program called changeMouseSensitivity.exe for changing the mouse speed. You can call this program from the command line passing mouse speed value (integer between 1 and 20) as the argument. This sets the mouse speed to the given value.

I calibrated both my mouse devices and found that the value of 6 for mouse_home and value of 14 for mouse_office gives me the same speed. I created two batch files mouse_home.bat and mouse_office.bat and in these two files I set the required speed values by calling the utility changeMouseSensitivity.exe. Following are the two bat files:

changeMouseSensitivity.exe 6
changeMouseSensitivity.exe 14

I created shortcuts to these two batch files on my desktop and every time I change my mouse (that is my location changes) I launch the respective bat file.

I’m liking this setup. It has reduced my total number of clicks from 7 to 1 double-click.

In future, there is a scope of automating the process completely. Complete automation requires detection of the connected mouse and setting the respective speed when mouse is connected.

Following is the source of the utility changeMouseSensitivity.exe. It is written in C++.

#include <stdio.h>
#include <tchar.h>
#include "Windows.h"

int _tmain(int argc, _TCHAR* argv[])
{
 if(argc == 2)
 {
 int value = _tstoi(argv[1]);

 if(value > 20 || value <1)
 {
 printf("\nFailure: the value should be between 1 and 20\n");
 return 0;
 }

 BOOL result = SystemParametersInfo(SPI_SETMOUSESPEED, 0, (void*)value, 0);
 if(result)
 printf("\nSuccess\n");
 else
 printf("\nFailure\n");
 }
 else
 {
 printf("\nUsage:\n");
 printf("  changeMouseSensitivity <interger value between 1 and 20>\n");
 }

 return 0;
}

Use QRegExp Carefully

Lately, I found a silly mistake which I have repeated at a couple of places in my Qt code. I thought of noting it down.

Example Case

I have a QStringList (list) and I want to find the index of a string (str) in it.

// list     -  QStringList
// str      -  QString

int index = list.indexOf(QRegExp(str));
// this function accepts QRegExp only, though
// in the new releases of Qt an overload
// accepting QString is also available

Nothing wrong with this, it has been working great for me and I have used it at many places. But, this works as long as str doesn’t contain any RegExp special characters. If the str contains special characters, its meaning changes. For instance dealing with filePaths, filepaths may have special characters in it like the character +.

The meaning of QRegExp(str) changes if str has the character +:

  • str
    /home/dahiya/test+examples/newFile
  • QRegExp(str)
    /home/dahiya/testexamples/newFile
    /home/dahiya/testtexamples/newFile
    /home/dahiya/testttexamples/newFile
    /home/dahiya/testtttexamples/newFile
    /home/dahiya/testttttexamples/newFile

It will never match the original string (str). The index returned will be not be the valid one.

Solution

Escape all the RegExp special characters. On escaping the special characters, they will be treated normal and the code will behave correctly. Qt provides a utility function also.

QString QRegExp::escape(const QString&)

This function returns the escaped string (str).

  • str
    /home/dahiya/test+examples/newFile
  • escape(str)
    /home/dahiya/test\\+examples/newFile

So one can write the correct code like:

int index = list.indexOf(QRegExp(QRegExp::escape(str)));

Conclusion

In future, use QRegExp carefully if you just want to match a string.

QXmpp 0.3.0 Release

I’m glad to release the next version of QXmpp, version 0.3.0. It comes packed with a number new features, bug fixes and improvements.

Here is a list of new features in QXmpp 0.3.0, please look at the changelog for exhaustive list:

  • XEP-0153: vCard-Based Avatars
  • XEP-0202: Entity Time
  • Managers for all the XEPs
  • More examples:
    example_9_vCard: vCard handling
    GuiClient: Graphical chat client, test bench for QXmpp functionalities
    example_8_server: Server capability
  • Server framework: Yes you can write a server now look at the example example_8_server
  • Add support for DNS SRV lookups, meaning you can connect to nearly all servers using only a JID and a password. No need to explicitly specify the server information.
  • Add QXMPP_VERSION and QXmppVersion() for compile and run time version checks.
  • Improve code documentation coverage and quality.
  • Completely remove dependency on QtGui, making it easier to write console applications.

QXmpp 0.3.0 Release Details:

Project Page | Changelog | Readme | API Documentation | Download

As usual, thanks to the authors, community and the users who have been driving the project.

About QXmpp:

QXmpp is a cross-platform C++ XMPP client (and server!) library based on Qt and C++. It is an open source project licensed under a permissive license LGPL. As of today, the project is around two years old.

Splitting multiple-vCards-file to one-vCard-per-file

vCard is a standard format, defined for electronic business cards. vCards contain name, phone numbers, address, email address, URLs, photograph etc. These are stored as plain-text files of extension vcf or vcard.

Usually, one vCard file contains details of a single contact. But there are variations in its implementation. A few applications support multiple contacts in a single vCard file. GMail, Mac OS X and KDE Kontact are such applications. Microsoft Outlook and Symbian on the other hand allows only one contact per file. If you try to import a vCard file, with multiple contacts, they will import only the first contact.

I needed to convert single file containing multiple contacts to one-contact-per-file. For the same, I wrote a Python script. This script splits a vCard file to multiple files containing one contact each. This will help moving contacts to the applications which don’t support multiple contacts per file.

Example of vCard format

BEGIN:VCARD
VERSION:3.0
FN:Manjeet Dahiya
N:Dahiya;Manjeet;;;
EMAIL;TYPE=INTERNET:xxx@gmail.com
TEL;TYPE=CELL:xxx
END:VCARD

BEGIN:VCARD
VERSION:3.0
FN:Manjeet Dahiya
N:Dahiya;Manjeet;;;
EMAIL;TYPE=INTERNET:xxx@gmail.com
TEL;TYPE=CELL:xxx
END:VCARD
BEGIN:VCARD
VERSION:3.0
FN:Shivraj Singh
N:Singh;Shivraj;;;
EMAIL;TYPE=INTERNET:xxx@gmail.com
TEL;TYPE=CELL:xxx
END:VCARD

Script Usage

python vCardSplit <vcard-file>
import sys

if (len(sys.argv) != 2):
 print "Usage: vCardSplit <vcard file>\n"
 sys.exit()

vCardFilePath = sys.argv[1]

vCardFile = open(vCardFilePath, 'r')

a = 0
vcardStarted = False
while True:
 line = vCardFile.readline()
 if not line:
 break

 if line.startswith('BEGIN:VCARD'):
 vcardStarted = True
 a = a + 1
 splitFile = open('contact_' + str(a) + '.vcf', 'w')

 if vcardStarted:
 splitFile.write(line)

 if line.startswith('END:VCARD'):
 vcardStarted = False
 splitFile.close()

vCardFile.close()

print 'Generated ' + str(a) + ' vCards';

Regular Expressions

Regular Expressions (commonly referred to as RegEx or RegExp) are coded strings which represent text patterns. These can be used to search and replace patterns in the texts. A pattern defined by a regular expression can be used in the regular expression processors like grep, sed, awk, Notepad++, Visual Studio etc. for performing search, replace or modifications.

Programming languages also support regular expressions. It is more commonly found in scripting languages like Perl, Python, Ruby etc. but the compiled languages Java and C++ (using Boost, Qt) also support it.

Regular Expressions Syntax and Rules

A regular expression is a string and contains text characters. A few of the text characters have special meaning. These special characters perform various operations like grouping, quantification, NOT etc. Rest of the characters are normal and mean what they are.

List of special characters:  ” \  [  ]  ^ -  ?  .  *  +  |  (  )  $  /  {  }  %  <  >

To use these characters literally in a regex one has to escape them using a backslash (\) or enclose in quotes.

Normal Text

  • a matches a
  • hello matches hello
  • . a special character. It matches any character except a newline
  • \. matches .

Groups

Round brackets or parentheses () are used to create a group.

  • (a|b|c) matches a or b or c
  • (colour|color) matches colour or color

Ranges

Square brackets [] are used for specifying a range of characters.

  • [abc] matches a or b or c
  • [^abc] matches any character except a, b and c
  • [a-c] matches a or b or c, range from a to c
  • [A-C] matches A or B or C, range from A to C
  • [a-cA-C] matches a or b or c or A or B or C
  • [0-5] matches a digit from 0 to 5
  • [a-zA-Z0-9] matches one character of alphanumeric text

Quantifiers

It specifies how many times something is repeated.

  • a* zero or more, matches null, a, aa, aaa, aaaa, …
  • a+ one or more, matches a, aa, aaa, aaaa, …
  • a? zero or one, matches null or a
  • a{3} matches aaa
  • a{3,} three and more aaa, aaaa, aaaaa, …
  • a{3,6} 3 to 6 matches aaa, aaaa, aaaaa, aaaaaa

Eg.
[a-zA-Z0-9]{8} matches alphanumeric text of length 8

Shorthands

Shorthands exist for commonly used character classes. For example digits character class has a shorthand \d. It is short for [0-9]. Each lowercase shorthand character has an associated uppercase shorthand character with the opposite meaning. Thus [\D] matches any character that is not a digit, and is equivalent to [^\d].

  • \d a digit, short for [0-9]
  • \D a non-digit, short for [^0-9]
  • \w a word character, short for [a-zA-Z_0-9]
  • \W a non-word character equivalent to [^a-zA-Z_0-9]
  • \s a whitespace character, short for [ \t\n\x0b\r\f] matches any whitespace character. This includes spaces, tabs, and line breaks.
  • \S [^\s]

Anchors

  • ^ start of the subject, ^a makes sure that a occurs at the the beginning of the subject
  • $ end of the subject, a$ makes sure that a occurs at the the end of the subject
  • \b word boundaries, \ba\b makes sure that a is a whole word in the subject
  • \B nonboundaries, \Ba\B makes sure that a is not a whole word

Examples

  • .at matches any three-character string ending with at e.g. hat, cat and bat
  • [hc]at matches hat or cat
  • [hc]?at matches hat or cat or at
  • 0[xX][A-Fa-f0-9]+ matches hexadecimal number e.g. 0x2AB7
  • [A-Za-z_][A-Za-z_0-9]* identifier in a programming language
  • cal[ae]nd[ae]r matches misspelled calender
  • colou?r matches color or colour
  • gr[ae]u matches grey or gray
  • \d+ matches positive integers
  • -\d+ matches negative integers
  • -{0,1}\d+ matches integers
  • \d*\.{0,1}\d+ matches positive real numbers