Move date to tessesframework

This commit is contained in:
2025-05-10 19:54:03 -05:00
parent cabe5ba8cd
commit a684c9ba45
16 changed files with 404 additions and 20675 deletions

View File

@ -83,9 +83,19 @@ namespace Tesses::CrossLang
dict->DeclareFunction(gc,"AddValue","Add item",{"key","value"},[dict0](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {
std::string key;
std::string value;
if(GetArgument(args2,0,key) && GetArgument(args2,1,value))
int64_t i64;
double d64;
TDateTime da;
if(GetArgument(args2,0,key) )
{
dict0->AddValue(key,value);
if(GetArgument(args2,1,value))
dict0->AddValue(key,value);
else if(GetArgument(args2,1,i64))
dict0->AddValue(key,i64);
else if(GetArgument(args2,1,d64))
dict0->AddValue(key, d64);
else if(GetArgument(args2,1,da))
dict0->AddValue(key, da.GetDate());
}
return nullptr;
});
@ -93,9 +103,19 @@ namespace Tesses::CrossLang
dict->DeclareFunction(gc,"SetValue","Set item",{"key","value"},[dict0](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {
std::string key;
std::string value;
if(GetArgument(args2,0,key) && GetArgument(args2,1,value))
int64_t i64;
double d64;
TDateTime da;
if(GetArgument(args2,0,key) )
{
dict0->SetValue(key,value);
if(GetArgument(args2,1,value))
dict0->SetValue(key,value);
else if(GetArgument(args2,1,i64))
dict0->SetValue(key,i64);
else if(GetArgument(args2,1,d64))
dict0->SetValue(key, d64);
else if(GetArgument(args2,1,da))
dict0->SetValue(key, da.GetDate());
}
return nullptr;
});
@ -140,6 +160,15 @@ namespace Tesses::CrossLang
}
return nullptr;
});
dict->DeclareFunction(gc,"TryGetFirstDate","Try Get first date",{"key"},[dict0](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {
std::string key;
Tesses::Framework::Date::DateTime value;
if(GetArgument(args2,0,key) && dict0->TryGetFirstDate(key,value))
{
return value;
}
return nullptr;
});
dict->DeclareFunction(gc, "ToList","To List",{}, [dict0](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {
TList* ls = TList::Create(ls2);
@ -205,6 +234,16 @@ namespace Tesses::CrossLang
dict->DeclareFunction(gc,"ReadString","Read string from request",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
return ctx->ReadString();
});
dict->DeclareFunction(gc, "ReadJson","Read json from request",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
return Json_Decode(ls2,ctx->ReadString());
});
dict->DeclareFunction(gc,"SendJson","Send object as json",{"object"},[ctx](Tesses::CrossLang::GCList& ls2, std::vector<TObject> args2)->TObject{
if(args2.size() > 0)
{
ctx->WithMimeType("application/json").SendText(Json_Encode(args2[0]));
}
return nullptr;
});
dict->DeclareFunction(gc,"SendText","Send response text",{"text"},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
std::string text;
@ -218,6 +257,12 @@ namespace Tesses::CrossLang
ctx->WithMimeType(text);
return dict;
});
dict->DeclareFunction(gc,"WithLastModified","Set last modified date",{"date"},[ctx,dict](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
TDateTime da;
if(GetArgument(args2,0,da))
ctx->WithLastModified(da.GetDate());
return dict;
});
dict->DeclareFunction(gc,"WithContentDisposition","Set content disposition",{"filename","inline"},[ctx,dict](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
std::string filename;
bool isInline;
@ -491,6 +536,21 @@ namespace Tesses::CrossLang
}
return nullptr;
}
static TObject Net_Http_ListenOnUnusedPort(GCList& ls, std::vector<TObject> 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();
}
return nullptr;
}
static TObject Net_Http_MimeType(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath p;
@ -818,6 +878,7 @@ namespace Tesses::CrossLang
});
http->DeclareFunction(gc, "MakeRequest", "Create an http request", {"url","$extra"}, Net_Http_MakeRequest);
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<TObject> args)->TObject{
@ -842,6 +903,21 @@ namespace Tesses::CrossLang
});
dict->DeclareFunction(gc, "NetworkStream","Create a network stream",{"ipv6","datagram"},Net_NetworkStream);
smtp->DeclareFunction(gc, "Send","Send email via smtp server",{"messageStruct"},Net_Smtp_Send);
dict->DeclareFunction(gc, "getIPAddresses","Get the ip addresses of this machine",{"$ipv6"},[](GCList& ls, std::vector<TObject> args)->TObject{
TList* a = TList::Create(ls);
bool ipv6=false;
GetArgument(args,0,ipv6);
ls.GetGC()->BarrierBegin();
for(auto item : Tesses::Framework::Streams::NetworkStream::GetIPs(ipv6))
{
a->Add(TDictionary::Create(ls,{
TDItem("Interface", item.first),
TDItem("Address", item.second)
}));
}
ls.GetGC()->BarrierEnd();;
return a;
});
gc->BarrierBegin();
dict->SetValue("Http", http);
dict->SetValue("Smtp", smtp);

