blueloveTH 2 лет назад
Родитель
Сommit
4ccf4d304b
6 измененных файлов с 43 добавлено и 30 удалено
  1. 3 4
      src/ceval.h
  2. 15 15
      src/io.h
  3. 15 3
      src/obj.h
  4. 6 4
      src/pocketpy.h
  5. 3 3
      src/str.h
  6. 1 1
      src/vm.h

+ 3 - 4
src/ceval.h

@@ -441,10 +441,9 @@ __NEXT_STEP:;
             Str source;
             auto it = _lazy_modules.find(name);
             if(it == _lazy_modules.end()){
-                bool ok = false;
-                Bytes b = _read_file_cwd(fmt(name, ".py"), &ok);
-                source = Str(b._data);
-                if(!ok) _error("ImportError", fmt("module ", name.escape(), " not found"));
+                Bytes b = _read_file_cwd(fmt(name, ".py"));
+                if(!b) _error("ImportError", fmt("module ", name.escape(), " not found"));
+                source = Str(b.str());
             }else{
                 source = it->second;
                 _lazy_modules.erase(it);

+ 15 - 15
src/io.h

@@ -11,18 +11,14 @@
 
 namespace pkpy{
 
-inline Bytes _read_file_cwd(const Str& name, bool* ok){
+inline Bytes _read_file_cwd(const Str& name){
     std::filesystem::path path(name.sv());
     bool exists = std::filesystem::exists(path);
-    if(!exists){
-        *ok = false;
-        return Bytes();
-    }
+    if(!exists) return Bytes();
     std::ifstream ifs(path);
-    std::string buffer((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
+    std::vector<char> buffer(std::istreambuf_iterator<char>(ifs), {});
     ifs.close();
-    *ok = true;
-    return Bytes({std::move(buffer)});
+    return Bytes(std::move(buffer));
 }
 
 struct FileIO {
@@ -56,10 +52,15 @@ struct FileIO {
 
         vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){
             FileIO& io = CAST(FileIO&, args[0]);
-            Bytes buffer;
-            io._fs >> buffer._data;
-            if(io.is_text()) return VAR(Str(buffer._data));
-            return VAR(buffer);
+            std::vector<char> buffer;
+            while(true){
+                char c = io._fs.get();
+                if(io._fs.eof()) break;
+                buffer.push_back(c);
+            }
+            Bytes b(std::move(buffer));
+            if(io.is_text()) return VAR(Str(b.str()));
+            return VAR(std::move(b));
         });
 
         vm->bind_method<1>(type, "write", [](VM* vm, ArgsView args){
@@ -67,7 +68,7 @@ struct FileIO {
             if(io.is_text()) io._fs << CAST(Str&, args[1]);
             else{
                 Bytes& buffer = CAST(Bytes&, args[1]);
-                io._fs << buffer._data;
+                io._fs.write(buffer.data(), buffer.size());
             }
             return vm->None;
         });
@@ -175,8 +176,7 @@ namespace pkpy{
 inline void add_module_io(VM* vm){}
 inline void add_module_os(VM* vm){}
 
-inline Bytes _read_file_cwd(const Str& name, bool* ok){
-    *ok = false;
+inline Bytes _read_file_cwd(const Str& name){
     return Bytes();
 }
 

+ 15 - 3
src/obj.h

@@ -58,13 +58,25 @@ struct Range {
 };
 
 struct Bytes{
-    std::string _data;
+    std::vector<char> _data;
+    bool _ok;
 
     int size() const noexcept { return _data.size(); }
     int operator[](int i) const noexcept { return (int)(uint8_t)_data[i]; }
+    const char* data() const noexcept { return _data.data(); }
 
-    bool operator==(const Bytes& rhs) const noexcept { return _data == rhs._data; }
-    bool operator!=(const Bytes& rhs) const noexcept { return _data != rhs._data; }
+    bool operator==(const Bytes& rhs) const noexcept {
+        return _data == rhs._data;
+    }
+    bool operator!=(const Bytes& rhs) const noexcept {
+        return _data != rhs._data;
+    }
+
+    std::string str() const noexcept { return std::string(_data.begin(), _data.end()); }
+
+    Bytes() : _data(), _ok(false) {}
+    Bytes(std::vector<char>&& data) : _data(std::move(data)), _ok(true) {}
+    operator bool() const noexcept { return _ok; }
 };
 
 using Super = std::pair<PyObject*, Type>;

+ 6 - 4
src/pocketpy.h

@@ -343,8 +343,8 @@ inline void init_builtins(VM* _vm) {
     _vm->bind_method<0>("str", "__iter__", CPP_LAMBDA(vm->PyIter(StringIter(vm, args[0]))));
 
     _vm->bind_method<0>("str", "__repr__", [](VM* vm, ArgsView args) {
-        const Str& _self = CAST(Str&, args[0]);
-        return VAR(_self.escape());
+        const Str& self = CAST(Str&, args[0]);
+        return VAR(self.escape());
     });
 
     _vm->bind_method<0>("str", "__json__", [](VM* vm, ArgsView args) {
@@ -414,7 +414,9 @@ inline void init_builtins(VM* _vm) {
 
     _vm->bind_method<0>("str", "encode", [](VM* vm, ArgsView args) {
         const Str& self = CAST(Str&, args[0]);
-        return VAR(Bytes{self.str()});
+        std::vector<char> buffer(self.length());
+        memcpy(buffer.data(), self.data, self.length());
+        return VAR(Bytes(std::move(buffer)));
     });
 
     _vm->bind_method<1>("str", "join", [](VM* vm, ArgsView args) {
@@ -606,7 +608,7 @@ inline void init_builtins(VM* _vm) {
     _vm->bind_method<0>("bytes", "decode", [](VM* vm, ArgsView args) {
         const Bytes& self = CAST(Bytes&, args[0]);
         // TODO: check encoding is utf-8
-        return VAR(Str(self._data));
+        return VAR(Str(self.str()));
     });
 
     _vm->bind_method<1>("bytes", "__eq__", [](VM* vm, ArgsView args) {

+ 3 - 3
src/str.h

@@ -207,10 +207,10 @@ struct Str{
                 case '\r': ss << "\\r"; break;
                 case '\t': ss << "\\t"; break;
                 default:
-                    if (c >= 32 && c <= 126) {
-                        ss << c;
+                    if ('\x00' <= c && c <= '\x1f') {
+                        ss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << (int)c;
                     } else {
-                        ss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << (int)(uint8_t)c;
+                        ss << c;
                     }
             }
         }

+ 1 - 1
src/vm.h

@@ -24,7 +24,7 @@ namespace pkpy{
 #define POPX()            (s_data.popx())
 #define STACK_VIEW(n)     (s_data.view(n))
 
-Bytes _read_file_cwd(const Str& name, bool* ok);
+Bytes _read_file_cwd(const Str& name);
 
 #define DEF_NATIVE_2(ctype, ptype)                                      \
     template<> inline ctype py_cast<ctype>(VM* vm, PyObject* obj) {     \