2 * Copyright (C) 2013 Thadeu Lima de Souza Cascardo <cascardo@minaslivre.org>
3 * Copyright (C) 2014 Alexandre Oliva <lxoliva@fsfla.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "rnet_message.h"
28 #define MAX(a,b) (a >= b) ? a : b
31 int rnet_message_expand(struct rnet_message **message, size_t len)
33 struct rnet_message *msg = *message;
34 struct rnet_message *nmsg;
37 nmsg = realloc(msg, sizeof(*msg) + len);
47 struct rnet_message * rnet_message_new(void)
49 struct rnet_message *msg = NULL;
51 r = rnet_message_expand(&msg, 1118);
57 void rnet_message_del(struct rnet_message *message)
62 int rnet_message_strip(struct rnet_message *message, size_t len)
64 if (len > message->len)
67 memmove(message->buffer, message->buffer + len, message->len);
71 static int add_field(struct rnet_message **message, char *key, int klen,
76 struct rnet_message *msg = *message;
77 if ((msg->alen - msg->len) < (klen + vlen + 3)) {
78 if (rnet_message_expand(message, MAX(msg->len, klen + vlen + 3)))
82 buffer = msg->buffer + msg->len;
83 if (klen > 0x7f || klen < 0)
85 if (vlen > 0x7fff || vlen < 0)
87 buffer[0] = klen & 0x7f;
92 memcpy(buffer, key, klen);
96 buffer[0] = (vlen >> 8) & 0x7f;
97 buffer[1] = vlen & 0xff;
101 buffer[0] = vlen & 0x7f;
105 memcpy(buffer, val, vlen);
111 int rnet_message_add_u32(struct rnet_message **msg, char *key, uint32_t val)
113 uint32_t nval = htonl(val);
114 return add_field(msg, key, strlen(key), (char *) &nval, sizeof(val));
117 int rnet_message_add_ascii(struct rnet_message **msg, char *key, char *val)
119 return add_field(msg, key, strlen(key), val, strlen(val));
122 int rnet_message_add_u8(struct rnet_message **msg, char *key, uint8_t val)
124 return add_field(msg, key, strlen(key), (char *) &val, sizeof(val));
127 int rnet_message_add_u16(struct rnet_message **msg, char *key, uint16_t val)
129 uint16_t nval = htons(val);
130 return add_field(msg, key, strlen(key), (char *) &nval, sizeof(val));
133 int rnet_message_add_u64(struct rnet_message **msg, char *key, uint64_t val)
135 uint64_t nval = htobe64(val);
136 return add_field(msg, key, strlen(key), (char *) &nval, sizeof(val));
139 int rnet_message_add_buffer(struct rnet_message **msg, char *key,
140 char *buffer, size_t len)
142 return add_field(msg, key, strlen(key), buffer, len);
145 int rnet_message_parse(struct rnet_message *msg, char *skey,
146 char** value, int *vlen)
148 char * buffer = msg->buffer;
149 size_t len = msg->len;
155 /* skip first byte */
158 j = (unsigned char)buffer[i];
167 j = (unsigned char)buffer[i];
170 j = j << 8 | (unsigned char)buffer[i++];
174 if (strlen(skey) == klen && !strncasecmp(key, skey, klen))