Fix crosslang Stat, StatVFS for custom crosslang filesystems and add queryable

This commit is contained in:
2026-05-08 23:10:20 -05:00
parent 28eff630c6
commit 7008a6ae61
13 changed files with 940 additions and 36 deletions
+9
View File
@@ -132,6 +132,7 @@ namespace Tesses::CrossLang
TDynamicDictionary* dynDict;
TDictionary* dict;
TEnumerator* enumerator;
TQueryable* q;
if(GetObject(obj,str))
{
return TStringEnumerator::Create(ls, str);
@@ -156,6 +157,14 @@ namespace Tesses::CrossLang
return enumerator;
}
}
else if(GetObjectHeap(obj, q))
{
return q->GetEnumerator(ls);
}
else if(GetObjectHeap(obj, enumerator))
{
return enumerator;
}
return nullptr;
}
TVFSPathEnumerator* TVFSPathEnumerator::Create(GCList& ls, Tesses::Framework::Filesystem::VFSPathEnumerator enumerator)
+522
View File
@@ -0,0 +1,522 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
TQueryable::TQueryable(TObject parent) : TQueryable(parent,TQueryableMode::Passthrough, {})
{
}
TQueryable::TQueryable(TObject parent, TQueryableMode mode, std::vector<TObject> args): parent(parent), mode(mode), args(args)
{
}
TQueryable* TQueryable::Skip(GCList& ls,int64_t no)
{
return TQueryable::Create(ls,this,TQueryableMode::Skip, {no});
}
TQueryable* TQueryable::SkipWhile(GCList& ls, TCallable* call)
{
return TQueryable::Create(ls,this,TQueryableMode::SkipWhile, {call});
}
TQueryable* TQueryable::Take(GCList& ls, int64_t no)
{
return TQueryable::Create(ls,this,TQueryableMode::Take, {no});
}
TQueryable* TQueryable::TakeWhile(GCList& ls, TCallable* call)
{
return TQueryable::Create(ls,this,TQueryableMode::TakeWhile, {call});
}
TQueryable* TQueryable::Select(GCList& ls, TCallable* call)
{
return TQueryable::Create(ls,this,TQueryableMode::Select, {call});
}
TQueryable* TQueryable::Where(GCList& ls, TCallable* call)
{
return TQueryable::Create(ls,this,TQueryableMode::Where, {call});
}
TList* TQueryable::ToList(GCList& ls)
{
auto gc = ls.GetGC();
GCList ls2(gc);
auto enumerator = this->GetEnumerator(ls);
if(enumerator == nullptr) return nullptr;
auto list = TList::Create(ls);
while(enumerator->MoveNext(gc))
{
gc->BarrierBegin();
list->Add(enumerator->GetCurrent(ls));
gc->BarrierEnd();
}
return list;
}
TQueryable* TQueryable::Create(GCList& ls, TObject parent)
{
TQueryable* queryable = new TQueryable(parent);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
TQueryable* TQueryable::Create(GCList& ls, TObject parent, TQueryableMode mode, std::vector<TObject> args)
{
TQueryable* queryable = new TQueryable(parent, mode,args);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
void TQueryable::Mark()
{
if(this->marked) return;
this->marked=true;
GC::Mark(this->parent);
for(auto& item : args)
GC::Mark(item);
}
void TQueryable::ForEach(std::shared_ptr<GC> gc, TCallable* call)
{
if(call == nullptr) return;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if(enumerator == nullptr) return;
while(enumerator->MoveNext(gc))
{
GCList ls2(gc);
call->Call(ls2,{enumerator->GetCurrent(ls2)});
}
}
int64_t TQueryable::Count(std::shared_ptr<GC> gc, TCallable* call)
{
if(call == nullptr) return 0;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if(enumerator == nullptr) return 0;
int64_t count=0;
while(enumerator->MoveNext(gc))
{
GCList ls2(gc);
if(ToBool(call->Call(ls2,{enumerator->GetCurrent(ls2)}))) count++;
}
return count;
}
int64_t TQueryable::Count(std::shared_ptr<GC> gc)
{
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if(enumerator == nullptr) return 0;
int64_t count=0;
while(enumerator->MoveNext(gc))
{
count++;
}
return count;
}
bool TQueryable::Contains(std::shared_ptr<GC> gc, TObject value)
{
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if(enumerator == nullptr) return false;
while(enumerator->MoveNext(gc))
{
GCList ls2(gc);
if(Equals(gc,value,enumerator->GetCurrent(ls2)))
return true;
}
return false;
}
bool TQueryable::Any(std::shared_ptr<GC> gc, TCallable* call)
{
if(call == nullptr) return false;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if(enumerator == nullptr) return false;
while(enumerator->MoveNext(gc))
{
GCList ls2(gc);
if(ToBool(call->Call(ls2,{enumerator->GetCurrent(ls2)}))) return true;
}
return false;
}
bool TQueryable::All(std::shared_ptr<GC> gc, TCallable* call)
{
if(call == nullptr) return true;
GCList ls(gc);
auto enumerator = this->GetEnumerator(ls);
if(enumerator == nullptr) return true;
while(enumerator->MoveNext(gc))
{
GCList ls2(gc);
if(!ToBool(call->Call(ls2,{enumerator->GetCurrent(ls2)}))) return false;
}
return true;
}
class SkipItterator : public TEnumerator {
private:
TEnumerator* parentEnum;
int64_t skipCount;
SkipItterator(TEnumerator* parentEnum, int64_t skipCount) : parentEnum(parentEnum), skipCount(skipCount)
{
}
public:
static SkipItterator* Create(GCList& ls, TEnumerator* parentEnum, int64_t skipCount)
{
SkipItterator* queryable = new SkipItterator(parentEnum, skipCount);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls)
{
if(this->parentEnum == nullptr) return false;
while(skipCount > 0)
{
if(!this->parentEnum->MoveNext(ls)) {
skipCount=0;
return false;
}
skipCount--;
}
return this->parentEnum->MoveNext(ls);
}
TObject GetCurrent(GCList& ls)
{
return this->parentEnum->GetCurrent(ls);
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(parentEnum != nullptr) parentEnum->Mark();
}
};
class TakeItterator : public TEnumerator {
private:
TEnumerator* parentEnum;
int64_t takeCount;
TakeItterator(TEnumerator* parentEnum, int64_t takeCount) : parentEnum(parentEnum), takeCount(takeCount)
{
}
public:
static TakeItterator* Create(GCList& ls, TEnumerator* parentEnum, int64_t takeCount)
{
TakeItterator* queryable = new TakeItterator(parentEnum, takeCount);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls)
{
if(this->parentEnum == nullptr) return false;
if(takeCount > 0)
{
takeCount--;
return this->parentEnum->MoveNext(ls);
}
return false;
}
TObject GetCurrent(GCList& ls)
{
return this->parentEnum->GetCurrent(ls);
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(parentEnum != nullptr) parentEnum->Mark();
}
};
class SkipWhileItterator : public TEnumerator {
private:
TEnumerator* parentEnum;
TCallable* callable;
SkipWhileItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
{
}
public:
static SkipWhileItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
{
SkipWhileItterator* queryable = new SkipWhileItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls)
{
if(this->parentEnum == nullptr) return false;
ls->BarrierBegin();
auto callable = this->callable;
ls->BarrierEnd();
if(callable != nullptr)
{
while(true)
{
if(this->parentEnum->MoveNext(ls))
{
GCList ls2(ls);
auto result = callable->Call(ls2,{this->parentEnum->GetCurrent(ls2)});
if(!ToBool(result))
{
ls->BarrierBegin();
this->callable=nullptr;
ls->BarrierEnd();
return true;
}
}
else
{
ls->BarrierBegin();
this->callable=nullptr;
ls->BarrierEnd();
return false;
}
}
}
else {
return this->parentEnum->MoveNext(ls);
}
return false;
}
TObject GetCurrent(GCList& ls)
{
return this->parentEnum->GetCurrent(ls);
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(parentEnum != nullptr) parentEnum->Mark();
if(callable != nullptr) callable->Mark();
}
};
class TakeWhileItterator : public TEnumerator {
private:
TEnumerator* parentEnum;
TCallable* callable;
TakeWhileItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
{
}
public:
static TakeWhileItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
{
TakeWhileItterator* queryable = new TakeWhileItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls)
{
if(this->parentEnum == nullptr) return false;
ls->BarrierBegin();
auto callable = this->callable;
ls->BarrierEnd();
if(callable != nullptr)
{
if(this->parentEnum->MoveNext(ls))
{
GCList ls2(ls);
auto result = callable->Call(ls2,{this->parentEnum->GetCurrent(ls2)});
if(!ToBool(result))
{
ls->BarrierBegin();
this->callable=nullptr;
ls->BarrierEnd();
return false;
}
return true;
}
}
return false;
}
TObject GetCurrent(GCList& ls)
{
return this->parentEnum->GetCurrent(ls);
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(parentEnum != nullptr) parentEnum->Mark();
if(callable != nullptr) callable->Mark();
}
};
class WhereItterator : public TEnumerator {
private:
TEnumerator* parentEnum;
TCallable* callable;
WhereItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
{
}
public:
static WhereItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
{
WhereItterator* queryable = new WhereItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls)
{
if(this->parentEnum == nullptr || this->callable == nullptr) return false;
while(this->parentEnum->MoveNext(ls))
{
GCList ls2(ls);
auto cur = this->parentEnum->GetCurrent(ls2);
if(ToBool(callable->Call(ls2,{cur})))
return true;
}
return false;
}
TObject GetCurrent(GCList& ls)
{
return this->parentEnum->GetCurrent(ls);
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(parentEnum != nullptr) parentEnum->Mark();
if(callable != nullptr) callable->Mark();
}
};
class SelectItterator : public TEnumerator {
private:
TEnumerator* parentEnum;
TCallable* callable;
TObject value;
SelectItterator(TEnumerator* parentEnum, TCallable* callable) : parentEnum(parentEnum), callable(callable)
{
}
public:
static SelectItterator* Create(GCList& ls, TEnumerator* parentEnum, TCallable* callable)
{
SelectItterator* queryable = new SelectItterator(parentEnum, callable);
std::shared_ptr<GC> gc = ls.GetGC();
ls.Add(queryable);
gc->Watch(queryable);
return queryable;
}
bool MoveNext(std::shared_ptr<GC> ls)
{
if(this->parentEnum == nullptr || this->callable == nullptr) return false;
if(this->parentEnum->MoveNext(ls))
{
GCList ls2(ls);
auto cur = this->parentEnum->GetCurrent(ls2);
auto value = this->callable->Call(ls2,{cur});
ls->BarrierBegin();
this->value = value;
ls->BarrierEnd();
return true;
}
return false;
}
TObject GetCurrent(GCList& ls)
{
ls.GetGC()->BarrierBegin();
auto value=this->value;
ls.GetGC()->BarrierEnd();
return value;
}
void Mark()
{
if(this->marked) return;
this->marked=true;
if(parentEnum != nullptr) parentEnum->Mark();
if(callable != nullptr) callable->Mark();
GC::Mark(this->value);
}
};
TEnumerator* TQueryable::GetEnumerator(GCList& ls)
{
switch(this->mode)
{
case TQueryableMode::Skip:
{
int64_t skipCount;
if(GetArgument(args,0,skipCount))
return SkipItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), skipCount);
}
break;
case TQueryableMode::Take:
{
int64_t takeCount;
if(GetArgument(args,0,takeCount))
return TakeItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), takeCount);
}
break;
case TQueryableMode::SkipWhile:
{
TCallable* callable;
if(GetArgumentHeap(args,0,callable))
return SkipWhileItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
}
break;
case TQueryableMode::TakeWhile:
{
TCallable* callable;
if(GetArgumentHeap(args,0,callable))
return TakeWhileItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
}
break;
case TQueryableMode::Select:
{
TCallable* callable;
if(GetArgumentHeap(args,0,callable))
return SelectItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
}
break;
case TQueryableMode::Where:
{
TCallable* callable;
if(GetArgumentHeap(args,0,callable))
return WhereItterator::Create(ls, TEnumerator::CreateFromObject(ls, this->parent), callable);
}
break;
}
return TEnumerator::CreateFromObject(ls, this->parent);
}
}
+2 -2
View File
@@ -205,7 +205,7 @@ namespace Tesses::CrossLang
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls,"Close",{});
dict->CallMethod(*ls,"Dispose",{});
}
}
TObjectStream::~TObjectStream()
@@ -213,7 +213,7 @@ namespace Tesses::CrossLang
TDictionary* dict;
if(GetObjectHeap(this->obj, dict))
{
dict->CallMethod(*ls,"Close",{});
dict->CallMethod(*ls,"Dispose",{});
}
delete this->ls;
}
+25 -25
View File
@@ -281,45 +281,45 @@ namespace Tesses::CrossLang {
if(GetObjectHeap(res,_dict))
{
this->ls->GetGC()->BarrierBegin();
_o = dict->GetValue("BlockSize");
_o = _dict->GetValue("BlockSize");
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
_o = dict->GetValue("BlockCount");
_o = _dict->GetValue("BlockCount");
if(GetObject(_o,_num)) data.BlockCount = (uint64_t)_num;
_o = dict->GetValue("Device");
_o = _dict->GetValue("Device");
if(GetObject(_o,_num)) data.Device = (uint64_t)_num;
_o = dict->GetValue("DeviceId");
_o = _dict->GetValue("DeviceId");
if(GetObject(_o,_num)) data.DeviceId = (uint64_t)_num;
_o = dict->GetValue("GroupId");
_o = _dict->GetValue("GroupId");
if(GetObject(_o,_num)) data.GroupId = (uint32_t)_num;
_o = dict->GetValue("HardLinks");
_o = _dict->GetValue("HardLinks");
if(GetObject(_o,_num)) data.HardLinks = (uint64_t)_num;
std::shared_ptr<Tesses::Framework::Date::DateTime> dt;
_o = dict->GetValue("LastAccess");
_o = _dict->GetValue("LastAccess");
if(GetObject(_o,dt)) data.LastAccess = dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = dict->GetValue("LastModified");
_o = _dict->GetValue("LastModified");
if(GetObject(_o,dt)) data.LastModified = dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = dict->GetValue("LastStatus");
_o = _dict->GetValue("LastStatus");
if(GetObject(_o,dt)) data.LastStatus = dt ? *dt : Tesses::Framework::Date::DateTime(0);
_o = dict->GetValue("Mode");
_o = _dict->GetValue("Mode");
if(GetObject(_o,_num)) data.Mode = (uint32_t)_num;
_o = dict->GetValue("Size");
_o = _dict->GetValue("Size");
if(GetObject(_o,_num)) data.Size = (uint64_t)_num;
_o = dict->GetValue("UserId");
_o = _dict->GetValue("UserId");
if(GetObject(_o,_num)) data.UserId = (uint32_t)_num;
@@ -344,28 +344,28 @@ namespace Tesses::CrossLang {
if(GetObjectHeap(res,_dict))
{
this->ls->GetGC()->BarrierBegin();
_o = dict->GetValue("BlockSize");
_o = _dict->GetValue("BlockSize");
if(GetObject(_o,_num)) data.BlockSize = (uint64_t)_num;
_o = dict->GetValue("FragmentSize");
_o = _dict->GetValue("FragmentSize");
if(GetObject(_o,_num)) data.FragmentSize = (uint64_t)_num;
_o = dict->GetValue("Blocks");
_o = _dict->GetValue("Blocks");
if(GetObject(_o,_num)) data.Blocks = (uint64_t)_num;
_o = dict->GetValue("BlocksFree");
_o = _dict->GetValue("BlocksFree");
if(GetObject(_o,_num)) data.BlocksFree = (uint64_t)_num;
_o = dict->GetValue("BlocksAvailable");
_o = _dict->GetValue("BlocksAvailable");
if(GetObject(_o,_num)) data.BlocksAvailable = (uint64_t)_num;
_o = dict->GetValue("TotalInodes");
_o = _dict->GetValue("TotalInodes");
if(GetObject(_o,_num)) data.TotalInodes = (uint64_t)_num;
_o = dict->GetValue("FreeInodes");
_o = _dict->GetValue("FreeInodes");
if(GetObject(_o,_num)) data.FreeInodes = (uint64_t)_num;
_o = dict->GetValue("AvailableInodes");
_o = _dict->GetValue("AvailableInodes");
if(GetObject(_o,_num)) data.AvailableInodes = (uint64_t)_num;
_o = dict->GetValue("Id");
_o = _dict->GetValue("Id");
if(GetObject(_o,_num)) data.Id = (uint64_t)_num;
_o = dict->GetValue("Flags");
_o = _dict->GetValue("Flags");
if(GetObject(_o,_num)) data.Flags = (uint64_t)_num;
_o = dict->GetValue("MaxNameLength");
_o = _dict->GetValue("MaxNameLength");
if(GetObject(_o,_num)) data.MaxNameLength = (uint64_t)_num;
@@ -386,7 +386,7 @@ namespace Tesses::CrossLang {
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls,"Close",{});
dict->CallMethod(ls,"Dispose",{});
}
}
TObjectVFS::~TObjectVFS()
@@ -395,7 +395,7 @@ namespace Tesses::CrossLang {
if(GetObjectHeap(this->obj, dict))
{
GCList ls(this->ls->GetGC());
dict->CallMethod(ls,"Close",{});
dict->CallMethod(ls,"Dispose",{});
}
delete this->ls;
}