/*
* 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
#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;
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)
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;
+}