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) { static int l_bytearray_append(lua::State* L) {
if (auto buffer = touserdata<Bytearray>(L, 1)) { if (auto buffer = touserdata<Bytearray>(L, 1)) {
auto value = tointeger(L, 2); auto value = tointeger(L, 2);
buffer->append(static_cast<ubyte>(value)); buffer->data().push_back(static_cast<ubyte>(value));
} }
return 0; 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) { 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); auto size = tointeger(L, 2);
if (size < 0) { if (size < 0) {
throw std::runtime_error("size can not be less than 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) { static int l_bytearray_meta_index(lua::State* L) {
auto buffer = touserdata<Bytearray>(L, 1); auto buffer = touserdata<Bytearray>(L, 1);
if (buffer == nullptr) {
return 0;
}
auto& data = buffer->data();
if (isstring(L, 2)) { if (isstring(L, 2)) {
std::string member = tostring(L, 2); auto found = bytearray_methods.find(tostring(L, 2));
if (member == "append") { if (found != bytearray_methods.end()) {
return pushcfunction(L, l_bytearray_append); return pushcfunction(L, found->second);
} }
} }
auto index = tointeger(L, 2)-1; 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 0;
} }
return pushinteger(L, (*buffer)[index]); return pushinteger(L, data[index]);
} }
static int l_bytearray_meta_newindex(lua::State* L) { static int l_bytearray_meta_newindex(lua::State* L) {
auto buffer = touserdata<Bytearray>(L, 1); auto buffer = touserdata<Bytearray>(L, 1);
if (buffer == nullptr) {
return 0;
}
auto& data = buffer->data();
auto index = tointeger(L, 2)-1; 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 0;
} }
auto value = tointeger(L, 3); auto value = tointeger(L, 3);
(*buffer)[index] = static_cast<ubyte>(value); data[index] = static_cast<ubyte>(value);
return 0; return 0;
} }
static int l_bytearray_meta_len(lua::State* L) { static int l_bytearray_meta_len(lua::State* L) {
if (auto buffer = touserdata<Bytearray>(L, 1)) { if (auto buffer = touserdata<Bytearray>(L, 1)) {
return pushinteger(L, buffer->size()); return pushinteger(L, buffer->data().size());
} }
return 0; return 0;
} }
static int l_bytearray_meta_tostring(lua::State* L) { static int l_bytearray_meta_tostring(lua::State* L) {
auto& buffer = *touserdata<Bytearray>(L, 1); auto buffer = touserdata<Bytearray>(L, 1);
if (buffer.size() > 512) { if (buffer == nullptr) {
return pushstring(L, "bytearray["+std::to_string(buffer.size())+"]{...}"); return 0;
}
auto& data = buffer->data();
if (data.size() > 512) {
return pushstring(L, "bytearray["+std::to_string(data.size())+"]{...}");
} else { } else {
std::stringstream ss; std::stringstream ss;
ss << "bytearray[" << std::to_string(buffer.size()) << "]{"; ss << "bytearray[" << std::to_string(data.size()) << "]{";
for (size_t i = 0; i < buffer.size(); i++) { for (size_t i = 0; i < data.size(); i++) {
if (i > 0) { if (i > 0) {
ss << " "; ss << " ";
} }
ss << static_cast<uint>(buffer[i]); ss << static_cast<uint>(data[i]);
} }
ss << "}"; ss << "}";
return pushstring(L, ss.str()); return pushstring(L, ss.str());

View File

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