Um pequeno programa de teste para obter alguns campos de uma declaração.
[cascardo/libreceita.git] / rnet_message.c
index 8933861..95d8b41 100644 (file)
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 2013  Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
+ *  Copyright (C) 2014  Alexandre Oliva <lxoliva@fsfla.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -27,7 +28,7 @@
 #define MAX(a,b) (a >= b) ? a : b
 #endif
 
-static int rnet_message_expand(struct rnet_message **message, size_t len)
+int rnet_message_expand(struct rnet_message **message, size_t len)
 {
        struct rnet_message *msg = *message;
        struct rnet_message *nmsg;
@@ -58,13 +59,25 @@ void rnet_message_del(struct rnet_message *message)
        free(message);
 }
 
-static int add_field(struct rnet_message *msg, char *key, int klen, char *val, int vlen)
+int rnet_message_strip(struct rnet_message *message, size_t len)
+{
+       if (len > message->len)
+               return -1;
+       message->len -= len;
+       memmove(message->buffer, message->buffer + len, message->len);
+       return 0;
+}
+
+static int add_field(struct rnet_message **message, char *key, int klen,
+                                               char *val, int vlen)
 {
        int n = 0;
        char *buffer;
-       if ((msg->alen - msg->len) < (klen + vlen + 3)) {
-               if (rnet_message_expand(&msg, MAX(msg->len, klen + vlen + 3)))
+       struct rnet_message *msg = *message;
+       if ((msg->alen - msg->len) < (size_t) (klen + vlen + 3)) {
+               if (rnet_message_expand(message, MAX(msg->len, (size_t) (klen + vlen + 3))))
                        return -ENOMEM;
+               msg = *message;
        }
        buffer = msg->buffer + msg->len;
        if (klen > 0x7f || klen < 0)
@@ -95,18 +108,69 @@ static int add_field(struct rnet_message *msg, char *key, int klen, char *val, i
        return n;
 }
 
-int rnet_message_add_u32(struct rnet_message *msg, char *key, uint32_t val)
+int rnet_message_add_u32(struct rnet_message **msg, char *key, uint32_t val)
 {
        uint32_t nval = htonl(val);
        return add_field(msg, key, strlen(key), (char *) &nval, sizeof(val));
 }
 
-int rnet_message_add_ascii(struct rnet_message *msg, char *key, char *val)
+int rnet_message_add_ascii(struct rnet_message **msg, char *key, char *val)
 {
        return add_field(msg, key, strlen(key), val, strlen(val));
 }
 
-int rnet_message_add_u8(struct rnet_message *msg, char *key, uint8_t val)
+int rnet_message_add_u8(struct rnet_message **msg, char *key, uint8_t val)
 {
        return add_field(msg, key, strlen(key), (char *) &val, sizeof(val));
 }
+
+int rnet_message_add_u16(struct rnet_message **msg, char *key, uint16_t val)
+{
+       uint16_t nval = htons(val);
+       return add_field(msg, key, strlen(key), (char *) &nval, sizeof(val));
+}
+
+int rnet_message_add_u64(struct rnet_message **msg, char *key, uint64_t val)
+{
+       uint64_t nval = htobe64(val);
+       return add_field(msg, key, strlen(key), (char *) &nval, sizeof(val));
+}
+
+int rnet_message_add_buffer(struct rnet_message **msg, char *key,
+                               char *buffer, size_t len)
+{
+       return add_field(msg, key, strlen(key), buffer, len);
+}
+
+int rnet_message_parse(struct rnet_message *msg, char *skey,
+                               char** value, int *vlen)
+{
+       char * buffer = msg->buffer;
+       size_t len = msg->len;
+       unsigned int i = 0;
+       unsigned int j;
+       int b;
+       char *key;
+       unsigned int klen;
+       /* skip first byte */
+       i++;
+       while (i < len) {
+               j = (unsigned char)buffer[i];
+               b = j & 0x80;
+               j = j & 0x7f;
+               i++;
+               key = buffer + i;
+               klen = j;
+               i += j;
+               j = (unsigned char)buffer[i];
+               i++;
+               if (b)
+                       j = j << 8 | (unsigned char)buffer[i++];
+               *value = buffer + i;
+               *vlen = j;
+               i += j;
+               if (strlen(skey) == klen && !strncasecmp(key, skey, klen))
+                       return 0;
+       }
+       return 1;
+}