#include <stdio.h>
#include <stdarg.h>

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long  ulong;

int pack(uchar *buf, char *fmt, ...)
{
 va_list args;
 char *p;
 uchar *bp;
 ushort s;
 ulong l;

 bp=buf;

 va_start(args, fmt);
 for(p=fmt; *p!='\0'; p++)
  {
    switch(*p)
     {
       case 'c' : *bp++ = va_arg(args,int);
                   break;
       case 's' :  s = va_arg(args, int);
                   *bp++ = s >> 8;
                   *bp++ = s;
                   break;
       case 'l' :  l = va_arg(args, ulong);
                   *bp++ = l >> 24;
                   *bp++ = l >> 16;
                   *bp++ = l >> 8;
                   *bp++ = l;
                   break;
       default  :  va_end(args);
                   return -1;
      }
   }
  va_end(args);
  return bp-buf;
}

int unpack(uchar *buf, char *fmt, ...)
{
 va_list args;
 char *p;
 uchar *bp, *pc;
 ushort *ps;
 ulong *pl;

 bp=buf;
 va_start(args, fmt);
 for(p=fmt; *p!='\0'; *p++)
  {
    switch(*p)
     {
      case 'c' :  pc = va_arg(args, uchar*);
                  *pc = *bp++;
                  break;
      case 's' :  ps = va_arg(args, ushort*);
                  *ps = *bp++ << 8;
                  *ps |=*bp++;
                  break;
      case 'l' :  pl = va_arg(args, ulong*);
                  *pl = *bp++ << 24;
                  *pl |= *bp++ << 16;
                  *pl |= *bp++ << 8;
                  *pl |= *bp++;
                  break;
      default  :  va_end(args);
                  return -1;
     }
  }
 va_end(args);
 return bp-buf;
}


int main()
{
 int p;
 uchar *buf,*buf2;
 ushort count = 10, ucount;
 uchar val = 'a', uval,c;
 ulong data = 10000, data2=12345, udata, udata2;

 p=pack(buf, "cscll", 0x01, count, val, data, data2);
 printf("Gepackt in %d Bytes\n",p);
 unpack(buf, "cscll", &c, &ucount, &uval, &udata, &udata2);
 printf("Und wieder entpackt = ");
 printf("%d:%c:%ld:%ld\n", ucount, uval, udata, udata2);

 return 0;
}