reimpl bytes

This commit is contained in:
blueloveTH 2023-10-02 03:05:21 +08:00
parent fb5e57b98b
commit 724f693761
5 changed files with 77 additions and 48 deletions

View File

@ -48,43 +48,74 @@ struct StarWrapper{
};
struct Bytes{
std::vector<char> _v;
bool valid;
unsigned char* _data;
int _size;
int size() const noexcept { return (int)_v.size(); }
int operator[](int i) const noexcept { return (int)(uint8_t)_v[i]; }
const char* data() const noexcept { return _v.data(); }
int size() const noexcept { return _size; }
int operator[](int i) const noexcept { return (int)_data[i]; }
const unsigned char* data() const noexcept { return _data; }
bool operator==(const Bytes& rhs) const{ return _v == rhs._v && valid == rhs.valid; }
bool operator!=(const Bytes& rhs) const{ return _v != rhs._v || valid != rhs.valid; }
bool operator==(const Bytes& rhs) const{
if(_size != rhs._size) return false;
for(int i=0; i<_size; i++) if(_data[i] != rhs._data[i]) return false;
return true;
}
bool operator!=(const Bytes& rhs) const{ return !(*this == rhs); }
Str str() const noexcept { return Str(_v.data(), _v.size()); }
std::string_view sv() const noexcept { return std::string_view(_v.data(), _v.size()); }
Str str() const noexcept { return Str((char*)_data, _size); }
std::string_view sv() const noexcept { return std::string_view((char*)_data, _size); }
Bytes() : valid(false) {}
Bytes(std::vector<char>&& v): _v(std::move(v)), valid(true) {}
Bytes(std::string_view sv): valid(true) {
_v.resize(sv.size());
for(int i=0; i<sv.size(); i++) _v[i] = sv[i];
Bytes() : _data(nullptr), _size(0) {}
Bytes(unsigned char* p, int size): _data(p), _size(size) {}
Bytes(const std::vector<unsigned char>& v){
_data = new unsigned char[v.size()];
_size = v.size();
for(int i=0; i<_size; i++) _data[i] = v[i];
}
Bytes(std::string_view sv){
_data = new unsigned char[sv.size()];
_size = sv.size();
for(int i=0; i<_size; i++) _data[i] = sv[i];
}
Bytes(const Str& str): Bytes(str.sv()) {}
operator bool() const noexcept { return valid; }
operator bool() const noexcept { return _data != nullptr; }
// copy constructor
Bytes(const Bytes& rhs) : _v(rhs._v), valid(rhs.valid) {}
Bytes(const Bytes& rhs){
_data = new unsigned char[rhs._size];
_size = rhs._size;
for(int i=0; i<_size; i++) _data[i] = rhs._data[i];
}
// move constructor
Bytes(Bytes&& rhs) noexcept : _v(std::move(rhs._v)), valid(rhs.valid) {
rhs.valid = false;
Bytes(Bytes&& rhs) noexcept {
_data = rhs._data;
_size = rhs._size;
rhs._data = nullptr;
rhs._size = 0;
}
Bytes& operator=(Bytes&& rhs) noexcept {
_v = std::move(rhs._v);
valid = rhs.valid;
rhs.valid = false;
delete[] _data;
_data = rhs._data;
_size = rhs._size;
rhs._data = nullptr;
rhs._size = 0;
return *this;
}
std::pair<unsigned char*, int> detach() noexcept {
unsigned char* p = _data;
int size = _size;
_data = nullptr;
_size = 0;
return {p, size};
}
~Bytes(){
delete[] _data;
}
// delete copy assignment
Bytes& operator=(const Bytes& rhs) = delete;
};

View File

@ -171,19 +171,17 @@ void add_module_base64(VM* vm){
// b64encode
vm->bind_func<1>(mod, "b64encode", [](VM* vm, ArgsView args){
Bytes& b = CAST(Bytes&, args[0]);
std::vector<char> out(b.size() * 2);
int size = base64_encode((const unsigned char*)b.data(), b.size(), out.data());
out.resize(size);
return VAR(Bytes(std::move(out)));
unsigned char* p = new unsigned char[b.size() * 2];
int size = base64_encode((const unsigned char*)b.data(), b.size(), (char*)p);
return VAR(Bytes(p, size));
});
// b64decode
vm->bind_func<1>(mod, "b64decode", [](VM* vm, ArgsView args){
Bytes& b = CAST(Bytes&, args[0]);
std::vector<char> out(b.size());
int size = base64_decode(b.data(), b.size(), (unsigned char*)out.data());
out.resize(size);
return VAR(Bytes(std::move(out)));
unsigned char* p = new unsigned char[b.size()];
int size = base64_decode((const char*)b.data(), b.size(), p);
return VAR(Bytes(p, size));
});
}

View File

@ -248,9 +248,9 @@ __NEXT_STEP:;
} DISPATCH();
TARGET(BUILD_BYTES) {
const Str& s = CAST(Str&, TOP());
std::vector<char> buffer(s.size);
memcpy(buffer.data(), s.data, s.size);
TOP() = VAR(Bytes(std::move(buffer)));
unsigned char* p = new unsigned char[s.size];
memcpy(p, s.data, s.size);
TOP() = VAR(Bytes(p, s.size));
} DISPATCH();
TARGET(BUILD_TUPLE)
_0 = VAR(STACK_VIEW(byte.arg).to_tuple());

View File

@ -32,12 +32,13 @@ Bytes _default_import_handler(const Str& name){
FILE* fp = io_fopen(cname.c_str(), "rb");
if(!fp) return Bytes();
fseek(fp, 0, SEEK_END);
std::vector<char> buffer(ftell(fp));
int buffer_size = ftell(fp);
unsigned char* buffer = new unsigned char[buffer_size];
fseek(fp, 0, SEEK_SET);
size_t sz = io_fread(buffer.data(), 1, buffer.size(), fp);
size_t sz = io_fread(buffer, 1, buffer_size, fp);
PK_UNUSED(sz);
fclose(fp);
return Bytes(std::move(buffer));
return Bytes(buffer, buffer_size);
#else
return Bytes();
#endif
@ -55,14 +56,13 @@ Bytes _default_import_handler(const Str& name){
vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){
FileIO& io = CAST(FileIO&, args[0]);
fseek(io.fp, 0, SEEK_END);
std::vector<char> buffer(ftell(io.fp));
int buffer_size = ftell(io.fp);
unsigned char* buffer = new unsigned char[buffer_size];
fseek(io.fp, 0, SEEK_SET);
size_t sz = io_fread(buffer.data(), 1, buffer.size(), io.fp);
PK_ASSERT(sz <= buffer.size());
// in text mode, CR may be dropped, which may cause `sz < buffer.size()`
if(sz < buffer.size()) buffer.resize(sz);
PK_UNUSED(sz);
Bytes b(std::move(buffer));
size_t actual_size = io_fread(buffer, 1, buffer_size, io.fp);
PK_ASSERT(actual_size <= buffer_size);
// in text mode, CR may be dropped, which may cause `actual_size < buffer_size`
Bytes b(buffer, actual_size);
if(io.is_text()) return VAR(b.str());
return VAR(std::move(b));
});

View File

@ -653,9 +653,9 @@ void init_builtins(VM* _vm) {
_vm->bind_method<0>("str", "encode", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
std::vector<char> buffer(self.length());
memcpy(buffer.data(), self.data, self.length());
return VAR(Bytes(std::move(buffer)));
unsigned char* buffer = new unsigned char[self.length()];
memcpy(buffer, self.data, self.length());
return VAR(Bytes(buffer, self.length()));
});
_vm->bind_method<1>("str", "join", [](VM* vm, ArgsView args) {
@ -1027,13 +1027,13 @@ void init_builtins(VM* _vm) {
/************ bytes ************/
_vm->bind_constructor<2>("bytes", [](VM* vm, ArgsView args){
List& list = CAST(List&, args[1]);
std::vector<char> buffer(list.size());
std::vector<unsigned char> buffer(list.size());
for(int i=0; i<list.size(); i++){
i64 b = CAST(i64, list[i]);
if(b<0 || b>255) vm->ValueError("byte must be in range[0, 256)");
buffer[i] = (char)b;
}
return VAR(Bytes(std::move(buffer)));
return VAR(Bytes(buffer));
});
_vm->bind__getitem__(_vm->tp_bytes, [](VM* vm, PyObject* obj, PyObject* index) {
@ -1045,7 +1045,7 @@ void init_builtins(VM* _vm) {
_vm->bind__hash__(_vm->tp_bytes, [](VM* vm, PyObject* obj) {
const Bytes& self = _CAST(Bytes&, obj);
std::string_view view(self.data(), self.size());
std::string_view view((char*)self.data(), self.size());
return (i64)std::hash<std::string_view>()(view);
});