2020-11-24 15:41:18 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cassert>
|
2021-04-30 16:10:14 +02:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
2020-11-24 15:41:18 +01:00
|
|
|
|
|
|
|
namespace brynet { namespace base {
|
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
struct array_s
|
|
|
|
{
|
|
|
|
void* buffer;
|
|
|
|
size_t buffer_size;
|
|
|
|
size_t element_size;
|
|
|
|
size_t element_num;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void array_delete(struct array_s* self)
|
|
|
|
{
|
|
|
|
if (self == nullptr)
|
2020-11-24 15:41:18 +01:00
|
|
|
{
|
2021-04-30 16:10:14 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
if (self->buffer != nullptr)
|
2020-11-24 15:41:18 +01:00
|
|
|
{
|
2021-04-30 16:10:14 +02:00
|
|
|
free(self->buffer);
|
|
|
|
self->buffer = nullptr;
|
2020-11-24 15:41:18 +01:00
|
|
|
}
|
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
self->element_num = 0;
|
|
|
|
free(self);
|
|
|
|
self = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct array_s* array_new(size_t num, size_t element_size)
|
|
|
|
{
|
|
|
|
auto ret = (struct array_s*) malloc(sizeof(struct array_s));
|
|
|
|
if (ret == nullptr)
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto buffer_size = num * element_size;
|
|
|
|
|
|
|
|
ret->buffer_size = 0;
|
|
|
|
ret->element_size = 0;
|
|
|
|
ret->element_num = 0;
|
|
|
|
ret->buffer = malloc(buffer_size);
|
|
|
|
|
|
|
|
if (ret->buffer != nullptr)
|
|
|
|
{
|
|
|
|
ret->element_size = element_size;
|
|
|
|
ret->element_num = num;
|
|
|
|
ret->buffer_size = buffer_size;
|
|
|
|
}
|
|
|
|
else
|
2020-11-24 15:41:18 +01:00
|
|
|
{
|
2021-04-30 16:10:14 +02:00
|
|
|
array_delete(ret);
|
|
|
|
ret = nullptr;
|
2020-11-24 15:41:18 +01:00
|
|
|
}
|
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void* array_at(struct array_s* self, size_t index)
|
|
|
|
{
|
|
|
|
void* ret = nullptr;
|
|
|
|
|
|
|
|
if (index < self->element_num)
|
|
|
|
{
|
|
|
|
ret = (char*) (self->buffer) + (index * self->element_size);
|
|
|
|
}
|
|
|
|
else
|
2020-11-24 15:41:18 +01:00
|
|
|
{
|
2021-04-30 16:10:14 +02:00
|
|
|
assert(false);
|
2020-11-24 15:41:18 +01:00
|
|
|
}
|
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool array_set(struct array_s* self, size_t index, const void* data)
|
|
|
|
{
|
|
|
|
void* old_data = array_at(self, index);
|
|
|
|
|
|
|
|
if (old_data != nullptr)
|
2020-11-24 15:41:18 +01:00
|
|
|
{
|
2021-04-30 16:10:14 +02:00
|
|
|
memcpy(old_data, data, self->element_size);
|
|
|
|
return true;
|
2020-11-24 15:41:18 +01:00
|
|
|
}
|
2021-04-30 16:10:14 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
static bool array_increase(struct array_s* self, size_t increase_num)
|
|
|
|
{
|
|
|
|
if (increase_num == 0)
|
2020-11-24 15:41:18 +01:00
|
|
|
{
|
2021-04-30 16:10:14 +02:00
|
|
|
return false;
|
2020-11-24 15:41:18 +01:00
|
|
|
}
|
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
const auto new_buffer_size = self->buffer_size + increase_num * self->element_size;
|
|
|
|
auto new_buffer = malloc(new_buffer_size);
|
|
|
|
|
|
|
|
if (new_buffer != nullptr)
|
|
|
|
{
|
|
|
|
memcpy(new_buffer, self->buffer, self->buffer_size);
|
|
|
|
free(self->buffer);
|
|
|
|
self->buffer = new_buffer;
|
|
|
|
self->element_num += increase_num;
|
|
|
|
self->buffer_size = new_buffer_size;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
2020-11-24 15:41:18 +01:00
|
|
|
{
|
2021-04-30 16:10:14 +02:00
|
|
|
assert(false);
|
|
|
|
return false;
|
2020-11-24 15:41:18 +01:00
|
|
|
}
|
2021-04-30 16:10:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static size_t array_num(const struct array_s* self)
|
|
|
|
{
|
|
|
|
return self->element_num;
|
|
|
|
}
|
2020-11-24 15:41:18 +01:00
|
|
|
|
2021-04-30 16:10:14 +02:00
|
|
|
}}// namespace brynet::base
|