#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include "netstring.h"
int netstring_read(char *buffer, size_t buffer_length,
char **netstring_start, size_t *netstring_length) {
int i;
size_t len = 0;
*netstring_start = NULL; *netstring_length = 0;
if (buffer_length < 3) return NETSTRING_ERROR_TOO_SHORT;
if (buffer[0] == '0' && isdigit(buffer[1]))
return NETSTRING_ERROR_LEADING_ZERO;
if (!isdigit(buffer[0])) return NETSTRING_ERROR_NO_LENGTH;
for (i = 0; i < buffer_length && isdigit(buffer[i]); i++) {
if (i >= 9) return NETSTRING_ERROR_TOO_LONG;
len = len*10 + (buffer[i] - '0');
}
if (i + len + 1 >= buffer_length) return NETSTRING_ERROR_TOO_SHORT;
if (buffer[i++] != ':') return NETSTRING_ERROR_NO_COLON;
if (buffer[i + len] != ',') return NETSTRING_ERROR_NO_COMMA;
*netstring_start = &buffer[i]; *netstring_length = len;
return 0;
}
size_t netstring_buffer_size(size_t data_length) {
if (data_length == 0) return 3;
return (size_t)ceil(log10((double)data_length + 1)) + data_length + 2;
}
size_t netstring_encode_new(char **netstring, char *data, size_t len) {
char *ns;
size_t num_len = 1;
if (len == 0) {
ns = malloc(3);
ns[0] = '0';
ns[1] = ':';
ns[2] = ',';
} else {
num_len = (size_t)ceil(log10((double)len + 1));
ns = malloc(num_len + len + 2);
sprintf(ns, "%lu:", (unsigned long)len);
memcpy(ns + num_len + 1, data, len);
ns[num_len + len + 1] = ',';
}
*netstring = ns;
return num_len + len + 2;
}