Sunday, July 23, 2006

C Macro innovation

This trick I learnt while working on Kannel, an open source WAP & SMS Gateway has helped me a lot in coding.
This is used in programs which use many similar & related data types for example packets in various protocols. There are 'N' different type of messages sharing some fields and passing through same processing cycle i.e. create packet, send packet, display contents of the packet, parse packet etc. etc.

Let us start with two messages used in some 'X' protocol

login request {
char * username;
char * passwd_encrypted;
int protocol_ver;
};

login response {
int response;
int protocol_ver;
int max_simult_con;
};

Now we require to code for handling these two protocol packets. In future some new fields can also be added (which should be easy)

We use C preprocesser feature to handling such problem.

MSG(loginreq,
STRING(username)
STRING(
passwd_encrypted)
INTEGER(protocol_ver)
)

MSG(loginres,
INTEGER(response);
INTEGER(protocol_ver);
INTEGER(max_simult_con)

)

These packet descriptions are places in a separate header file "msg.h".

Lot lets proceed to define actual data types.

struct msg {
int type;
#define INTEGER(name) int name;
#define STRING(name) char *name;
#define PACKET(name, fields) struct name {fields} name;
#include "msg.h"
};


The above code after preprocessor expension will look like

struct msg {
int type;
struct loginreq {
char *username;
char *passwd_encrpted;
int protocol_ver;
} loginreq;
struct loginres {
int response;
int protocol_ver;
int max_simul_con;
} loginres;
};

For further details refer to Kannel's source code.

No comments: