Browse Source

+ f2b_buf_t

master
Alex 'AdUser' Z 3 years ago
parent
commit
11aa09abeb
  1. 74
      src/buf.c
  2. 15
      src/buf.h
  3. 2
      t/CMakeLists.txt
  4. 48
      t/t_buf.c

74
src/buf.c

@ -0,0 +1,74 @@
#include "common.h"
#include "buf.h"
bool
f2b_buf_alloc(f2b_buf_t *buf, size_t size) {
assert(buf != NULL);
assert(size > 0);
memset(buf, 0x0, sizeof(f2b_buf_t));
if ((buf->data = malloc(size)) == NULL)
return false; /* can't allocate memory */
buf->size = size;
return true;
}
void
f2b_buf_free(f2b_buf_t *buf) {
assert(buf != NULL);
free(buf->data);
memset(buf, 0x0, sizeof(f2b_buf_t));
}
bool
f2b_buf_append(f2b_buf_t *buf, const char *str, size_t len) {
assert(buf != NULL);
assert(str != NULL);
if (len == 0)
len = strlen(str);
if (buf->size < (buf->used + len))
return false; /* not enough space */
memcpy(&buf->data[buf->used], str, len);
buf->used += len;
buf->data[buf->used] = '\0';
return true;
}
/**
* @brief Extracts line terminated by '\r', '\n'
* @return Pointer to extracted string on success or NULL otherwise
* @note Use only with 'read' buffer type
*/
char *
f2b_buf_extract(f2b_buf_t *buf, const char *end) {
char *s = NULL;
size_t len = 0;
assert(buf != NULL);
assert(end != NULL);
if (buf->data == NULL || buf->used == 0)
return NULL; /* no data */
if ((s = strstr(buf->data, end)) == NULL)
return NULL; /* not found */
/* copy the data before modifying buffer */
len = s - buf->data;
if ((s = strndup(buf->data, len)) == NULL)
return NULL; /* malloc error */
/* shift data inside buffer */
len += strlen(end);
assert(buf->used >= len);
buf->used -= len,
memmove(buf->data, &buf->data[len], buf->used);
buf->data[buf->used] = '\0';
return s;
}

15
src/buf.h

@ -0,0 +1,15 @@
#ifndef F2B_BUF_H_
#define F2B_BUF_H_
typedef struct f2b_buf_t {
size_t used; /**< bytes used in buffer */
size_t size; /**< available size in data */
char *data; /**< allocated buffer */
} f2b_buf_t;
bool f2b_buf_alloc(f2b_buf_t *buf, size_t max);
void f2b_buf_free(f2b_buf_t *buf);
bool f2b_buf_append(f2b_buf_t *buf, const char *str, size_t size);
char * f2b_buf_extract(f2b_buf_t *buf, const char *end);
#endif /* F2B_BUF_H_ */

2
t/CMakeLists.txt

@ -2,6 +2,7 @@ enable_testing()
set(SRC_DIR "../src")
add_executable("t_buf" "t_buf.c" "${SRC_DIR}/strlcpy.c" "${SRC_DIR}/buf.c")
add_executable("t_cmd" "t_cmd.c" "${SRC_DIR}/strlcpy.c" "${SRC_DIR}/commands.c")
add_executable("t_cmsg" "t_cmsg.c" "${SRC_DIR}/strlcpy.c" "${SRC_DIR}/cmsg.c")
add_executable("t_matches" "t_matches.c" "${SRC_DIR}/strlcpy.c" "${SRC_DIR}/matches.c")
@ -10,6 +11,7 @@ add_executable("t_statefile" "t_statefile.c" "${SRC_DIR}/strlcpy.c" "${SRC_D
add_executable("t_config_param" "t_config_param.c" "${SRC_DIR}/strlcpy.c" "${SRC_DIR}/config.c" "${SRC_DIR}/log.c")
add_executable("t_backend_usage" "t_backend_usage.c" "${SRC_DIR}/strlcpy.c")
add_test("tests/f2b_buf_*" "t_buf")
add_test("tests/f2b_cmd_*" "t_cmd")
add_test("tests/f2b_cmsg_*" "t_cmsg")
add_test("tests/f2b_matches_*" "t_matches")

48
t/t_buf.c

@ -0,0 +1,48 @@
#include "../src/common.h"
#include "../src/buf.h"
int main() {
f2b_buf_t buf;
char *line;
bool ret;
memset(&buf, 0x0, sizeof(buf));
ret = f2b_buf_alloc(&buf, 512);
assert(ret = true);
assert(buf.used == 0);
assert(buf.size == 512);
ret = f2b_buf_append(&buf, "test ", 0);
assert(ret == true);
assert(buf.used == 5);
line = f2b_buf_extract(&buf, "\n");
assert(line == NULL);
ret = f2b_buf_append(&buf, "test2\n", 0);
assert(ret == true);
assert(buf.used == 11);
ret = f2b_buf_append(&buf, "test3\n", 0);
assert(ret == true);
assert(buf.used == 17);
line = f2b_buf_extract(&buf, "\n");
assert(line != NULL);
assert(strcmp(line, "test test2") == 0);
assert(buf.used == 6);
free(line);
line = f2b_buf_extract(&buf, "\n");
assert(line != NULL);
assert(buf.used == 0);
free(line);
f2b_buf_free(&buf);
assert(buf.used == 0);
assert(buf.size == 0);
assert(buf.data == NULL);
return 0;
}
Loading…
Cancel
Save