add bytearray.remove, .insert and constructor using array

This commit is contained in:
MihailRis 2024-06-16 21:19:49 +03:00
parent 20ef11e5a2
commit 19a012f9c6
2 changed files with 76 additions and 27 deletions

View File

@ -21,12 +21,58 @@ Bytearray::~Bytearray() {
static int l_bytearray_append(lua::State* L) {
if (auto buffer = touserdata<Bytearray>(L, 1)) {
auto value = tointeger(L, 2);
buffer->append(static_cast<ubyte>(value));
buffer->data().push_back(static_cast<ubyte>(value));
}
return 0;
}
static int l_bytearray_insert(lua::State* L) {
auto buffer = touserdata<Bytearray>(L, 1);
if (buffer == nullptr) {
return 0;
}
auto& data = buffer->data();
auto index = tointeger(L, 2)-1;
if (static_cast<size_t>(index) > data.size()) {
return 0;
}
auto value = tointeger(L, 3);
data.insert(data.begin() + index, static_cast<ubyte>(value));
return 0;
}
static int l_bytearray_remove(lua::State* L) {
auto buffer = touserdata<Bytearray>(L, 1);
if (buffer == nullptr) {
return 0;
}
auto& data = buffer->data();
auto index = tointeger(L, 2)-1;
if (static_cast<size_t>(index) > data.size()) {
return 0;
}
data.erase(data.begin()+index);
return 0;
}
static std::unordered_map<std::string, lua_CFunction> bytearray_methods {
{"append", lua::wrap<l_bytearray_append>},
{"insert", lua::wrap<l_bytearray_insert>},
{"remove", lua::wrap<l_bytearray_remove>},
};
static int l_bytearray_meta_meta_call(lua::State* L) {
if (lua_istable(L, 2)) {
size_t len = objlen(L, 2);
std::vector<ubyte> buffer(len);
buffer.resize(len);
for (size_t i = 0; i < len; i++) {
rawgeti(L, i+1);
buffer[i] = static_cast<ubyte>(tointeger(L, -1));
pop(L);
}
return newuserdata<Bytearray>(L, std::move(buffer));
}
auto size = tointeger(L, 2);
if (size < 0) {
throw std::runtime_error("size can not be less than 0");
@ -36,49 +82,61 @@ static int l_bytearray_meta_meta_call(lua::State* L) {
static int l_bytearray_meta_index(lua::State* L) {
auto buffer = touserdata<Bytearray>(L, 1);
if (buffer == nullptr) {
return 0;
}
auto& data = buffer->data();
if (isstring(L, 2)) {
std::string member = tostring(L, 2);
if (member == "append") {
return pushcfunction(L, l_bytearray_append);
auto found = bytearray_methods.find(tostring(L, 2));
if (found != bytearray_methods.end()) {
return pushcfunction(L, found->second);
}
}
auto index = tointeger(L, 2)-1;
if (buffer == nullptr || static_cast<size_t>(index) > buffer->size()) {
if (static_cast<size_t>(index) > data.size()) {
return 0;
}
return pushinteger(L, (*buffer)[index]);
return pushinteger(L, data[index]);
}
static int l_bytearray_meta_newindex(lua::State* L) {
auto buffer = touserdata<Bytearray>(L, 1);
if (buffer == nullptr) {
return 0;
}
auto& data = buffer->data();
auto index = tointeger(L, 2)-1;
if (buffer == nullptr || static_cast<size_t>(index) > buffer->size()) {
if (static_cast<size_t>(index) > data.size()) {
return 0;
}
auto value = tointeger(L, 3);
(*buffer)[index] = static_cast<ubyte>(value);
data[index] = static_cast<ubyte>(value);
return 0;
}
static int l_bytearray_meta_len(lua::State* L) {
if (auto buffer = touserdata<Bytearray>(L, 1)) {
return pushinteger(L, buffer->size());
return pushinteger(L, buffer->data().size());
}
return 0;
}
static int l_bytearray_meta_tostring(lua::State* L) {
auto& buffer = *touserdata<Bytearray>(L, 1);
if (buffer.size() > 512) {
return pushstring(L, "bytearray["+std::to_string(buffer.size())+"]{...}");
auto buffer = touserdata<Bytearray>(L, 1);
if (buffer == nullptr) {
return 0;
}
auto& data = buffer->data();
if (data.size() > 512) {
return pushstring(L, "bytearray["+std::to_string(data.size())+"]{...}");
} else {
std::stringstream ss;
ss << "bytearray[" << std::to_string(buffer.size()) << "]{";
for (size_t i = 0; i < buffer.size(); i++) {
ss << "bytearray[" << std::to_string(data.size()) << "]{";
for (size_t i = 0; i < data.size(); i++) {
if (i > 0) {
ss << " ";
}
ss << static_cast<uint>(buffer[i]);
ss << static_cast<uint>(data[i]);
}
ss << "}";
return pushstring(L, ss.str());

View File

@ -19,21 +19,12 @@ namespace lua {
Bytearray(size_t capacity);
Bytearray(std::vector<ubyte> buffer);
virtual ~Bytearray();
inline ubyte& operator[](size_t index) {
return buffer[index];
}
const std::string& getTypeName() const override {
return TYPENAME;
}
inline size_t size() const {
return buffer.size();
}
inline void append(ubyte b) {
buffer.push_back(b);
inline std::vector<ubyte>& data() {
return buffer;
}
static int createMetatable(lua::State*);