From b92db28bba6495dd8caef5c97d30c4252f737ccd Mon Sep 17 00:00:00 2001 From: Mike Nolan Date: Mon, 29 Sep 2025 03:03:46 -0500 Subject: [PATCH] use shared ptrs for stream, vfs and ihttpserver and add progress --- Packaging/CPKG/ConsoleOrServer/main.cpp | 10 +- include/CrossLang.hpp | 114 +- src/archive.cpp | 32 +- src/assembler/asm.cpp | 31 +- src/assembler/disasm.cpp | 14 +- src/assembler/merge.cpp | 20 +- src/compiler/codegen.cpp | 17 +- src/compiler/parser.cpp | 8 +- src/crossarchivecreate.cpp | 11 +- src/crossarchiveextract.cpp | 7 +- src/crossasmcli.cpp | 4 +- src/crossdisasmcli.cpp | 10 +- src/crosslang.cpp | 29 +- src/crosslangcompiler.cpp | 9 +- src/crosslanginterperter.cpp | 29 +- src/crosslangvm.cpp | 4 +- src/crossmergecli.cpp | 10 +- src/crossthumbnailer.cpp | 19 +- src/runtime_methods/console.cpp | 84 +- src/runtime_methods/crypto.cpp | 18 +- src/runtime_methods/helpers.cpp | 54 + src/runtime_methods/io.cpp | 60 +- src/runtime_methods/net.cpp | 269 ++-- src/runtime_methods/process.cpp | 6 +- src/runtime_methods/std.cpp | 132 +- src/runtime_methods/vm.cpp | 38 +- src/types/rootenvironment.cpp | 26 +- src/types/streamheapobject.cpp | 93 +- src/types/vfsheapobject.cpp | 186 +-- src/vm/filereader.cpp | 12 +- src/vm/vm.cpp | 1531 +++++++++++------------ 31 files changed, 1394 insertions(+), 1493 deletions(-) create mode 100644 src/runtime_methods/helpers.cpp diff --git a/Packaging/CPKG/ConsoleOrServer/main.cpp b/Packaging/CPKG/ConsoleOrServer/main.cpp index ef46e47..738ea7d 100644 --- a/Packaging/CPKG/ConsoleOrServer/main.cpp +++ b/Packaging/CPKG/ConsoleOrServer/main.cpp @@ -4,8 +4,7 @@ using namespace Tesses::CrossLang; int main(int argc, char** argv) { std::string name = argv[0]; - Tesses::Framework::Filesystem::LocalFilesystem fs; - Tesses::Framework::Filesystem::VFSPath exePath=fs.SystemToVFSPath(name); + Tesses::Framework::Filesystem::VFSPath exePath=Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(name); exePath.MakeAbsolute(); exePath.ChangeExtension(".crvm"); @@ -18,7 +17,7 @@ int main(int argc, char** argv) TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); TStd::RegisterStd(&gc,env); - env->LoadFileWithDependencies(&gc, &fs, exePath); + env->LoadFileWithDependencies(&gc, Tesses::Framework::Filesystem::LocalFS, exePath); @@ -41,8 +40,9 @@ int main(int argc, char** argv) } auto res = env->CallFunction(ls, "WebAppMain", {args2}); - TObjectHttpServer http(&gc, res); - Tesses::Framework::Http::HttpServer svr(port,http,false); + auto svr2 = Tesses::CrossLang::ToHttpServer(&gc,res); + if(svr2 == nullptr) return 1; + Tesses::Framework::Http::HttpServer svr(port,svr2); svr.StartAccepting(); TF_RunEventLoop(); TF_Quit(); diff --git a/include/CrossLang.hpp b/include/CrossLang.hpp index 32192b3..d9dc154 100644 --- a/include/CrossLang.hpp +++ b/include/CrossLang.hpp @@ -489,7 +489,7 @@ namespace Tesses::CrossLang { * @param info the crvm info * @param icon the crvm icon */ - void CrossArchiveCreate(Tesses::Framework::Filesystem::VFS* vfs,Tesses::Framework::Streams::Stream* strm,std::string name,TVMVersion version,std::string info, std::string icon=""); + void CrossArchiveCreate(std::shared_ptr vfs,std::shared_ptr strm,std::string name,TVMVersion version,std::string info, std::string icon=""); /** * @brief * @@ -497,7 +497,7 @@ namespace Tesses::CrossLang { * @param vfs vfs to extract to (as root) * @return std::pair,std::string> ((name, version),info) */ - std::pair,std::string> CrossArchiveExtract(Tesses::Framework::Streams::Stream* strm,Tesses::Framework::Filesystem::VFS* vfs); + std::pair,std::string> CrossArchiveExtract(std::shared_ptr strm,std::shared_ptr vfs); @@ -800,7 +800,7 @@ class CharInstruction : public ByteCodeInstruction { void Write(std::vector& data); }; -using SyntaxNode = std::variant, AdvancedSyntaxNode>; +using SyntaxNode = std::variant, AdvancedSyntaxNode,std::shared_ptr,std::shared_ptr>; @@ -821,21 +821,21 @@ struct CodeGenClass { class ResourceBase { public: - virtual uint32_t GetLength(Tesses::Framework::Filesystem::VFS* embedFS)=0; - virtual void Write(Tesses::Framework::Streams::Stream* output)=0; + virtual uint32_t GetLength(std::shared_ptr embedFS)=0; + virtual void Write(std::shared_ptr output)=0; virtual ~ResourceBase(); virtual bool IsEqual(ResourceBase* base); }; class ResourceFile : public ResourceBase { - Tesses::Framework::Streams::Stream* strm=nullptr; + std::shared_ptr strm=nullptr; public: ResourceFile(); ResourceFile(std::string file); std::string file; - uint32_t GetLength(Tesses::Framework::Filesystem::VFS* embedFS); - void Write(Tesses::Framework::Streams::Stream* output); + uint32_t GetLength(std::shared_ptr embedFS); + void Write(std::shared_ptr output); bool IsEqual(ResourceBase* base); ~ResourceFile(); }; @@ -844,8 +844,8 @@ class ResourceByteArray : public ResourceBase { public: std::vector data; - uint32_t GetLength(Tesses::Framework::Filesystem::VFS* embedFS); - void Write(Tesses::Framework::Streams::Stream* output); + uint32_t GetLength(std::shared_ptr embedFS); + void Write(std::shared_ptr output); }; @@ -878,7 +878,7 @@ class CodeGen { std::string info; std::string icon; void GenRoot(SyntaxNode n); - void Save(Tesses::Framework::Filesystem::VFS* embedFS,Tesses::Framework::Streams::Stream* output); + void Save(std::shared_ptr embedFS,std::shared_ptr output); ~CodeGen(); }; /** @@ -1395,7 +1395,7 @@ class TContinue { * */ -using TObject = std::variant; +using TObject = std::variant,std::shared_ptr,std::shared_ptr,std::shared_ptr,std::shared_ptr,std::shared_ptr>; class TRootEnvironment; class GC; @@ -1533,13 +1533,13 @@ class GC { std::string info; int32_t icon; - void Load(GC* gc, Tesses::Framework::Streams::Stream* strm); - void Skip(Tesses::Framework::Streams::Stream* strm,size_t len); - void Ensure(Tesses::Framework::Streams::Stream* strm,uint8_t* buffer, size_t len); - uint32_t EnsureInt(Tesses::Framework::Streams::Stream* strm); - std::string EnsureString(Tesses::Framework::Streams::Stream* strm); + void Load(GC* gc, std::shared_ptr strm); + void Skip(std::shared_ptr strm,size_t len); + void Ensure(std::shared_ptr strm,uint8_t* buffer, size_t len); + uint32_t EnsureInt(std::shared_ptr strm); + std::string EnsureString(std::shared_ptr strm); - std::string GetString(Tesses::Framework::Streams::Stream* strm); + std::string GetString(std::shared_ptr strm); void Mark(); void EnsureCanRunInCrossLang(); @@ -1781,7 +1781,7 @@ class GC { TDictionary* dict; TCallable* error=nullptr; - void LoadDependency(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, std::pair dep); + void LoadDependency(GC* gc,std::shared_ptr vfs, std::pair dep); public: EnvironmentPermissions permissions; @@ -1790,8 +1790,8 @@ class GC { bool TryFindClass(std::vector& name, size_t& index); - void LoadFileWithDependencies(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, TFile* f); - void LoadFileWithDependencies(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path); + void LoadFileWithDependencies(GC* gc,std::shared_ptr vfs, TFile* f); + void LoadFileWithDependencies(GC* gc,std::shared_ptr vfs, Tesses::Framework::Filesystem::VFSPath path); TDictionary* GetDictionary(); static TRootEnvironment* Create(GCList* gc,TDictionary* dict); @@ -1815,6 +1815,8 @@ class GC { void Mark(); }; class TStd { + private: + static void RegisterHelpers(GC* gc, TRootEnvironment* env); public: static void RegisterStd(GC* gc, TRootEnvironment* env); static void RegisterConsole(GC* gc,TRootEnvironment* env); @@ -1990,69 +1992,14 @@ class GC { }; - class TStreamHeapObject : public THeapObject - { - public: - Tesses::Framework::Streams::Stream* stream; - std::vector watch; - - static TStreamHeapObject* Create(GCList& ls, Tesses::Framework::Streams::Stream* strm); - static TStreamHeapObject* Create(GCList* ls, Tesses::Framework::Streams::Stream* strm); - ~TStreamHeapObject(); - void Close(); - void Mark() - { - if(this->marked) return; - this->marked=true; - for(auto item : watch) - GC::Mark(item); - } - }; - - class TVFSHeapObject : public THeapObject - { - public: - Tesses::Framework::Filesystem::VFS* vfs; - std::vector watch; - static TVFSHeapObject* Create(GCList& ls, Tesses::Framework::Filesystem::VFS* vfs); - static TVFSHeapObject* Create(GCList* ls, Tesses::Framework::Filesystem::VFS* vfs); - ~TVFSHeapObject(); - void Close(); - - void Mark() - { - if(this->marked) return; - this->marked=true; - for(auto item : watch) - GC::Mark(item); - } - }; - - class TServerHeapObject : public THeapObject - { - public: - Tesses::Framework::Http::IHttpServer* server; - std::vector watch; - static TServerHeapObject* Create(GCList& ls, Tesses::Framework::Http::IHttpServer* vfs); - static TServerHeapObject* Create(GCList* ls, Tesses::Framework::Http::IHttpServer* vfs); - ~TServerHeapObject(); - void Close(); - bool Handle(std::vector args); - void Mark() - { - if(this->marked) return; - this->marked=true; - for(auto item : watch) - GC::Mark(item); - } - }; + class TObjectVFS : public Tesses::Framework::Filesystem::VFS { public: TObject obj; GCList* ls; TObjectVFS(GC* gc, TObject obj); - Tesses::Framework::Streams::Stream* OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode); + std::shared_ptr OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode); void CreateDirectory(Tesses::Framework::Filesystem::VFSPath path); void DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path); bool RegularFileExists(Tesses::Framework::Filesystem::VFSPath path); @@ -2187,7 +2134,7 @@ class GC { }; - class CallStackEntry : public THeapObject + class CallStackEntry : public THeapObject { public: static CallStackEntry* Create(GCList* ls); @@ -2554,7 +2501,10 @@ class GC { extern Tesses::Framework::Filesystem::VFSPath CrossLangConfigPath; - Tesses::Framework::Filesystem::VFSPath Assemble(Tesses::Framework::Filesystem::VFS* vfs); - void Disassemble(Tesses::Framework::Streams::Stream* src,Tesses::Framework::Filesystem::VFS* vfs, bool generateJSON=true,bool extractResources=true); - Tesses::Framework::Filesystem::VFSPath Merge(Tesses::Framework::Filesystem::VFS* srcFS, Tesses::Framework::Filesystem::VFSPath sourcePath, Tesses::Framework::Filesystem::VFS* destFS); + Tesses::Framework::Filesystem::VFSPath Assemble(std::shared_ptr vfs); + void Disassemble(std::shared_ptr src,std::shared_ptr vfs, bool generateJSON=true,bool extractResources=true); + Tesses::Framework::Filesystem::VFSPath Merge(std::shared_ptr srcFS, Tesses::Framework::Filesystem::VFSPath sourcePath, std::shared_ptr destFS); + + + std::shared_ptr ToHttpServer(GC* gc,TObject obj); }; diff --git a/src/archive.cpp b/src/archive.cpp index 0fc79a2..82386bd 100644 --- a/src/archive.cpp +++ b/src/archive.cpp @@ -3,7 +3,7 @@ namespace Tesses::CrossLang { - void CrossArchiveCreate(Tesses::Framework::Filesystem::VFS* vfs,Tesses::Framework::Streams::Stream* strm,std::string name, TVMVersion version, std::string info, std::string icon) + void CrossArchiveCreate(std::shared_ptr vfs,std::shared_ptr strm,std::string name, TVMVersion version, std::string info, std::string icon) { std::vector ignored_files; std::string file = "/.crossarchiveignore"; @@ -12,7 +12,7 @@ namespace Tesses::CrossLang auto strm = vfs->OpenFile(file,"rb"); if(strm != nullptr) { - Tesses::Framework::TextStreams::StreamReader reader(strm,true); + Tesses::Framework::TextStreams::StreamReader reader(strm); std::string ignores; while(reader.ReadLine(ignores)) { @@ -53,12 +53,12 @@ namespace Tesses::CrossLang CALLMETHOD, RET }; - auto writeInt = [](Tesses::Framework::Streams::Stream* strm,uint32_t number)->void{ + auto writeInt = [](std::shared_ptr strm,uint32_t number)->void{ uint8_t buff[4]; BitConverter::FromUint32BE(buff[0],number); strm->WriteBlock(buff,4); }; - auto writeStr = [&writeInt](Tesses::Framework::Streams::Stream* strm,std::string text)->void { + auto writeStr = [&writeInt](std::shared_ptr strm,std::string text)->void { writeInt(strm,(uint32_t)text.size()); strm->WriteBlock((const uint8_t*)text.c_str(),text.size()); }; @@ -90,14 +90,14 @@ namespace Tesses::CrossLang strs.push_back(str); return index; }; - Tesses::Framework::Streams::MemoryStream ms(true); + auto ms = std::make_shared(true); std::function walkFS = [&ignored_files,vfs,&ensureString,&ensureResource,&ms,&walkFS,&writeInt](Tesses::Framework::Filesystem::VFSPath path)->void { if(vfs->DirectoryExists(path)) { - ms.WriteByte(1); + ms->WriteByte(1); std::vector paths; for(auto item : vfs->EnumeratePaths(path)) { @@ -110,17 +110,17 @@ namespace Tesses::CrossLang if(vfs->DirectoryExists(item) || vfs->RegularFileExists(item)) paths.push_back(item.GetFileName()); } - writeInt(&ms,(uint32_t)paths.size()); + writeInt(ms,(uint32_t)paths.size()); for(auto item : paths) { - writeInt(&ms,ensureString(item)); + writeInt(ms,ensureString(item)); walkFS(path / item); } } else if(vfs->RegularFileExists(path)) { - ms.WriteByte(0); - writeInt(&ms,ensureResource(path.ToString())); + ms->WriteByte(0); + writeInt(ms,ensureResource(path.ToString())); } }; @@ -166,14 +166,14 @@ namespace Tesses::CrossLang auto strm2 = vfs->OpenFile(res,"rb"); writeInt(strm,(uint32_t)strm2->GetLength()); strm2->CopyTo(strm); - delete strm2; + } strm->WriteBlock((const uint8_t*)"ARCV",4); - writeInt(strm,(uint32_t)ms.GetLength()); - ms.Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); - ms.CopyTo(strm); + writeInt(strm,(uint32_t)ms->GetLength()); + ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); + ms->CopyTo(strm); } - std::pair,std::string> CrossArchiveExtract(Tesses::Framework::Streams::Stream* strm,Tesses::Framework::Filesystem::VFS* vfs) + std::pair,std::string> CrossArchiveExtract(std::shared_ptr strm,std::shared_ptr vfs) { auto ensure = [strm](uint8_t* buffer,size_t count)->void{ @@ -252,7 +252,7 @@ namespace Tesses::CrossLang strm2->WriteBlock(buff,read); offset+=read; } while(read > 0); - delete strm2; + resource_id++; } diff --git a/src/assembler/asm.cpp b/src/assembler/asm.cpp index 30bfe17..ab17e88 100644 --- a/src/assembler/asm.cpp +++ b/src/assembler/asm.cpp @@ -723,22 +723,22 @@ namespace Tesses::CrossLang { class CodeGen2 { public: - void Write(Tesses::Framework::Streams::Stream* strm, uint8_t* buffer, size_t len) + void Write(std::shared_ptr strm, uint8_t* buffer, size_t len) { strm->WriteBlock(buffer,len); } - void WriteInt(Tesses::Framework::Streams::Stream* strm,uint32_t v) + void WriteInt(std::shared_ptr strm,uint32_t v) { uint8_t buffer[4]; BitConverter::FromUint32BE(buffer[0],v); Write(strm,buffer,4); } - void WriteString(Tesses::Framework::Streams::Stream* strm,std::string v) + void WriteString(std::shared_ptr strm,std::string v) { WriteInt(strm,(uint32_t)v.size()); Write(strm,(uint8_t*)v.data(),v.size()); } - void Save(Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Streams::Stream* stream) + void Save(std::shared_ptr vfs, std::shared_ptr stream) { TVMVersion runtime_version(TVM_MAJOR,TVM_MINOR,TVM_PATCH,TVM_BUILD,TVM_VERSIONSTAGE); @@ -941,7 +941,6 @@ namespace Tesses::CrossLang { strm->CopyTo(stream); } - delete strm; } if(!this->icon.empty()) { @@ -1085,7 +1084,7 @@ namespace Tesses::CrossLang { - Tesses::Framework::Filesystem::VFSPath Assemble(Tesses::Framework::Filesystem::VFS* vfs) + Tesses::Framework::Filesystem::VFSPath Assemble(std::shared_ptr vfs) { using namespace Tesses::Framework::Filesystem; using namespace Tesses::Framework::TextStreams; @@ -1104,7 +1103,7 @@ namespace Tesses::CrossLang { else { if(item.GetExtension() == ".tcasm") { - StreamReader reader(vfs->OpenFile(item,"rb"),true); + StreamReader reader(vfs->OpenFile(item,"rb")); std::stringstream strm(reader.ReadToEnd(),std::ios_base::binary | std::ios_base::in); Lex(item.ToString(), strm, tokens); @@ -1124,7 +1123,7 @@ namespace Tesses::CrossLang { auto confFile = VFSPath() / "crossapp.json"; if(vfs->FileExists(confFile)) { - Tesses::Framework::TextStreams::StreamReader reader(vfs->OpenFile(confFile,"rb"),true); + Tesses::Framework::TextStreams::StreamReader reader(vfs->OpenFile(confFile,"rb")); auto jobj = Json::Decode(reader.ReadToEnd()); JObject main; if(TryGetJToken(jobj,main)) @@ -1249,14 +1248,14 @@ namespace Tesses::CrossLang { vfs->CreateDirectory(VFSPath() / "bin"); vfs->CreateDirectory(VFSPath() / "sections"); - SubdirFilesystem sectionsdir(vfs,VFSPath() / "sections",false); - SubdirFilesystem resdir(vfs,VFSPath() / "res",false); + auto sectionsdir = std::make_shared(vfs,VFSPath() / "sections"); + auto resdir = std::make_shared(vfs,VFSPath() / "res"); - for(auto file : sectionsdir.EnumeratePaths(VFSPath())) + for(auto file : sectionsdir->EnumeratePaths(VFSPath())) { - if(file.GetExtension() == ".tsec" && sectionsdir.FileExists(file)) + if(file.GetExtension() == ".tsec" && sectionsdir->FileExists(file)) { - auto strm0 = sectionsdir.OpenFile(file,"rb"); + auto strm0 = sectionsdir->OpenFile(file,"rb"); int64_t len = strm0->GetLength(); if(len > 4) { @@ -1269,15 +1268,15 @@ namespace Tesses::CrossLang { strm0->ReadBlock(cg2.sections[off].second.data(), cg2.sections[off].second.size()); } - delete strm0; + } } auto strm = vfs->OpenFile(VFSPath() / "bin" / cg2.name + "-" + cg2.version.ToString() + ".crvm","wb"); - cg2.Save(&resdir, strm); - delete strm; + cg2.Save(resdir, strm); + return VFSPath() / "bin" / cg2.name + "-" + cg2.version.ToString() + ".crvm"; diff --git a/src/assembler/disasm.cpp b/src/assembler/disasm.cpp index 1577369..02280c6 100644 --- a/src/assembler/disasm.cpp +++ b/src/assembler/disasm.cpp @@ -2,7 +2,7 @@ namespace Tesses::CrossLang { class CrossLangFileReader { - Tesses::Framework::Streams::Stream* strm; + std::shared_ptr strm; void Ensure(uint8_t* buffer, size_t len) { @@ -34,7 +34,7 @@ namespace Tesses::CrossLang { } public: - CrossLangFileReader(Tesses::Framework::Streams::Stream* strm) + CrossLangFileReader(std::shared_ptr strm) { this->strm = strm; @@ -639,7 +639,7 @@ namespace Tesses::CrossLang { - void Disassemble(Tesses::Framework::Streams::Stream* src,Tesses::Framework::Filesystem::VFS* vfs, bool generateJSON,bool extractResources) + void Disassemble(std::shared_ptr src,std::shared_ptr vfs, bool generateJSON,bool extractResources) { using namespace Tesses::Framework::Filesystem; CrossLangFileReader file(src); @@ -653,7 +653,7 @@ namespace Tesses::CrossLang { auto path2 = path / file.name + "-" + file.version.ToString()+"_"+ std::to_string((uint32_t)i) + ".bin"; auto strm = vfs->OpenFile(path2,"wb"); strm->WriteBlock(file.resources[i].data(),file.resources[i].size()); - delete strm; + } std::string secdir = "sections"; @@ -670,7 +670,7 @@ namespace Tesses::CrossLang { auto strm = vfs->OpenFile(path2,"wb"); strm->WriteBlock((const uint8_t*)file.sections[i].first.data(), 4); strm->WriteBlock(file.sections[i].second.data(),file.sections[i].second.size()); - delete strm; + } } @@ -812,7 +812,7 @@ namespace Tesses::CrossLang { std::string srcdirs = "src"; VFSPath srcdir=srcdirs; vfs->CreateDirectory(srcdir); - Tesses::Framework::TextStreams::StreamWriter writer(vfs->OpenFile(srcdir / file.name + "-" + file.version.ToString() + ".tcasm","wb"),true); + Tesses::Framework::TextStreams::StreamWriter writer(vfs->OpenFile(srcdir / file.name + "-" + file.version.ToString() + ".tcasm","wb")); writer.Write(srcFile); if(generateJSON) @@ -889,7 +889,7 @@ namespace Tesses::CrossLang { } - Tesses::Framework::TextStreams::StreamWriter json_writer(vfs->OpenFile(VFSPath() / "crossapp.json","wb" ),true); + Tesses::Framework::TextStreams::StreamWriter json_writer(vfs->OpenFile(VFSPath() / "crossapp.json","wb" )); json_writer.WriteLine(Json::Encode(json_data,true)); } diff --git a/src/assembler/merge.cpp b/src/assembler/merge.cpp index 9ccf5de..62803f1 100644 --- a/src/assembler/merge.cpp +++ b/src/assembler/merge.cpp @@ -1,9 +1,9 @@ #include "CrossLang.hpp" using namespace Tesses::Framework::Serialization::Json; namespace Tesses::CrossLang { - static void LoadDependency(Tesses::Framework::Filesystem::VFS* srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir, std::pair dep, std::vector>& files, std::vector>& tools); - static void LoadDependencies(Tesses::Framework::Filesystem::VFS* srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,TFile* file, std::vector>& files, std::vector>& tools); - static void LoadDependency(Tesses::Framework::Filesystem::VFS* srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir, std::pair dep, std::vector>& files, std::vector>& tools) + static void LoadDependency(std::shared_ptr srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir, std::pair dep, std::vector>& files, std::vector>& tools); + static void LoadDependencies(std::shared_ptr srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,TFile* file, std::vector>& files, std::vector>& tools); + static void LoadDependency(std::shared_ptr srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir, std::pair dep, std::vector>& files, std::vector>& tools) { for(auto index = files.begin(); index != files.end(); index++) { @@ -23,17 +23,17 @@ namespace Tesses::CrossLang { if(srcFS->RegularFileExists(filename)) { - Tesses::Framework::Streams::Stream* file = srcFS->OpenFile(filename,"rb"); + auto file = srcFS->OpenFile(filename,"rb"); TFile f; f.Load(nullptr, file); - delete file; + LoadDependencies(srcFS,sourceDir,&f,files,tools); } else throw VMException("Could not open file: \"" + name + "\"."); } - static void LoadDependencies(Tesses::Framework::Filesystem::VFS* srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,TFile* file, std::vector>& files, std::vector>& tools) + static void LoadDependencies(std::shared_ptr srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,TFile* file, std::vector>& files, std::vector>& tools) { files.push_back(std::pair(file->name,file->version)); for(auto item : file->tools) @@ -58,7 +58,7 @@ namespace Tesses::CrossLang { LoadDependency(srcFS,sourceDir,item,files,tools); } } - static void EnumerateCRVM(Tesses::Framework::Filesystem::VFS* srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,std::string filename, std::vector>& files, Tesses::Framework::Filesystem::VFS* destFS) + static void EnumerateCRVM(std::shared_ptr srcFS, Tesses::Framework::Filesystem::VFSPath sourceDir,std::string filename, std::vector>& files, std::shared_ptr destFS) { @@ -66,14 +66,12 @@ namespace Tesses::CrossLang { auto strm = srcFS->OpenFile(sourceDir / filename,"rb"); if(strm->EndOfStream()) { - delete strm; throw std::runtime_error("File does not exist: " + (sourceDir / filename).ToString() ); } file.Load(nullptr,strm); - delete strm; std::vector> tools; LoadDependencies(srcFS,sourceDir,&file,files,tools); @@ -135,10 +133,10 @@ namespace Tesses::CrossLang { } - Tesses::Framework::TextStreams::StreamWriter json_writer(destFS->OpenFile(Tesses::Framework::Filesystem::VFSPath() / "crossapp.json","wb" ),true); + Tesses::Framework::TextStreams::StreamWriter json_writer(destFS->OpenFile(Tesses::Framework::Filesystem::VFSPath() / "crossapp.json","wb" )); json_writer.WriteLine(Json::Encode(json_data,true)); } - Tesses::Framework::Filesystem::VFSPath Merge(Tesses::Framework::Filesystem::VFS* srcFS, Tesses::Framework::Filesystem::VFSPath sourcePath, Tesses::Framework::Filesystem::VFS* destFS) + Tesses::Framework::Filesystem::VFSPath Merge(std::shared_ptr srcFS, Tesses::Framework::Filesystem::VFSPath sourcePath, std::shared_ptr destFS) { std::vector> files; diff --git a/src/compiler/codegen.cpp b/src/compiler/codegen.cpp index 212e943..b8d008b 100644 --- a/src/compiler/codegen.cpp +++ b/src/compiler/codegen.cpp @@ -7,17 +7,17 @@ namespace Tesses::CrossLang { - void Write(Tesses::Framework::Streams::Stream* strm, uint8_t* buffer, size_t len) + void Write(std::shared_ptr strm, uint8_t* buffer, size_t len) { strm->WriteBlock(buffer,len); } - void WriteInt(Tesses::Framework::Streams::Stream* strm,uint32_t v) + void WriteInt(std::shared_ptr strm,uint32_t v) { uint8_t buffer[4]; BitConverter::FromUint32BE(buffer[0],v); Write(strm,buffer,4); } - void WriteString(Tesses::Framework::Streams::Stream* strm,std::string v) + void WriteString(std::shared_ptr strm,std::string v) { WriteInt(strm,(uint32_t)v.size()); Write(strm,(uint8_t*)v.data(),v.size()); @@ -34,7 +34,7 @@ namespace Tesses::CrossLang } - void CodeGen::Save(Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Streams::Stream* stream) + void CodeGen::Save(std::shared_ptr vfs, std::shared_ptr stream) { TVMVersion runtime_version(TVM_MAJOR,TVM_MINOR,TVM_PATCH,TVM_BUILD,TVM_VERSIONSTAGE); uint8_t buffer[18]; @@ -1765,10 +1765,9 @@ namespace Tesses::CrossLang } ResourceFile::~ResourceFile() { - delete this->strm; } - uint32_t ResourceFile::GetLength(Tesses::Framework::Filesystem::VFS* embedFS) + uint32_t ResourceFile::GetLength(std::shared_ptr embedFS) { if(embedFS == nullptr) return 0; if(strm != nullptr) return strm->GetLength(); @@ -1783,17 +1782,17 @@ namespace Tesses::CrossLang if(res != nullptr) return this->file == res->file; return ResourceBase::IsEqual(base); } - void ResourceFile::Write(Tesses::Framework::Streams::Stream* output) + void ResourceFile::Write(std::shared_ptr output) { if(this->strm != nullptr) this->strm->CopyTo(output); } - uint32_t ResourceByteArray::GetLength(Tesses::Framework::Filesystem::VFS* embedFS) + uint32_t ResourceByteArray::GetLength(std::shared_ptr embedFS) { return (uint32_t)this->data.size(); } - void ResourceByteArray::Write(Tesses::Framework::Streams::Stream* output) + void ResourceByteArray::Write(std::shared_ptr output) { output->WriteBlock(this->data.data(),this->data.size()); } diff --git a/src/compiler/parser.cpp b/src/compiler/parser.cpp index d6703cd..c2e61db 100644 --- a/src/compiler/parser.cpp +++ b/src/compiler/parser.cpp @@ -718,14 +718,14 @@ namespace Tesses::CrossLang CodeGen gen; gen.GenRoot(n); - Tesses::Framework::Streams::MemoryStream ms(true); + auto ms = std::make_shared(true); - gen.Save(nullptr,&ms); + gen.Save(nullptr,ms); - ms.Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin); + ms->Seek(0, Tesses::Framework::Streams::SeekOrigin::Begin); TFile* f = TFile::Create(ls); - f->Load(gc,&ms); + f->Load(gc,ms); node = TObject2SyntaxNode(env->LoadFile(gc,f)); } diff --git a/src/crossarchivecreate.cpp b/src/crossarchivecreate.cpp index 617fab0..d7630ff 100644 --- a/src/crossarchivecreate.cpp +++ b/src/crossarchivecreate.cpp @@ -74,10 +74,9 @@ int main(int argc, char** argv) if(args.size() < 2) Help(argv[0]); - LocalFilesystem fs; - auto path = fs.SystemToVFSPath(args[0]); - fs.CreateDirectory(path); - SubdirFilesystem sdfs(&fs,path,false); + auto path = Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(args[0]); + Tesses::Framework::Filesystem::LocalFS->CreateDirectory(path); + auto sdfs = std::make_shared(Tesses::Framework::Filesystem::LocalFS,path); FILE* f = fopen(args[1].c_str(),"wb"); if(f == NULL) @@ -86,8 +85,8 @@ int main(int argc, char** argv) return 1; } - FileStream strm(f,true,"wb",true); - CrossArchiveCreate(&sdfs,&strm,name,version,info,icon); + auto strm = std::make_shared(f,true,"wb",true); + CrossArchiveCreate(sdfs,strm,name,version,info,icon); return 0; } \ No newline at end of file diff --git a/src/crossarchiveextract.cpp b/src/crossarchiveextract.cpp index 0949fda..46064ed 100644 --- a/src/crossarchiveextract.cpp +++ b/src/crossarchiveextract.cpp @@ -12,8 +12,7 @@ int main(int argc, char** argv) return 1; } - LocalFilesystem fs; - SubdirFilesystem sdfs(&fs,std::string(argv[2]),false); + auto sdfs= std::make_shared(Tesses::Framework::Filesystem::LocalFS,std::string(argv[2])); FILE* f = fopen(argv[1],"rb"); if(f == NULL) @@ -22,9 +21,9 @@ int main(int argc, char** argv) return 1; } - FileStream strm(f,true,"rb",true); + auto strm = std::make_shared(f,true,"rb",true); - auto res = CrossArchiveExtract(&strm,&sdfs); + auto res = CrossArchiveExtract(strm,sdfs); std::cout << "Crvm Name: " << res.first.first << std::endl; std::cout << "Crvm Version: " << res.first.second.ToString() << std::endl; diff --git a/src/crossasmcli.cpp b/src/crossasmcli.cpp index b5eaa60..7d402f6 100644 --- a/src/crossasmcli.cpp +++ b/src/crossasmcli.cpp @@ -12,8 +12,8 @@ int main(int argc, char** argv) return 0; } auto curdir = VFSPath::GetAbsoluteCurrentDirectory(); - SubdirFilesystem sdfs(&LocalFS,curdir,false); - auto path = Assemble(&sdfs); + auto sdfs=std::make_shared(LocalFS,curdir); + auto path = Assemble(sdfs); path.relative = true; std::cout << "Output: " << (curdir / path).ToString() << std::endl; diff --git a/src/crossdisasmcli.cpp b/src/crossdisasmcli.cpp index 82f9df7..60d4dd1 100644 --- a/src/crossdisasmcli.cpp +++ b/src/crossdisasmcli.cpp @@ -44,7 +44,7 @@ int main(int argc, char** argv) } else if(curPos == 1) { - path = LocalFS.SystemToVFSPath(argv[i]); + path = LocalFS->SystemToVFSPath(argv[i]); } } } @@ -52,10 +52,10 @@ int main(int argc, char** argv) { help(argv[0]); } - auto strm = LocalFS.OpenFile(file,"rb"); - SubdirFilesystem sdir(&LocalFS,path,false); + auto strm = LocalFS->OpenFile(file,"rb"); + auto sdir = std::make_shared(LocalFS,path); if(strm->CanRead()) - Disassemble(strm, &sdir,json,resources); - delete strm; + Disassemble(strm, sdir,json,resources); + return 0; } \ No newline at end of file diff --git a/src/crosslang.cpp b/src/crosslang.cpp index 3bf4b99..a033d86 100644 --- a/src/crosslang.cpp +++ b/src/crosslang.cpp @@ -6,7 +6,7 @@ using namespace Tesses::Framework; using namespace Tesses::CrossLang; using namespace Tesses::Framework::Http; -bool Download(Tesses::Framework::Filesystem::VFSPath filename,Tesses::Framework::Filesystem::VFS* vfs) +bool Download(Tesses::Framework::Filesystem::VFSPath filename,std::shared_ptr vfs) { while(true) { @@ -23,7 +23,7 @@ bool Download(Tesses::Framework::Filesystem::VFSPath filename,Tesses::Framework: { auto strm = resp.ReadAsStream(); CrossArchiveExtract(strm, vfs); - delete strm; + return true; } else @@ -56,14 +56,13 @@ int main(int argc, char** argv) Tesses::Framework::Filesystem::VFSPath filename = dir / "Shell" / "Shell.crvm"; - Tesses::Framework::Filesystem::LocalFilesystem fs; - auto p = Tesses::Framework::Platform::Environment::GetRealExecutablePath(fs.SystemToVFSPath(argv[0])).GetParent().GetParent() / "share" / "Tesses" / "CrossLang" / "Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm"; + auto p = Tesses::Framework::Platform::Environment::GetRealExecutablePath(Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[0])).GetParent().GetParent() / "share" / "Tesses" / "CrossLang" / "Tesses.CrossLang.ShellPackage-1.0.0.0-prod.crvm"; if(argc > 1 && strcmp(argv[1],"update-shell") == 0) { - Tesses::Framework::Filesystem::SubdirFilesystem subdir(&fs,dir,false); + auto subdir = std::make_shared(Tesses::Framework::Filesystem::LocalFS,dir); HttpRequest req; req.url = "https://downloads.tesses.net/ShellPackage.crvm"; req.method = "GET"; @@ -71,8 +70,8 @@ int main(int argc, char** argv) if(resp.statusCode == StatusCode::OK) { auto strm = resp.ReadAsStream(); - CrossArchiveExtract(strm, &subdir); - delete strm; + CrossArchiveExtract(strm, subdir); + return 0; } else @@ -83,17 +82,17 @@ int main(int argc, char** argv) return 0; } - if(!fs.RegularFileExists(filename)) + if(!Tesses::Framework::Filesystem::LocalFS->RegularFileExists(filename)) { - Tesses::Framework::Filesystem::SubdirFilesystem subdir(&fs,dir,false); - if(fs.RegularFileExists(p)) + auto subdir = std::make_shared(Tesses::Framework::Filesystem::LocalFS,dir); + if(Tesses::Framework::Filesystem::LocalFS->RegularFileExists(p)) { std::cout << "Installing " << p.ToString() << " -> " << dir.ToString() << std::endl; - auto strm = fs.OpenFile(p,"rb"); + auto strm = Tesses::Framework::Filesystem::LocalFS->OpenFile(p,"rb"); if(strm != nullptr) { - CrossArchiveExtract(strm, &subdir); - delete strm; + CrossArchiveExtract(strm, subdir); + } else { @@ -102,7 +101,7 @@ int main(int argc, char** argv) } else { - if(!Download(filename,&subdir)) return 1; + if(!Download(filename,subdir)) return 1; return 0; } } @@ -118,7 +117,7 @@ int main(int argc, char** argv) TStd::RegisterStd(&gc,env); - env->LoadFileWithDependencies(&gc, &fs, filename); + env->LoadFileWithDependencies(&gc, Tesses::Framework::Filesystem::LocalFS, filename); TList* args = TList::Create(ls); diff --git a/src/crosslangcompiler.cpp b/src/crosslangcompiler.cpp index 5515412..7e29fe1 100644 --- a/src/crosslangcompiler.cpp +++ b/src/crosslangcompiler.cpp @@ -238,7 +238,7 @@ int main(int argc, char** argv) TStd::RegisterIO(gc,env,false); env->permissions.locked=true; auto fs = env->EnsureDictionary(gc,"FS"); - fs->SetValue("Local",TVFSHeapObject::Create(ls, new SubdirFilesystem(new Tesses::Framework::Filesystem::LocalFilesystem(),Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory(),true))); + fs->SetValue("Local", std::make_shared(LocalFS,Tesses::Framework::Filesystem::VFSPath::GetAbsoluteCurrentDirectory())); } else if(comptime == "full") { @@ -267,12 +267,11 @@ int main(int argc, char** argv) std::filesystem::create_directory(outputDir); { - Tesses::Framework::Streams::FileStream strm(outputDir / (name + "-" + version.ToString() + ".crvm"),"wb"); + auto strm = std::make_shared(outputDir / (name + "-" + version.ToString() + ".crvm"),"wb"); - LocalFilesystem fs; - SubdirFilesystem sfs(&fs,fs.SystemToVFSPath(resourceDir.string()),false); + auto sfs = std::make_shared(LocalFS,LocalFS->SystemToVFSPath(resourceDir.string())); - gen.Save(&sfs,&strm); + gen.Save(sfs,strm); } if(gc != nullptr) { diff --git a/src/crosslanginterperter.cpp b/src/crosslanginterperter.cpp index d618d87..d99c88f 100644 --- a/src/crosslanginterperter.cpp +++ b/src/crosslanginterperter.cpp @@ -26,23 +26,24 @@ int main(int argc, char** argv) CodeGen gen; gen.GenRoot(parser.ParseRoot()); std::vector data; - LocalFilesystem fs; - SubdirFilesystem sfs(&fs,VFSPath("."),false); + { + auto sfs = std::make_shared(LocalFS,VFSPath(".")); - Tesses::Framework::Streams::MemoryStream strm2(true); - gen.Save(&sfs,&strm2); + auto strm2 = std::make_shared(true); + gen.Save(sfs,strm2); { TFile* file = TFile::Create(ls); - strm2.Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); - file->Load(&gc,&strm2); + strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); + file->Load(&gc,strm2); env->LoadFile(&gc, file); } + } TList* args = TList::Create(ls); for(int arg=1;arg(true); if(source.find("loadfile ") == 0) { @@ -79,10 +80,9 @@ int main(int argc, char** argv) CodeGen gen; gen.GenRoot(parser.ParseRoot()); - LocalFilesystem fs; - SubdirFilesystem sfs(&fs,VFSPath("."),false); + auto sfs = std::make_shared(LocalFS,VFSPath(".")); - gen.Save(&sfs, &strm2); + gen.Save(sfs, strm2); } else if(source == "exit") @@ -100,18 +100,17 @@ int main(int argc, char** argv) CodeGen gen; gen.GenRoot(parser.ParseRoot()); - LocalFilesystem fs; - SubdirFilesystem sfs(&fs,VFSPath("."),false); + auto sfs = std::make_shared(LocalFS,VFSPath(".")); - gen.Save(&sfs,&strm2); + gen.Save(sfs,strm2); } { TFile* file = TFile::Create(ls); - strm2.Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); - file->Load(&gc,&strm2); + strm2->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); + file->Load(&gc,strm2); env->LoadFile(&gc, file); diff --git a/src/crosslangvm.cpp b/src/crosslangvm.cpp index c7f8738..f51ac90 100644 --- a/src/crosslangvm.cpp +++ b/src/crosslangvm.cpp @@ -14,9 +14,9 @@ int main(int argc, char** argv) gc.Start(); GCList ls(gc); TRootEnvironment* env = TRootEnvironment::Create(ls, TDictionary::Create(ls)); - Tesses::Framework::Filesystem::LocalFilesystem fs; + TStd::RegisterStd(&gc,env); - env->LoadFileWithDependencies(&gc, &fs, fs.SystemToVFSPath(argv[1])); + env->LoadFileWithDependencies(&gc, Tesses::Framework::Filesystem::LocalFS, Tesses::Framework::Filesystem::LocalFS->SystemToVFSPath(argv[1])); TList* args = TList::Create(ls); for(int arg=1;arg(LocalFS,srcF.GetParent()); + auto ddir = std::make_shared(LocalFS,destF+"_tmp"); - auto outpath = Merge(&sdir,"/"+srcF.GetFileName(), &ddir); + auto outpath = Merge(sdir,"/"+srcF.GetFileName(), ddir); outpath.relative=true; outpath = (destF+"_tmp") / outpath; - LocalFS.MoveFile(outpath,destF); - LocalFS.DeleteDirectoryRecurse(destF+"_tmp"); + LocalFS->MoveFile(outpath,destF); + LocalFS->DeleteDirectoryRecurse(destF+"_tmp"); return 0; diff --git a/src/crossthumbnailer.cpp b/src/crossthumbnailer.cpp index db619c5..784e545 100644 --- a/src/crossthumbnailer.cpp +++ b/src/crossthumbnailer.cpp @@ -19,26 +19,24 @@ int main(int argc,char** argv) std::string crvm = argv[1]; std::string png = argv[2]; - Tesses::Framework::Filesystem::LocalFilesystem lfs; - if(lfs.FileExists(crvm)) + if(Tesses::Framework::Filesystem::LocalFS->FileExists(crvm)) { Tesses::CrossLang::TFile file; - auto f = lfs.OpenFile(crvm, "rb"); + auto f = Tesses::Framework::Filesystem::LocalFS->OpenFile(crvm, "rb"); file.Load(nullptr,f); - delete f; if(file.icon >= 0 && file.icon < file.resources.size()) { - auto f2 = lfs.OpenFile(png, "wb"); + auto f2 = Tesses::Framework::Filesystem::LocalFS->OpenFile(png, "wb"); if(f2 != nullptr) { auto& icon = file.resources[file.icon]; f2->WriteBlock(icon.data(),icon.size()); - delete f2; + } return 0; @@ -46,16 +44,15 @@ int main(int argc,char** argv) } - if(lfs.FileExists(emptyThumb)) + if(Tesses::Framework::Filesystem::LocalFS->FileExists(emptyThumb)) { - auto src = lfs.OpenFile(emptyThumb,"rb"); - auto dest = lfs.OpenFile(png,"wb"); + auto src = Tesses::Framework::Filesystem::LocalFS->OpenFile(emptyThumb,"rb"); + auto dest = Tesses::Framework::Filesystem::LocalFS->OpenFile(png,"wb"); if(src != nullptr && dest != nullptr) { src->CopyTo(dest); } - delete src; - delete dest; + } return 0; } \ No newline at end of file diff --git a/src/runtime_methods/console.cpp b/src/runtime_methods/console.cpp index 1774d04..230ac67 100644 --- a/src/runtime_methods/console.cpp +++ b/src/runtime_methods/console.cpp @@ -8,6 +8,7 @@ #ifdef CROSSLANG_ENABLE_TERMIOS #include +#include #endif namespace Tesses::CrossLang { #ifdef CROSSLANG_ENABLE_TERMIOS @@ -182,16 +183,16 @@ namespace Tesses::CrossLang { } TObject Console_getIn(GCList& ls, std::vector args) { - return TStreamHeapObject::Create(ls, new Tesses::Framework::Streams::FileStream(stdin,false,"r",false)); + return std::make_shared(stdin,false,"r",false); } TObject Console_getOut(GCList& ls, std::vector args) { - return TStreamHeapObject::Create(ls, new Tesses::Framework::Streams::FileStream(stdout,false,"w",false)); + return std::make_shared(stdout,false,"w",false); } TObject Console_getError(GCList& ls, std::vector args) { - return TStreamHeapObject::Create(ls, new Tesses::Framework::Streams::FileStream(stderr,false,"w",false)); + return std::make_shared(stderr,false,"w",false); } TObject Console_Clear(GCList& ls, std::vector args) { @@ -203,6 +204,81 @@ namespace Tesses::CrossLang { #endif return Undefined(); } + static void con_sz(int& w, int& h) + { + w = 0; + h = 0; + + + #if defined(_WIN32) + + #elif defined(CROSSLANG_ENABLE_TERMIOS) + if(!isatty(STDOUT_FILENO)) + return; + struct winsize ws; + if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) + { + w = ws.ws_col; + h = ws.ws_row; + } + #endif + } + + TObject Console_ProgressBar(GCList& ls, std::vector args) + { + //[=== ] 50% + bool showBar = true; + #if defined(CROSSLANG_ENABLE_TERMIOS) + if(!isatty(STDOUT_FILENO)) showBar=false; + #endif + int64_t progress = 0; + double pdbl = 0; + GetArgument(args,0,pdbl); + if(GetArgument(args,0,progress)) pdbl = progress / 100.0; + if(pdbl < 0) pdbl=0; + if(pdbl > 1) pdbl=1; + + std::cout << "\r"; + if(showBar) + { + int w,h; + con_sz(w,h); + + int totalBlocks = w - 10; + if(totalBlocks > 0) + { + std::cout << "[\033[0;32m"; + int i; + int off = pdbl * totalBlocks; + for(int i = 0; i < totalBlocks; i++) + { + if(i < off) + std::cout << "="; + else + std::cout << " "; + } + + std::cout << "\033[0m] "; + } + } + + std::cout << std::setw(3) << progress << "%" << std::flush; + return Undefined(); + } + TObject Console_getSize(GCList& ls, std::vector args) + { + #if defined(CROSSLANG_ENABLE_TERMIOS) + if(!isatty(STDOUT_FILENO)) return nullptr; + #endif + int w, h; + con_sz(w,h); + TDictionary* dict = TDictionary::Create(ls,{ + TDItem("Width", (int64_t)w), + TDItem("Height",(int64_t)h) + }); + + return dict; + } void TStd::RegisterConsole(GC* gc,TRootEnvironment* env) { env->permissions.canRegisterConsole=true; @@ -234,11 +310,13 @@ namespace Tesses::CrossLang { dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"$text"},Console_WriteLine); dict->DeclareFunction(gc,"Error", "Write text \"error\" to stderr",{"error"},Console_Error); dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"$error"},Console_ErrorLine); + dict->DeclareFunction(gc,"ProgressBar","Draw progressbar", {}, Console_ProgressBar); if(env->permissions.canRegisterEverything) dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal); dict->DeclareFunction(gc,"getIn","Get stdin Stream",{},Console_getIn); dict->DeclareFunction(gc,"getOut","Get stdout Stream",{},Console_getOut); dict->DeclareFunction(gc,"getError", "Get stderr Stream",{},Console_getError); + dict->DeclareFunction(gc, "getSize", "Get console size",{},Console_getSize); gc->BarrierBegin(); env->DeclareVariable("Console", dict); gc->BarrierEnd(); diff --git a/src/runtime_methods/crypto.cpp b/src/runtime_methods/crypto.cpp index a91ae17..348e01a 100644 --- a/src/runtime_methods/crypto.cpp +++ b/src/runtime_methods/crypto.cpp @@ -113,11 +113,11 @@ namespace Tesses::CrossLang dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode); dict->DeclareFunction(gc, "Sha1", "Hash with sha1 algorithm (please don't use sha1 unless you need to)",{"strm"}, [](GCList& ls, std::vector args)->TObject { TByteArray* baSrc; - TStreamHeapObject* sho; + std::shared_ptr sho; - if(GetArgumentHeap(args, 0, sho)) + if(GetArgument(args, 0, sho)) { - auto bytes = Sha1::ComputeHash(sho->stream); + auto bytes = Sha1::ComputeHash(sho); auto ba = TByteArray::Create(ls); ba->data = bytes; return ba; @@ -133,13 +133,13 @@ namespace Tesses::CrossLang }); dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector args)->TObject { TByteArray* baSrc; - TStreamHeapObject* sho; + std::shared_ptr sho; bool is224=false; GetArgument(args,1,is224); - if(GetArgumentHeap(args, 0, sho)) + if(GetArgument(args, 0, sho)) { - auto bytes = Sha256::ComputeHash(sho->stream,is224); + auto bytes = Sha256::ComputeHash(sho,is224); auto ba = TByteArray::Create(ls); ba->data = bytes; return ba; @@ -155,13 +155,13 @@ namespace Tesses::CrossLang }); dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector args)->TObject { TByteArray* baSrc; - TStreamHeapObject* sho; + std::shared_ptr sho; bool is384=false; GetArgument(args,1,is384); - if(GetArgumentHeap(args, 0, sho)) + if(GetArgument(args, 0, sho)) { - auto bytes = Sha512::ComputeHash(sho->stream,is384); + auto bytes = Sha512::ComputeHash(sho,is384); auto ba = TByteArray::Create(ls); ba->data = bytes; return ba; diff --git a/src/runtime_methods/helpers.cpp b/src/runtime_methods/helpers.cpp new file mode 100644 index 0000000..3ee4d37 --- /dev/null +++ b/src/runtime_methods/helpers.cpp @@ -0,0 +1,54 @@ +#include "CrossLang.hpp" + +namespace Tesses::CrossLang { + static TObject Helpers_CopyToProgress(GCList& ls, std::vector args) + { + std::shared_ptr src; + std::shared_ptr dest; + TCallable* callable; + if(GetArgument(args,0,src) && GetArgument(args,1,dest) && GetArgumentHeap(args,2,callable)) + { + auto len = src->GetLength(); + callable->Call(ls,{0.0}); + if(len > 0) + { + std::shared_ptr buff=std::make_shared(1024); + int64_t pos=0; + int curPercent=0; + int lastPercent=0; + size_t read = 0; + do { + read = src->ReadBlock(buff.get(),1024); + dest->WriteBlock(buff.get(),read); + + if(read == 0) break; + pos += (int64_t)read; + + double percent = (double)(pos / len); + percent *= 10000; + + curPercent = (int)percent; + + if(curPercent > lastPercent) + { + lastPercent = curPercent; + callable->Call(ls,{curPercent/10000.0}); + } + + + } while(read != 0); + } + else { + src->CopyTo(dest); + + } + callable->Call(ls,{1.0}); + } + return Undefined(); + } + void TStd::RegisterHelpers(GC* gc, TRootEnvironment* env) + { + auto helpers=env->EnsureDictionary(gc,"Helpers"); + helpers->DeclareFunction(gc,"CopyToProgress","Copy Stream to another (but with progress event)",{"src","dest","progressCB"},Helpers_CopyToProgress); + } +} \ No newline at end of file diff --git a/src/runtime_methods/io.cpp b/src/runtime_methods/io.cpp index 92d0231..f7cd2c6 100644 --- a/src/runtime_methods/io.cpp +++ b/src/runtime_methods/io.cpp @@ -23,29 +23,33 @@ namespace Tesses::CrossLang } static TObject FS_CreateArchive(GCList& ls, std::vector args) { - TVFSHeapObject* vfs; - TStreamHeapObject* strm; + std::shared_ptr vfs; + + std::shared_ptr strm; + std::string name; std::string version; std::string info; std::string icon=""; TVMVersion version2; - if(GetArgumentHeap(args,0,vfs) && GetArgumentHeap(args,1,strm) && GetArgument(args,2,name) && GetArgument(args,4,info) && ((GetArgument(args,3,version) && TVMVersion::TryParse(version,version2)) || GetArgument(args,3,version2))) + if(GetArgument(args,0,vfs) && GetArgument(args,1,strm) && GetArgument(args,2,name) && GetArgument(args,4,info) && ((GetArgument(args,3,version) && TVMVersion::TryParse(version,version2)) || GetArgument(args,3,version2))) { GetArgument(args,5,icon); - CrossArchiveCreate(vfs->vfs,strm->stream,name,version2,info,icon); + CrossArchiveCreate(vfs,strm,name,version2,info,icon); } return nullptr; } static TObject FS_ExtractArchive(GCList& ls, std::vector args) { - TVFSHeapObject* vfs; - TStreamHeapObject* strm; + std::shared_ptr vfs; + + std::shared_ptr strm; + - if(GetArgumentHeap(args,0,strm) && GetArgumentHeap(args,1,vfs)) + if(GetArgument(args,0,strm) && GetArgument(args,1,vfs)) { - auto res = CrossArchiveExtract(strm->stream,vfs->vfs); + auto res = CrossArchiveExtract(strm,vfs); TDictionary* dict = TDictionary::Create(ls); ls.GetGC()->BarrierBegin(); @@ -62,12 +66,13 @@ namespace Tesses::CrossLang { Tesses::Framework::Filesystem::VFSPath path; - TVFSHeapObject* vfs; - if(GetArgumentHeap(args,0,vfs) && GetArgumentAsPath(args,1,path)) + std::shared_ptr vfs; + + if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path)) { - auto txtFile = vfs->vfs->OpenFile(path,"rb"); + auto txtFile = vfs->OpenFile(path,"rb"); if(txtFile == nullptr) return ""; - Tesses::Framework::TextStreams::StreamReader reader(txtFile,true); + Tesses::Framework::TextStreams::StreamReader reader(txtFile); return reader.ReadToEnd(); } return ""; @@ -75,10 +80,11 @@ namespace Tesses::CrossLang static TObject FS_ReadAllBytes(GCList& ls, std::vector args) { Tesses::Framework::Filesystem::VFSPath path; - TVFSHeapObject* vfs; - if(GetArgumentHeap(args,0,vfs) && GetArgumentAsPath(args,1,path)) + std::shared_ptr vfs; + + if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path)) { - auto txtFile = vfs->vfs->OpenFile(path,"rb"); + auto txtFile = vfs->OpenFile(path,"rb"); if(txtFile == nullptr) return nullptr; auto res = TByteArray::Create(ls); std::array data; @@ -87,7 +93,7 @@ namespace Tesses::CrossLang read = txtFile->ReadBlock(data.data(),data.size()); res->data.insert(res->data.end(),data.begin(),data.begin()+read); } while(read != 0); - delete txtFile; + return res; } return nullptr; @@ -97,15 +103,15 @@ namespace Tesses::CrossLang static TObject FS_WriteAllText(GCList& ls, std::vector args) { Tesses::Framework::Filesystem::VFSPath path; - - TVFSHeapObject* vfs; + std::shared_ptr vfs; + std::string content; - if(GetArgumentHeap(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content)) + if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content)) { - auto txtFile = vfs->vfs->OpenFile(path,"wb"); + auto txtFile = vfs->OpenFile(path,"wb"); if(txtFile == nullptr) return nullptr; - Tesses::Framework::TextStreams::StreamWriter writer(txtFile,true); + Tesses::Framework::TextStreams::StreamWriter writer(txtFile); writer.Write(content); } return nullptr; @@ -114,15 +120,15 @@ namespace Tesses::CrossLang { Tesses::Framework::Filesystem::VFSPath path; - TVFSHeapObject* vfs; + std::shared_ptr vfs; TByteArray* bArray; - if(GetArgumentHeap(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray)) + if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgumentHeap(args,2,bArray)) { - auto txtFile = vfs->vfs->OpenFile(path,"wb"); + auto txtFile = vfs->OpenFile(path,"wb"); if(txtFile == nullptr) return nullptr; txtFile->WriteBlock(bArray->data.data(),bArray->data.size()); - delete txtFile; + } return nullptr; } @@ -150,9 +156,9 @@ namespace Tesses::CrossLang gc->BarrierBegin(); if(enableLocalFilesystem) { - TVFSHeapObject* vfs = TVFSHeapObject::Create(ls, new Tesses::Framework::Filesystem::LocalFilesystem()); + - dict->SetValue("Local", vfs); + dict->SetValue("Local", Tesses::Framework::Filesystem::LocalFS); dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},FS_MakeFull); dict->DeclareFunction(gc,"getCurrentPath","Get current path",{},FS_getCurrentPath); dict->DeclareFunction(gc,"setCurrentPath","Set the current path",{"path"},FS_setCurrentPath); diff --git a/src/runtime_methods/net.cpp b/src/runtime_methods/net.cpp index 2100e23..ea1b290 100644 --- a/src/runtime_methods/net.cpp +++ b/src/runtime_methods/net.cpp @@ -14,64 +14,32 @@ using namespace Tesses::Framework::Http; using namespace Tesses::Framework::Mail; namespace Tesses::CrossLang { - static SMTPBody* TObjectToSMTPBody(GCList& ls,std::string mimeType, TObject obj) + static std::shared_ptr TObjectToSMTPBody(GCList& ls,std::string mimeType, TObject obj) { - SMTPBody* body = nullptr; + std::shared_ptr body; std::string text; TByteArray* ba; - TStreamHeapObject* sho; + std::shared_ptr sho; if(GetObject(obj,text)) { - body = new SMTPStringBody(text,mimeType); + body = std::make_shared(text,mimeType); } else if(GetObjectHeap(obj,ba)) { - MemoryStream* ms = new MemoryStream(true); + std::shared_ptr ms = std::make_shared(true); ms->WriteBlock(ba->data.data(), ba->data.size()); ms->Seek(0L, SeekOrigin::Begin); - body = new SMTPStreamBody(mimeType,ms,true); + body = std::make_shared(mimeType,ms); } - else if(GetObjectHeap(obj,sho)) + else if(GetObject(obj,sho)) { ls.Add(sho); - body = new SMTPStreamBody(mimeType,sho->stream,false); + body = std::make_shared(mimeType,sho); } return body; } - TServerHeapObject* TServerHeapObject::Create(GCList& ls, Tesses::Framework::Http::IHttpServer* svr) - { - TServerHeapObject* ho = new TServerHeapObject(); - ls.Add(ho); - auto gc = ls.GetGC(); - gc->Watch(ho); - ho->server = svr; - return ho; - } - TServerHeapObject* TServerHeapObject::Create(GCList* ls, Tesses::Framework::Http::IHttpServer* svr) - { - TServerHeapObject* ho = new TServerHeapObject(); - ls->Add(ho); - auto gc = ls->GetGC(); - gc->Watch(ho); - ho->server = svr; - return ho; - } - - void TServerHeapObject::Close() - { - if(this->server != nullptr) - { - delete this->server; - this->server = nullptr; - } - } - TServerHeapObject::~TServerHeapObject() - { - if(this->server != nullptr) - { - delete this->server; - } - } + + class TNativeObjectThatReturnsHttpDictionary : public TNativeObject { public: virtual bool IsAvailable()=0; @@ -293,26 +261,31 @@ namespace Tesses::CrossLang else if(key == "getQueryParams") return TNativeObject::Create(ls, &ctx->queryParams,this); else if(key == "getRequestHeaders") return TNativeObject::Create(ls, &ctx->requestHeaders,this); else if(key == "getResponseHeaders") return TNativeObject::Create(ls, &ctx->responseHeaders,this); - else if(key == "GetStream") return TStreamHeapObject::Create(ls, &ctx->GetStream()); - else if(key == "OpenRequestStream") return TStreamHeapObject::Create(ls, ctx->OpenRequestStream()); - else if(key == "OpenResponseStream") return TStreamHeapObject::Create(ls, ctx->OpenResponseStream()); + else if(key == "GetStream") return ctx->GetStream(); + else if(key == "OpenRequestStream") return ctx->OpenRequestStream(); + else if(key == "OpenResponseStream") return ctx->OpenResponseStream(); else if(key == "ParseFormData") { TCallable* callable; - TVFSHeapObject* vfsHeapObject; + std::shared_ptr vfs; if(GetArgumentHeap(args, 0, callable)) { - ctx->ParseFormData([callable,&ls](std::string a,std::string b, std::string c)->Tesses::Framework::Streams::Stream*{ + ctx->ParseFormData([callable,&ls](std::string a,std::string b, std::string c)->std::shared_ptr { auto res = callable->Call(ls,{a,b,c}); - return new Tesses::CrossLang::TObjectStream(ls.GetGC(),res); + std::shared_ptr strm; + if(GetObject(res,strm)) + { + return strm; + } + return nullptr; }); } - else if(GetArgumentHeap(args,0,vfsHeapObject)) + else if(GetArgument(args,0,vfs)) { int i = 1; std::vector response; - ctx->ParseFormData([vfsHeapObject,&response,&ls,&i](std::string mime,std::string filename, std::string name)->Tesses::Framework::Streams::Stream* { + ctx->ParseFormData([vfs,&response,&ls,&i](std::string mime,std::string filename, std::string name)->std::shared_ptr { std::string realFileName = "/" + std::to_string(i) + ".bin"; i++; response.push_back(TDictionary::Create(ls,{ @@ -322,7 +295,7 @@ namespace Tesses::CrossLang TDItem("Name", name) })); - auto strm = vfsHeapObject->vfs->OpenFile(realFileName,"wb"); + auto strm = vfs->OpenFile(realFileName,"wb"); return strm; @@ -334,10 +307,10 @@ namespace Tesses::CrossLang else if(key == "getNeedToParseFormData") return ctx->NeedToParseFormData(); else if(key == "ReadString") return ctx->ReadString(); else if(key == "ReadStream") { - Tesses::CrossLang::TStreamHeapObject* strm; - if(GetArgumentHeap(args,0,strm)) + std::shared_ptr strm; + if(GetArgument(args,0,strm)) { - ctx->ReadStream(strm->stream); + ctx->ReadStream(strm); } } else if(key == "ReadJson") @@ -397,9 +370,9 @@ namespace Tesses::CrossLang } else if(key == "SendStream") { - TStreamHeapObject* strmHeapObj; - if(GetArgumentHeap(args,0,strmHeapObj)) - ctx->SendStream(strmHeapObj->stream); + std::shared_ptr strm; + if(GetArgument(args,0,strm)) + ctx->SendStream(strm); } else if(key == "SendBytes") @@ -552,12 +525,12 @@ namespace Tesses::CrossLang req->CallMethod(ls,"HandleHeaders",{res}); dummy->Close(); } - void Write(Tesses::Framework::Streams::Stream* strm) + void Write(std::shared_ptr strm) { GCList ls(gc); - auto res=TStreamHeapObject::Create(ls,strm); - req->CallMethod(ls,"Write",{res}); - res->stream=nullptr; + + req->CallMethod(ls,"Write",{strm}); + } ~TDictionaryHttpRequestBody() @@ -571,7 +544,6 @@ namespace Tesses::CrossLang { TCallable* callable; TDictionary* dict; - TServerHeapObject* server; TClassObject* clsObj; if(GetObjectHeap(this->obj,callable)) { @@ -620,10 +592,6 @@ namespace Tesses::CrossLang } } - else if(GetObjectHeap(this->obj,server)) - { - return server->server->Handle(ctx); - } return false; } @@ -678,7 +646,7 @@ namespace Tesses::CrossLang bool datagram; if(GetArgument(args,0,ipv6) && GetArgument(args,1,datagram)) { - return TStreamHeapObject::Create(ls,new NetworkStream(ipv6,datagram)); + return std::make_shared(ipv6,datagram); } return nullptr; } @@ -686,13 +654,13 @@ namespace Tesses::CrossLang { HttpServer* server; public: - HttpServerNativeObject(uint16_t port, TObjectHttpServer* httpServer,bool printIps) + HttpServerNativeObject(uint16_t port, std::shared_ptr httpServer,bool printIps) { - server=new HttpServer(port,httpServer,true,printIps); + server=new HttpServer(port,httpServer,printIps); } - HttpServerNativeObject(std::string unixPath, TObjectHttpServer* httpServer) + HttpServerNativeObject(std::string unixPath, std::shared_ptr httpServer) { - server=new HttpServer(unixPath,httpServer,true); + server=new HttpServer(unixPath,httpServer); } std::string TypeName() { @@ -722,15 +690,25 @@ namespace Tesses::CrossLang { bool printIPs=true; GetArgument(args,2,printIPs); - TObjectHttpServer* httpServer = new TObjectHttpServer(ls.GetGC(),args[0]); - uint16_t p = (uint16_t)port; - return TNativeObject::Create(ls,port,httpServer,printIPs); + + std::shared_ptr httpSvr = ToHttpServer(ls.GetGC(),args[0]); + + if(httpSvr) { + uint16_t p = (uint16_t)port; + return TNativeObject::Create(ls,port,httpSvr,printIPs); + } + } + if(GetArgument(args,1,pathStr) && env->permissions.canRegisterLocalFS) { - TObjectHttpServer* httpServer = new TObjectHttpServer(ls.GetGC(),args[0]); + std::shared_ptr httpSvr = ToHttpServer(ls.GetGC(),args[0]); + + + if(httpSvr) { + return TNativeObject::Create(ls,pathStr,httpSvr); + } - return TNativeObject::Create(ls,pathStr,httpServer); } return nullptr; @@ -740,27 +718,31 @@ namespace Tesses::CrossLang int64_t port; if(GetArgument(args,1,port)) { - TObjectHttpServer httpServer(ls.GetGC(),args[0]); - uint16_t p = (uint16_t)port; - HttpServer server(p,httpServer); - server.StartAccepting(); - Tesses::Framework::TF_RunEventLoop(); + std::shared_ptr httpSvr = ToHttpServer(ls.GetGC(),args[0]); + + if(httpSvr) { + uint16_t p = (uint16_t)port; + HttpServer server(p,httpSvr); + server.StartAccepting(); + Tesses::Framework::TF_RunEventLoop(); + } + } return nullptr; } static TObject Net_Http_ListenOnUnusedPort(GCList& ls, std::vector args) { - if(args.size() > 0) - { - TObjectHttpServer httpServer(ls.GetGC(),args[0]); - - - uint16_t port=0; - HttpServer server(port,httpServer, false); - std::cout << "Port: " << server.GetPort() << std::endl; - server.StartAccepting(); - Tesses::Framework::TF_RunEventLoop(); + if(args.empty()) return nullptr; + std::shared_ptr httpSvr=ToHttpServer(ls.GetGC(),args.front()); + if(httpSvr) { + uint16_t p = 0; + HttpServer server(p,httpSvr); + std::cout << "Port: " << server.GetPort() << std::endl; + server.StartAccepting(); + + Tesses::Framework::TF_RunEventLoop(); } + return nullptr; } static TObject Net_Http_MimeType(GCList& ls, std::vector args) @@ -840,10 +822,10 @@ namespace Tesses::CrossLang else if(key == "CopyToStream") { - TStreamHeapObject* strm; - if(GetArgumentHeap(args,0,strm)) + std::shared_ptr strm; + if(GetArgument(args,0,strm)) { - response->CopyToStream(strm->stream); + response->CopyToStream(strm); } } else if(key == "ReadAsString") @@ -856,10 +838,9 @@ namespace Tesses::CrossLang } else if(key == "ReadAsStream") { - auto strm = TStreamHeapObject::Create(ls, response->ReadAsStream()); - strm->watch.push_back(this); + - return strm; + return response->ReadAsStream(); } else if(key == "getStatusCode") { @@ -1018,9 +999,9 @@ namespace Tesses::CrossLang ls.GetGC()->BarrierBegin(); auto server = dict->GetValue("server"); TDictionary* dict2; - Tesses::Framework::Streams::Stream* strm=nullptr; + std::shared_ptr strm; bool ownsStream=true; - TStreamHeapObject* objStrm; + std::shared_ptr objStrm; if(GetObjectHeap(server,dict2)) { auto tlsO = dict2->GetValue("tls"); @@ -1034,19 +1015,19 @@ namespace Tesses::CrossLang if(!GetObject(portO, port)) port = tls ? 465 : 25; GetObject(hostO,host); - strm = new NetworkStream(host,(uint16_t)port,false,false,false); + strm = std::make_shared(host,(uint16_t)port,false,false,false); if(tls) { - strm = new Framework::Crypto::ClientTLSStream(strm,true,true,host); + strm = std::make_shared(strm,true,host); } } - else if (GetObjectHeap(server, objStrm)) { + else if (GetObject(server, objStrm)) { ownsStream=false; - strm = objStrm->stream; + strm = objStrm; } - Tesses::Framework::Mail::SMTPClient client(strm,ownsStream); + Tesses::Framework::Mail::SMTPClient client(strm); auto o = dict->GetValue("domain"); GetObject(o,client.domain); @@ -1097,7 +1078,7 @@ namespace Tesses::CrossLang GetObject(o,type); o = dict2->GetValue("data"); - client.attachments.push_back(std::pair(name,TObjectToSMTPBody(ls, type, o))); + client.attachments.push_back(std::pair>(name,TObjectToSMTPBody(ls, type, o))); } } } @@ -1139,7 +1120,7 @@ namespace Tesses::CrossLang hdict.AddValue(key,value); } } - CallbackWebSocketConnection conn([dict,&ls](std::function sendMessage,std::function ping,std::function close)->void{ + auto conn = std::make_shared([dict,&ls](std::function sendMessage,std::function ping,std::function close)->void{ GCList ls2(ls.GetGC()); dict->CallMethod(ls2,"Open",{ TExternalMethod::Create(ls2,"Send a message",{"messageTextOrByteArray"},[sendMessage](GCList& ls,std::vector args)->TObject{ @@ -1225,7 +1206,7 @@ namespace Tesses::CrossLang } } - CallbackWebSocketConnection conn([co,&ls](std::function sendMessage,std::function ping,std::function close)->void{ + auto conn = std::make_shared([co,&ls](std::function sendMessage,std::function ping,std::function close)->void{ GCList ls2(ls.GetGC()); co->CallMethod(ls2,"","Open",{ TExternalMethod::Create(ls2,"Send a message",{"messageTextOrByteArray"},[sendMessage](GCList& ls,std::vector args)->TObject{ @@ -1298,33 +1279,55 @@ namespace Tesses::CrossLang static TObject Net_Http_DownloadToStream(GCList& ls, std::vector args) { std::string url; - TStreamHeapObject* strm; - if(GetArgument(args,0,url) && GetArgumentHeap(args,1,strm)) + std::shared_ptr strm; + if(GetArgument(args,0,url) && GetArgument(args,1,strm)) { - DownloadToStreamSimple(url,strm->stream); + DownloadToStreamSimple(url,strm); } return nullptr; } static TObject Net_Http_DownloadToFile(GCList& ls, std::vector args) { std::string url; - TVFSHeapObject* vfs; + std::shared_ptr vfs; Tesses::Framework::Filesystem::VFSPath path; - if(GetArgument(args,0,url) && GetArgumentHeap(args,1,vfs) && GetArgumentAsPath(args,2, path)) + if(GetArgument(args,0,url) && GetArgument(args,1,vfs) && GetArgumentAsPath(args,2, path)) { - DownloadToFileSimple(url,vfs->vfs,path); + DownloadToFileSimple(url,vfs,path); } return nullptr; } - bool TServerHeapObject::Handle(std::vector args) + bool IHttpServer_Handle(std::shared_ptr svr,std::vector& args) { TServerContext* ctx; - if(this->server != nullptr && GetArgumentHeap(args,0,ctx) && ctx->IsAvailable()) + if(GetArgumentHeap(args,0,ctx)) { - return this->server->Handle(*ctx->GetContext()); + return svr->Handle(*ctx->GetContext()); } return false; } + + std::shared_ptr ToHttpServer(GC* gc, TObject obj) + { + if(std::holds_alternative>(obj)) return std::get>(obj); + TDictionary* dict; + TClassObject* clo; + TCallable* call; + if(GetObjectHeap(obj,dict)) + { + return std::make_shared(gc,dict); + } + else if(GetObjectHeap(obj,clo)) + { + return std::make_shared(gc,clo); + } + else if(GetObjectHeap(obj,call)) + { + return std::make_shared(gc,call); + } + return nullptr; + } + void TStd::RegisterNet(GC* gc, TRootEnvironment* env) { @@ -1345,10 +1348,12 @@ namespace Tesses::CrossLang //http->DeclareFunction(gc, "ProcessServer","Process HTTP server connection",{"networkstream","server","ip","port","encrypted"},, Net_ProcessServer); http->DeclareFunction(gc, "StreamHttpRequestBody","Create a stream request body",{"stream","mimeType"},[](GCList& ls, std::vector args)->TObject { + std::shared_ptr strm; std::string mimeType; - if(GetArgument(args, 1, mimeType)) + + if(GetArgument(args,0,strm) && GetArgument(args, 1, mimeType)) { - return TNativeObject::Create(ls, new StreamHttpRequestBody(new TObjectStream(ls.GetGC(),args[0]), true, mimeType)); + return TNativeObject::Create(ls, new StreamHttpRequestBody(strm, mimeType)); } return nullptr; }); @@ -1382,24 +1387,36 @@ namespace Tesses::CrossLang http->DeclareFunction(gc, "ListenSimpleWithLoop", "Listen (creates application loop)", {"server","port"},Net_Http_ListenSimpleWithLoop); http->DeclareFunction(gc, "ListenOnUnusedPort","Listen on unused localhost port and print Port: theport",{"server"},Net_Http_ListenOnUnusedPort); //FileServer svr() - http->DeclareFunction(gc, "FileServer","Create a file server",{"path","allowlisting","spa"}, [](GCList& ls, std::vector args)->TObject{ + http->DeclareFunction(gc, "FileServer","Create a file server",{"vfs","allowlisting","spa"}, [](GCList& ls, std::vector args)->TObject{ + std::shared_ptr vfs; bool allowlisting; bool spa; - if(GetArgument(args,1,allowlisting) && GetArgument(args,2,spa)) + if(GetArgument(args,0,vfs) && GetArgument(args,1,allowlisting) && GetArgument(args,2,spa)) { - auto fserver = new FileServer(new TObjectVFS(ls.GetGC(),args[0]),true,allowlisting,spa); - return TServerHeapObject::Create(ls,fserver); + return std::make_shared(vfs,allowlisting,spa); + } return nullptr; }); http->DeclareFunction(gc, "MountableServer","Create a server you can mount to, must mount parents before child",{"root"}, [](GCList& ls, std::vector args)->TObject{ - if(args.size() > 0) + TDictionary* dict; + TClassObject* cls; + std::shared_ptr mySvr; + if(GetArgumentHeap(args,0,dict)) { - auto svr = new TObjectHttpServer(ls.GetGC(), args[0]); - auto svr2 = new MountableServer(svr,true); + auto svr = std::make_shared(ls.GetGC(), dict); + return std::make_shared(svr); - return TServerHeapObject::Create(ls,svr2); + } + else if(GetArgumentHeap(args,0,cls)) + { + auto svr = std::make_shared(ls.GetGC(), cls); + return std::make_shared(svr); + } + else if(GetArgument(args,0,mySvr)) + { + return std::make_shared(mySvr); } return nullptr; }); diff --git a/src/runtime_methods/process.cpp b/src/runtime_methods/process.cpp index 7e2acc4..9f863e0 100644 --- a/src/runtime_methods/process.cpp +++ b/src/runtime_methods/process.cpp @@ -171,15 +171,15 @@ namespace Tesses::CrossLang } if(key == "getStandardInput") { - return TStreamHeapObject::Create(ls,process.GetStdinStream()); + return process.GetStdinStream(); } if(key == "getStandardOutput") { - return TStreamHeapObject::Create(ls,process.GetStdoutStream()); + return process.GetStdoutStream(); } if(key == "getStandardError") { - return TStreamHeapObject::Create(ls,process.GetStderrStream()); + return process.GetStderrStream(); } return Undefined(); } diff --git a/src/runtime_methods/std.cpp b/src/runtime_methods/std.cpp index 06675d4..03e50dc 100644 --- a/src/runtime_methods/std.cpp +++ b/src/runtime_methods/std.cpp @@ -844,14 +844,14 @@ namespace Tesses::CrossLang static TObject TypeIsStream(GCList& ls, std::vector args) { if(args.empty()) return nullptr; - TStreamHeapObject* strm; - return GetArgumentHeap(args,0,strm); + std::shared_ptr strm; + return GetArgument(args,0,strm); } static TObject TypeIsVFS(GCList& ls, std::vector args) { if(args.empty()) return nullptr; - TVFSHeapObject* vfs; - return GetArgumentHeap(args,0,vfs); + std::shared_ptr vfs; + return GetArgument(args,0,vfs); } static TObject TypeIsDateTime(GCList& ls, std::vector args) @@ -862,23 +862,23 @@ namespace Tesses::CrossLang } static TObject New_SubdirFilesystem(GCList& ls, std::vector args) { - TVFSHeapObject* vfsho; + std::shared_ptr vfs; Tesses::Framework::Filesystem::VFSPath path; - if(GetArgumentHeap(args,0,vfsho) && GetArgumentAsPath(args,1,path)) + if(GetArgument(args,0,vfs) && GetArgumentAsPath(args,1,path)) { - return TVFSHeapObject::Create(ls,new Tesses::Framework::Filesystem::SubdirFilesystem(new TObjectVFS(ls.GetGC(),vfsho),path,true)); + return std::make_shared(vfs,path); } return nullptr; } static TObject New_MountableFilesystem(GCList& ls, std::vector args) { - TVFSHeapObject* vfsho; + std::shared_ptr vfs; - if(GetArgumentHeap(args,0,vfsho)) + if(GetArgument(args,0,vfs)) { - return TVFSHeapObject::Create(ls,new Tesses::Framework::Filesystem::MountableFilesystem(new TObjectVFS(ls.GetGC(),vfsho),true)); + return std::make_shared(vfs); } return nullptr; } @@ -887,13 +887,13 @@ namespace Tesses::CrossLang bool writable; if(GetArgument(args,0,writable)) { - return TStreamHeapObject::Create(ls,new Tesses::Framework::Streams::MemoryStream(writable)); + return std::make_shared(writable); } return nullptr; } static TObject New_MemoryFilesystem(GCList& ls, std::vector args) { - return TVFSHeapObject::Create(ls, new Tesses::Framework::Filesystem::MemoryFilesystem()); + return std::make_shared(); } static TObject New_Filesystem(GCList& ls, std::vector args) @@ -901,7 +901,7 @@ namespace Tesses::CrossLang TDictionary* dict; if(GetArgumentHeap(args,0,dict)) { - return TVFSHeapObject::Create(ls, new TObjectVFS(ls.GetGC(),dict)); + return std::make_shared(ls.GetGC(),dict); } return nullptr; } @@ -910,7 +910,7 @@ namespace Tesses::CrossLang TDictionary* dict; if(GetArgumentHeap(args,0,dict)) { - return TStreamHeapObject::Create(ls, new TObjectStream(ls.GetGC(),dict)); + return std::make_shared(ls.GetGC(), dict); } return nullptr; } @@ -960,6 +960,62 @@ namespace Tesses::CrossLang if(std::holds_alternative(_obj)) return "Path"; if(std::holds_alternative(_obj)) return "DateTime"; + if(std::holds_alternative>(_obj)) + { + auto strm = std::get>(_obj); + if(strm != nullptr) + { + auto netStrm = std::dynamic_pointer_cast(strm); + if(netStrm != nullptr) + { + return "NetworkStream"; + } + + + + } + return "Stream"; + } + if(std::holds_alternative>(_obj)) + { + auto svr = std::get>(_obj); + if(svr != nullptr) + { + auto fileServer = std::dynamic_pointer_cast(svr); + auto mountableServer = std::dynamic_pointer_cast(svr); + if(fileServer != nullptr) + { + return "FileServer"; + } + if(mountableServer != nullptr) + { + return "MountableServer"; + } + + } + return "HttpServer"; + + } + if(std::holds_alternative>(_obj)) + { + auto vfs = std::get>(_obj); + if(vfs != nullptr) + { + auto localVFS = std::dynamic_pointer_cast(vfs); + + auto mountableVFS = std::dynamic_pointer_cast(vfs); + + + auto subFS = std::dynamic_pointer_cast(vfs); + + if(localVFS != nullptr) return "LocalFilesystem"; + if(subFS != nullptr) return "SubdirFilesystem"; + if(mountableVFS != nullptr) return "MountableFilesystem"; + + + } + return "VFS"; + } if(std::holds_alternative(_obj)) { auto obj = std::get(_obj).obj; @@ -974,9 +1030,7 @@ namespace Tesses::CrossLang auto byteArray = dynamic_cast(obj); auto native = dynamic_cast(obj); auto any = dynamic_cast(obj); - auto vfs = dynamic_cast(obj); - auto strm = dynamic_cast(obj); - auto svr = dynamic_cast(obj); + auto cse = dynamic_cast(obj); auto rootEnv = dynamic_cast(obj); auto subEnv = dynamic_cast(obj); @@ -995,46 +1049,7 @@ namespace Tesses::CrossLang if(dynList != nullptr) return "DynamicList"; if(aarray != nullptr) return "AssociativeArray"; if(natObj != nullptr) return natObj->TypeName(); - if(strm != nullptr) - { - auto netStrm = dynamic_cast(strm->stream); - if(netStrm != nullptr) - { - return "NetworkStream"; - } - - - return "Stream"; - } - if(svr != nullptr) - { - auto fileServer = dynamic_cast(svr->server); - auto mountableServer = dynamic_cast(svr->server); - if(fileServer != nullptr) - { - return "FileServer"; - } - if(mountableServer != nullptr) - { - return "MountableServer"; - } - return "HttpServer"; - } - if(vfs != nullptr) - { - auto localVFS = dynamic_cast(vfs->vfs); - - auto mountableVFS = dynamic_cast(vfs->vfs); - - - auto subFS = dynamic_cast(vfs->vfs); - - if(localVFS != nullptr) return "LocalFilesystem"; - if(subFS != nullptr) return "SubdirFilesystem"; - if(mountableVFS != nullptr) return "MountableFilesystem"; - - return "VFS"; - } + if(dict != nullptr) return "Dictionary"; if(list != nullptr) return "List"; if(argWrapper != nullptr) return "ArgWrapper"; @@ -1221,6 +1236,7 @@ namespace Tesses::CrossLang gc->BarrierBegin(); env->permissions.canRegisterRoot=true; + RegisterHelpers(gc,env); auto date =env->EnsureDictionary(gc,"DateTime"); date->DeclareFunction(gc, "Sleep","Sleep for a specified amount of milliseconds (multiply seconds by 1000 to get milliseconds)", {"ms"},DateTime_Sleep); @@ -1258,8 +1274,8 @@ namespace Tesses::CrossLang newTypes->DeclareFunction(gc, "MountableFilesystem","Create a mountable filesystem",{"root"}, New_MountableFilesystem); newTypes->DeclareFunction(gc, "SubdirFilesystem","Create a subdir filesystem",{"fs","subdir"}, New_SubdirFilesystem); newTypes->DeclareFunction(gc, "MemoryStream","Create a memory stream",{"writable"}, New_MemoryStream); - newTypes->DeclareFunction(gc, "Stream","Create stream", {"strm"},New_Stream); newTypes->DeclareFunction(gc, "Filesystem","Create filesystem", {"fs"},New_Filesystem); + newTypes->DeclareFunction(gc, "Stream","Create stream", {"strm"},New_Stream); newTypes->DeclareFunction(gc, "MemoryFilesystem","Create in memory filesystem", {},New_MemoryFilesystem); diff --git a/src/runtime_methods/vm.cpp b/src/runtime_methods/vm.cpp index ae2dd3d..e3c6b24 100644 --- a/src/runtime_methods/vm.cpp +++ b/src/runtime_methods/vm.cpp @@ -232,7 +232,7 @@ namespace Tesses::CrossLang std::vector> tools; std::string info; std::string icon; - TVFSHeapObject* vfsHO =nullptr; + std::shared_ptr vfs; ls.GetGC()->BarrierBegin(); TObject _name = dict->GetValue("Name"); @@ -252,7 +252,7 @@ namespace Tesses::CrossLang GetObject(_name,name); GetObject(_info,info); GetObject(_icon,icon); - GetObjectHeap(_resourceFileSystem, vfsHO); + GetObject(_resourceFileSystem, vfs); GetObjectHeap(_comptime,comptimeEnv); std::string v2; if(GetObject(_version,v2)) @@ -362,10 +362,10 @@ namespace Tesses::CrossLang gen.version = version; gen.icon = icon; std::string outpath; - TStreamHeapObject* stream; - if(GetObjectHeap(_out, stream)) + std::shared_ptr stream; + if(GetObject(_out, stream)) { - gen.Save(vfsHO != nullptr ? vfsHO->vfs : nullptr, stream->stream); + gen.Save(vfs, stream); } @@ -403,11 +403,11 @@ namespace Tesses::CrossLang } }); dict->DeclareFunction(gc, "LoadExecutable", "Load a crossvm executable",{"stream"},[](GCList& ls,std::vector args)->TObject{ - TStreamHeapObject* strm; - if(GetArgumentHeap(args,0,strm)) + std::shared_ptr strm; + if(GetArgument(args,0,strm)) { TFile* f =TFile::Create(ls); - f->Load(ls.GetGC(),strm->stream); + f->Load(ls.GetGC(),strm); return f; } return nullptr; @@ -431,30 +431,30 @@ namespace Tesses::CrossLang return Undefined(); }); dict->DeclareFunction(gc, "Merge", "Merge crvm files", {"srcVFS","sourcePath","destVFS"},[](GCList& ls, std::vector args)->TObject { - TVFSHeapObject* srcVFS; - TVFSHeapObject* destVFS; + std::shared_ptr srcVFS; + std::shared_ptr destVFS; Tesses::Framework::Filesystem::VFSPath sourcePath; - if(GetArgumentHeap(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgumentHeap(args,2,destVFS)) - return Merge(srcVFS->vfs, sourcePath, destVFS->vfs); + if(GetArgument(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgument(args,2,destVFS)) + return Merge(srcVFS, sourcePath, destVFS); return Undefined(); }); dict->DeclareFunction(gc, "Disassemble","Disassemble crvm file",{"strm","vfs","$generateJSON","$extractResources"},[](GCList& ls, std::vector args)->TObject { - TStreamHeapObject* strm; - TVFSHeapObject* vfs; + std::shared_ptr strm; + std::shared_ptr vfs; bool generateJSON=true; bool extractResources=true; - if(GetArgumentHeap(args,0,strm) && GetArgumentHeap(args,1, vfs)) + if(GetArgument(args,0,strm) && GetArgument(args,1, vfs)) { GetArgument(args,2,generateJSON); GetArgument(args,3,extractResources); - Disassemble(strm->stream,vfs->vfs, generateJSON, extractResources); + Disassemble(strm,vfs, generateJSON, extractResources); } return Undefined(); }); dict->DeclareFunction(gc, "Assemble", "Assemble crvm file",{"vfs"},[](GCList& ls, std::vector args)->TObject { - TVFSHeapObject* vfs; - if(GetArgumentHeap(args,0, vfs)) - return Assemble(vfs->vfs); + std::shared_ptr vfs; + if(GetArgument(args,0, vfs)) + return Assemble(vfs); return Undefined(); }); diff --git a/src/types/rootenvironment.cpp b/src/types/rootenvironment.cpp index e39462c..d485921 100644 --- a/src/types/rootenvironment.cpp +++ b/src/types/rootenvironment.cpp @@ -65,7 +65,7 @@ namespace Tesses::CrossLang { return value; } - void TRootEnvironment::LoadDependency(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, std::pair dep) + void TRootEnvironment::LoadDependency(GC* gc,std::shared_ptr vfs, std::pair dep) { for(auto item : this->dependencies) if(item.first == dep.first && item.second.CompareTo(dep.second) >= 0) return; @@ -78,11 +78,11 @@ namespace Tesses::CrossLang { if(vfs->RegularFileExists(filename)) { - Tesses::Framework::Streams::Stream* file = vfs->OpenFile(filename,"rb"); + auto file = vfs->OpenFile(filename,"rb"); GCList ls(gc); TFile* f = TFile::Create(ls); f->Load(gc, file); - delete file; + LoadFileWithDependencies(gc, vfs, f); } else throw VMException("Could not open file: \"" + name + "\"."); @@ -100,11 +100,11 @@ namespace Tesses::CrossLang { SyntaxNode n = parser.ParseRoot(); CodeGen gen; gen.GenRoot(n); - Tesses::Framework::Streams::MemoryStream ms(true); - gen.Save(nullptr, &ms); - ms.Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); + auto ms = std::make_shared(true); + gen.Save(nullptr, ms); + ms->Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin); TFile* f = TFile::Create(ls); - f->Load(ls.GetGC(),&ms); + f->Load(ls.GetGC(),ms); return this->LoadFile(ls.GetGC(), f); } TDictionary* TEnvironment::EnsureDictionary(GC* gc, std::string key) @@ -241,7 +241,7 @@ namespace Tesses::CrossLang { } return nullptr; } - void TRootEnvironment::LoadFileWithDependencies(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, TFile* file) + void TRootEnvironment::LoadFileWithDependencies(GC* gc,std::shared_ptr vfs, TFile* file) { this->dependencies.push_back(std::pair(file->name,file->version)); for(auto item : file->dependencies) @@ -251,19 +251,19 @@ namespace Tesses::CrossLang { LoadFile(gc, file); } - void TRootEnvironment::LoadFileWithDependencies(GC* gc,Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path) + void TRootEnvironment::LoadFileWithDependencies(GC* gc,std::shared_ptr vfs, Tesses::Framework::Filesystem::VFSPath path) { if(vfs->RegularFileExists(path)) { - Tesses::Framework::Streams::Stream* file=vfs->OpenFile(path,"rb"); + auto file=vfs->OpenFile(path,"rb"); GCList ls(gc); TFile* f = TFile::Create(ls); f->Load(gc, file); - delete file; - Tesses::Framework::Filesystem::SubdirFilesystem dir(vfs,path.GetParent(),false); - LoadFileWithDependencies(gc,&dir,f); + + auto dir = std::make_shared(vfs,path.GetParent()); + LoadFileWithDependencies(gc,dir,f); } else throw VMException("Could not open file: \"" + path.GetFileName() + "\"."); diff --git a/src/types/streamheapobject.cpp b/src/types/streamheapobject.cpp index 74093d2..d8bf408 100644 --- a/src/types/streamheapobject.cpp +++ b/src/types/streamheapobject.cpp @@ -70,23 +70,18 @@ namespace Tesses::CrossLang bool TObjectStream::EndOfStream() { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { auto res = dict->CallMethod(*ls, "getEndOfStream",{}); bool r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->EndOfStream(); - } + return false; } size_t TObjectStream::Read(uint8_t* buff, size_t sz) { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { GCList ls2(this->ls->GetGC()); @@ -101,16 +96,11 @@ namespace Tesses::CrossLang int64_t r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->Read(buff,sz); - } return 0; } size_t TObjectStream::Write(const uint8_t* buff, size_t sz) { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { GCList ls2(this->ls->GetGC()); @@ -123,124 +113,92 @@ namespace Tesses::CrossLang int64_t r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->Write(buff,sz); - } + return 0; } bool TObjectStream::CanRead() { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { auto res = dict->CallMethod(*ls, "getCanRead",{}); bool r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->CanRead(); - } + return false; } bool TObjectStream::CanWrite() { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { auto res = dict->CallMethod(*ls, "getCanWrite",{}); bool r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->CanWrite(); - } return false; } bool TObjectStream::CanSeek() { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { auto res = dict->CallMethod(*ls, "getCanSeek",{}); bool r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->CanSeek(); - } + return false; } int64_t TObjectStream::GetPosition() { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { auto res = dict->CallMethod(*ls, "getPosition",{}); int64_t r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->GetPosition(); - } + return 0; } int64_t TObjectStream::GetLength() { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { auto res = dict->CallMethod(*ls, "getEndOfStream",{}); bool r; if(GetObject(res,r)) return r; } - else if(GetObjectHeap(this->obj, strm)) - { - return strm->stream->GetLength(); - } + return Tesses::Framework::Streams::Stream::GetLength(); } void TObjectStream::Flush() { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { dict->CallMethod(*ls, "Flush",{}); } - else if(GetObjectHeap(this->obj, strm)) - { - strm->stream->Flush(); - } + } void TObjectStream::Seek(int64_t pos, Tesses::Framework::Streams::SeekOrigin whence) { TDictionary* dict; - TStreamHeapObject* strm; if(GetObjectHeap(this->obj, dict)) { dict->CallMethod(*ls, "Seek",{pos,(int64_t)(whence == Tesses::Framework::Streams::SeekOrigin::Begin ? 0 : whence == Tesses::Framework::Streams::SeekOrigin::Current ? 1 : 2) }); } - else if(GetObjectHeap(this->obj, strm)) - { - strm->stream->Seek(pos,whence); - } + } TObjectStream::~TObjectStream() { @@ -248,37 +206,6 @@ namespace Tesses::CrossLang } - TStreamHeapObject* TStreamHeapObject::Create(GCList& ls, Tesses::Framework::Streams::Stream* strm) - { - TStreamHeapObject* heapObj = new TStreamHeapObject(); - GC* _gc = ls.GetGC(); - ls.Add(heapObj); - _gc->Watch(heapObj); - heapObj->stream = strm; - return heapObj; - } - TStreamHeapObject* TStreamHeapObject::Create(GCList* ls, Tesses::Framework::Streams::Stream* strm) - { - TStreamHeapObject* heapObj = new TStreamHeapObject(); - GC* _gc = ls->GetGC(); - ls->Add(heapObj); - _gc->Watch(heapObj); - heapObj->stream = strm; - return heapObj; - } - TStreamHeapObject::~TStreamHeapObject() - { - if(this->stream != nullptr) - { - delete this->stream; - } - } - void TStreamHeapObject::Close() - { - if(this->stream != nullptr) - { - delete this->stream; - this->stream = nullptr; - } - } + + } \ No newline at end of file diff --git a/src/types/vfsheapobject.cpp b/src/types/vfsheapobject.cpp index b25af7c..58d086c 100644 --- a/src/types/vfsheapobject.cpp +++ b/src/types/vfsheapobject.cpp @@ -131,34 +131,26 @@ namespace Tesses::CrossLang { } } - Tesses::Framework::Streams::Stream* TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode) + std::shared_ptr TObjectVFS::OpenFile(Tesses::Framework::Filesystem::VFSPath path, std::string mode) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->OpenFile(path,mode); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); auto res = dict->CallMethod(ls, "OpenFile",{path,mode}); - TStreamHeapObject* strm; - if(GetObjectHeap(res,strm)) + std::shared_ptr strm; + if(GetObject(res,strm)) { - return new TObjectStream(this->ls->GetGC(), strm); + return strm; } } return nullptr; } void TObjectVFS::CreateDirectory(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->CreateDirectory(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -169,12 +161,7 @@ namespace Tesses::CrossLang { } void TObjectVFS::DeleteDirectory(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->DeleteDirectory(path); - } if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -185,12 +172,7 @@ namespace Tesses::CrossLang { bool TObjectVFS::RegularFileExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->RegularFileExists(path); - } if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -206,12 +188,8 @@ namespace Tesses::CrossLang { bool TObjectVFS::SymlinkExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->SymlinkExists(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -226,12 +204,8 @@ namespace Tesses::CrossLang { } bool TObjectVFS::CharacterDeviceExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->CharacterDeviceExists(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -246,12 +220,8 @@ namespace Tesses::CrossLang { } bool TObjectVFS::BlockDeviceExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->BlockDeviceExists(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -266,12 +236,8 @@ namespace Tesses::CrossLang { } bool TObjectVFS::SocketFileExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->SocketFileExists(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -286,12 +252,8 @@ namespace Tesses::CrossLang { } bool TObjectVFS::FIFOFileExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->FIFOFileExists(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -306,12 +268,8 @@ namespace Tesses::CrossLang { } bool TObjectVFS::FileExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->FileExists(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -326,12 +284,8 @@ namespace Tesses::CrossLang { } bool TObjectVFS::SpecialFileExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->SpecialFileExists(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -346,12 +300,8 @@ namespace Tesses::CrossLang { } void TObjectVFS::CreateSymlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath symlinkFile) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->CreateSymlink(existingFile,symlinkFile); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -361,12 +311,8 @@ namespace Tesses::CrossLang { } void TObjectVFS::CreateHardlink(Tesses::Framework::Filesystem::VFSPath existingFile, Tesses::Framework::Filesystem::VFSPath newName) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->CreateHardlink(existingFile,newName); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -376,12 +322,7 @@ namespace Tesses::CrossLang { } bool TObjectVFS::DirectoryExists(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->DirectoryExists(path); - } if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -396,12 +337,8 @@ namespace Tesses::CrossLang { } void TObjectVFS::DeleteFile(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->DeleteFile(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -411,12 +348,8 @@ namespace Tesses::CrossLang { } void TObjectVFS::DeleteDirectoryRecurse(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->DeleteDirectoryRecurse(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -426,12 +359,8 @@ namespace Tesses::CrossLang { } Tesses::Framework::Filesystem::VFSPathEnumerator TObjectVFS::EnumeratePaths(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->EnumeratePaths(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList* ls=new GCList(this->ls->GetGC()); @@ -465,12 +394,8 @@ namespace Tesses::CrossLang { void TObjectVFS::MoveFile(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->MoveFile(src,dest); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -481,12 +406,8 @@ namespace Tesses::CrossLang { void TObjectVFS::MoveDirectory(Tesses::Framework::Filesystem::VFSPath src, Tesses::Framework::Filesystem::VFSPath dest) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->MoveDirectory(src,dest); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -497,12 +418,7 @@ namespace Tesses::CrossLang { Tesses::Framework::Filesystem::VFSPath TObjectVFS::ReadLink(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->ReadLink(path); - } if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -518,12 +434,8 @@ namespace Tesses::CrossLang { std::string TObjectVFS::VFSPathToSystem(Tesses::Framework::Filesystem::VFSPath path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->VFSPathToSystem(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -538,12 +450,8 @@ namespace Tesses::CrossLang { } Tesses::Framework::Filesystem::VFSPath TObjectVFS::SystemToVFSPath(std::string path) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - return vfs->vfs->SystemToVFSPath(path); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -559,12 +467,7 @@ namespace Tesses::CrossLang { void TObjectVFS::GetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime& lastWrite, Tesses::Framework::Date::DateTime& lastAccess) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->GetDate(path,lastWrite,lastAccess); - } if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -589,12 +492,8 @@ namespace Tesses::CrossLang { void TObjectVFS::SetDate(Tesses::Framework::Filesystem::VFSPath path, Tesses::Framework::Date::DateTime lastWrite, Tesses::Framework::Date::DateTime lastAccess) { - TVFSHeapObject* vfs; TDictionary* dict; - if(GetObjectHeap(this->obj, vfs)) - { - vfs->vfs->SetDate(path,lastWrite,lastAccess); - } + if(GetObjectHeap(this->obj, dict)) { GCList ls(this->ls->GetGC()); @@ -604,37 +503,14 @@ namespace Tesses::CrossLang { } TObjectVFS::~TObjectVFS() { + + TDictionary* dict; + if(GetObjectHeap(this->obj, dict)) + { + GCList ls(this->ls->GetGC()); + dict->CallMethod(ls,"Dispose",{}); + } delete this->ls; } - TVFSHeapObject* TVFSHeapObject::Create(GCList& ls, Tesses::Framework::Filesystem::VFS* vfs) - { - TVFSHeapObject* heapObj = new TVFSHeapObject(); - GC* _gc = ls.GetGC(); - ls.Add(heapObj); - _gc->Watch(heapObj); - heapObj->vfs = vfs; - return heapObj; - } - TVFSHeapObject* TVFSHeapObject::Create(GCList* ls, Tesses::Framework::Filesystem::VFS* vfs) - { - TVFSHeapObject* heapObj = new TVFSHeapObject(); - GC* _gc = ls->GetGC(); - ls->Add(heapObj); - _gc->Watch(heapObj); - heapObj->vfs = vfs; - return heapObj; - } - TVFSHeapObject::~TVFSHeapObject() - { - if(this->vfs != nullptr) - delete this->vfs; - } - void TVFSHeapObject::Close() - { - if(this->vfs != nullptr) - { - delete this->vfs; - this->vfs = nullptr; - } - } + } \ No newline at end of file diff --git a/src/vm/filereader.cpp b/src/vm/filereader.cpp index 233913c..dcb76af 100644 --- a/src/vm/filereader.cpp +++ b/src/vm/filereader.cpp @@ -57,7 +57,7 @@ namespace Tesses::CrossLang item->Mark(); } - void TFile::Skip(Tesses::Framework::Streams::Stream* stream,size_t len) + void TFile::Skip(std::shared_ptr stream,size_t len) { if(stream->CanSeek()) { @@ -69,12 +69,12 @@ namespace Tesses::CrossLang delete[] buffer; } } - void TFile::Ensure(Tesses::Framework::Streams::Stream* stream, uint8_t* buffer,size_t len) + void TFile::Ensure(std::shared_ptr stream, uint8_t* buffer,size_t len) { size_t read = stream->ReadBlock(buffer, len); if(read < len) throw VMException("End of file, could not read " + std::to_string((int64_t)len) + " byte(s)., offset=" + std::to_string(stream->GetLength())); } - std::string TFile::EnsureString(Tesses::Framework::Streams::Stream* stream) + std::string TFile::EnsureString(std::shared_ptr stream) { auto len = EnsureInt(stream); if(len == 0) return {}; @@ -84,13 +84,13 @@ namespace Tesses::CrossLang return str; } - uint32_t TFile::EnsureInt(Tesses::Framework::Streams::Stream* stream) + uint32_t TFile::EnsureInt(std::shared_ptr stream) { uint8_t buffer[4]; Ensure(stream,buffer,4); return BitConverter::ToUint32BE(buffer[0]); } - std::string TFile::GetString(Tesses::Framework::Streams::Stream* stream) + std::string TFile::GetString(std::shared_ptr stream) { uint32_t index=EnsureInt(stream); if(index >= this->strings.size()) throw VMException("String does not exist in TCrossVM file, expected string index: " + std::to_string(index) + ", total strings: " + std::to_string(this->strings.size())); @@ -118,7 +118,7 @@ namespace Tesses::CrossLang throw VMException(errorMessage); } - void TFile::Load(GC* gc, Tesses::Framework::Streams::Stream* stream) + void TFile::Load(GC* gc, std::shared_ptr stream) { uint8_t main_header[18]; diff --git a/src/vm/vm.cpp b/src/vm/vm.cpp index 60bd75b..2b253d7 100644 --- a/src/vm/vm.cpp +++ b/src/vm/vm.cpp @@ -9,6 +9,8 @@ namespace Tesses::CrossLang { + + extern bool IHttpServer_Handle(std::shared_ptr svr,std::vector& args); thread_local CallStackEntry* current_function=nullptr; @@ -3222,6 +3224,676 @@ namespace Tesses::CrossLang { cse.back()->Push(gc, nullptr); return false; + } + else if(std::holds_alternative>(instance)) + { + auto strm = std::get>(instance); + if(strm != nullptr) + { + auto memStrm = std::dynamic_pointer_cast(strm); + auto netStrm = std::dynamic_pointer_cast(strm); + + auto mystrm = std::dynamic_pointer_cast(strm); + + if(mystrm != nullptr) + { + TDictionary* dict2; + if(GetObjectHeap(mystrm->obj, dict2)) + { + + gc->BarrierBegin(); + auto o = dict2->GetValue(key); + gc->BarrierEnd(); + + return InvokeMethod(ls,o,dict2,args); + } + } + if(memStrm != nullptr) + { + if(key == "GetBytes") + { + auto res = TByteArray::Create(ls); + res->data = memStrm->GetBuffer(); + cse.back()->Push(gc, res); + return false; + } + } + if(netStrm != nullptr) + { + if(key == "GetPort") + { + cse.back()->Push(gc, (int64_t)netStrm->GetPort()); + return false; + } + if(key == "Bind") + { + std::string ip; + int64_t port; + if(GetArgument(args,0,ip) && GetArgument(args,1,port)) + netStrm->Bind(ip,(uint16_t)port); + + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "Accept") + { + std::string ip; + uint16_t port; + auto strm = netStrm->Accept(ip,port); + TDictionary* dict = TDictionary::Create(ls); + gc->BarrierBegin(); + dict->SetValue("IP",ip); + dict->SetValue("Port",(int64_t)port); + dict->SetValue("Stream", strm); + + gc->BarrierEnd(); + cse.back()->Push(gc, dict); + return false; + } + if(key == "Listen") + { + int64_t backlog; + if(GetArgument(args,0,backlog)) + { + netStrm->Listen((int32_t)backlog); + } + else + { + netStrm->Listen(10); + } + + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "ReadFrom") + { + TByteArray* data; + int64_t offset; + int64_t length; + if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) + { + size_t off = (size_t)offset; + size_t len = (size_t)length; + std::string ip={}; + uint16_t port=0; + + if(off < len) + + len = netStrm->ReadFrom(data->data.data()+off,std::min(len,std::min(data->data.size() - off, data->data.size())),ip,port); + + else + len = 0; + + TDictionary* dict = TDictionary::Create(ls); + gc->BarrierBegin(); + dict->SetValue("IP",ip); + dict->SetValue("Port",(int64_t)port); + dict->SetValue("Read", (int64_t)len); + + gc->BarrierEnd(); + cse.back()->Push(gc, dict); + + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "WriteTo") + { + TByteArray* data; + int64_t offset; + int64_t length; + std::string ip; + int64_t port; + if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length) && GetArgument(args,3,ip) && GetArgument(args,4,port)) + { + size_t off = (size_t)offset; + size_t len = (size_t)length; + + if(off < len) + + len = netStrm->WriteTo(data->data.data()+off,std::min(len, std::min(data->data.size() - off, data->data.size())), ip, (int64_t)port); + + else + len = 0; + + cse.back()->Push(gc, (int64_t)len); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + } + + if(key == "Read") + { + TByteArray* data; + int64_t offset; + int64_t length; + if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) + { + size_t off = (size_t)offset; + size_t len = (size_t)length; + + if(off < len) + + len = strm->Read(data->data.data()+off,std::min(len,std::min(data->data.size() - off, data->data.size()))); + + else + len = 0; + + cse.back()->Push(gc, (int64_t)len); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "Write") + { + TByteArray* data; + int64_t offset; + int64_t length; + if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) + { + size_t off = (size_t)offset; + size_t len = (size_t)length; + + if(off < len) + + len = strm->Write(data->data.data()+off,std::min(len, std::min(data->data.size() - off, data->data.size()))); + + else + len = 0; + + cse.back()->Push(gc, (int64_t)len); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "ReadBlock") + { + TByteArray* data; + int64_t offset; + int64_t length; + if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) + { + size_t off = (size_t)offset; + size_t len = (size_t)length; + + if(off < len) + + len = strm->ReadBlock(data->data.data()+off,std::min(len, std::min(data->data.size() - off, data->data.size()))); + + else + len = 0; + + cse.back()->Push(gc, (int64_t)len); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "WriteText") + { + std::string text; + + if(GetArgument(args,0,text)) + { + strm->WriteBlock((const uint8_t*)text.data(), text.size()); + } + + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "WriteBlock") + { + TByteArray* data; + int64_t offset; + int64_t length; + if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) + { + size_t off = (size_t)offset; + size_t len = (size_t)length; + + if(off < len) + + strm->WriteBlock(data->data.data()+off,std::min(len,std::min(data->data.size() - off, data->data.size()))); + + + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "CopyTo") + { + std::shared_ptr data; + int64_t buffSize; + if(GetArgument(args,0,data)) + { + if(!GetArgument(args,1,buffSize)) buffSize=1024; + strm->CopyTo(data,(size_t)buffSize); + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "Flush") + { + strm->Flush(); + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "Seek") + { + int64_t pos,whence; + if(!GetArgument(args,0,pos)) pos=0; + + if(!GetArgument(args,1,whence)) whence=0; + + + strm->Seek(pos, whence == 0 ? Tesses::Framework::Streams::SeekOrigin::Begin : whence == 1 ? Tesses::Framework::Streams::SeekOrigin::Current : Tesses::Framework::Streams::SeekOrigin::End); + + cse.back()->Push(gc, nullptr); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + } + else if(std::holds_alternative>(instance)) + { + auto svr = std::get>(instance); + if(svr != nullptr) + { + auto mountable = std::dynamic_pointer_cast(svr); + if(mountable != nullptr) + { + if(key == "Mount") + { + Tesses::Framework::Filesystem::VFSPath p; + + if(args.size() > 1 && GetArgumentAsPath(args,0,p)) + { + std::shared_ptr svr2=ToHttpServer(gc,args[1]); + + if(svr2) + mountable->Mount(p.ToString(), svr2); + + cse.back()->Push(gc,nullptr); + return false; + } + } + if(key == "Unmount") + { + Tesses::Framework::Filesystem::VFSPath p; + + if(GetArgumentAsPath(args,0,p)) + { + mountable->Unmount(p.ToString()); + cse.back()->Push(gc,nullptr); + return false; + } + } + } + if(key == "Handle") + { + cse.back()->Push(gc,IHttpServer_Handle(svr,args)); + return false; + } + cse.back()->Push(gc,Undefined()); + return false; + } + } + else if(std::holds_alternative>(instance)) + { + auto vfs = std::get>(instance); + if(vfs != nullptr) + { + auto myvfs = std::dynamic_pointer_cast(vfs); + + auto mountable = std::dynamic_pointer_cast(vfs); + if(myvfs != nullptr) + { + TDictionary* dict2; + if(GetObjectHeap(myvfs->obj, dict2)) + { + + gc->BarrierBegin(); + auto o = dict2->GetValue(key); + gc->BarrierEnd(); + + return InvokeMethod(ls,o,dict2,args); + } + } + if(mountable != nullptr) + { + if(key == "Unmount") + { + Tesses::Framework::Filesystem::VFSPath path; + + if(GetArgumentAsPath(args,0,path)) + { + mountable->Unmount(path); + } + + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "Mount") + { + Tesses::Framework::Filesystem::VFSPath path; + std::shared_ptr vfs2; + if(GetArgumentAsPath(args,0,path) && GetArgument(args,1,vfs2)) + { + + //mountable->Mount(path, , true); + mountable->Mount(path, vfs2); + } + + cse.back()->Push(gc, nullptr); + return false; + } + } + + if(key == "EnumeratePaths") + { + Tesses::Framework::Filesystem::VFSPath dir; + if(GetArgumentAsPath(args,0,dir)) + { + auto tem = TExternalMethod::Create(ls,"Get the enumerator",{},[vfs,dir](GCList& ls, std::vector args)->TObject{ + return TVFSPathEnumerator::Create(ls,vfs->EnumeratePaths(dir)); + }); + auto d1=TDictionary::Create(ls); + gc->BarrierBegin(); + tem->watch.push_back(vfs); + d1->SetValue("GetEnumerator", tem); + gc->BarrierEnd(); + + cse.back()->Push(gc,d1); + return false; + } + + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "MoveDirectory") + { + Tesses::Framework::Filesystem::VFSPath existingFile; + + Tesses::Framework::Filesystem::VFSPath symlinkFile; + if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) + { + vfs->MoveDirectory(existingFile,symlinkFile); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "SetDate") + { + Tesses::Framework::Filesystem::VFSPath path; + TDateTime lastWrite; + TDateTime lastAccess; + if(GetArgumentAsPath(args,0,path) && GetArgument(args,1,lastWrite) && GetArgument(args,2,lastAccess)) + { + vfs->SetDate(path,lastWrite.GetDate(), lastAccess.GetDate()); + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "GetDate") + { + Tesses::Framework::Filesystem::VFSPath path; + if(GetArgumentAsPath(args,0,path)) + { + Tesses::Framework::Date::DateTime lastWrite; + Tesses::Framework::Date::DateTime lastAccess; + vfs->GetDate(path,lastWrite,lastAccess); + + auto dict = TDictionary::Create(ls); + ls.GetGC()->BarrierBegin(); + + dict->SetValue("LastWrite", TDateTime(lastWrite)); + dict->SetValue("LastAccess", TDateTime(lastAccess)); + ls.GetGC()->BarrierEnd(); + + cse.back()->Push(gc, dict); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "MoveFile") + { + Tesses::Framework::Filesystem::VFSPath existingFile; + + Tesses::Framework::Filesystem::VFSPath symlinkFile; + if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) + { + vfs->MoveFile(existingFile,symlinkFile); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "CreateHardlink") + { + Tesses::Framework::Filesystem::VFSPath existingFile; + + Tesses::Framework::Filesystem::VFSPath symlinkFile; + if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) + { + vfs->CreateHardlink(existingFile,symlinkFile); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "CreateSymlink") + { + Tesses::Framework::Filesystem::VFSPath existingFile; + + Tesses::Framework::Filesystem::VFSPath symlinkFile; + if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) + { + vfs->CreateSymlink(existingFile,symlinkFile); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "RegularFileExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->RegularFileExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "SpecialFileExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->SpecialFileExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "FIFOFileExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->FIFOFileExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "SocketFileExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->SocketFileExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "BlockDeviceExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->BlockDeviceExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "CharacterDeviceExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->CharacterDeviceExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "SymlinkExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->SymlinkExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "DirectoryExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->DirectoryExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "FileExists") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->FileExists(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "ReadLink") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->ReadLink(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "VFSPathToSystem") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + cse.back()->Push(gc,vfs->VFSPathToSystem(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "SystemToVFSPath") + { + std::string filename; + if(GetArgument(args,0,filename)) + { + cse.back()->Push(gc,vfs->SystemToVFSPath(filename)); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "DeleteFile") + { + Tesses::Framework::Filesystem::VFSPath filename; + if(GetArgumentAsPath(args,0,filename)) + { + vfs->DeleteFile(filename); + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "DeleteDirectoryRecurse") + { + Tesses::Framework::Filesystem::VFSPath dirname; + if(GetArgumentAsPath(args,0,dirname)) + { + vfs->DeleteDirectoryRecurse(dirname); + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "DeleteDirectory") + { + Tesses::Framework::Filesystem::VFSPath dirname; + if(GetArgumentAsPath(args,0,dirname)) + { + vfs->DeleteDirectory(dirname); + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "CreateDirectory") + { + + Tesses::Framework::Filesystem::VFSPath dirname; + if(GetArgumentAsPath(args,0,dirname)) + { + vfs->CreateDirectory(dirname); + } + cse.back()->Push(gc, nullptr); + return false; + } + if(key == "OpenFile") + { + + Tesses::Framework::Filesystem::VFSPath path; + std::string mode; + if(GetArgumentAsPath(args,0,path) && GetArgument(args,1,mode)) + { + auto res = vfs->OpenFile(path,mode); + cse.back()->Push(gc, res); + return false; + } + cse.back()->Push(gc, nullptr); + return false; + } + + cse.back()->Push(gc, nullptr); + return false; + } + } else if(std::holds_alternative(instance)) { @@ -3232,8 +3904,7 @@ namespace Tesses::CrossLang { auto dict = dynamic_cast(obj); auto dynDict = dynamic_cast(obj); auto ittr = dynamic_cast(obj); - auto strm = dynamic_cast(obj); - auto vfs = dynamic_cast(obj); + auto env = dynamic_cast(obj); auto subEnv = dynamic_cast(obj); @@ -3242,7 +3913,6 @@ namespace Tesses::CrossLang { auto callstackEntry = dynamic_cast(obj); - auto svr = dynamic_cast(obj); auto natObj = dynamic_cast(obj); auto cls = dynamic_cast(obj); auto aArray=dynamic_cast(obj); @@ -3299,48 +3969,7 @@ namespace Tesses::CrossLang { } } - if(svr != nullptr) - { - auto mountable = dynamic_cast(svr->server); - if(mountable != nullptr) - { - if(key == "Mount") - { - Tesses::Framework::Filesystem::VFSPath p; - - if(args.size() > 1 && GetArgumentAsPath(args,0,p)) - { - mountable->Mount(p.ToString(),new TObjectHttpServer(gc,args[1]),true); - cse.back()->Push(gc,nullptr); - return false; - } - } - if(key == "Unmount") - { - Tesses::Framework::Filesystem::VFSPath p; - - if(GetArgumentAsPath(args,0,p)) - { - mountable->Unmount(p.ToString()); - cse.back()->Push(gc,nullptr); - return false; - } - } - } - if(key == "Handle") - { - cse.back()->Push(gc,svr->Handle(args)); - return false; - } - if(key == "Close") - { - svr->Close(); - cse.back()->Push(gc, nullptr); - return false; - } - cse.back()->Push(gc,Undefined()); - return false; - } + if(rootEnv != nullptr) { //TStd::RegisterCrypto @@ -3590,18 +4219,18 @@ namespace Tesses::CrossLang { } if(key == "LoadFileWithDependencies") { - TVFSHeapObject* vfs0; + std::shared_ptr vfs0; TFile* f; Tesses::Framework::Filesystem::VFSPath p; - if(GetArgumentHeap(args,0,vfs0) ) + if(GetArgument(args,0,vfs0) ) { if(GetArgumentHeap(args,1,f)) { - rootEnv->LoadFileWithDependencies(gc,vfs0->vfs,f); + rootEnv->LoadFileWithDependencies(gc,vfs0,f); } else if(GetArgumentAsPath(args,1,p)) { - rootEnv->LoadFileWithDependencies(gc,vfs0->vfs,p); + rootEnv->LoadFileWithDependencies(gc,vfs0,p); } } cse.back()->Push(gc,nullptr); @@ -3694,636 +4323,8 @@ namespace Tesses::CrossLang { cse.back()->Push(gc,nullptr); return false; } - if(vfs != nullptr) - { - auto myvfs = dynamic_cast(vfs->vfs); - - auto mountable = dynamic_cast(vfs->vfs); - if(myvfs != nullptr) - { - TDictionary* dict2; - if(GetObjectHeap(myvfs->obj, dict2)) - { - - gc->BarrierBegin(); - auto o = dict2->GetValue(key); - gc->BarrierEnd(); - - return InvokeMethod(ls,o,dict2,args); - } - } - if(mountable != nullptr) - { - if(key == "Unmount") - { - Tesses::Framework::Filesystem::VFSPath path; - - if(GetArgumentAsPath(args,0,path)) - { - mountable->Unmount(path); - } - - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "Mount") - { - Tesses::Framework::Filesystem::VFSPath path; - TVFSHeapObject* vfs2; - if(GetArgumentAsPath(args,0,path) && GetArgumentHeap(args,1,vfs2)) - { - TObjectVFS* vfs3 = new TObjectVFS(gc, vfs2); - //mountable->Mount(path, , true); - mountable->Mount(path, vfs3, true); - } - - cse.back()->Push(gc, nullptr); - return false; - } - } - - if(key == "EnumeratePaths") - { - Tesses::Framework::Filesystem::VFSPath dir; - if(GetArgumentAsPath(args,0,dir)) - { - auto tem = TExternalMethod::Create(ls,"Get the enumerator",{},[vfs,dir](GCList& ls, std::vector args)->TObject{ - return TVFSPathEnumerator::Create(ls,vfs->vfs->EnumeratePaths(dir)); - }); - auto d1=TDictionary::Create(ls); - gc->BarrierBegin(); - tem->watch.push_back(vfs); - d1->SetValue("GetEnumerator", tem); - gc->BarrierEnd(); - - cse.back()->Push(gc,d1); - return false; - } - - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "MoveDirectory") - { - Tesses::Framework::Filesystem::VFSPath existingFile; - - Tesses::Framework::Filesystem::VFSPath symlinkFile; - if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) - { - vfs->vfs->MoveDirectory(existingFile,symlinkFile); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "SetDate") - { - Tesses::Framework::Filesystem::VFSPath path; - TDateTime lastWrite; - TDateTime lastAccess; - if(GetArgumentAsPath(args,0,path) && GetArgument(args,1,lastWrite) && GetArgument(args,2,lastAccess)) - { - vfs->vfs->SetDate(path,lastWrite.GetDate(), lastAccess.GetDate()); - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "GetDate") - { - Tesses::Framework::Filesystem::VFSPath path; - if(GetArgumentAsPath(args,0,path)) - { - Tesses::Framework::Date::DateTime lastWrite; - Tesses::Framework::Date::DateTime lastAccess; - vfs->vfs->GetDate(path,lastWrite,lastAccess); - - auto dict = TDictionary::Create(ls); - ls.GetGC()->BarrierBegin(); - - dict->SetValue("LastWrite", TDateTime(lastWrite)); - dict->SetValue("LastAccess", TDateTime(lastAccess)); - ls.GetGC()->BarrierEnd(); - - cse.back()->Push(gc, dict); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "MoveFile") - { - Tesses::Framework::Filesystem::VFSPath existingFile; - - Tesses::Framework::Filesystem::VFSPath symlinkFile; - if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) - { - vfs->vfs->MoveFile(existingFile,symlinkFile); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "CreateHardlink") - { - Tesses::Framework::Filesystem::VFSPath existingFile; - - Tesses::Framework::Filesystem::VFSPath symlinkFile; - if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) - { - vfs->vfs->CreateHardlink(existingFile,symlinkFile); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "CreateSymlink") - { - Tesses::Framework::Filesystem::VFSPath existingFile; - - Tesses::Framework::Filesystem::VFSPath symlinkFile; - if(GetArgumentAsPath(args,0,existingFile) && GetArgumentAsPath(args,1,symlinkFile)) - { - vfs->vfs->CreateSymlink(existingFile,symlinkFile); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "RegularFileExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->RegularFileExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "SpecialFileExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->SpecialFileExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "FIFOFileExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->FIFOFileExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "SocketFileExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->SocketFileExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "BlockDeviceExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->BlockDeviceExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "CharacterDeviceExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->CharacterDeviceExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "SymlinkExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->SymlinkExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "DirectoryExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->DirectoryExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "FileExists") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->FileExists(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "ReadLink") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->ReadLink(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "VFSPathToSystem") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->VFSPathToSystem(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "SystemToVFSPath") - { - std::string filename; - if(GetArgument(args,0,filename)) - { - cse.back()->Push(gc,vfs->vfs->SystemToVFSPath(filename)); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "DeleteFile") - { - Tesses::Framework::Filesystem::VFSPath filename; - if(GetArgumentAsPath(args,0,filename)) - { - vfs->vfs->DeleteFile(filename); - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "DeleteDirectoryRecurse") - { - Tesses::Framework::Filesystem::VFSPath dirname; - if(GetArgumentAsPath(args,0,dirname)) - { - vfs->vfs->DeleteDirectoryRecurse(dirname); - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "DeleteDirectory") - { - Tesses::Framework::Filesystem::VFSPath dirname; - if(GetArgumentAsPath(args,0,dirname)) - { - vfs->vfs->DeleteDirectory(dirname); - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "CreateDirectory") - { - - Tesses::Framework::Filesystem::VFSPath dirname; - if(GetArgumentAsPath(args,0,dirname)) - { - vfs->vfs->CreateDirectory(dirname); - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "OpenFile") - { - - Tesses::Framework::Filesystem::VFSPath path; - std::string mode; - if(GetArgumentAsPath(args,0,path) && GetArgument(args,1,mode)) - { - auto res = vfs->vfs->OpenFile(path,mode); - TStreamHeapObject* strm = TStreamHeapObject::Create(ls,res); - cse.back()->Push(gc, strm); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "Close") - { - vfs->Close(); - cse.back()->Push(gc, nullptr); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } + - if(strm != nullptr) - { - auto memStrm = dynamic_cast(strm->stream); - auto netStrm = dynamic_cast(strm->stream); - - auto mystrm = dynamic_cast(strm->stream); - - if(mystrm != nullptr) - { - TDictionary* dict2; - if(GetObjectHeap(mystrm->obj, dict2)) - { - - gc->BarrierBegin(); - auto o = dict2->GetValue(key); - gc->BarrierEnd(); - - return InvokeMethod(ls,o,dict2,args); - } - } - if(memStrm != nullptr) - { - if(key == "GetBytes") - { - auto res = TByteArray::Create(ls); - res->data = memStrm->GetBuffer(); - cse.back()->Push(gc, res); - return false; - } - } - if(netStrm != nullptr) - { - if(key == "GetPort") - { - cse.back()->Push(gc, (int64_t)netStrm->GetPort()); - return false; - } - if(key == "Bind") - { - std::string ip; - int64_t port; - if(GetArgument(args,0,ip) && GetArgument(args,1,port)) - netStrm->Bind(ip,(uint16_t)port); - - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "Accept") - { - std::string ip; - uint16_t port; - auto strm = netStrm->Accept(ip,port); - TDictionary* dict = TDictionary::Create(ls); - gc->BarrierBegin(); - dict->SetValue("IP",ip); - dict->SetValue("Port",(int64_t)port); - dict->SetValue("Stream", TStreamHeapObject::Create(ls,strm)); - - gc->BarrierEnd(); - cse.back()->Push(gc, dict); - return false; - } - if(key == "Listen") - { - int64_t backlog; - if(GetArgument(args,0,backlog)) - { - netStrm->Listen((int32_t)backlog); - } - else - { - netStrm->Listen(10); - } - - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "ReadFrom") - { - TByteArray* data; - int64_t offset; - int64_t length; - if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) - { - size_t off = (size_t)offset; - size_t len = (size_t)length; - std::string ip={}; - uint16_t port=0; - - if(off < len) - - len = netStrm->ReadFrom(data->data.data()+off,std::min(len,std::min(data->data.size() - off, data->data.size())),ip,port); - - else - len = 0; - - TDictionary* dict = TDictionary::Create(ls); - gc->BarrierBegin(); - dict->SetValue("IP",ip); - dict->SetValue("Port",(int64_t)port); - dict->SetValue("Read", (int64_t)len); - - gc->BarrierEnd(); - cse.back()->Push(gc, dict); - - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "WriteTo") - { - TByteArray* data; - int64_t offset; - int64_t length; - std::string ip; - int64_t port; - if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length) && GetArgument(args,3,ip) && GetArgument(args,4,port)) - { - size_t off = (size_t)offset; - size_t len = (size_t)length; - - if(off < len) - - len = netStrm->WriteTo(data->data.data()+off,std::min(len, std::min(data->data.size() - off, data->data.size())), ip, (int64_t)port); - - else - len = 0; - - cse.back()->Push(gc, (int64_t)len); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - } - - if(key == "Read") - { - TByteArray* data; - int64_t offset; - int64_t length; - if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) - { - size_t off = (size_t)offset; - size_t len = (size_t)length; - - if(off < len) - - len = strm->stream->Read(data->data.data()+off,std::min(len,std::min(data->data.size() - off, data->data.size()))); - - else - len = 0; - - cse.back()->Push(gc, (int64_t)len); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "Write") - { - TByteArray* data; - int64_t offset; - int64_t length; - if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) - { - size_t off = (size_t)offset; - size_t len = (size_t)length; - - if(off < len) - - len = strm->stream->Write(data->data.data()+off,std::min(len, std::min(data->data.size() - off, data->data.size()))); - - else - len = 0; - - cse.back()->Push(gc, (int64_t)len); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "ReadBlock") - { - TByteArray* data; - int64_t offset; - int64_t length; - if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) - { - size_t off = (size_t)offset; - size_t len = (size_t)length; - - if(off < len) - - len = strm->stream->ReadBlock(data->data.data()+off,std::min(len, std::min(data->data.size() - off, data->data.size()))); - - else - len = 0; - - cse.back()->Push(gc, (int64_t)len); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "WriteText") - { - std::string text; - - if(GetArgument(args,0,text)) - { - strm->stream->WriteBlock((const uint8_t*)text.data(), text.size()); - } - - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "WriteBlock") - { - TByteArray* data; - int64_t offset; - int64_t length; - if(GetArgumentHeap(args, 0, data) && GetArgument(args, 1, offset) && GetArgument(args,2,length)) - { - size_t off = (size_t)offset; - size_t len = (size_t)length; - - if(off < len) - - strm->stream->WriteBlock(data->data.data()+off,std::min(len,std::min(data->data.size() - off, data->data.size()))); - - - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "CopyTo") - { - TStreamHeapObject* data; - int64_t buffSize; - if(GetArgumentHeap(args,0,data)) - { - if(!GetArgument(args,1,buffSize)) buffSize=1024; - strm->stream->CopyTo(*data->stream,(size_t)buffSize); - } - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "Flush") - { - strm->stream->Flush(); - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "Seek") - { - int64_t pos,whence; - if(!GetArgument(args,0,pos)) pos=0; - - if(!GetArgument(args,1,whence)) whence=0; - - - strm->stream->Seek(pos, whence == 0 ? Tesses::Framework::Streams::SeekOrigin::Begin : whence == 1 ? Tesses::Framework::Streams::SeekOrigin::Current : Tesses::Framework::Streams::SeekOrigin::End); - - cse.back()->Push(gc, nullptr); - return false; - } - if(key == "Close") - { - strm->Close(); - cse.back()->Push(gc, nullptr); - return false; - } - cse.back()->Push(gc, nullptr); - return false; - } if(ittr != nullptr) { @@ -5202,6 +5203,67 @@ namespace Tesses::CrossLang { cse.back()->Push(gc, Undefined()); return false; } + if(std::holds_alternative>(instance)) + { + auto strm = std::get>(instance); + if(strm != nullptr) + { + auto netStrm = std::dynamic_pointer_cast(strm); + + if(key == "CanRead") + { + ; + + cse.back()->Push(gc, strm->CanRead()); + return false; + } + if(key == "CanWrite") + { + + cse.back()->Push(gc, strm->CanWrite()); + return false; + } + if(key == "CanSeek") + { + + + cse.back()->Push(gc, strm->CanSeek()); + return false; + } + if(key == "EndOfStream") + { + + cse.back()->Push(gc, strm->EndOfStream()); + return false; + } + if(key == "Length") + { + + cse.back()->Push(gc, strm->GetLength()); + return false; + } + if(key == "Position") + { + + cse.back()->Push(gc, strm->GetPosition()); + return false; + } + + if(netStrm != nullptr) + { + if(key == "Port") + { + cse.back()->Push(gc, netStrm->GetPort()); + return false; + } + } + + cse.back()->Push(gc, Undefined()); + + return false; + + } + } if(std::holds_alternative(instance)) { TVMVersion& version = std::get(instance); @@ -5312,8 +5374,7 @@ namespace Tesses::CrossLang { auto closure = dynamic_cast(obj); auto externalMethod = dynamic_cast(obj); auto ittr = dynamic_cast(obj); - auto strm = dynamic_cast(obj); - auto vfs = dynamic_cast(obj); + auto callstackEntry = dynamic_cast(obj); auto file = dynamic_cast(obj); auto chunk = dynamic_cast(obj); @@ -5593,70 +5654,8 @@ namespace Tesses::CrossLang { return false; } - if(strm != nullptr) - { - auto netStrm = dynamic_cast(strm->stream); - auto objStrm = dynamic_cast(strm->stream); - if(objStrm != nullptr) - { - GetObjectHeap(objStrm->obj,dict); - }else{ - if(key == "CanRead") - { - bool r = strm->stream != nullptr ? strm->stream->CanRead() : false; - - cse.back()->Push(gc, r); - return false; - } - if(key == "CanWrite") - { - bool r = strm->stream != nullptr ? strm->stream->CanWrite() : false; - - cse.back()->Push(gc, r); - return false; - } - if(key == "CanSeek") - { - bool r = strm->stream != nullptr ? strm->stream->CanSeek() : false; - - cse.back()->Push(gc, r); - return false; - } - if(key == "EndOfStream") - { - bool r = strm->stream != nullptr ? strm->stream->EndOfStream() : false; - - cse.back()->Push(gc, r); - return false; - } - if(key == "Length") - { - int64_t r = strm->stream != nullptr ? strm->stream->GetLength() : 0; - - cse.back()->Push(gc, r); - return false; - } - if(key == "Position") - { - int64_t r = strm->stream != nullptr ? strm->stream->GetPosition() : 0; - - cse.back()->Push(gc, r); - return false; - } - - cse.back()->Push(gc, Undefined()); - - return false; - } - } - if(vfs != nullptr) - { - auto d = dynamic_cast(vfs->vfs); - if(d != nullptr) - { - GetObjectHeap(d->obj,dict); - } - } + + if(ittr != nullptr) { @@ -5811,11 +5810,26 @@ namespace Tesses::CrossLang { } std::string key = std::get(_key); + if(std::holds_alternative>(instance)) + { + auto strm = std::get>(instance); + + auto netStrm = std::dynamic_pointer_cast(strm); + if(netStrm != nullptr) + { + bool bc; + if(key == "Broadcast" && GetObject(value,bc)) + netStrm->SetBroadcast(bc); + if(key == "NoDelay" && GetObject(value,bc)) + netStrm->SetNoDelay(bc); + } + stk->Push(gc, Undefined()); + return false; + } if(std::holds_alternative(instance)) { auto obj = std::get(instance).obj; - auto vfs = dynamic_cast(obj); - auto strm = dynamic_cast(obj); + auto dict = dynamic_cast(obj); auto dynDict = dynamic_cast(obj); auto natObj = dynamic_cast(obj); @@ -5862,31 +5876,6 @@ namespace Tesses::CrossLang { return false; } } - if(strm != nullptr) - { - auto netStrm = dynamic_cast(strm->stream); - auto objStrm = dynamic_cast(strm->stream); - if(objStrm != nullptr) - { - GetObjectHeap(objStrm->obj,dict); - } - if(netStrm != nullptr && key == "Broadcast") - { - bool r; - if(GetObject(value,r)) netStrm->SetBroadcast(r); - cse.back()->Push(gc,nullptr); - return false; - } - } - if(vfs != nullptr) - { - auto d = dynamic_cast(vfs->vfs); - if(d != nullptr) - { - GetObjectHeap(d->obj,dict); - - } - } if(dynDict != nullptr) { if(dynDict->MethodExists(ls,"set" + key))