2020-11-24 15:41:18 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
struct buffer_s {
|
|
|
|
char *data;
|
|
|
|
size_t data_len;
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
size_t write_pos;
|
|
|
|
size_t read_pos;
|
2021-04-30 16:10:14 +02:00
|
|
|
};
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static void buffer_delete(struct buffer_s *self) {
|
|
|
|
if (self == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self->data != nullptr) {
|
|
|
|
free(self->data);
|
|
|
|
self->data = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(self);
|
|
|
|
self = nullptr;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static struct buffer_s *buffer_new(size_t buffer_size) {
|
|
|
|
struct buffer_s *ret = (struct buffer_s *)malloc(sizeof(struct buffer_s));
|
|
|
|
if (ret == nullptr) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret->data_len = 0;
|
|
|
|
ret->read_pos = 0;
|
|
|
|
ret->write_pos = 0;
|
|
|
|
ret->data = (char *)malloc(sizeof(char) * buffer_size);
|
|
|
|
|
|
|
|
if (ret->data != nullptr) {
|
|
|
|
ret->data_len = buffer_size;
|
|
|
|
} else {
|
|
|
|
buffer_delete(ret);
|
|
|
|
ret = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static size_t buffer_getreadvalidcount(struct buffer_s *self) {
|
|
|
|
return self->write_pos - self->read_pos;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static void buffer_adjustto_head(struct buffer_s *self) {
|
|
|
|
if (self->read_pos == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto len = buffer_getreadvalidcount(self);
|
|
|
|
if (len > 0) {
|
|
|
|
memmove(self->data, self->data + self->read_pos, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
self->read_pos = 0;
|
|
|
|
self->write_pos = len;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static void buffer_init(struct buffer_s *self) {
|
|
|
|
self->read_pos = 0;
|
|
|
|
self->write_pos = 0;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static size_t buffer_getwritepos(struct buffer_s *self) {
|
|
|
|
return self->write_pos;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static size_t buffer_getreadpos(struct buffer_s *self) {
|
|
|
|
return self->read_pos;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static bool buffer_addwritepos(struct buffer_s *self, size_t value) {
|
|
|
|
const size_t temp = self->write_pos + value;
|
|
|
|
if (temp <= self->data_len) {
|
|
|
|
self->write_pos = temp;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static bool buffer_addreadpos(struct buffer_s *self, size_t value) {
|
|
|
|
const size_t temp = self->read_pos + value;
|
|
|
|
if (temp <= self->data_len) {
|
|
|
|
self->read_pos = temp;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static size_t buffer_getwritevalidcount(struct buffer_s *self) {
|
|
|
|
return self->data_len - self->write_pos;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static size_t buffer_getsize(struct buffer_s *self) {
|
|
|
|
return self->data_len;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static char *buffer_getwriteptr(struct buffer_s *self) {
|
|
|
|
if (self->write_pos < self->data_len) {
|
|
|
|
return self->data + self->write_pos;
|
|
|
|
} else {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static char *buffer_getreadptr(struct buffer_s *self) {
|
|
|
|
if (self->read_pos < self->data_len) {
|
|
|
|
return self->data + self->read_pos;
|
|
|
|
} else {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
2021-05-14 17:16:45 +02:00
|
|
|
static bool buffer_write(struct buffer_s *self, const char *data, size_t len) {
|
|
|
|
bool write_ret = true;
|
|
|
|
|
|
|
|
if (buffer_getwritevalidcount(self) >= len) {
|
|
|
|
memcpy(buffer_getwriteptr(self), data, len);
|
|
|
|
buffer_addwritepos(self, len);
|
|
|
|
} else {
|
|
|
|
size_t left_len = self->data_len - buffer_getreadvalidcount(self);
|
|
|
|
if (left_len >= len) {
|
|
|
|
buffer_adjustto_head(self);
|
|
|
|
buffer_write(self, data, len);
|
|
|
|
} else {
|
|
|
|
write_ret = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return write_ret;
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|