View File

@ -2,10 +2,28 @@
#if defined(CROSSLANG_ENABLE_SHARED)
#if defined(_WIN32)
#include <windows.h>
#include <time.h>
#undef min
#undef max
#else
#include <dlfcn.h>
#include <unistd.h>
#endif
#else
#if defined(_WIN32)
#include <windows.h>
#include <time.h>
#undef min
#undef max
#else
#include <unistd.h>
#endif
#endif
namespace Tesses::CrossLang
{
#if defined(CROSSLANG_ENABLE_SHARED)
@ -118,6 +136,13 @@ namespace Tesses::CrossLang
TVFSHeapObject* vfs;
return GetArgumentHeap(args,0,vfs);
}
static TObject TypeIsDateTime(GCList& ls, std::vector<TObject> args)
{
if(args.empty()) return nullptr;
TDateTime* dt;
return GetArgumentHeap(args,0,dt);
}
static TObject New_SubdirFilesystem(GCList& ls, std::vector<TObject> args)
{
TVFSHeapObject* vfsho;
@ -172,6 +197,38 @@ namespace Tesses::CrossLang
}
return nullptr;
}
static TObject New_DateTime(GCList& ls, std::vector<TObject> args)
{
int64_t year;
if(GetArgument(args,0,year))
{
if(args.size()==1)
{
Tesses::Framework::Date::DateTime dt(year);
return dt;
}
else
{
int64_t month=1;
int64_t day=1;
int64_t hour=0;
int64_t minute=0;
int64_t second=0;
bool isLocal=true;
GetArgument(args,1,month);
GetArgument(args,2,day);
GetArgument(args,3,hour);
GetArgument(args,4,minute);
GetArgument(args,5,second);
GetArgument(args,6,isLocal);
Tesses::Framework::Date::DateTime dt((int)year,(int)month,(int)day,(int)hour,(int)minute,(int)second,isLocal);
return dt;
}
}
return nullptr;
}
static TObject TypeOf(GCList& ls, std::vector<TObject> args)
{
@ -187,6 +244,7 @@ namespace Tesses::CrossLang
if(std::holds_alternative<std::string>(args[0])) return "String";
if(std::holds_alternative<Tesses::Framework::Filesystem::VFSPath>(args[0])) return "Path";
if(std::holds_alternative<TDateTime>(args[0])) return "DateTime";
if(std::holds_alternative<THeapObjectHolder>(args[0]))
{
auto obj = std::get<THeapObjectHolder>(args[0]).obj;
@ -207,6 +265,7 @@ namespace Tesses::CrossLang
auto rootEnv = dynamic_cast<TRootEnvironment*>(obj);
auto subEnv = dynamic_cast<TSubEnvironment*>(obj);
auto env = dynamic_cast<TEnvironment*>(obj);
if(rootEnv != nullptr) return "RootEnvironment";
if(subEnv != nullptr) return "SubEnvironment";
@ -390,13 +449,70 @@ namespace Tesses::CrossLang
return Undefined();
}
static TObject DateTime_Sleep(GCList& ls, std::vector<TObject> args)
{
int64_t msec;
if(GetArgument(args,0,msec))
{
#if defined(_WIN32)
Sleep((int)msec);
#else
usleep(1000*msec);
#endif
}
return nullptr;
}
static TObject DateTime_getNow(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Date::DateTime::Now();
}
static TObject DateTime_getNowUTC(GCList& ls, std::vector<TObject> args)
{
return Tesses::Framework::Date::DateTime::NowUTC();
}
static TObject DateTime_getNowEpoch(GCList& ls, std::vector<TObject> args)
{
return (int64_t)time(NULL);
}
static TObject DateTime_TryParseHttpDate(GCList& ls, std::vector<TObject> args)
{
std::string d;
Tesses::Framework::Date::DateTime dt;
if(GetArgument(args,0,d) && Tesses::Framework::Date::DateTime::TryParseHttpDate(d,dt))
{
return dt;
}
return nullptr;
}
void TStd::RegisterRoot(GC* gc, TRootEnvironment* env)
{
GCList ls(gc);
env->permissions.canRegisterRoot=true;
TDictionary* date = TDictionary::Create(ls);
date->DeclareFunction(gc, "Sleep","Sleep for a specified amount of milliseconds (multiply seconds by 1000 to get milliseconds)", {"ms"},DateTime_Sleep);
date->DeclareFunction(gc, "getNow", "Get the current time",{},DateTime_getNow);
date->DeclareFunction(gc, "getNowUTC","Get the current time in UTC",{},DateTime_getNowUTC);
date->DeclareFunction(gc, "getNowEpoch","Get the time_t time now",{},DateTime_getNowEpoch);
date->DeclareFunction(gc, "TryParseHttpDate","Parse the http date",{},DateTime_TryParseHttpDate);
gc->BarrierBegin();
date->SetValue("Zone", Tesses::Framework::Date::GetTimeZone());
date->SetValue("SupportsDaylightSavings",Tesses::Framework::Date::TimeZoneSupportDST());
env->DeclareVariable("DateTime", date);
gc->BarrierEnd();
TDictionary* newTypes = TDictionary::Create(ls);
newTypes->DeclareFunction(gc, "DateTime","Create a DateTime object, if only one arg is provided year is epoch, isLocal defaults to true unless epoch",{"year","$month","$day","$hour","$minute","$second","$isLocal"},New_DateTime);
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);
@ -444,6 +560,7 @@ namespace Tesses::CrossLang
env->DeclareFunction(gc, "TypeIsList","Get whether object is a list or dynamic list",{"object"},TypeIsList);
env->DeclareFunction(gc, "TypeIsStream","Get whether object is a stream",{"object"},TypeIsStream);
env->DeclareFunction(gc, "TypeIsVFS","Get whether object is a virtual filesystem",{"object"},TypeIsVFS);
env->DeclareFunction(gc, "TypeIsDateTime","Get whether object is a DateTime",{"object"},TypeIsDateTime);
newTypes->DeclareFunction(gc, "Regex", "Create regex object",{"regex"},[](GCList& ls,std::vector<TObject> args)->TObject {
@ -569,7 +686,6 @@ namespace Tesses::CrossLang
RegisterCrypto(gc,env);
RegisterOGC(gc, env);
RegisterProcess(gc,env);
RegisterTime(gc, env);
gc->RegisterEverything(env);

View File

@ -1,248 +0,0 @@
#include "CrossLang.hpp"
#if defined(CROSSLANG_ENABLE_TIME)
#if defined(_WIN32)
#include <windows.h>
#include <time.h>
#undef min
#undef max
#else
#include <unistd.h>
#endif
#include "../HowardHinnant_date/date.h"
#endif
namespace Tesses::CrossLang
{
#if defined(CROSSLANG_ENABLE_TIME)
static int64_t ToLocalTime(int64_t local)
{
#if defined(__SWITCH__) || defined(_WIN32)
local -= _timezone;
if(_daylight)
#else
local -= timezone;
if(daylight)
#endif
{
auto epoch = date::sys_days{date::January/1/1970};
epoch += date::days(local/86400);
bool isDST = false;
date::year_month_day ymd(epoch);
auto month = (uint32_t)ymd.month();
if(month > 3 && month < 11)
{
isDST=true;
}
else if(month == 3)
{
auto day = (uint32_t)ymd.day();
if(day > 14) isDST=true;
else if(day >= 8 && day <= 14)
{
date::year_month_weekday ymw(epoch);
auto dow=ymw.weekday().c_encoding();
auto secondSunday = day - dow;
if(secondSunday < 8) secondSunday+=7;
if(day > secondSunday) isDST=true;
else if(day == secondSunday)
{
std::chrono::duration<int64_t> local_epoch_time(local);
date::hh_mm_ss hms(local_epoch_time%86400);
if(hms.hours().count() >= 2) isDST=true;
}
}
}
else if(month == 11)
{
auto day = (uint32_t)ymd.day();
if(day >= 1 && day <= 7)
{
date::year_month_weekday ymw(epoch);
auto dow=ymw.weekday().c_encoding();
int32_t firstSunday = (int32_t)day - (int32_t)dow;
if(firstSunday < 1) firstSunday+=7;
if(day < firstSunday) isDST=true;
else if(day == firstSunday)
{
std::chrono::duration<int64_t> local_epoch_time(local);
date::hh_mm_ss hms(local_epoch_time%86400);
if(hms.hours().count() <=1) isDST=true;
}
}
}
if(isDST) local += 3600;
}
return local;
}
static TObject Time_getNow(GCList& ls, std::vector<TObject> args)
{
time_t t = time(NULL);
return (time_t)t;
}
static TObject Time_Sleep(GCList& ls, std::vector<TObject> args)
{
int64_t msec;
if(GetArgument(args,0,msec))
{
#if defined(_WIN32)
Sleep((int)msec);
#else
usleep(1000*msec);
#endif
}
return nullptr;
}
static TObject Time_LocalTime(GCList& ls, std::vector<TObject> args)
{
//THIS code isn't the best but should work
int64_t local;
if(GetArgument(args,0,local))
{
local = ToLocalTime(local);
std::chrono::duration<int64_t> local_epoch_time(local);
date::hh_mm_ss hms(local_epoch_time%86400);
auto epoch = date::sys_days{date::January/1/1970};
epoch += date::days(local/86400);
//date::days<int64_t> sys_days_since_epoch = date::days<int64_t>(gmt);
// Convert sys_days to year_month_day
date::year_month_day ymd = date::year_month_day(epoch);
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Hour",hms.hours().count());
dict->SetValue("Minute",hms.minutes().count());
dict->SetValue("Second",hms.seconds().count());
dict->SetValue("Day",(int64_t)(uint32_t)ymd.day());
dict->SetValue("Month",(int64_t)(uint32_t)ymd.month());
dict->SetValue("Year",(int64_t)(int32_t)ymd.year());
ls.GetGC()->BarrierEnd();
return dict;
}
return nullptr;
}
static TObject Time_LocalUsSlashDate(GCList& ls, std::vector<TObject> args)
{
//THIS code isn't the best but should work
int64_t local;
if(GetArgument(args,0,local))
{
local = ToLocalTime(local);
std::chrono::duration<int64_t> local_epoch_time(local);
date::hh_mm_ss hms(local_epoch_time%86400);
auto epoch = date::sys_days{date::January/1/1970};
epoch += date::days(local/86400);
//date::days<int64_t> sys_days_since_epoch = date::days<int64_t>(gmt);
// Convert sys_days to year_month_day
date::year_month_day ymd = date::year_month_day(epoch);
return std::to_string((uint32_t)ymd.month()) + "/" + std::to_string((uint32_t)ymd.day()) + "/" + std::to_string((int)ymd.year());
}
return "";
}
static TObject Time_UTCUsSlashDate(GCList& ls,std::vector<TObject> args)
{
int64_t gmt;
if(GetArgument(args,0,gmt))
{
std::chrono::duration<int64_t> epoch_time(gmt);
date::hh_mm_ss hms(epoch_time%86400);
auto epoch = date::sys_days{date::January/1/1970};
epoch += date::days(gmt/86400);
//date::days<int64_t> sys_days_since_epoch = date::days<int64_t>(gmt);
// Convert sys_days to year_month_day
date::year_month_day ymd = date::year_month_day(epoch);
return std::to_string((uint32_t)ymd.month()) + "/" + std::to_string((uint32_t)ymd.day()) + "/" + std::to_string((int)ymd.year());
}
return "";
}
static TObject Time_GMTTime(GCList& ls, std::vector<TObject> args)
{
int64_t gmt;
if(GetArgument(args,0,gmt))
{
std::chrono::duration<int64_t> epoch_time(gmt);
date::hh_mm_ss hms(epoch_time%86400);
auto epoch = date::sys_days{date::January/1/1970};
epoch += date::days(gmt/86400);
//date::days<int64_t> sys_days_since_epoch = date::days<int64_t>(gmt);
// Convert sys_days to year_month_day
date::year_month_day ymd = date::year_month_day(epoch);
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Hour",hms.hours().count());
dict->SetValue("Minute",hms.minutes().count());
dict->SetValue("Second",hms.seconds().count());
dict->SetValue("Day",(int64_t)(uint32_t)ymd.day());
dict->SetValue("Month",(int64_t)(uint32_t)ymd.month());
dict->SetValue("Year",(int64_t)(int32_t)ymd.year());
ls.GetGC()->BarrierEnd();
return dict;
}
return nullptr;
}
#endif
void TStd::RegisterTime(GC* gc,TRootEnvironment* env)
{
#if defined(CROSSLANG_ENABLE_TIME)
env->permissions.canRegisterTime=true;
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "GetLocalTime", "Get local time from epoch value",{"epoch"},Time_LocalTime);
dict->DeclareFunction(gc, "GetGMTTime","Get the GMT time from epoch value",{"epoch"},Time_GMTTime);
dict->DeclareFunction(gc, "getNow","Get the time right now, returns C's time(NULL) return value",{},Time_getNow);
dict->DeclareFunction(gc, "Sleep","Sleep for a specified amount of milliseconds (multiply seconds by 1000 to get milliseconds)", {"ms"},Time_Sleep);
dict->DeclareFunction(gc, "UTCUsSlashDate","Get a utc date like 8/20/1992 from epoch value",{"epoch"},Time_UTCUsSlashDate);
dict->DeclareFunction(gc, "LocalUsSlashDate","Get a local date like 8/20/1992 from epoch value",{"epoch"},Time_LocalUsSlashDate);
gc->BarrierBegin();
#if defined(__SWITCH__) || defined(_WIN32)
dict->SetValue("Zone", (int64_t)-(_timezone));
dict->SetValue("SupportsDaylightSavings",(int64_t)_daylight);
#else
dict->SetValue("Zone", (int64_t)-(timezone));
dict->SetValue("SupportsDaylightSavings",(int64_t)daylight);
#endif
env->DeclareVariable("Time", dict);
gc->BarrierEnd();
#endif
}
}