mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-07-30 20:51:48 +02:00
Rename source to module.
This commit is contained in:
309
module/Library/Chrono.cpp
Normal file
309
module/Library/Chrono.cpp
Normal file
@@ -0,0 +1,309 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono.hpp"
|
||||
#include "Library/Chrono/Date.hpp"
|
||||
#include "Library/Chrono/Datetime.hpp"
|
||||
#include "Library/Chrono/Time.hpp"
|
||||
#include "Library/Chrono/Timer.hpp"
|
||||
#include "Library/Chrono/Timestamp.hpp"
|
||||
#include "Library/Numeric/LongInt.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#ifdef SQMOD_OS_WINDOWS
|
||||
|
||||
#if defined(_SQ64) && (_WIN32_WINNT < 0x0600)
|
||||
// We need this for the GetTickCount64() function
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif // _SQ64
|
||||
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif // SQMOD_OS_WINDOWS
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_ChronoDate(HSQUIRRELVM vm, Table & cns);
|
||||
extern void Register_ChronoDatetime(HSQUIRRELVM vm, Table & cns);
|
||||
extern void Register_ChronoTime(HSQUIRRELVM vm, Table & cns);
|
||||
extern void Register_ChronoTimer(HSQUIRRELVM vm, Table & cns);
|
||||
extern void Register_ChronoTimestamp(HSQUIRRELVM vm, Table & cns);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Uint8 Chrono::MonthLengths[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#ifdef SQMOD_OS_WINDOWS
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Used by GetCurrentSysTime to obtain the system frequency on initial call.
|
||||
*/
|
||||
inline LARGE_INTEGER GetFrequency()
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
return frequency;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Chrono::GetCurrentSysTime()
|
||||
{
|
||||
// Force the following code to run on first core
|
||||
// (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx)
|
||||
HANDLE current_thread = GetCurrentThread();
|
||||
DWORD_PTR previous_mask = SetThreadAffinityMask(current_thread, 1);
|
||||
|
||||
// Get the frequency of the performance counter
|
||||
// (it is constant across the program lifetime)
|
||||
static const LARGE_INTEGER frequency = GetFrequency();
|
||||
|
||||
// Get the current time
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
|
||||
// Restore the thread affinity
|
||||
SetThreadAffinityMask(current_thread, previous_mask);
|
||||
|
||||
// Return the current time as microseconds
|
||||
return Int64(1000000LL * time.QuadPart / frequency.QuadPart);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Chrono::GetEpochTimeMicro()
|
||||
{
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
// Extract the nanoseconds from the resulted timestamp
|
||||
Uint64 time = ft.dwHighDateTime;
|
||||
time <<= 32;
|
||||
time |= ft.dwLowDateTime;
|
||||
time /= 10;
|
||||
time -= 11644473600000000ULL;
|
||||
// Return the resulted timestamp
|
||||
return Int64(time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#ifndef _SQ64
|
||||
Int64 GetTickCount64()
|
||||
{
|
||||
return static_cast< Int64 >(GetTickCount()); // Fall-back to 32 bit?
|
||||
}
|
||||
#endif // _SQ64
|
||||
|
||||
#else
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Chrono::GetCurrentSysTime()
|
||||
{
|
||||
// POSIX implementation
|
||||
timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return Int64(Uint64(time.tv_sec) * 1000000 + time.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Chrono::GetEpochTimeMicro()
|
||||
{
|
||||
// POSIX implementation
|
||||
timespec time;
|
||||
clock_gettime(CLOCK_REALTIME, &time);
|
||||
return Int64(Uint64(time.tv_sec) * 1000000 + time.tv_nsec / 1000);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 GetTickCount()
|
||||
{
|
||||
// POSIX implementation
|
||||
struct timespec time;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &time))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return time.tv_sec * 1000.0 + time.tv_nsec / 1000000.0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 GetTickCount64()
|
||||
{
|
||||
struct timespec time;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &time))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return time.tv_sec * 1000.0 + time.tv_nsec / 1000000.0;
|
||||
}
|
||||
|
||||
#endif // SQMOD_OS_WINDOWS
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Chrono::GetEpochTimeMilli()
|
||||
{
|
||||
return (GetEpochTimeMicro() / 1000L);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Chrono::ValidDate(Uint16 year, Uint8 month, Uint8 day)
|
||||
{
|
||||
// Is this a valid date?
|
||||
if (year == 0 || month == 0 || day == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Is the month within range?
|
||||
else if (month > 12)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Return whether the day inside the month
|
||||
return day <= DaysInMonth(year, month);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint8 Chrono::DaysInMonth(Uint16 year, Uint8 month)
|
||||
{
|
||||
// Is the specified month within range?
|
||||
if (month > 12)
|
||||
{
|
||||
STHROWF("Month value is out of range: %u > 12", month);
|
||||
}
|
||||
// Obtain the days in this month
|
||||
Uint8 days = *(MonthLengths + month);
|
||||
// Should we account for January?
|
||||
if (month == 2 && IsLeapYear(year))
|
||||
{
|
||||
++days;
|
||||
}
|
||||
// Return the resulted days
|
||||
return days;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint16 Chrono::DayOfYear(Uint16 year, Uint8 month, Uint8 day)
|
||||
{
|
||||
// Start with 0 days
|
||||
Uint16 doy = 0;
|
||||
// Cumulate the days in months
|
||||
for (Uint8 m = 1; m < month; ++month)
|
||||
{
|
||||
doy += DaysInMonth(year, m);
|
||||
}
|
||||
// Add the specified days
|
||||
doy += day;
|
||||
// Return the result
|
||||
return doy;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Chrono::ReverseDayOfyear(Uint16 year, Uint16 doy)
|
||||
{
|
||||
// The resulted month
|
||||
Uint8 month = 1;
|
||||
// Calculate the months till the specified day of year
|
||||
for (; month < 12; ++month)
|
||||
{
|
||||
// Get the number of days in the current month
|
||||
Uint32 days = DaysInMonth(year, month);
|
||||
// Can this month fit in the remaining days?
|
||||
if (days >= doy)
|
||||
{
|
||||
break; // The search is complete
|
||||
}
|
||||
// Subtract the month days from days of year
|
||||
doy -= days;
|
||||
}
|
||||
// Return the resulted date
|
||||
return Date(year, month, doy);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Chrono::DateRangeToSeconds(Uint16 _year, Uint8 _month, Uint8 _day, Uint16 year_, Uint8 month_, Uint8 day_)
|
||||
{
|
||||
// Are we within the same year?
|
||||
if (_year == year_)
|
||||
{
|
||||
return std::abs((DayOfYear(_year, _month, _day) - DayOfYear(year_, month_, day_)) * 86400LL);
|
||||
}
|
||||
// Is the start year greater than the end year?
|
||||
else if (_year > year_)
|
||||
{
|
||||
std::swap(_year, year_);
|
||||
std::swap(_month, month_);
|
||||
std::swap(_day, day_);
|
||||
}
|
||||
// Calculate the remaining days from the first year
|
||||
Int64 num = DaysInYear(_year) - DayOfYear(_year, _month, _day);
|
||||
// Calculate the days withing the years range
|
||||
while (++_year < year_)
|
||||
{
|
||||
num += DaysInYear(_year);
|
||||
}
|
||||
// Calculate the days up to the last day
|
||||
num += DayOfYear(year_, month_, day_);
|
||||
// Convert the obtained days in seconds
|
||||
num *= 86400ULL;
|
||||
// Return the result
|
||||
return std::abs(num);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SLongInt SqGetEpochTimeMicro()
|
||||
{
|
||||
return SLongInt(Chrono::GetEpochTimeMicro());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SLongInt SqGetEpochTimeMilli()
|
||||
{
|
||||
return SLongInt(Chrono::GetEpochTimeMilli());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SLongInt SqGetCurrentSysTime()
|
||||
{
|
||||
return SLongInt(Chrono::GetCurrentSysTime());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger SqGetTickCount()
|
||||
{
|
||||
return ConvTo< SQInteger >::From(GetTickCount());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SLongInt SqGetTickCount64()
|
||||
{
|
||||
return SLongInt(GetTickCount64());
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Chrono(HSQUIRRELVM vm)
|
||||
{
|
||||
Table cns(vm);
|
||||
|
||||
Register_ChronoDate(vm, cns);
|
||||
Register_ChronoDatetime(vm, cns);
|
||||
Register_ChronoTime(vm, cns);
|
||||
Register_ChronoTimer(vm, cns);
|
||||
Register_ChronoTimestamp(vm, cns);
|
||||
|
||||
cns
|
||||
.Func(_SC("EpochMicro"), &SqGetEpochTimeMicro)
|
||||
.Func(_SC("EpochMilli"), &SqGetEpochTimeMilli)
|
||||
.Func(_SC("Current"), &SqGetCurrentSysTime)
|
||||
.Func(_SC("TickCount"), &SqGetTickCount)
|
||||
.Func(_SC("TickCount64"), &SqGetTickCount64)
|
||||
.Func(_SC("IsLeapYear"), &Chrono::IsLeapYear)
|
||||
.Func(_SC("IsDateValid"), &Chrono::ValidDate)
|
||||
.Func(_SC("DaysInYear"), &Chrono::DaysInYear)
|
||||
.Func(_SC("DaysInMonth"), &Chrono::DaysInMonth)
|
||||
.Func(_SC("DayOfYear"), &Chrono::DayOfYear)
|
||||
.Func(_SC("ReverseDayOfyear"), &Chrono::ReverseDayOfyear);
|
||||
|
||||
RootTable(vm).Bind(_SC("SqChrono"), cns);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
116
module/Library/Chrono.hpp
Normal file
116
module/Library/Chrono.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef _LIBRARY_CHRONO_HPP_
|
||||
#define _LIBRARY_CHRONO_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class Date;
|
||||
class Time;
|
||||
class Datetime;
|
||||
class Timer;
|
||||
class Timestamp;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Class that offers helpers to work with time related information.
|
||||
*/
|
||||
class Chrono
|
||||
{
|
||||
public:
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static const Uint8 MonthLengths[12];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor. (disabled)
|
||||
*/
|
||||
Chrono() = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
Chrono(const Chrono & o) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
Chrono(Chrono && o) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor. (disabled)
|
||||
*/
|
||||
~Chrono() = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
Chrono & operator = (const Chrono & o) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
Chrono & operator = (Chrono && o) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current time as microseconds.
|
||||
*/
|
||||
static Int64 GetCurrentSysTime();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the epoch time as microseconds.
|
||||
*/
|
||||
static Int64 GetEpochTimeMicro();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the epoch time as milliseconds.
|
||||
*/
|
||||
static Int64 GetEpochTimeMilli();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the specified date is valid.
|
||||
*/
|
||||
static bool ValidDate(Uint16 year, Uint8 month, Uint8 day);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the specified year is a leap year.
|
||||
*/
|
||||
static bool IsLeapYear(Uint16 year)
|
||||
{
|
||||
return !(year % 400) || (!(year % 4) && (year % 100));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* retrieve the number of days in the specified year.
|
||||
*/
|
||||
static Uint16 DaysInYear(Uint16 year)
|
||||
{
|
||||
return IsLeapYear(year) ? 366 : 365;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of days in the specified month.
|
||||
*/
|
||||
static Uint8 DaysInMonth(Uint16 year, Uint8 month);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number/position of the specified day in the specified year and month.
|
||||
*/
|
||||
static Uint16 DayOfYear(Uint16 year, Uint8 month, Uint8 day);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Convert just the year and day of year to full date.
|
||||
*/
|
||||
static Date ReverseDayOfyear(Uint16 year, Uint16 doy);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Calculate the number of days in the specified date range.
|
||||
*/
|
||||
static Int64 DateRangeToSeconds(Uint16 _year, Uint8 _month, Uint8 _day, Uint16 year_, Uint8 month_, Uint8 day_);
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CHRONO_HPP_
|
414
module/Library/Chrono/Date.cpp
Normal file
414
module/Library/Chrono/Date.cpp
Normal file
@@ -0,0 +1,414 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono/Date.hpp"
|
||||
#include "Library/Chrono/Time.hpp"
|
||||
#include "Library/Chrono/Datetime.hpp"
|
||||
#include "Library/Chrono/Timestamp.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(Typename, _SC("SqDate"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Date::Delimiter = '-';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Date::Compare(const Date & o) const
|
||||
{
|
||||
if (m_Year < o.m_Year)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Year > o.m_Year)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Month < o.m_Month)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Month > o.m_Month)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Day < o.m_Day)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Day > o.m_Day)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
// They're equal
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Date::operator + (const Date & o) const
|
||||
{
|
||||
// Add the components individually
|
||||
return Date(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Date::operator - (const Date & o) const
|
||||
{
|
||||
return Date(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Date::operator * (const Date & o) const
|
||||
{
|
||||
return Date(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Date::operator / (const Date & o) const
|
||||
{
|
||||
return Date(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Date::ToString() const
|
||||
{
|
||||
return ToStrF("%04u%c%02u%c%02u", m_Year, m_Delimiter, m_Month, m_Delimiter, m_Day);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Date::Set(Uint16 year, Uint8 month, Uint8 day)
|
||||
{
|
||||
if (!Chrono::ValidDate(year, month, day))
|
||||
{
|
||||
STHROWF("Invalid date: %04u%c%02u%c%02u" , m_Year, m_Delimiter, m_Month, m_Delimiter, m_Day);
|
||||
}
|
||||
// Assign the specified values
|
||||
m_Year = year;
|
||||
m_Month = month;
|
||||
m_Day = day;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Date::SetStr(CSStr str)
|
||||
{
|
||||
// The format specifications that will be used to scan the string
|
||||
static SQChar fs[] = _SC(" %u - %u - %u ");
|
||||
// Is the specified string empty?
|
||||
if (!str || *str == '\0')
|
||||
{
|
||||
// Clear the values
|
||||
m_Year = 0;
|
||||
m_Month = 0;
|
||||
m_Day = 0;
|
||||
// We're done here
|
||||
return;
|
||||
}
|
||||
// Assign the specified delimiter
|
||||
fs[4] = m_Delimiter;
|
||||
fs[9] = m_Delimiter;
|
||||
// The sscanf function requires at least 32 bit integers
|
||||
Uint32 year = 0, month = 0, day = 0;
|
||||
// Attempt to extract the component values from the specified string
|
||||
sscanf(str, fs, &year, &month, &day);
|
||||
// Clamp the extracted values to the boundaries of associated type and assign them
|
||||
Set(ClampL< Uint32, Uint8 >(year),
|
||||
ClampL< Uint32, Uint8 >(month),
|
||||
ClampL< Uint32, Uint8 >(day)
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Date::SetDayOfYear(Uint16 doy)
|
||||
{
|
||||
// Reverse the given day of year to a full date
|
||||
Date d = Chrono::ReverseDayOfyear(m_Year, doy);
|
||||
// Set the obtained month
|
||||
SetMonth(d.m_Month);
|
||||
// Set the obtained day
|
||||
SetDay(d.m_Day);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Date::SetYear(Uint16 year)
|
||||
{
|
||||
// Make sure the year is valid
|
||||
if (!year)
|
||||
{
|
||||
STHROWF("Invalid year: %u", year);
|
||||
}
|
||||
// Assign the value
|
||||
m_Year = year;
|
||||
// Make sure the new date is valid
|
||||
if (!Chrono::ValidDate(m_Year, m_Month, m_Day))
|
||||
{
|
||||
m_Month = 1;
|
||||
m_Day = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Date::SetMonth(Uint8 month)
|
||||
{
|
||||
// Make sure the month is valid
|
||||
if (month == 0 || month > 12)
|
||||
{
|
||||
STHROWF("Invalid month: %u", month);
|
||||
}
|
||||
// Assign the value
|
||||
m_Month = month;
|
||||
// Make sure the month days are in range
|
||||
if (m_Day > Chrono::DaysInMonth(m_Year, m_Month))
|
||||
{
|
||||
m_Month = 1; // Fall back to the beginning of the month
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Date::SetDay(Uint8 day)
|
||||
{
|
||||
// Grab the amount of days in the current month
|
||||
const Uint8 dim = Chrono::DaysInMonth(m_Year, m_Month);
|
||||
// Make sure the day is valid
|
||||
if (day == 0)
|
||||
{
|
||||
STHROWF("Invalid day: %u", day);
|
||||
}
|
||||
else if (day > dim)
|
||||
{
|
||||
STHROWF("Day is out of range: %u > %u", day, dim);
|
||||
}
|
||||
// Assign the value
|
||||
m_Day = day;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date & Date::AddYears(Int32 years)
|
||||
{
|
||||
// Do we have a valid amount of years?
|
||||
if (years)
|
||||
{
|
||||
// Add the specified amount of years
|
||||
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date & Date::AddMonths(Int32 months)
|
||||
{
|
||||
// Do we have a valid amount of months?
|
||||
if (months)
|
||||
{
|
||||
// Extract the number of years
|
||||
Int32 years = static_cast< Int32 >(months / 12);
|
||||
// Extract the number of months
|
||||
months = (months % 12) + m_Month;
|
||||
// Do we have extra months?
|
||||
if (months >= 12)
|
||||
{
|
||||
// Increase the years
|
||||
++years;
|
||||
// Subtract one year from months
|
||||
months %= 12;
|
||||
}
|
||||
else if (months < 0)
|
||||
{
|
||||
// Decrease the years
|
||||
--years;
|
||||
// Add one year to months
|
||||
months = 12 - months;
|
||||
}
|
||||
// Are there any years to add?
|
||||
if (years)
|
||||
{
|
||||
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
}
|
||||
// Add the months
|
||||
SetMonth(months);
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date & Date::AddDays(Int32 days)
|
||||
{
|
||||
// Do we have a valid amount of days?
|
||||
if (days)
|
||||
{
|
||||
// Whether the number of days is positive or negative
|
||||
const Int32 dir = days > 0 ? 1 : -1;
|
||||
// Grab current year
|
||||
Int32 year = m_Year;
|
||||
// Calculate the days in the current year
|
||||
Int32 diy = Chrono::DaysInYear(year);
|
||||
// Calculate the day of year
|
||||
Int32 doy = GetDayOfYear() + days;
|
||||
// Calculate the resulting years
|
||||
while (doy > diy || doy < 0)
|
||||
{
|
||||
doy -= diy * dir;
|
||||
year += dir;
|
||||
diy = Chrono::DaysInYear(year);
|
||||
}
|
||||
// Set the obtained year
|
||||
SetYear(year);
|
||||
// Set the obtained day of year
|
||||
SetDayOfYear(doy);
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Date::AndYears(Int32 years)
|
||||
{
|
||||
// Do we have a valid amount of years?
|
||||
if (!years)
|
||||
{
|
||||
return Date(*this); // Return the date as is
|
||||
}
|
||||
// Replicate the current date
|
||||
Date d(*this);
|
||||
// Add the specified amount of years
|
||||
d.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
// Return the resulted date
|
||||
return d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Date::AndMonths(Int32 months)
|
||||
{
|
||||
// Do we have a valid amount of months?
|
||||
if (!months)
|
||||
{
|
||||
return Date(*this); // Return the date as is
|
||||
}
|
||||
// Extract the number of years
|
||||
Int32 years = static_cast< Int32 >(months / 12);
|
||||
// Extract the number of months
|
||||
months = (months % 12) + m_Month;
|
||||
// Do we have extra months?
|
||||
if (months >= 12)
|
||||
{
|
||||
// Increase the years
|
||||
++years;
|
||||
// Subtract one year from months
|
||||
months %= 12;
|
||||
}
|
||||
else if (months < 0)
|
||||
{
|
||||
// Decrease the years
|
||||
--years;
|
||||
// Add one year to months
|
||||
months = 12 - months;
|
||||
}
|
||||
// Replicate the current date
|
||||
Date d(*this);
|
||||
// Are there any years to add?
|
||||
if (years)
|
||||
{
|
||||
d.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
}
|
||||
// Add the months
|
||||
d.SetMonth(months);
|
||||
// Return the resulted date
|
||||
return d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Date::AndDays(Int32 days)
|
||||
{
|
||||
// Do we have a valid amount of days?
|
||||
if (!days)
|
||||
{
|
||||
return Date(*this); // Return the date as is
|
||||
}
|
||||
// Whether the number of days is positive or negative
|
||||
const Int32 dir = days > 0 ? 1 : -1;
|
||||
// Grab current year
|
||||
Int32 year = m_Year;
|
||||
// Calculate the days in the current year
|
||||
Int32 diy = Chrono::DaysInYear(year);
|
||||
// Calculate the day of year
|
||||
Int32 doy = GetDayOfYear() + days;
|
||||
// Calculate the resulting years
|
||||
while (doy > diy || doy < 0)
|
||||
{
|
||||
doy -= diy * dir;
|
||||
year += dir;
|
||||
diy = Chrono::DaysInYear(year);
|
||||
}
|
||||
// Replicate the current date
|
||||
Date d(*this);
|
||||
// Set the obtained year
|
||||
d.SetYear(year);
|
||||
// Set the obtained day of year
|
||||
d.SetDayOfYear(doy);
|
||||
// Return the resulted date
|
||||
return d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Timestamp Date::GetTimestamp() const
|
||||
{
|
||||
// Calculate the current day of the year
|
||||
Int32 days = Chrono::DayOfYear(m_Year, m_Month, m_Day);
|
||||
// Calculate all days till the current year
|
||||
for (Int32 year = 0; year < m_Year; --year)
|
||||
{
|
||||
days += Chrono::DaysInYear(year);
|
||||
}
|
||||
// Return the resulted timestamp
|
||||
return Timestamp(static_cast< Int64 >(days * 86400000000LL));
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_ChronoDate(HSQUIRRELVM vm, Table & /*cns*/)
|
||||
{
|
||||
RootTable(vm).Bind(Typename::Str,
|
||||
Class< Date >(vm, Typename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< Uint16 >()
|
||||
.Ctor< Uint16, Uint8 >()
|
||||
.Ctor< Uint16, Uint8, Uint8 >()
|
||||
// Static Properties
|
||||
.SetStaticValue(_SC("GlobalDelimiter"), &Date::Delimiter)
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
.Func(_SC("_tostring"), &Date::ToString)
|
||||
.Func(_SC("cmp"), &Date::Cmp)
|
||||
// Meta-methods
|
||||
.Func< Date (Date::*)(const Date &) const >(_SC("_add"), &Date::operator +)
|
||||
.Func< Date (Date::*)(const Date &) const >(_SC("_sub"), &Date::operator -)
|
||||
.Func< Date (Date::*)(const Date &) const >(_SC("_mul"), &Date::operator *)
|
||||
.Func< Date (Date::*)(const Date &) const >(_SC("_div"), &Date::operator /)
|
||||
// Properties
|
||||
.Prop(_SC("Delimiter"), &Date::GetDelimiter, &Date::SetDelimiter)
|
||||
.Prop(_SC("Str"), &Date::GetStr, &Date::SetStr)
|
||||
.Prop(_SC("DayOfYear"), &Date::GetDayOfYear, &Date::SetDayOfYear)
|
||||
.Prop(_SC("Year"), &Date::GetYear, &Date::SetYear)
|
||||
.Prop(_SC("Month"), &Date::GetMonth, &Date::SetMonth)
|
||||
.Prop(_SC("Day"), &Date::GetDay, &Date::SetDay)
|
||||
.Prop(_SC("LeapYear"), &Date::IsThisLeapYear)
|
||||
.Prop(_SC("YearDays"), &Date::GetYearDays)
|
||||
.Prop(_SC("MonthDays"), &Date::GetMonthDays)
|
||||
.Prop(_SC("Timestamp"), &Date::GetTimestamp)
|
||||
// Member Methods
|
||||
.Func(_SC("AddYears"), &Date::AddYears)
|
||||
.Func(_SC("AddMonths"), &Date::AddMonths)
|
||||
.Func(_SC("AddDays"), &Date::AddDays)
|
||||
.Func(_SC("AndYears"), &Date::AndYears)
|
||||
.Func(_SC("AndMonths"), &Date::AndMonths)
|
||||
.Func(_SC("AndDays"), &Date::AndDays)
|
||||
// Overloaded Methods
|
||||
.Overload< void (Date::*)(Uint16) >(_SC("Set"), &Date::Set)
|
||||
.Overload< void (Date::*)(Uint16, Uint8) >(_SC("Set"), &Date::Set)
|
||||
.Overload< void (Date::*)(Uint16, Uint8, Uint8) >(_SC("Set"), &Date::Set)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
357
module/Library/Chrono/Date.hpp
Normal file
357
module/Library/Chrono/Date.hpp
Normal file
@@ -0,0 +1,357 @@
|
||||
#ifndef _LIBRARY_CHRONO_DATE_HPP_
|
||||
#define _LIBRARY_CHRONO_DATE_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Helper class used to represent a certain date.
|
||||
*/
|
||||
class Date
|
||||
{
|
||||
public:
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQChar Delimiter;
|
||||
|
||||
private:
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint16 m_Year; // Year
|
||||
Uint8 m_Month; // Month
|
||||
Uint8 m_Day; // Day
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar m_Delimiter; // Component delimiter when generating strings.
|
||||
|
||||
protected:
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Compare the values of two instances.
|
||||
*/
|
||||
Int32 Compare(const Date & o) const;
|
||||
|
||||
public:
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Date()
|
||||
: m_Year(1970)
|
||||
, m_Month(1)
|
||||
, m_Day(1)
|
||||
, m_Delimiter(Delimiter)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic year constructor.
|
||||
*/
|
||||
Date(Uint16 year)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
Set(year, 1, 1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic year and month constructor.
|
||||
*/
|
||||
Date(Uint16 year, Uint8 month)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
Set(year, month, 1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic date constructor.
|
||||
*/
|
||||
Date(Uint16 year, Uint8 month, Uint8 day)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
Set(year, month, day);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* String constructor.
|
||||
*/
|
||||
Date(CSStr str)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
SetStr(str);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
Date(const Date & o) = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
Date(Date && o) = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Date() = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Date & operator = (const Date & o) = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Date & operator = (Date && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Date & o) const
|
||||
{
|
||||
return Compare(o) == 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Date & o) const
|
||||
{
|
||||
return Compare(o) != 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Date & o) const
|
||||
{
|
||||
return Compare(o) < 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Date & o) const
|
||||
{
|
||||
return Compare(o) > 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Date & o) const
|
||||
{
|
||||
return Compare(o) <= 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Date & o) const
|
||||
{
|
||||
return Compare(o) >= 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Addition operator.
|
||||
*/
|
||||
Date operator + (const Date & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Date operator - (const Date & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Date operator * (const Date & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Division operator.
|
||||
*/
|
||||
Date operator / (const Date & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Date & o) const
|
||||
{
|
||||
return Compare(o);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year)
|
||||
{
|
||||
Set(year, m_Month, m_Day);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month)
|
||||
{
|
||||
Set(year, month, m_Day);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month, Uint8 day);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the local delimiter character.
|
||||
*/
|
||||
SQChar GetDelimiter() const
|
||||
{
|
||||
return m_Delimiter;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the local delimiter character.
|
||||
*/
|
||||
void SetDelimiter(SQChar c)
|
||||
{
|
||||
m_Delimiter = c;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the values as a string.
|
||||
*/
|
||||
CSStr GetStr() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values from a string.
|
||||
*/
|
||||
void SetStr(CSStr str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the day component.
|
||||
*/
|
||||
Uint16 GetDayOfYear() const
|
||||
{
|
||||
return Chrono::DayOfYear(m_Year, m_Month, m_Day);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the day component.
|
||||
*/
|
||||
void SetDayOfYear(Uint16 doy);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the year component.
|
||||
*/
|
||||
Uint16 GetYear() const
|
||||
{
|
||||
return m_Year;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the year component.
|
||||
*/
|
||||
void SetYear(Uint16 year);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the month component.
|
||||
*/
|
||||
Uint8 GetMonth() const
|
||||
{
|
||||
return m_Month;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the month component.
|
||||
*/
|
||||
void SetMonth(Uint8 month);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the day component.
|
||||
*/
|
||||
Uint8 GetDay() const
|
||||
{
|
||||
return m_Day;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the day component.
|
||||
*/
|
||||
void SetDay(Uint8 day);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of years to the current date.
|
||||
*/
|
||||
Date & AddYears(Int32 years);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of months to the current date.
|
||||
*/
|
||||
Date & AddMonths(Int32 months);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of days to the current date.
|
||||
*/
|
||||
Date & AddDays(Int32 days);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of years to obtain a new date.
|
||||
*/
|
||||
Date AndYears(Int32 years);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of months to obtain a new date.
|
||||
*/
|
||||
Date AndMonths(Int32 months);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of days to obtain a new date.
|
||||
*/
|
||||
Date AndDays(Int32 days);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* See whether the associated year is a leap year.
|
||||
*/
|
||||
bool IsThisLeapYear() const
|
||||
{
|
||||
return Chrono::IsLeapYear(m_Year);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of days in the associated year.
|
||||
*/
|
||||
Uint16 GetYearDays() const
|
||||
{
|
||||
return Chrono::DaysInYear(m_Year);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of days in the associated month.
|
||||
*/
|
||||
Uint8 GetMonthDays() const
|
||||
{
|
||||
return Chrono::DaysInMonth(m_Year, m_Month);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Convert this date instance to a time-stamp.
|
||||
*/
|
||||
Timestamp GetTimestamp() const;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CHRONO_DATE_HPP_
|
822
module/Library/Chrono/Datetime.cpp
Normal file
822
module/Library/Chrono/Datetime.cpp
Normal file
@@ -0,0 +1,822 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono/Datetime.hpp"
|
||||
#include "Library/Chrono/Date.hpp"
|
||||
#include "Library/Chrono/Time.hpp"
|
||||
#include "Library/Chrono/Timestamp.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(Typename, _SC("SqDatetime"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Datetime::Delimiter = ' ';
|
||||
SQChar Datetime::DateDelim = '-';
|
||||
SQChar Datetime::TimeDelim = ':';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Datetime::Compare(const Datetime & o) const
|
||||
{
|
||||
if (m_Year < o.m_Year)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Year > o.m_Year)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Month < o.m_Month)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Month > o.m_Month)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Day < o.m_Day)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Day > o.m_Day)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Hour < o.m_Hour)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Hour > o.m_Hour)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Minute < o.m_Minute)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Minute > o.m_Minute)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Second < o.m_Second)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Second > o.m_Second)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Millisecond < o.m_Millisecond)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Millisecond == o.m_Millisecond)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::operator + (const Datetime & o) const
|
||||
{
|
||||
// Add the components individually
|
||||
return Datetime(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::operator - (const Datetime & o) const
|
||||
{
|
||||
return Datetime(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::operator * (const Datetime & o) const
|
||||
{
|
||||
return Datetime(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::operator / (const Datetime & o) const
|
||||
{
|
||||
return Datetime(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Datetime::ToString() const
|
||||
{
|
||||
return ToStrF("%04u%c%02u%c%02u%c%02u%c%02u%c%02u%c%u"
|
||||
, m_Year, m_DateDelim, m_Month, m_DateDelim, m_Day
|
||||
, m_Delimiter
|
||||
, m_Hour, m_TimeDelim, m_Minute, m_TimeDelim, m_Second , m_TimeDelim, m_Millisecond
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
|
||||
{
|
||||
// Validate the specified date
|
||||
if (!Chrono::ValidDate(year, month, day))
|
||||
{
|
||||
STHROWF("Invalid date: %04u%c%02u%c%02u%c%u"
|
||||
, m_DateDelim, m_Year
|
||||
, m_DateDelim, m_Month
|
||||
, m_DateDelim, m_Day
|
||||
);
|
||||
}
|
||||
// Is the specified hour within range?
|
||||
else if (hour >= 24)
|
||||
{
|
||||
STHROWF("Hour value is out of range: %u >= 24", hour);
|
||||
}
|
||||
// Is the specified minute within range?
|
||||
else if (minute >= 60)
|
||||
{
|
||||
STHROWF("Minute value is out of range: %u >= 60", minute);
|
||||
}
|
||||
// Is the specified second within range?
|
||||
else if (second >= 60)
|
||||
{
|
||||
STHROWF("Second value is out of range: %u >= 60", second);
|
||||
}
|
||||
// Is the specified millisecond within range?
|
||||
else if (millisecond >= 1000)
|
||||
{
|
||||
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
|
||||
}
|
||||
// Assign the specified values
|
||||
m_Year = year;
|
||||
m_Month = month;
|
||||
m_Day = day;
|
||||
m_Hour = hour;
|
||||
m_Minute = minute;
|
||||
m_Second = second;
|
||||
m_Millisecond = millisecond;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetStr(CSStr str)
|
||||
{
|
||||
// The format specifications that will be used to scan the string
|
||||
static SQChar fs[] = _SC(" %u - %u - %u %u : %u : %u : %u ");
|
||||
// Is the specified string empty?
|
||||
if (!str || *str == '\0')
|
||||
{
|
||||
// Clear the values
|
||||
m_Year = 0;
|
||||
m_Month = 0;
|
||||
m_Day = 0;
|
||||
m_Hour = 0;
|
||||
m_Minute = 0;
|
||||
m_Second = 0;
|
||||
m_Millisecond = 0;
|
||||
// We're done here
|
||||
return;
|
||||
}
|
||||
// Assign the specified delimiter
|
||||
fs[4] = m_DateDelim;
|
||||
fs[9] = m_DateDelim;
|
||||
fs[14] = m_Delimiter;
|
||||
fs[19] = m_TimeDelim;
|
||||
fs[24] = m_TimeDelim;
|
||||
fs[29] = m_TimeDelim;
|
||||
// The sscanf function requires at least 32 bit integers
|
||||
Uint32 year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, milli = 0;
|
||||
// Attempt to extract the component values from the specified string
|
||||
sscanf(str, fs, &year, &month, &day, &hour, &minute, &second, &milli);
|
||||
// Clamp the extracted values to the boundaries of associated type and assign them
|
||||
Set(ClampL< Uint32, Uint8 >(year),
|
||||
ClampL< Uint32, Uint8 >(month),
|
||||
ClampL< Uint32, Uint8 >(day),
|
||||
ClampL< Uint32, Uint8 >(hour),
|
||||
ClampL< Uint32, Uint8 >(minute),
|
||||
ClampL< Uint32, Uint8 >(second),
|
||||
ClampL< Uint32, Uint16 >(milli)
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetDayOfYear(Uint16 doy)
|
||||
{
|
||||
// Reverse the given day of year to a full date
|
||||
Date d = Chrono::ReverseDayOfyear(m_Year, doy);
|
||||
// Set the obtained month
|
||||
SetMonth(d.GetMonth());
|
||||
// Set the obtained day
|
||||
SetDay(d.GetDay());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetYear(Uint16 year)
|
||||
{
|
||||
// Make sure the year is valid
|
||||
if (!year)
|
||||
{
|
||||
STHROWF("Invalid year: %u", year);
|
||||
}
|
||||
// Assign the value
|
||||
m_Year = year;
|
||||
// Make sure the new date is valid
|
||||
if (!Chrono::ValidDate(m_Year, m_Month, m_Day))
|
||||
{
|
||||
m_Month = 1;
|
||||
m_Day = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetMonth(Uint8 month)
|
||||
{
|
||||
// Make sure the month is valid
|
||||
if (month == 0 || month > 12)
|
||||
{
|
||||
STHROWF("Invalid month: %u", month);
|
||||
}
|
||||
// Assign the value
|
||||
m_Month = month;
|
||||
// Make sure the month days are in range
|
||||
if (m_Day > Chrono::DaysInMonth(m_Year, m_Month))
|
||||
{
|
||||
m_Month = 1; // Fall back to the beginning of the month
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetDay(Uint8 day)
|
||||
{
|
||||
// Grab the amount of days in the current month
|
||||
const Uint8 dim = Chrono::DaysInMonth(m_Year, m_Month);
|
||||
// Make sure the day is valid
|
||||
if (day == 0)
|
||||
{
|
||||
STHROWF("Invalid day: %u", day);
|
||||
}
|
||||
else if (day > dim)
|
||||
{
|
||||
STHROWF("Day is out of range: %u > %u", day, dim);
|
||||
}
|
||||
// Assign the value
|
||||
m_Day = day;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetHour(Uint8 hour)
|
||||
{
|
||||
// Is the specified hour within range?
|
||||
if (hour >= 24)
|
||||
{
|
||||
STHROWF("Hour value is out of range: %u >= 24", hour);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Hour = hour;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetMinute(Uint8 minute)
|
||||
{
|
||||
// Is the specified minute within range?
|
||||
if (minute >= 60)
|
||||
{
|
||||
STHROWF("Minute value is out of range: %u >= 60", minute);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Minute = minute;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetSecond(Uint8 second)
|
||||
{
|
||||
// Is the specified second within range?
|
||||
if (second >= 60)
|
||||
{
|
||||
STHROWF("Second value is out of range: %u >= 60", second);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Second = second;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Datetime::SetMillisecond(Uint16 millisecond)
|
||||
{
|
||||
// Is the specified millisecond within range?
|
||||
if (millisecond >= 1000)
|
||||
{
|
||||
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Millisecond = millisecond;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime & Datetime::AddYears(Int32 years)
|
||||
{
|
||||
// Do we have a valid amount of years?
|
||||
if (years)
|
||||
{
|
||||
// Add the specified amount of years
|
||||
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime & Datetime::AddMonths(Int32 months)
|
||||
{
|
||||
// Do we have a valid amount of months?
|
||||
if (months)
|
||||
{
|
||||
// Extract the number of years
|
||||
Int32 years = static_cast< Int32 >(months / 12);
|
||||
// Extract the number of months
|
||||
months = (months % 12) + m_Month;
|
||||
// Do we have extra months?
|
||||
if (months >= 12)
|
||||
{
|
||||
// Increase the years
|
||||
++years;
|
||||
// Subtract one year from months
|
||||
months %= 12;
|
||||
}
|
||||
else if (months < 0)
|
||||
{
|
||||
// Decrease the years
|
||||
--years;
|
||||
// Add one year to months
|
||||
months = 12 - months;
|
||||
}
|
||||
// Are there any years to add?
|
||||
if (years)
|
||||
{
|
||||
SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
}
|
||||
// Add the months
|
||||
SetMonth(months);
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime & Datetime::AddDays(Int32 days)
|
||||
{
|
||||
// Do we have a valid amount of days?
|
||||
if (days)
|
||||
{
|
||||
// Whether the number of days is positive or negative
|
||||
const Int32 dir = days > 0 ? 1 : -1;
|
||||
// Grab current year
|
||||
Int32 year = m_Year;
|
||||
// Calculate the days in the current year
|
||||
Int32 diy = Chrono::DaysInYear(year);
|
||||
// Calculate the day of year
|
||||
Int32 doy = GetDayOfYear() + days;
|
||||
// Calculate the resulting years
|
||||
while (doy > diy || doy < 0)
|
||||
{
|
||||
doy -= diy * dir;
|
||||
year += dir;
|
||||
diy = Chrono::DaysInYear(year);
|
||||
}
|
||||
// Set the obtained year
|
||||
SetYear(year);
|
||||
// Set the obtained day of year
|
||||
SetDayOfYear(doy);
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime & Datetime::AddHours(Int32 hours)
|
||||
{
|
||||
// Did we even add any hours?
|
||||
if (hours)
|
||||
{
|
||||
// Extract the number of days
|
||||
Int32 days = static_cast< Int32 >(hours / 24);
|
||||
// Extract the number of hours
|
||||
m_Hour += (hours % 24);
|
||||
// Are the hours overlapping with the next day?
|
||||
if (m_Hour >= 24)
|
||||
{
|
||||
// Increase the days
|
||||
++days;
|
||||
// Subtract one day from hours
|
||||
m_Hour %= 24;
|
||||
}
|
||||
// Should we add any days?
|
||||
if (days)
|
||||
{
|
||||
AddDays(days);
|
||||
}
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime & Datetime::AddMinutes(Int32 minutes)
|
||||
{
|
||||
// Did we even add any minutes?
|
||||
if (minutes)
|
||||
{
|
||||
// Extract the number of hours
|
||||
Int32 hours = static_cast< Int32 >(minutes / 60);
|
||||
// Extract the number of minutes
|
||||
m_Minute += (minutes % 60);
|
||||
// Are the minutes overlapping with the next hour?
|
||||
if (m_Minute >= 60)
|
||||
{
|
||||
// Increase the hours
|
||||
++hours;
|
||||
// Subtract one hour from minutes
|
||||
m_Minute %= 60;
|
||||
}
|
||||
// Should we add any hours?
|
||||
if (hours)
|
||||
{
|
||||
AddHours(hours);
|
||||
}
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime & Datetime::AddSeconds(Int32 seconds)
|
||||
{
|
||||
// Did we even add any seconds?
|
||||
if (seconds)
|
||||
{
|
||||
// Extract the number of minutes
|
||||
Int32 minutes = static_cast< Int32 >(seconds / 60);
|
||||
// Extract the number of seconds
|
||||
m_Second += (seconds % 60);
|
||||
// Are the seconds overlapping with the next minute?
|
||||
if (m_Second >= 60)
|
||||
{
|
||||
// Increase the minutes
|
||||
++minutes;
|
||||
// Subtract one minute from seconds
|
||||
m_Second %= 60;
|
||||
}
|
||||
// Should we add any minutes?
|
||||
if (minutes)
|
||||
{
|
||||
AddMinutes(minutes);
|
||||
}
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime & Datetime::AddMilliseconds(Int32 milliseconds)
|
||||
{
|
||||
// Did we even add any milliseconds?
|
||||
if (milliseconds)
|
||||
{
|
||||
// Extract the number of seconds
|
||||
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
|
||||
// Extract the number of milliseconds
|
||||
m_Millisecond += (milliseconds / 1000);
|
||||
// Are the milliseconds overlapping with the next second?
|
||||
if (m_Millisecond >= 1000)
|
||||
{
|
||||
// Increase the seconds
|
||||
++seconds;
|
||||
// Subtract one second from milliseconds
|
||||
m_Millisecond %= 1000;
|
||||
}
|
||||
// Should we add any seconds?
|
||||
if (seconds)
|
||||
{
|
||||
AddSeconds(seconds);
|
||||
}
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::AndYears(Int32 years)
|
||||
{
|
||||
// Do we have a valid amount of years?
|
||||
if (!years)
|
||||
{
|
||||
return Datetime(*this); // Return the date-time as is
|
||||
}
|
||||
// Replicate the current date
|
||||
Datetime dt(*this);
|
||||
// Add the specified amount of years
|
||||
dt.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
// Return the resulted date
|
||||
return dt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::AndMonths(Int32 months)
|
||||
{
|
||||
// Do we have a valid amount of months?
|
||||
if (!months)
|
||||
{
|
||||
return Datetime(*this); // Return the date-time as is
|
||||
}
|
||||
// Extract the number of years
|
||||
Int32 years = static_cast< Int32 >(months / 12);
|
||||
// Extract the number of months
|
||||
months = (months % 12) + m_Month;
|
||||
// Do we have extra months?
|
||||
if (months >= 12)
|
||||
{
|
||||
// Increase the years
|
||||
++years;
|
||||
// Subtract one year from months
|
||||
months %= 12;
|
||||
}
|
||||
else if (months < 0)
|
||||
{
|
||||
// Decrease the years
|
||||
--years;
|
||||
// Add one year to months
|
||||
months = 12 - months;
|
||||
}
|
||||
// Replicate the current date
|
||||
Datetime dt(*this);
|
||||
// Are there any years to add?
|
||||
if (years)
|
||||
{
|
||||
dt.SetYear(ConvTo< Uint16 >::From(static_cast< Int32 >(m_Year) + years));
|
||||
}
|
||||
// Add the months
|
||||
dt.SetMonth(months);
|
||||
// Return the resulted date
|
||||
return dt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::AndDays(Int32 days)
|
||||
{
|
||||
// Do we have a valid amount of days?
|
||||
if (!days)
|
||||
{
|
||||
return Datetime(*this); // Return the date-time as is
|
||||
}
|
||||
// Whether the number of days is positive or negative
|
||||
const Int32 dir = days > 0 ? 1 : -1;
|
||||
// Grab current year
|
||||
Int32 year = m_Year;
|
||||
// Calculate the days in the current year
|
||||
Int32 diy = Chrono::DaysInYear(year);
|
||||
// Calculate the day of year
|
||||
Int32 doy = GetDayOfYear() + days;
|
||||
// Calculate the resulting years
|
||||
while (doy > diy || doy < 0)
|
||||
{
|
||||
doy -= diy * dir;
|
||||
year += dir;
|
||||
diy = Chrono::DaysInYear(year);
|
||||
}
|
||||
// Replicate the current date
|
||||
Datetime dt(*this);
|
||||
// Set the obtained year
|
||||
dt.SetYear(year);
|
||||
// Set the obtained day of year
|
||||
dt.SetDayOfYear(doy);
|
||||
// Return the resulted date
|
||||
return dt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::AndHours(Int32 hours)
|
||||
{
|
||||
// Did we even add any hours?
|
||||
if (!hours)
|
||||
{
|
||||
return Datetime(*this); // Return the date-time as is
|
||||
}
|
||||
// Extract the number of days
|
||||
Int32 days = static_cast< Int32 >(hours / 24);
|
||||
// Extract the number of hours
|
||||
hours = m_Hour + (hours % 24);
|
||||
// Are the hours overlapping with the next day?
|
||||
if (hours >= 24)
|
||||
{
|
||||
++days; // Increase the days
|
||||
}
|
||||
// Replicate the current time
|
||||
Datetime dt(*this);
|
||||
// Should we add any days?
|
||||
if (days)
|
||||
{
|
||||
dt.AddDays(days);
|
||||
}
|
||||
// Assign the resulted hours
|
||||
dt.m_Hour = (hours % 24);
|
||||
// Return the result
|
||||
return dt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::AndMinutes(Int32 minutes)
|
||||
{
|
||||
// Did we even added any minutes?
|
||||
if (!minutes)
|
||||
{
|
||||
return Datetime(*this); // Return the date-time as is
|
||||
}
|
||||
// Extract the number of hours
|
||||
Int32 hours = static_cast< Int32 >(minutes / 60);
|
||||
// Extract the number of minutes
|
||||
minutes = m_Minute + (minutes % 60);
|
||||
// Are the minutes overlapping with the next hour?
|
||||
if (minutes >= 60)
|
||||
{
|
||||
++hours; // Increase hours
|
||||
}
|
||||
// Replicate the current time
|
||||
Datetime dt(*this);
|
||||
// Should we add any hours?
|
||||
if (hours)
|
||||
{
|
||||
dt.AddHours(hours);
|
||||
}
|
||||
// Assign the resulted minutes
|
||||
dt.m_Minute = (minutes % 60);
|
||||
// Return the result
|
||||
return dt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::AndSeconds(Int32 seconds)
|
||||
{
|
||||
// Did we even added any seconds?
|
||||
if (!seconds)
|
||||
{
|
||||
return Datetime(*this); // Return the date-time as is
|
||||
}
|
||||
// Extract the number of minutes
|
||||
Int32 minutes = static_cast< Int32 >(seconds / 60);
|
||||
// Extract the number of seconds
|
||||
seconds = m_Second + (seconds % 60);
|
||||
// Are the seconds overlapping with the next minute?
|
||||
if (seconds >= 60)
|
||||
{
|
||||
++minutes; // Increase minutes
|
||||
}
|
||||
// Replicate the current time
|
||||
Datetime dt(*this);
|
||||
// Should we add any minutes?
|
||||
if (minutes)
|
||||
{
|
||||
dt.AddMinutes(minutes);
|
||||
}
|
||||
// Assign the resulted seconds
|
||||
dt.m_Second = (seconds % 60);
|
||||
// Return the result
|
||||
return dt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Datetime Datetime::AndMilliseconds(Int32 milliseconds)
|
||||
{
|
||||
// Did we even added any milliseconds?
|
||||
if (!milliseconds)
|
||||
{
|
||||
return Datetime(*this); // Return the date-time as is
|
||||
}
|
||||
// Extract the number of seconds
|
||||
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
|
||||
// Extract the number of milliseconds
|
||||
milliseconds = m_Millisecond + (milliseconds % 1000);
|
||||
// Are the milliseconds overlapping with the next second?
|
||||
if (milliseconds >= 1000)
|
||||
{
|
||||
++seconds; // Increase seconds
|
||||
}
|
||||
// Replicate the current time
|
||||
Datetime dt(*this);
|
||||
// Should we add any seconds?
|
||||
if (seconds)
|
||||
{
|
||||
dt.AddSeconds(seconds);
|
||||
}
|
||||
// Assign the resulted milliseconds
|
||||
dt.m_Millisecond = (milliseconds % 1000);
|
||||
// Return the result
|
||||
return dt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Date Datetime::GetDate() const
|
||||
{
|
||||
return Date(m_Year, m_Month, m_Day);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Datetime::GetTime() const
|
||||
{
|
||||
return Time(m_Hour, m_Minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Timestamp Datetime::GetTimestamp() const
|
||||
{
|
||||
// Calculate the current day of the year
|
||||
Int32 days = Chrono::DayOfYear(m_Year, m_Month, m_Day);
|
||||
// Calculate all days till the current year
|
||||
for (Int32 year = 0; year < m_Year; --year)
|
||||
{
|
||||
days += Chrono::DaysInYear(year);
|
||||
}
|
||||
// Calculate the microseconds in the resulted days
|
||||
Int64 ms = static_cast< Int64 >(days * 86400000000LL);
|
||||
// Calculate the microseconds in the current time
|
||||
ms += static_cast< Int64 >(m_Hour * 3600000000LL);
|
||||
ms += static_cast< Int64 >(m_Minute * 60000000L);
|
||||
ms += static_cast< Int64 >(m_Second * 1000000L);
|
||||
ms += static_cast< Int64 >(m_Millisecond * 1000L);
|
||||
// Return the resulted timestamp
|
||||
return Timestamp(ms);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_ChronoDatetime(HSQUIRRELVM vm, Table & /*cns*/)
|
||||
{
|
||||
RootTable(vm).Bind(Typename::Str,
|
||||
Class< Datetime >(vm, Typename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< Uint16 >()
|
||||
.Ctor< Uint16, Uint8 >()
|
||||
.Ctor< Uint16, Uint8, Uint8 >()
|
||||
.Ctor< Uint16, Uint8, Uint8, Uint8 >()
|
||||
.Ctor< Uint16, Uint8, Uint8, Uint8, Uint8 >()
|
||||
.Ctor< Uint16, Uint8, Uint8, Uint8, Uint8, Uint8 >()
|
||||
.Ctor< Uint16, Uint8, Uint8, Uint8, Uint8, Uint8, Uint16 >()
|
||||
// Static Properties
|
||||
.SetStaticValue(_SC("GlobalDelimiter"), &Datetime::Delimiter)
|
||||
.SetStaticValue(_SC("GlobalDateDelim"), &Datetime::DateDelim)
|
||||
.SetStaticValue(_SC("GlobalTimeDelim"), &Datetime::TimeDelim)
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
.Func(_SC("_tostring"), &Datetime::ToString)
|
||||
.Func(_SC("cmp"), &Datetime::Cmp)
|
||||
// Meta-methods
|
||||
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_add"), &Datetime::operator +)
|
||||
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_sub"), &Datetime::operator -)
|
||||
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_mul"), &Datetime::operator *)
|
||||
.Func< Datetime (Datetime::*)(const Datetime &) const >(_SC("_div"), &Datetime::operator /)
|
||||
// Properties
|
||||
.Prop(_SC("Delimiter"), &Datetime::GetDelimiter, &Datetime::SetDelimiter)
|
||||
.Prop(_SC("DateDelim"), &Datetime::GetDateDelim, &Datetime::SetDateDelim)
|
||||
.Prop(_SC("TimeDelim"), &Datetime::GetTimeDelim, &Datetime::SetTimeDelim)
|
||||
.Prop(_SC("Str"), &Datetime::GetStr, &Datetime::SetStr)
|
||||
.Prop(_SC("DayOfYear"), &Datetime::GetDayOfYear, &Datetime::SetDayOfYear)
|
||||
.Prop(_SC("Year"), &Datetime::GetYear, &Datetime::SetYear)
|
||||
.Prop(_SC("Month"), &Datetime::GetMonth, &Datetime::SetMonth)
|
||||
.Prop(_SC("Day"), &Datetime::GetDay, &Datetime::SetDay)
|
||||
.Prop(_SC("Hour"), &Datetime::GetHour, &Datetime::SetHour)
|
||||
.Prop(_SC("Minute"), &Datetime::GetMinute, &Datetime::SetMinute)
|
||||
.Prop(_SC("Second"), &Datetime::GetSecond, &Datetime::SetSecond)
|
||||
.Prop(_SC("Millisecond"), &Datetime::GetMillisecond, &Datetime::SetMillisecond)
|
||||
.Prop(_SC("LeapYear"), &Datetime::IsThisLeapYear)
|
||||
.Prop(_SC("YearDays"), &Datetime::GetYearDays)
|
||||
.Prop(_SC("MonthDays"), &Datetime::GetMonthDays)
|
||||
.Prop(_SC("Date"), &Datetime::GetDate)
|
||||
.Prop(_SC("Time"), &Datetime::GetTime)
|
||||
.Prop(_SC("Timestamp"), &Datetime::GetTimestamp)
|
||||
// Member Methods
|
||||
.Func(_SC("AddYears"), &Datetime::AddYears)
|
||||
.Func(_SC("AddMonths"), &Datetime::AddMonths)
|
||||
.Func(_SC("AddDays"), &Datetime::AddDays)
|
||||
.Func(_SC("AddHours"), &Datetime::AddHours)
|
||||
.Func(_SC("AddMinutes"), &Datetime::AddMinutes)
|
||||
.Func(_SC("AddSeconds"), &Datetime::AddSeconds)
|
||||
.Func(_SC("AddMillis"), &Datetime::AddMilliseconds)
|
||||
.Func(_SC("AddMilliseconds"), &Datetime::AddMilliseconds)
|
||||
.Func(_SC("AndYears"), &Datetime::AndYears)
|
||||
.Func(_SC("AndMonths"), &Datetime::AndMonths)
|
||||
.Func(_SC("AndDays"), &Datetime::AndDays)
|
||||
.Func(_SC("AndHours"), &Datetime::AndHours)
|
||||
.Func(_SC("AndMinutes"), &Datetime::AndMinutes)
|
||||
.Func(_SC("AndSeconds"), &Datetime::AndSeconds)
|
||||
.Func(_SC("AndMillis"), &Datetime::AndMilliseconds)
|
||||
.Func(_SC("AndMilliseconds"), &Datetime::AndMilliseconds)
|
||||
// Overloaded Methods
|
||||
.Overload< void (Datetime::*)(Uint16) >(_SC("Set"), &Datetime::Set)
|
||||
.Overload< void (Datetime::*)(Uint16, Uint8) >(_SC("Set"), &Datetime::Set)
|
||||
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
|
||||
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
|
||||
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
|
||||
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8, Uint8, Uint8) >(_SC("Set"), &Datetime::Set)
|
||||
.Overload< void (Datetime::*)(Uint16, Uint8, Uint8, Uint8, Uint8, Uint8, Uint16) >(_SC("Set"), &Datetime::Set)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
580
module/Library/Chrono/Datetime.hpp
Normal file
580
module/Library/Chrono/Datetime.hpp
Normal file
@@ -0,0 +1,580 @@
|
||||
#ifndef _LIBRARY_CHRONO_DATETIME_HPP_
|
||||
#define _LIBRARY_CHRONO_DATETIME_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Helper class used to represent a certain date and time.
|
||||
*/
|
||||
class Datetime
|
||||
{
|
||||
public:
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQChar Delimiter;
|
||||
static SQChar DateDelim;
|
||||
static SQChar TimeDelim;
|
||||
|
||||
private:
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint16 m_Year; // Year
|
||||
Uint8 m_Month; // Month
|
||||
Uint8 m_Day; // Day
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint8 m_Hour; // Hour
|
||||
Uint8 m_Minute; // Minute
|
||||
Uint8 m_Second; // Second
|
||||
Uint16 m_Millisecond; // Millisecond
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar m_Delimiter; // Date and time delimiter when generating strings.
|
||||
SQChar m_DateDelim; // Date component delimiter when generating strings.
|
||||
SQChar m_TimeDelim; // Time component delimiter when generating strings.
|
||||
|
||||
protected:
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Compare the values of two instances.
|
||||
*/
|
||||
Int32 Compare(const Datetime & o) const;
|
||||
|
||||
public:
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Datetime()
|
||||
: m_Year(1970)
|
||||
, m_Month(1)
|
||||
, m_Day(1)
|
||||
, m_Hour(0)
|
||||
, m_Minute(0)
|
||||
, m_Second(0)
|
||||
, m_Millisecond(0)
|
||||
, m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic year constructor.
|
||||
*/
|
||||
Datetime(Uint16 year)
|
||||
: m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
Set(year, 1, 1, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic year and month constructor.
|
||||
*/
|
||||
Datetime(Uint16 year, Uint8 month)
|
||||
: m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
Set(year, month, 1, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic date constructor.
|
||||
*/
|
||||
Datetime(Uint16 year, Uint8 month, Uint8 day)
|
||||
: m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
Set(year, month, day, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic date and hour constructor.
|
||||
*/
|
||||
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour)
|
||||
: m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
Set(year, month, day, hour, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic date, hour and minute constructor.
|
||||
*/
|
||||
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute)
|
||||
: m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
Set(year, month, day, hour, minute, 0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic date and time constructor.
|
||||
*/
|
||||
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second)
|
||||
: m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
Set(year, month, day, hour, minute, second, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Speciffic date and precise time constructor.
|
||||
*/
|
||||
Datetime(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
|
||||
: m_Delimiter(Delimiter)
|
||||
, m_DateDelim(DateDelim)
|
||||
, m_TimeDelim(TimeDelim)
|
||||
{
|
||||
Set(year, month, day, hour, minute, second, millisecond);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
Datetime(const Datetime & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
Datetime(Datetime && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Datetime() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Datetime & operator = (const Datetime & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Datetime & operator = (Datetime && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Datetime & o) const
|
||||
{
|
||||
return Compare(o) == 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Datetime & o) const
|
||||
{
|
||||
return Compare(o) != 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Datetime & o) const
|
||||
{
|
||||
return Compare(o) < 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Datetime & o) const
|
||||
{
|
||||
return Compare(o) > 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Datetime & o) const
|
||||
{
|
||||
return Compare(o) <= 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Datetime & o) const
|
||||
{
|
||||
return Compare(o) >= 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Addition operator.
|
||||
*/
|
||||
Datetime operator + (const Datetime & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Datetime operator - (const Datetime & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Datetime operator * (const Datetime & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Division operator.
|
||||
*/
|
||||
Datetime operator / (const Datetime & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Datetime & o) const
|
||||
{
|
||||
return Compare(o);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year)
|
||||
{
|
||||
Set(year, m_Month, m_Day, m_Hour, m_Minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month)
|
||||
{
|
||||
Set(year, month, m_Day, m_Hour, m_Minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month, Uint8 day)
|
||||
{
|
||||
Set(year, month, day, m_Hour, m_Minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour)
|
||||
{
|
||||
Set(year, month, day, hour, m_Minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute)
|
||||
{
|
||||
Set(year, month, day, hour, minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second)
|
||||
{
|
||||
Set(year, month, day, hour, minute, second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint16 year, Uint8 month, Uint8 day, Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the local delimiter character.
|
||||
*/
|
||||
SQChar GetDelimiter() const
|
||||
{
|
||||
return m_Delimiter;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the local delimiter character.
|
||||
*/
|
||||
void SetDelimiter(SQChar c)
|
||||
{
|
||||
m_Delimiter = c;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the local date delimiter character.
|
||||
*/
|
||||
SQChar GetDateDelim() const
|
||||
{
|
||||
return m_DateDelim;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the local date delimiter character.
|
||||
*/
|
||||
void SetDateDelim(SQChar c)
|
||||
{
|
||||
m_DateDelim = c;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the local time delimiter character.
|
||||
*/
|
||||
SQChar GetTimeDelim() const
|
||||
{
|
||||
return m_TimeDelim;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the local time delimiter character.
|
||||
*/
|
||||
void SetTimeDelim(SQChar c)
|
||||
{
|
||||
m_TimeDelim = c;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the values as a string.
|
||||
*/
|
||||
CSStr GetStr() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values from a string.
|
||||
*/
|
||||
void SetStr(CSStr str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the day component.
|
||||
*/
|
||||
Uint16 GetDayOfYear() const
|
||||
{
|
||||
return Chrono::DayOfYear(m_Year, m_Month, m_Day);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the day component.
|
||||
*/
|
||||
void SetDayOfYear(Uint16 doy);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the year component.
|
||||
*/
|
||||
Uint16 GetYear() const
|
||||
{
|
||||
return m_Year;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the year component.
|
||||
*/
|
||||
void SetYear(Uint16 year);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the month component.
|
||||
*/
|
||||
Uint8 GetMonth() const
|
||||
{
|
||||
return m_Month;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the month component.
|
||||
*/
|
||||
void SetMonth(Uint8 month);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the day component.
|
||||
*/
|
||||
Uint8 GetDay() const
|
||||
{
|
||||
return m_Day;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the day component.
|
||||
*/
|
||||
void SetDay(Uint8 day);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the hour component.
|
||||
*/
|
||||
Uint8 GetHour() const
|
||||
{
|
||||
return m_Hour;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the hour component.
|
||||
*/
|
||||
void SetHour(Uint8 hour);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the minute component.
|
||||
*/
|
||||
Uint8 GetMinute() const
|
||||
{
|
||||
return m_Minute;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the minute component.
|
||||
*/
|
||||
void SetMinute(Uint8 minute);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the second component.
|
||||
*/
|
||||
Uint8 GetSecond() const
|
||||
{
|
||||
return m_Second;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the second component.
|
||||
*/
|
||||
void SetSecond(Uint8 second);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the millisecond component.
|
||||
*/
|
||||
Uint16 GetMillisecond() const
|
||||
{
|
||||
return m_Millisecond;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the millisecond component.
|
||||
*/
|
||||
void SetMillisecond(Uint16 millisecond);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of years to the current date.
|
||||
*/
|
||||
Datetime & AddYears(Int32 years);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of months to the current date.
|
||||
*/
|
||||
Datetime & AddMonths(Int32 months);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of days to the current date.
|
||||
*/
|
||||
Datetime & AddDays(Int32 days);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of hours to the current time.
|
||||
*/
|
||||
Datetime & AddHours(Int32 hours);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of minutes to the current time.
|
||||
*/
|
||||
Datetime & AddMinutes(Int32 minutes);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of seconds to the current time.
|
||||
*/
|
||||
Datetime & AddSeconds(Int32 seconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of milliseconds to the current time.
|
||||
*/
|
||||
Datetime & AddMilliseconds(Int32 milliseconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of years to obtain a new date.
|
||||
*/
|
||||
Datetime AndYears(Int32 years);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of months to obtain a new date.
|
||||
*/
|
||||
Datetime AndMonths(Int32 months);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of days to obtain a new date.
|
||||
*/
|
||||
Datetime AndDays(Int32 days);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of hours to obtain a new time.
|
||||
*/
|
||||
Datetime AndHours(Int32 hours);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of minutes to obtain a new time.
|
||||
*/
|
||||
Datetime AndMinutes(Int32 minutes);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of seconds to obtain a new time.
|
||||
*/
|
||||
Datetime AndSeconds(Int32 seconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of milliseconds to obtain a new time.
|
||||
*/
|
||||
Datetime AndMilliseconds(Int32 milliseconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* See whether the associated year is a leap year.
|
||||
*/
|
||||
bool IsThisLeapYear() const
|
||||
{
|
||||
return Chrono::IsLeapYear(m_Year);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of days in the associated year.
|
||||
*/
|
||||
Uint16 GetYearDays() const
|
||||
{
|
||||
return Chrono::DaysInYear(m_Year);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of days in the associated month.
|
||||
*/
|
||||
Uint8 GetMonthDays() const
|
||||
{
|
||||
return Chrono::DaysInMonth(m_Year, m_Month);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the date from this date-time instance.
|
||||
*/
|
||||
Date GetDate() const;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the time from this date-time instance.
|
||||
*/
|
||||
Time GetTime() const;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Convert this date-time instance to a time-stamp.
|
||||
*/
|
||||
Timestamp GetTimestamp() const;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CHRONO_DATETIME_HPP_
|
464
module/Library/Chrono/Time.cpp
Normal file
464
module/Library/Chrono/Time.cpp
Normal file
@@ -0,0 +1,464 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono/Time.hpp"
|
||||
#include "Library/Chrono/Date.hpp"
|
||||
#include "Library/Chrono/Datetime.hpp"
|
||||
#include "Library/Chrono/Timestamp.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(Typename, _SC("SqTime"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Time::Delimiter = ':';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Time::Compare(const Time & o) const
|
||||
{
|
||||
if (m_Hour < o.m_Hour)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Hour > o.m_Hour)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Minute < o.m_Minute)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Minute > o.m_Minute)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Second < o.m_Second)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Second > o.m_Second)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (m_Millisecond < o.m_Millisecond)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (m_Millisecond == o.m_Millisecond)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::operator + (const Time & o) const
|
||||
{
|
||||
return Time(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::operator - (const Time & o) const
|
||||
{
|
||||
return Time(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::operator * (const Time & o) const
|
||||
{
|
||||
return Time(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::operator / (const Time & o) const
|
||||
{
|
||||
return Time(o);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Time::ToString() const
|
||||
{
|
||||
return ToStrF("%02u%c%02u%c%02u%c%u",
|
||||
m_Hour, m_Delimiter,
|
||||
m_Minute, m_Delimiter,
|
||||
m_Second, m_Delimiter,
|
||||
m_Millisecond);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Time::Set(Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
|
||||
{
|
||||
// Is the specified hour within range?
|
||||
if (hour >= 24)
|
||||
{
|
||||
STHROWF("Hour value is out of range: %u >= 24", hour);
|
||||
}
|
||||
// Is the specified minute within range?
|
||||
else if (minute >= 60)
|
||||
{
|
||||
STHROWF("Minute value is out of range: %u >= 60", minute);
|
||||
}
|
||||
// Is the specified second within range?
|
||||
else if (second >= 60)
|
||||
{
|
||||
STHROWF("Second value is out of range: %u >= 60", second);
|
||||
}
|
||||
// Is the specified millisecond within range?
|
||||
else if (millisecond >= 1000)
|
||||
{
|
||||
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
|
||||
}
|
||||
// Now it's safe to assign the values
|
||||
m_Hour = hour;
|
||||
m_Minute = minute;
|
||||
m_Second = second;
|
||||
m_Millisecond = millisecond;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Time::SetStr(CSStr str)
|
||||
{
|
||||
// The format specifications that will be used to scan the string
|
||||
static SQChar fs[] = _SC(" %u : %u : %u : %u ");
|
||||
// Is the specified string empty?
|
||||
if (!str || *str == '\0')
|
||||
{
|
||||
// Clear the values
|
||||
m_Hour = 0;
|
||||
m_Minute = 0;
|
||||
m_Second = 0;
|
||||
m_Millisecond = 0;
|
||||
// We're done here
|
||||
return;
|
||||
}
|
||||
// Assign the specified delimiter
|
||||
fs[4] = m_Delimiter;
|
||||
fs[9] = m_Delimiter;
|
||||
fs[14] = m_Delimiter;
|
||||
// The sscanf function requires at least 32 bit integers
|
||||
Uint32 hour = 0, minute = 0, second = 0, milli = 0;
|
||||
// Attempt to extract the component values from the specified string
|
||||
sscanf(str, fs, &hour, &minute, &second, &milli);
|
||||
// Clamp the extracted values to the boundaries of associated type and assign them
|
||||
Set(ClampL< Uint32, Uint8 >(hour),
|
||||
ClampL< Uint32, Uint8 >(minute),
|
||||
ClampL< Uint32, Uint8 >(second),
|
||||
ClampL< Uint32, Uint16 >(milli)
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Time::SetHour(Uint8 hour)
|
||||
{
|
||||
// Is the specified hour within range?
|
||||
if (hour >= 24)
|
||||
{
|
||||
STHROWF("Hour value is out of range: %u >= 24", hour);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Hour = hour;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Time::SetMinute(Uint8 minute)
|
||||
{
|
||||
// Is the specified minute within range?
|
||||
if (minute >= 60)
|
||||
{
|
||||
STHROWF("Minute value is out of range: %u >= 60", minute);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Minute = minute;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Time::SetSecond(Uint8 second)
|
||||
{
|
||||
// Is the specified second within range?
|
||||
if (second >= 60)
|
||||
{
|
||||
STHROWF("Second value is out of range: %u >= 60", second);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Second = second;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Time::SetMillisecond(Uint16 millisecond)
|
||||
{
|
||||
// Is the specified millisecond within range?
|
||||
if (millisecond >= 1000)
|
||||
{
|
||||
STHROWF("Millisecond value is out of range: %u >= 1000", millisecond);
|
||||
}
|
||||
// Now it's safe to assign the value
|
||||
m_Millisecond = millisecond;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time & Time::AddHours(Int32 hours)
|
||||
{
|
||||
// Did we even add any hours?
|
||||
if (hours)
|
||||
{
|
||||
// Add the specified amount of hours
|
||||
m_Hour += (hours % 24);
|
||||
// Make sure the value is within range
|
||||
m_Hour %= 24;
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time & Time::AddMinutes(Int32 minutes)
|
||||
{
|
||||
// Did we even add any minutes?
|
||||
if (minutes)
|
||||
{
|
||||
// Extract the number of hours
|
||||
Int32 hours = static_cast< Int32 >(minutes / 60);
|
||||
// Extract the number of minutes
|
||||
m_Minute += (minutes % 60);
|
||||
// Are the minutes overlapping with the next hour?
|
||||
if (m_Minute >= 60)
|
||||
{
|
||||
// Increase the hours
|
||||
++hours;
|
||||
// Subtract one hour from minutes
|
||||
m_Minute %= 60;
|
||||
}
|
||||
// Should we add any hours?
|
||||
if (hours)
|
||||
{
|
||||
AddHours(hours);
|
||||
}
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time & Time::AddSeconds(Int32 seconds)
|
||||
{
|
||||
// Did we even add any seconds?
|
||||
if (seconds)
|
||||
{
|
||||
// Extract the number of minutes
|
||||
Int32 minutes = static_cast< Int32 >(seconds / 60);
|
||||
// Extract the number of seconds
|
||||
m_Second += (seconds % 60);
|
||||
// Are the seconds overlapping with the next minute?
|
||||
if (m_Second >= 60)
|
||||
{
|
||||
// Increase the minutes
|
||||
++minutes;
|
||||
// Subtract one minute from seconds
|
||||
m_Second %= 60;
|
||||
}
|
||||
// Should we add any minutes?
|
||||
if (minutes)
|
||||
{
|
||||
AddMinutes(minutes);
|
||||
}
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time & Time::AddMilliseconds(Int32 milliseconds)
|
||||
{
|
||||
// Did we even add any milliseconds?
|
||||
if (milliseconds)
|
||||
{
|
||||
// Extract the number of seconds
|
||||
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
|
||||
// Extract the number of milliseconds
|
||||
m_Millisecond += (milliseconds / 1000);
|
||||
// Are the milliseconds overlapping with the next second?
|
||||
if (m_Millisecond >= 1000)
|
||||
{
|
||||
// Increase the seconds
|
||||
++seconds;
|
||||
// Subtract one second from milliseconds
|
||||
m_Millisecond %= 1000;
|
||||
}
|
||||
// Should we add any seconds?
|
||||
if (seconds)
|
||||
{
|
||||
AddSeconds(seconds);
|
||||
}
|
||||
}
|
||||
// Allow chaining operations
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::AndHours(Int32 hours)
|
||||
{
|
||||
// Did we even add any hours?
|
||||
if (hours)
|
||||
{
|
||||
return Time((m_Hour + (hours % 24)) % 24, m_Minute, m_Second, m_Millisecond);
|
||||
}
|
||||
// Return the time as is
|
||||
return Time(*this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::AndMinutes(Int32 minutes)
|
||||
{
|
||||
// Did we even added any minutes?
|
||||
if (!minutes)
|
||||
{
|
||||
return Time(*this); // Return the time as is
|
||||
}
|
||||
// Extract the number of hours
|
||||
Int32 hours = static_cast< Int32 >(minutes / 60);
|
||||
// Extract the number of minutes
|
||||
minutes = m_Minute + (minutes % 60);
|
||||
// Are the minutes overlapping with the next hour?
|
||||
if (minutes >= 60)
|
||||
{
|
||||
++hours; // Increase hours
|
||||
}
|
||||
// Replicate the current time
|
||||
Time t(*this);
|
||||
// Should we add any hours?
|
||||
if (hours)
|
||||
{
|
||||
t.AddHours(hours);
|
||||
}
|
||||
// Assign the resulted minutes
|
||||
t.m_Minute = (minutes % 60);
|
||||
// Return the result
|
||||
return t;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::AndSeconds(Int32 seconds)
|
||||
{
|
||||
// Did we even added any seconds?
|
||||
if (!seconds)
|
||||
{
|
||||
return Time(*this); // Return the time as is
|
||||
}
|
||||
// Extract the number of minutes
|
||||
Int32 minutes = static_cast< Int32 >(seconds / 60);
|
||||
// Extract the number of seconds
|
||||
seconds = m_Second + (seconds % 60);
|
||||
// Are the seconds overlapping with the next minute?
|
||||
if (seconds >= 60)
|
||||
{
|
||||
++minutes; // Increase minutes
|
||||
}
|
||||
// Replicate the current time
|
||||
Time t(*this);
|
||||
// Should we add any minutes?
|
||||
if (minutes)
|
||||
{
|
||||
t.AddMinutes(minutes);
|
||||
}
|
||||
// Assign the resulted seconds
|
||||
t.m_Second = (seconds % 60);
|
||||
// Return the result
|
||||
return t;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Time Time::AndMilliseconds(Int32 milliseconds)
|
||||
{
|
||||
// Did we even added any milliseconds?
|
||||
if (!milliseconds)
|
||||
{
|
||||
return Time(*this); // Return the time as is
|
||||
}
|
||||
// Extract the number of seconds
|
||||
Int32 seconds = static_cast< Int32 >(milliseconds / 1000);
|
||||
// Extract the number of milliseconds
|
||||
milliseconds = m_Millisecond + (milliseconds % 1000);
|
||||
// Are the milliseconds overlapping with the next second?
|
||||
if (milliseconds >= 1000)
|
||||
{
|
||||
++seconds; // Increase seconds
|
||||
}
|
||||
// Replicate the current time
|
||||
Time t(*this);
|
||||
// Should we add any seconds?
|
||||
if (seconds)
|
||||
{
|
||||
t.AddSeconds(seconds);
|
||||
}
|
||||
// Assign the resulted milliseconds
|
||||
t.m_Millisecond = (milliseconds % 1000);
|
||||
// Return the result
|
||||
return t;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Timestamp Time::GetTimestamp() const
|
||||
{
|
||||
// Calculate the microseconds in the current time
|
||||
Int64 ms = static_cast< Int64 >(m_Hour * 3600000000LL);
|
||||
ms += static_cast< Int64 >(m_Minute * 60000000L);
|
||||
ms += static_cast< Int64 >(m_Second * 1000000L);
|
||||
ms += static_cast< Int64 >(m_Millisecond * 1000L);
|
||||
// Return the resulted timestamp
|
||||
return Timestamp(ms);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_ChronoTime(HSQUIRRELVM vm, Table & /*cns*/)
|
||||
{
|
||||
RootTable(vm).Bind(Typename::Str,
|
||||
Class< Time >(vm, Typename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< Uint8 >()
|
||||
.Ctor< Uint8, Uint8 >()
|
||||
.Ctor< Uint8, Uint8, Uint8 >()
|
||||
.Ctor< Uint8, Uint8, Uint8, Uint16 >()
|
||||
// Static Properties
|
||||
.SetStaticValue(_SC("GlobalDelimiter"), &Time::Delimiter)
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
.Func(_SC("_tostring"), &Time::ToString)
|
||||
.Func(_SC("cmp"), &Time::Cmp)
|
||||
// Meta-methods
|
||||
.Func< Time (Time::*)(const Time &) const >(_SC("_add"), &Time::operator +)
|
||||
.Func< Time (Time::*)(const Time &) const >(_SC("_sub"), &Time::operator -)
|
||||
.Func< Time (Time::*)(const Time &) const >(_SC("_mul"), &Time::operator *)
|
||||
.Func< Time (Time::*)(const Time &) const >(_SC("_div"), &Time::operator /)
|
||||
// Properties
|
||||
.Prop(_SC("Delimiter"), &Time::GetDelimiter, &Time::SetDelimiter)
|
||||
.Prop(_SC("Str"), &Time::GetStr, &Time::SetStr)
|
||||
.Prop(_SC("Hour"), &Time::GetHour, &Time::SetHour)
|
||||
.Prop(_SC("Minute"), &Time::GetMinute, &Time::SetMinute)
|
||||
.Prop(_SC("Second"), &Time::GetSecond, &Time::SetSecond)
|
||||
.Prop(_SC("Millisecond"), &Time::GetMillisecond, &Time::SetMillisecond)
|
||||
.Prop(_SC("Timestamp"), &Time::GetTimestamp)
|
||||
// Member Methods
|
||||
.Func(_SC("AddHours"), &Time::AddHours)
|
||||
.Func(_SC("AddMinutes"), &Time::AddMinutes)
|
||||
.Func(_SC("AddSeconds"), &Time::AddSeconds)
|
||||
.Func(_SC("AddMillis"), &Time::AddMilliseconds)
|
||||
.Func(_SC("AddMilliseconds"), &Time::AddMilliseconds)
|
||||
.Func(_SC("AndHours"), &Time::AndHours)
|
||||
.Func(_SC("AndMinutes"), &Time::AndMinutes)
|
||||
.Func(_SC("AndSeconds"), &Time::AndSeconds)
|
||||
.Func(_SC("AndMillis"), &Time::AndMilliseconds)
|
||||
.Func(_SC("AndMilliseconds"), &Time::AndMilliseconds)
|
||||
// Overloaded Methods
|
||||
.Overload< void (Time::*)(Uint8) >(_SC("Set"), &Time::Set)
|
||||
.Overload< void (Time::*)(Uint8, Uint8) >(_SC("Set"), &Time::Set)
|
||||
.Overload< void (Time::*)(Uint8, Uint8, Uint8) >(_SC("Set"), &Time::Set)
|
||||
.Overload< void (Time::*)(Uint8, Uint8, Uint8, Uint16) >(_SC("Set"), &Time::Set)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
362
module/Library/Chrono/Time.hpp
Normal file
362
module/Library/Chrono/Time.hpp
Normal file
@@ -0,0 +1,362 @@
|
||||
#ifndef _LIBRARY_CHRONO_TIME_HPP_
|
||||
#define _LIBRARY_CHRONO_TIME_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Helper class used to represent a certain time.
|
||||
*/
|
||||
class Time
|
||||
{
|
||||
public:
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQChar Delimiter;
|
||||
|
||||
protected:
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Compare the values of two instances.
|
||||
*/
|
||||
Int32 Compare(const Time & o) const;
|
||||
|
||||
private:
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint8 m_Hour; // Hour
|
||||
Uint8 m_Minute; // Minute
|
||||
Uint8 m_Second; // Second
|
||||
Uint16 m_Millisecond; // Millisecond
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar m_Delimiter; // Component delimiter when generating strings.
|
||||
|
||||
public:
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Time()
|
||||
: m_Hour(0)
|
||||
, m_Minute(0)
|
||||
, m_Second(0)
|
||||
, m_Millisecond(0)
|
||||
, m_Delimiter(Delimiter)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Time(Uint8 hour)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
Set(hour, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Time(Uint8 hour, Uint8 minute)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
Set(hour, minute, 0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Time(Uint8 hour, Uint8 minute, Uint8 second)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
Set(hour, minute, second, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Time(Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
Set(hour, minute, second, millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* String constructor.
|
||||
*/
|
||||
Time(CSStr str)
|
||||
: m_Delimiter(Delimiter)
|
||||
{
|
||||
SetStr(str);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
Time(const Time & o) = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
Time(Time && o) = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Time() = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Time & operator = (const Time & o) = default;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Time & operator = (Time && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Time & o) const
|
||||
{
|
||||
return Compare(o) == 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Time & o) const
|
||||
{
|
||||
return Compare(o) != 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Time & o) const
|
||||
{
|
||||
return Compare(o) < 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Time & o) const
|
||||
{
|
||||
return Compare(o) > 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Time & o) const
|
||||
{
|
||||
return Compare(o) <= 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Time & o) const
|
||||
{
|
||||
return Compare(o) >= 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Addition operator.
|
||||
*/
|
||||
Time operator + (const Time & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Time operator - (const Time & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Time operator * (const Time & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Division operator.
|
||||
*/
|
||||
Time operator / (const Time & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Time & o) const
|
||||
{
|
||||
return Compare(o);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint8 hour)
|
||||
{
|
||||
Set(hour, m_Minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint8 hour, Uint8 minute)
|
||||
{
|
||||
Set(hour, minute, m_Second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint8 hour, Uint8 minute, Uint8 second)
|
||||
{
|
||||
Set(hour, minute, second, m_Millisecond);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Assign the specified values.
|
||||
*/
|
||||
void Set(Uint8 hour, Uint8 minute, Uint8 second, Uint16 millisecond);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the local delimiter character.
|
||||
*/
|
||||
SQChar GetDelimiter() const
|
||||
{
|
||||
return m_Delimiter;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the local delimiter character.
|
||||
*/
|
||||
void SetDelimiter(SQChar c)
|
||||
{
|
||||
m_Delimiter = c;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the values as a string.
|
||||
*/
|
||||
CSStr GetStr() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values from a string.
|
||||
*/
|
||||
void SetStr(CSStr str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the hour component.
|
||||
*/
|
||||
Uint8 GetHour() const
|
||||
{
|
||||
return m_Hour;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the hour component.
|
||||
*/
|
||||
void SetHour(Uint8 hour);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the minute component.
|
||||
*/
|
||||
Uint8 GetMinute() const
|
||||
{
|
||||
return m_Minute;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the minute component.
|
||||
*/
|
||||
void SetMinute(Uint8 minute);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the second component.
|
||||
*/
|
||||
Uint8 GetSecond() const
|
||||
{
|
||||
return m_Second;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the second component.
|
||||
*/
|
||||
void SetSecond(Uint8 second);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the millisecond component.
|
||||
*/
|
||||
Uint16 GetMillisecond() const
|
||||
{
|
||||
return m_Millisecond;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Modify the millisecond component.
|
||||
*/
|
||||
void SetMillisecond(Uint16 millisecond);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of hours to the current time.
|
||||
*/
|
||||
Time & AddHours(Int32 hours);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of minutes to the current time.
|
||||
*/
|
||||
Time & AddMinutes(Int32 minutes);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of seconds to the current time.
|
||||
*/
|
||||
Time & AddSeconds(Int32 seconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of milliseconds to the current time.
|
||||
*/
|
||||
Time & AddMilliseconds(Int32 milliseconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of hours to obtain a new time.
|
||||
*/
|
||||
Time AndHours(Int32 hours);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of minutes to obtain a new time.
|
||||
*/
|
||||
Time AndMinutes(Int32 minutes);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of seconds to obtain a new time.
|
||||
*/
|
||||
Time AndSeconds(Int32 seconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Add the specified amount of milliseconds to obtain a new time.
|
||||
*/
|
||||
Time AndMilliseconds(Int32 milliseconds);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Convert this time instance to a time-stamp.
|
||||
*/
|
||||
Timestamp GetTimestamp() const;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CHRONO_TIME_HPP_
|
92
module/Library/Chrono/Timer.cpp
Normal file
92
module/Library/Chrono/Timer.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono/Timer.hpp"
|
||||
#include "Library/Chrono/Timestamp.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(Typename, _SC("SqTimer"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Timer::Timer()
|
||||
: m_Timestamp(Chrono::GetCurrentSysTime())
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Timer::Cmp(const Timer & o) const
|
||||
{
|
||||
if (m_Timestamp == o.m_Timestamp)
|
||||
return 0;
|
||||
else if (m_Timestamp > o.m_Timestamp)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Timer::ToString() const
|
||||
{
|
||||
return ToStrF("%lld", m_Timestamp);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Timer::Reset()
|
||||
{
|
||||
m_Timestamp = Chrono::GetCurrentSysTime();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Timestamp Timer::Restart()
|
||||
{
|
||||
const Int64 now = Chrono::GetCurrentSysTime(), elapsed = now - m_Timestamp;
|
||||
m_Timestamp = now;
|
||||
return Timestamp(elapsed);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Timer::RestartRaw()
|
||||
{
|
||||
const Int64 now = Chrono::GetCurrentSysTime(), elapsed = now - m_Timestamp;
|
||||
m_Timestamp = now;
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Timestamp Timer::GetElapsedTime() const
|
||||
{
|
||||
return Timestamp(Chrono::GetCurrentSysTime() - m_Timestamp);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 Timer::GetElapsedTimeRaw() const
|
||||
{
|
||||
return (Chrono::GetCurrentSysTime() - m_Timestamp);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_ChronoTimer(HSQUIRRELVM vm, Table & /*cns*/)
|
||||
{
|
||||
RootTable(vm).Bind(Typename::Str,
|
||||
Class< Timer >(vm, Typename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< const Timer & >()
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
.Func(_SC("_tostring"), &Timer::ToString)
|
||||
.Func(_SC("cmp"), &Timer::Cmp)
|
||||
// Properties
|
||||
.Prop(_SC("Elapsed"), &Timer::GetElapsedTime)
|
||||
.Prop(_SC("ElapsedRaw"), &Timer::GetElapsedTimeRaw)
|
||||
// Functions
|
||||
.Func(_SC("Reset"), &Timer::Reset)
|
||||
.Func(_SC("Restart"), &Timer::Restart)
|
||||
.Func(_SC("RestartRaw"), &Timer::RestartRaw)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
100
module/Library/Chrono/Timer.hpp
Normal file
100
module/Library/Chrono/Timer.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef _LIBRARY_CHRONO_TIMER_HPP_
|
||||
#define _LIBRARY_CHRONO_TIMER_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
class Timer
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timer(Int64 t)
|
||||
: m_Timestamp(t)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timer();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timer(const Timer & o)
|
||||
: m_Timestamp(o.m_Timestamp)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
~Timer()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timer & operator = (const Timer o)
|
||||
{
|
||||
m_Timestamp = o.m_Timestamp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
Int32 Cmp(const Timer & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timestamp Restart();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Int64 RestartRaw();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timestamp GetElapsedTime() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Int64 GetElapsedTimeRaw() const;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Int64 m_Timestamp;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CHRONO_TIMER_HPP_
|
180
module/Library/Chrono/Timestamp.cpp
Normal file
180
module/Library/Chrono/Timestamp.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono/Timestamp.hpp"
|
||||
#include "Library/Chrono/Timer.hpp"
|
||||
#include "Library/Chrono/Date.hpp"
|
||||
#include "Library/Chrono/Time.hpp"
|
||||
#include "Library/Chrono/Datetime.hpp"
|
||||
#include "Library/Numeric/LongInt.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(Typename, _SC("SqTimestamp"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Timestamp::Timestamp(const SLongInt & t)
|
||||
: m_Timestamp(t.GetNum())
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Timestamp::Cmp(const Timestamp & o) const
|
||||
{
|
||||
if (m_Timestamp == o.m_Timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_Timestamp > o.m_Timestamp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Timestamp::ToString() const
|
||||
{
|
||||
return ToStrF("%lld", m_Timestamp);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Timestamp::SetNow()
|
||||
{
|
||||
m_Timestamp = Chrono::GetCurrentSysTime();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SLongInt Timestamp::GetMicroseconds() const
|
||||
{
|
||||
return SLongInt(m_Timestamp);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Timestamp::SetMicroseconds(const SLongInt & ammount)
|
||||
{
|
||||
m_Timestamp = ammount.GetNum();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SLongInt Timestamp::GetMilliseconds() const
|
||||
{
|
||||
return SLongInt(m_Timestamp / 1000L);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Timestamp::SetMilliseconds(const SLongInt & ammount)
|
||||
{
|
||||
m_Timestamp = (ammount.GetNum() * 1000L);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetEpochTimeNow()
|
||||
{
|
||||
return Timestamp(Chrono::GetEpochTimeMicro());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetMicrosecondsRaw(Int64 ammount)
|
||||
{
|
||||
return Timestamp(ammount);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetMicroseconds(const SLongInt & ammount)
|
||||
{
|
||||
return Timestamp(ammount);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetMilliseconds(SQInteger ammount)
|
||||
{
|
||||
return Timestamp(Int64(Int64(ammount) * 1000L));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetSeconds(SQFloat ammount)
|
||||
{
|
||||
return Timestamp(Int64(Float64(ammount) * 1000000L));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetMinutes(SQFloat ammount)
|
||||
{
|
||||
return Timestamp(Int64((Float64(ammount) * 60000000L)));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetHours(SQFloat ammount)
|
||||
{
|
||||
return Timestamp(Int64(Float64(ammount) * 3600000000LL));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetDays(SQFloat ammount)
|
||||
{
|
||||
return Timestamp(Int64(Float64(ammount) * 86400000000LL));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Timestamp SqGetYears(SQFloat ammount)
|
||||
{
|
||||
return Timestamp(Int64(Float64(ammount) * 31557600000000LL));
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_ChronoTimestamp(HSQUIRRELVM vm, Table & /*cns*/)
|
||||
{
|
||||
RootTable(vm).Bind(Typename::Str,
|
||||
Class< Timestamp >(vm, Typename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< const Timestamp & >()
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
.Func(_SC("_tostring"), &Timestamp::ToString)
|
||||
.Func(_SC("cmp"), &Timestamp::Cmp)
|
||||
// Meta-methods
|
||||
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_add"), &Timestamp::operator +)
|
||||
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_sub"), &Timestamp::operator -)
|
||||
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_mul"), &Timestamp::operator *)
|
||||
.Func< Timestamp (Timestamp::*)(const Timestamp &) const >(_SC("_div"), &Timestamp::operator /)
|
||||
// Properties
|
||||
.Prop(_SC("Microseconds"), &Timestamp::GetMicroseconds, &Timestamp::SetMicroseconds)
|
||||
.Prop(_SC("MicrosecondsRaw"), &Timestamp::GetMicrosecondsRaw, &Timestamp::SetMicrosecondsRaw)
|
||||
.Prop(_SC("Milliseconds"), &Timestamp::GetMilliseconds, &Timestamp::SetMilliseconds)
|
||||
.Prop(_SC("MillisecondsRaw"), &Timestamp::GetMillisecondsRaw, &Timestamp::SetMillisecondsRaw)
|
||||
.Prop(_SC("SecondsF"), &Timestamp::GetSecondsF, &Timestamp::SetSecondsF)
|
||||
.Prop(_SC("SecondsI"), &Timestamp::GetSecondsI, &Timestamp::SetSecondsI)
|
||||
.Prop(_SC("MinutesF"), &Timestamp::GetMinutesF, &Timestamp::SetMinutesF)
|
||||
.Prop(_SC("MinutesI"), &Timestamp::GetMinutesI, &Timestamp::SetMinutesI)
|
||||
.Prop(_SC("HoursF"), &Timestamp::GetHoursF, &Timestamp::SetHoursF)
|
||||
.Prop(_SC("HoursI"), &Timestamp::GetHoursI, &Timestamp::SetHoursI)
|
||||
.Prop(_SC("DaysF"), &Timestamp::GetDaysF, &Timestamp::SetDaysF)
|
||||
.Prop(_SC("DaysI"), &Timestamp::GetDaysI, &Timestamp::SetDaysI)
|
||||
.Prop(_SC("YearsF"), &Timestamp::GetYearsF, &Timestamp::SetYearsF)
|
||||
.Prop(_SC("YearsI"), &Timestamp::GetYearsI, &Timestamp::SetYearsI)
|
||||
// Member Methods
|
||||
.Func(_SC("SetNow"), &Timestamp::SetNow)
|
||||
// Static Functions
|
||||
.StaticFunc(_SC("GetNow"), &SqGetEpochTimeNow)
|
||||
.StaticFunc(_SC("GetMicrosRaw"), &SqGetMicrosecondsRaw)
|
||||
.StaticFunc(_SC("GetMicrosecondsRaw"), &SqGetMicrosecondsRaw)
|
||||
.StaticFunc(_SC("GetMicros"), &SqGetMicroseconds)
|
||||
.StaticFunc(_SC("GetMicroseconds"), &SqGetMicroseconds)
|
||||
.StaticFunc(_SC("GetMillis"), &SqGetMilliseconds)
|
||||
.StaticFunc(_SC("GetMilliseconds"), &SqGetMilliseconds)
|
||||
.StaticFunc(_SC("GetSeconds"), &SqGetSeconds)
|
||||
.StaticFunc(_SC("GetMinutes"), &SqGetMinutes)
|
||||
.StaticFunc(_SC("GetHours"), &SqGetHours)
|
||||
.StaticFunc(_SC("GetDays"), &SqGetDays)
|
||||
.StaticFunc(_SC("GetYears"), &SqGetYears)
|
||||
);
|
||||
;
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
347
module/Library/Chrono/Timestamp.hpp
Normal file
347
module/Library/Chrono/Timestamp.hpp
Normal file
@@ -0,0 +1,347 @@
|
||||
#ifndef _LIBRARY_CHRONO_TIMESTAMP_HPP_
|
||||
#define _LIBRARY_CHRONO_TIMESTAMP_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Chrono.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class Timer;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
class Timestamp
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Timer;
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timestamp()
|
||||
: m_Timestamp(0)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timestamp(Int64 t)
|
||||
: m_Timestamp(t)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
explicit Timestamp(const SLongInt & t);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timestamp(const Timestamp & o)
|
||||
: m_Timestamp(o.m_Timestamp)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
~Timestamp()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Timestamp & operator = (const Timestamp o)
|
||||
{
|
||||
m_Timestamp = o.m_Timestamp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
Timestamp operator + (const Timestamp & o) const
|
||||
{
|
||||
return Timestamp(m_Timestamp + o.m_Timestamp);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
Timestamp operator - (const Timestamp & o) const
|
||||
{
|
||||
return Timestamp(m_Timestamp - o.m_Timestamp);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
Timestamp operator * (const Timestamp & o) const
|
||||
{
|
||||
return Timestamp(m_Timestamp * o.m_Timestamp);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
Timestamp operator / (const Timestamp & o) const
|
||||
{
|
||||
return Timestamp(m_Timestamp / o.m_Timestamp);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
Int32 Cmp(const Timestamp & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
*/
|
||||
void SetNow();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
Int64 GetNum() const
|
||||
{
|
||||
return m_Timestamp;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SLongInt GetMicroseconds() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetMicroseconds(const SLongInt & ammount);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQInteger GetMicrosecondsRaw() const
|
||||
{
|
||||
return SQInteger(m_Timestamp);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetMicrosecondsRaw(SQInteger ammount)
|
||||
{
|
||||
m_Timestamp = ammount;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SLongInt GetMilliseconds() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetMilliseconds(const SLongInt & ammount);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQInteger GetMillisecondsRaw() const
|
||||
{
|
||||
return SQInteger(m_Timestamp / 1000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetMillisecondsRaw(SQInteger ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Int64(ammount) * 1000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQFloat GetSecondsF() const
|
||||
{
|
||||
return SQFloat(m_Timestamp / 1000000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetSecondsF(SQFloat ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 1000000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQInteger GetSecondsI() const
|
||||
{
|
||||
return SQInteger(m_Timestamp / 1000000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetSecondsI(SQInteger ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Int64(ammount) * 1000000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQFloat GetMinutesF() const
|
||||
{
|
||||
return SQFloat(m_Timestamp / 60000000.0f);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetMinutesF(SQFloat ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 60000000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQInteger GetMinutesI() const
|
||||
{
|
||||
return SQInteger(m_Timestamp / 60000000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetMinutesI(SQInteger ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Int64(ammount) * 60000000L);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQFloat GetHoursF() const
|
||||
{
|
||||
return SQFloat(m_Timestamp / 3600000000.0d);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetHoursF(SQFloat ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 3600000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQInteger GetHoursI() const
|
||||
{
|
||||
return SQInteger(m_Timestamp / 3600000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetHoursI(SQInteger ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 3600000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQFloat GetDaysF() const
|
||||
{
|
||||
return SQFloat(m_Timestamp / 86400000000.0d);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetDaysF(SQFloat ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 86400000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQInteger GetDaysI() const
|
||||
{
|
||||
return SQInteger(m_Timestamp / 86400000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetDaysI(SQInteger ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 86400000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQFloat GetYearsF() const
|
||||
{
|
||||
return SQFloat(m_Timestamp / 31557600000000.0d);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetYearsF(SQFloat ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 31557600000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
SQInteger GetYearsI() const
|
||||
{
|
||||
return SQInteger(m_Timestamp / 31557600000000LL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void SetYearsI(SQInteger ammount)
|
||||
{
|
||||
m_Timestamp = Int64(Float64(ammount) * 31557600000000LL);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Int64 m_Timestamp;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CHRONO_TIMESTAMP_HPP_
|
23
module/Library/Crypt.cpp
Normal file
23
module/Library/Crypt.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Crypt.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_Hash(HSQUIRRELVM vm);
|
||||
extern void Register_AES(HSQUIRRELVM vm);
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Crypt(HSQUIRRELVM vm)
|
||||
{
|
||||
Register_Hash(vm);
|
||||
Register_AES(vm);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
14
module/Library/Crypt.hpp
Normal file
14
module/Library/Crypt.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LIBRARY_CRYPT_HPP_
|
||||
#define _LIBRARY_CRYPT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CRYPT_HPP_
|
155
module/Library/Crypt/AES.cpp
Normal file
155
module/Library/Crypt/AES.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Crypt/AES.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(Typename, _SC("SqAES256"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AES256::AES256()
|
||||
: m_Context(), m_Buffer()
|
||||
{
|
||||
aes256_done(&m_Context);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AES256::AES256(CSStr key)
|
||||
: m_Context(), m_Buffer()
|
||||
{
|
||||
Init(key);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 AES256::Cmp(const AES256 & o) const
|
||||
{
|
||||
return std::memcmp(m_Buffer, o.m_Buffer, sizeof(m_Buffer));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr AES256::ToString() const
|
||||
{
|
||||
return ToStrF("%s", m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr AES256::GetKey() const
|
||||
{
|
||||
return reinterpret_cast< CSStr >(m_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool AES256::Init(CSStr key)
|
||||
{
|
||||
// Clear current key, if any
|
||||
aes256_done(&m_Context);
|
||||
// Is the specified key empty?
|
||||
if (!key || *key == '\0')
|
||||
{
|
||||
return false; // Leave the context with an empty key
|
||||
}
|
||||
// Obtain the specified key size
|
||||
const Uint32 size = (std::strlen(key) * sizeof(SQChar));
|
||||
// See if the key size is accepted
|
||||
if (size > sizeof(m_Buffer))
|
||||
{
|
||||
STHROWF("The specified key is out of bounds: %u > %u", size, sizeof(m_Buffer));
|
||||
}
|
||||
// Initialize the key buffer to 0
|
||||
std::memset(m_Buffer, 0, sizeof(m_Buffer));
|
||||
// Copy the key into the key buffer
|
||||
std::memcpy(m_Buffer, key, size);
|
||||
// Initialize the context with the specified key
|
||||
aes256_init(&m_Context, m_Buffer);
|
||||
// This context was successfully initialized
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void AES256::Done()
|
||||
{
|
||||
aes256_done(&m_Context);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
String AES256::Encrypt(CSStr data)
|
||||
{
|
||||
// Is there any data to encrypt?
|
||||
if (!data || *data == 0)
|
||||
{
|
||||
return String();
|
||||
}
|
||||
// Copy the data into an editable string
|
||||
String str(data);
|
||||
// Make sure that we have a size with a multiple of 16
|
||||
if ((str.size() % 16) != 0)
|
||||
{
|
||||
str.resize(str.size() - (str.size() % 16) + 16);
|
||||
}
|
||||
// Encrypt in chunks of 16 characters
|
||||
for (Uint32 n = 0; n < str.size(); n += 16)
|
||||
{
|
||||
aes256_encrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n]));
|
||||
}
|
||||
// Return ownership of the encrypted string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
String AES256::Decrypt(CSStr data)
|
||||
{
|
||||
// Is there any data to decrypt?
|
||||
if (!data || *data == 0)
|
||||
{
|
||||
return String();
|
||||
}
|
||||
// Copy the data into an editable string
|
||||
String str(data);
|
||||
// Make sure that we have a size with a multiple of 16
|
||||
if ((str.size() % 16) != 0)
|
||||
{
|
||||
str.resize(str.size() - (str.size() % 16) + 16);
|
||||
}
|
||||
// Decrypt inc chunks of 16 characters
|
||||
for (Uint32 n = 0; n < str.size(); n += 16)
|
||||
{
|
||||
aes256_decrypt_ecb(&m_Context, reinterpret_cast< Uint8 * >(&str[n]));
|
||||
}
|
||||
// Remove null characters in case the string was not a multiple of 16 when encrypted
|
||||
while (!str.empty() && str.back() == 0)
|
||||
{
|
||||
str.pop_back();
|
||||
}
|
||||
// Return ownership of the encrypted string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_AES(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(Typename::Str,
|
||||
Class< AES256 >(vm, Typename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< CSStr >()
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
.Func(_SC("_tostring"), &AES256::ToString)
|
||||
.Func(_SC("cmp"), &AES256::Cmp)
|
||||
/* Properties */
|
||||
.Prop(_SC("Key"), &AES256::GetKey)
|
||||
/* Functions */
|
||||
.Func(_SC("Init"), &AES256::Init)
|
||||
.Func(_SC("Done"), &AES256::Done)
|
||||
.Func(_SC("Encrypt"), &AES256::Encrypt)
|
||||
.Func(_SC("Decrypt"), &AES256::Decrypt)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
105
module/Library/Crypt/AES.hpp
Normal file
105
module/Library/Crypt/AES.hpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#ifndef _LIBRARY_CRYPT_AES_HPP_
|
||||
#define _LIBRARY_CRYPT_AES_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <aes256.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Simple wrapper around a the AES encryption context.
|
||||
*/
|
||||
class AES256
|
||||
{
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
AES256();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct with an explicit key.
|
||||
*/
|
||||
AES256(CSStr key);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
AES256(const AES256 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
AES256(AES256 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~AES256() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
AES256 & operator = (const AES256 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
AES256 & operator = (AES256 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const AES256 & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated key.
|
||||
*/
|
||||
CSStr GetKey() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Initialize the context key.
|
||||
*/
|
||||
bool Init(CSStr key);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reset the associated context.
|
||||
*/
|
||||
void Done();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Encrypt the specified string.
|
||||
*/
|
||||
String Encrypt(CSStr data);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Decrypt the specified string.
|
||||
*/
|
||||
String Decrypt(CSStr data);
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The managed encryption context.
|
||||
*/
|
||||
aes256_context m_Context;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The key used to encrypt data.
|
||||
*/
|
||||
Uint8 m_Buffer[32]{0};
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CRYPT_AES_HPP_
|
192
module/Library/Crypt/Hash.cpp
Normal file
192
module/Library/Crypt/Hash.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Crypt/Hash.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <crc32.h>
|
||||
#include <keccak.h>
|
||||
#include <md5.h>
|
||||
#include <sha1.h>
|
||||
#include <sha256.h>
|
||||
#include <sha3.h>
|
||||
#include <b64.h>
|
||||
#include <whirlpool.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Utility to avoid creating encoder instances for each call.
|
||||
*/
|
||||
template < class T > struct BaseHash
|
||||
{
|
||||
static T Algo;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < class T > T BaseHash< T >::Algo;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Hash the specified value or the result of a formatted string.
|
||||
*/
|
||||
template < class T > static SQInteger HashF(HSQUIRRELVM vm)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Forward the call to the actual implementation and store the string
|
||||
String str(BaseHash< T >::Algo(val.mPtr));
|
||||
// Push the string on the stack
|
||||
sq_pushstring(vm, str.data(), str.size());
|
||||
// At this point we have a valid string on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Hash the specified value or the result of a formatted string with whirlpool algorithm.
|
||||
*/
|
||||
static SQInteger WhirlpoolF(HSQUIRRELVM vm)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Prepare a whirlpool hashing context
|
||||
whirlpool_ctx ctx;
|
||||
// Initialize the hashing context
|
||||
rhash_whirlpool_init(&ctx);
|
||||
// Update the context with the given string
|
||||
rhash_whirlpool_update(&ctx, reinterpret_cast< const unsigned char * >(val.mPtr),
|
||||
val.mLen < 0 ? 0 : static_cast< size_t >(val.mLen));
|
||||
// Reserve space for the result in binary form
|
||||
unsigned char raw_hash[whirlpool_block_size];
|
||||
// Finalize hashing and obtain the result
|
||||
rhash_whirlpool_final(&ctx, raw_hash);
|
||||
// Reserve space for the hexadecimal string
|
||||
char hex_hash[whirlpool_block_size * 2];
|
||||
// Convert from binary form to hex string
|
||||
for (int i = 0, p = 0; i < whirlpool_block_size; ++i)
|
||||
{
|
||||
static const char dec2hex[16+1] = "0123456789abcdef";
|
||||
hex_hash[p++] = dec2hex[(raw_hash[i] >> 4) & 15];
|
||||
hex_hash[p++] = dec2hex[ raw_hash[i] & 15];
|
||||
}
|
||||
// Push the string on the stack
|
||||
sq_pushstring(vm, hex_hash, whirlpool_block_size * 2);
|
||||
// At this point we have a valid string on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Encode the specified value or the result of a formatted string with base64 algorithm.
|
||||
*/
|
||||
static SQInteger EncodeBase64F(HSQUIRRELVM vm)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Size of the encoded string
|
||||
size_t enclen = 0;
|
||||
// Attempt to encode the resulted string
|
||||
char * result = b64_encode_ex(reinterpret_cast< const unsigned char * >(val.mPtr),
|
||||
val.mLen < 0 ? 0 : static_cast< size_t >(val.mLen), &enclen);
|
||||
// Did we fail to allocate memory for it?
|
||||
if (!result)
|
||||
{
|
||||
return sq_throwerror(vm, _SC("Unable to allocate memory for output"));
|
||||
}
|
||||
// Push the string on the stack
|
||||
sq_pushstring(vm, result, ConvTo< SQInteger >::From(enclen));
|
||||
// At this point we have a valid string on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Decode the specified value or the result of a formatted string with base64 algorithm.
|
||||
*/
|
||||
static SQInteger DecodeBase64F(HSQUIRRELVM vm)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Size of the decoded string
|
||||
size_t declen = 0;
|
||||
// Attempt to decode the resulted string
|
||||
unsigned char * result = b64_decode_ex(val.mPtr, val.mLen < 0 ? 0 : static_cast< size_t >(val.mLen), &declen);
|
||||
// Did we fail to allocate memory for it?
|
||||
if (!result)
|
||||
{
|
||||
return sq_throwerror(vm, _SC("Unable to allocate memory for output"));
|
||||
}
|
||||
// Push the string on the stack
|
||||
sq_pushstring(vm, reinterpret_cast< CSStr >(result), ConvTo< SQInteger >::From(declen));
|
||||
// At this point we have a valid string on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
template < class T > static void RegisterWrapper(Table & hashns, CCStr cname)
|
||||
{
|
||||
typedef HashWrapper< T > Hash;
|
||||
hashns.Bind(cname,
|
||||
Class< Hash >(hashns.GetVM(), cname)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
// Meta-methods
|
||||
.Func(_SC("_tostring"), &Hash::ToString)
|
||||
// Properties
|
||||
.Prop(_SC("Hash"), &Hash::GetHash)
|
||||
// Functions
|
||||
.Func(_SC("Reset"), &Hash::Reset)
|
||||
.Func(_SC("Compute"), &Hash::Compute)
|
||||
.Func(_SC("GetHash"), &Hash::GetHash)
|
||||
.Func(_SC("Add"), &Hash::AddStr)
|
||||
.Func(_SC("AddStr"), &Hash::AddStr)
|
||||
);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Hash(HSQUIRRELVM vm)
|
||||
{
|
||||
Table hashns(vm);
|
||||
|
||||
RegisterWrapper< CRC32 >(hashns, _SC("CRC32"));
|
||||
RegisterWrapper< Keccak >(hashns, _SC("Keccak"));
|
||||
RegisterWrapper< MD5 >(hashns, _SC("MD5"));
|
||||
RegisterWrapper< SHA1 >(hashns, _SC("SHA1"));
|
||||
RegisterWrapper< SHA256 >(hashns, _SC("SHA256"));
|
||||
RegisterWrapper< SHA3 >(hashns, _SC("SHA3"));
|
||||
|
||||
hashns.SquirrelFunc(_SC("GetCRC32"), &HashF< CRC32 >);
|
||||
hashns.SquirrelFunc(_SC("GetKeccak"), &HashF< Keccak >);
|
||||
hashns.SquirrelFunc(_SC("GetMD5"), &HashF< MD5 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA1"), &HashF< SHA1 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA256"), &HashF< SHA256 >);
|
||||
hashns.SquirrelFunc(_SC("GetSHA3"), &HashF< SHA3 >);
|
||||
hashns.SquirrelFunc(_SC("GetWhirlpool"), &WhirlpoolF);
|
||||
hashns.SquirrelFunc(_SC("EncodeBase64"), &EncodeBase64F);
|
||||
hashns.SquirrelFunc(_SC("DecodeBase64"), &DecodeBase64F);
|
||||
|
||||
RootTable(vm).Bind(_SC("SqHash"), hashns);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
102
module/Library/Crypt/Hash.hpp
Normal file
102
module/Library/Crypt/Hash.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#ifndef _LIBRARY_CRYPT_HASH_HPP_
|
||||
#define _LIBRARY_CRYPT_HASH_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Simple class to maintain the state of an encoder.
|
||||
*/
|
||||
template < class T > class HashWrapper
|
||||
{
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
HashWrapper()
|
||||
: m_Encoder()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy operator.
|
||||
*/
|
||||
HashWrapper(const HashWrapper & o)
|
||||
: m_Encoder(o.m_Encoder)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~HashWrapper()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
HashWrapper & operator = (const HashWrapper & o)
|
||||
{
|
||||
m_Encoder = o.m_Encoder;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
String ToString()
|
||||
{
|
||||
return m_Encoder.getHash();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reset the encoder state.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
m_Encoder.reset();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Compute the hash of the specified string.
|
||||
*/
|
||||
String Compute(const String & str)
|
||||
{
|
||||
return m_Encoder(str);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the hash value of the data hashed so far.
|
||||
*/
|
||||
String GetHash()
|
||||
{
|
||||
return m_Encoder.getHash();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add a string value to be hashed.
|
||||
*/
|
||||
void AddStr(const String & str)
|
||||
{
|
||||
m_Encoder.add(str.data(), str.length() * sizeof(String::value_type));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The managed encoder state.
|
||||
*/
|
||||
T m_Encoder;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_CRYPT_HASH_HPP_
|
16
module/Library/IO.cpp
Normal file
16
module/Library/IO.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/IO.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_INI(HSQUIRRELVM vm);
|
||||
|
||||
// ================================================================================================
|
||||
void Register_IO(HSQUIRRELVM vm)
|
||||
{
|
||||
Register_INI(vm);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
14
module/Library/IO.hpp
Normal file
14
module/Library/IO.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LIBRARY_IO_HPP_
|
||||
#define _LIBRARY_IO_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_IO_HPP_
|
0
module/Library/IO/File.cpp
Normal file
0
module/Library/IO/File.cpp
Normal file
0
module/Library/IO/File.hpp
Normal file
0
module/Library/IO/File.hpp
Normal file
479
module/Library/IO/INI.cpp
Normal file
479
module/Library/IO/INI.cpp
Normal file
@@ -0,0 +1,479 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/IO/INI.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cerrno>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(ResultTypename, _SC("SqIniResult"))
|
||||
SQMODE_DECL_TYPENAME(EntriesTypename, _SC("SqIniEntries"))
|
||||
SQMODE_DECL_TYPENAME(DocumentTypename, _SC("SqIniDocument"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void IniResult::Check() const
|
||||
{
|
||||
// Identify the error type
|
||||
switch (m_Result)
|
||||
{
|
||||
case SI_FAIL:
|
||||
STHROWF("Unable to %s. Probably invalid", m_Action.c_str());
|
||||
break;
|
||||
case SI_NOMEM:
|
||||
STHROWF("Unable to %s. Ran out of memory", m_Action.c_str());
|
||||
break;
|
||||
case SI_FILE:
|
||||
STHROWF("Unable to %s. %s", strerror(errno));
|
||||
break;
|
||||
case SI_OK:
|
||||
case SI_UPDATED:
|
||||
case SI_INSERTED:
|
||||
break; /* These are not error messahes. */
|
||||
default:
|
||||
STHROWF("Unable to %s for some unforeseen reason", m_Action.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DocumentRef::Validate() const
|
||||
{
|
||||
// Is the document handle valid?
|
||||
if (!m_Ptr)
|
||||
{
|
||||
STHROWF("Invalid INI document reference");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Entries::Cmp(const Entries & o) const
|
||||
{
|
||||
if (m_Elem == o.m_Elem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_List.size() > o.m_List.size())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Entries::Next()
|
||||
{
|
||||
// Are there any other elements ahead?
|
||||
if (!m_List.empty() && m_Elem != m_List.end())
|
||||
{
|
||||
++m_Elem; // Go ahead one element
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Entries::Prev()
|
||||
{
|
||||
// Are there any other elements behind?
|
||||
if (!m_List.empty() && m_Elem != m_List.begin())
|
||||
{
|
||||
--m_Elem; // Go back one element
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Entries::Advance(Int32 n)
|
||||
{
|
||||
// Are there any other elements ahead?
|
||||
if (m_List.empty() || m_Elem == m_List.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Jump as many elements as possible within the specified distance
|
||||
while ((--n >= 0) && m_Elem != m_List.end())
|
||||
{
|
||||
++m_Elem;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Entries::Retreat(Int32 n)
|
||||
{
|
||||
// Are there any other elements behind?
|
||||
if (m_List.empty() || m_Elem == m_List.begin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Jump as many elements as possible within the specified distance
|
||||
while ((--n >= 0) && m_Elem != m_List.begin())
|
||||
{
|
||||
--m_Elem;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Entries::GetItem() const
|
||||
{
|
||||
// is the current element valid?
|
||||
if (m_List.empty() || m_Elem == m_List.end())
|
||||
{
|
||||
STHROWF("Invalid INI entry [item]");
|
||||
}
|
||||
// Return the requested information
|
||||
return m_Elem->pItem;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Entries::GetComment() const
|
||||
{
|
||||
// is the current element valid?
|
||||
if (m_List.empty() || m_Elem == m_List.end())
|
||||
{
|
||||
STHROWF("Invalid INI entry [comment]");
|
||||
}
|
||||
// Return the requested information
|
||||
return m_Elem->pComment;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Entries::GetOrder() const
|
||||
{
|
||||
// is the current element valid?
|
||||
if (m_List.empty() || m_Elem == m_List.end())
|
||||
{
|
||||
STHROWF("Invalid INI entry [order]");
|
||||
}
|
||||
// Return the requested information
|
||||
return m_Elem->nOrder;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Document::Cmp(const Document & o) const
|
||||
{
|
||||
if (m_Doc == o.m_Doc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_Doc.m_Ptr > o.m_Doc.m_Ptr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IniResult Document::LoadFile(CSStr filepath)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to load the file from disk and return the result
|
||||
return IniResult("load INI file", m_Doc->LoadFile(filepath));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IniResult Document::LoadData(CSStr source, Int32 size)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to load the file from memory and return the result
|
||||
return IniResult("load INI file", m_Doc->LoadData(source, size < 0 ? strlen(source) : size));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IniResult Document::SaveFile(CSStr filepath, bool signature)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to save the file to disk and return the result
|
||||
return IniResult("save INI file", m_Doc->SaveFile(filepath, signature));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object Document::SaveData(bool signature)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// The string where the content will be saved
|
||||
String source;
|
||||
// Attempt to save the data to string
|
||||
if (m_Doc->Save(source, signature) < 0)
|
||||
{
|
||||
STHROWF("Unable to save INI document");
|
||||
}
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(DefaultVM::Get());
|
||||
// Transform it into a script object
|
||||
sq_pushstring(DefaultVM::Get(), source.c_str(), source.size());
|
||||
// Get the object from the stack and return it
|
||||
return Var< Object >(DefaultVM::Get(), -1).value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Entries Document::GetAllSections() const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Prepare a container to receive the entries
|
||||
static Container entries;
|
||||
// Obtain all sections from the INI document
|
||||
m_Doc->GetAllSections(entries);
|
||||
// Return the entries and take over content
|
||||
return Entries(m_Doc, entries);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Entries Document::GetAllKeys(CSStr section) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Prepare a container to receive the entries
|
||||
static Container entries;
|
||||
// Obtain all sections from the INI document
|
||||
m_Doc->GetAllKeys(section, entries);
|
||||
// Return the entries and take over content
|
||||
return Entries(m_Doc, entries);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Entries Document::GetAllValues(CSStr section, CSStr key) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Prepare a container to receive the entries
|
||||
static Container entries;
|
||||
// Obtain all sections from the INI document
|
||||
m_Doc->GetAllValues(section, key, entries);
|
||||
// Return the entries and take over content
|
||||
return Entries(m_Doc, entries);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Document::GetSectionSize(CSStr section) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Return the requested information
|
||||
return m_Doc->GetSectionSize(section);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Document::HasMultipleKeys(CSStr section, CSStr key) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Where to retrive whether the key has multiple instances
|
||||
bool multiple = false;
|
||||
// Attempt to query the information
|
||||
if (m_Doc->GetValue(section, key, nullptr, &multiple) == nullptr)
|
||||
{
|
||||
return true; // Doesn't exist
|
||||
}
|
||||
// Return the result
|
||||
return multiple;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CCStr Document::GetValue(CSStr section, CSStr key, CSStr def) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to query the information and return it
|
||||
return m_Doc->GetValue(section, key, def, nullptr);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Document::GetInteger(CSStr section, CSStr key, SQInteger def) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to query the information and return it
|
||||
return static_cast< SQInteger >(m_Doc->GetLongValue(section, key, def, nullptr));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQFloat Document::GetFloat(CSStr section, CSStr key, SQFloat def) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to query the information and return it
|
||||
return static_cast< SQFloat >(m_Doc->GetDoubleValue(section, key, def, nullptr));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Document::GetBoolean(CSStr section, CSStr key, bool def) const
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to query the information and return it
|
||||
return m_Doc->GetBoolValue(section, key, def, nullptr);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IniResult Document::SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to apply the specified information and return the result
|
||||
return IniResult("set INI value", m_Doc->SetValue(section, key, value, comment, force));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IniResult Document::SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to apply the specified information and return the result
|
||||
return IniResult("set INI integer", m_Doc->SetLongValue(section, key, value, comment, hex, force));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IniResult Document::SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to apply the specified information and return the result
|
||||
return IniResult("set INI float", m_Doc->SetDoubleValue(section, key, value, comment, force));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
IniResult Document::SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to apply the specified information
|
||||
return IniResult("set INI boolean", m_Doc->SetBoolValue(section, key, value, comment, force));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Document::DeleteValue(CSStr section, CSStr key, CSStr value, bool empty)
|
||||
{
|
||||
// Validate the handle
|
||||
m_Doc.Validate();
|
||||
// Attempt to remove the specified value and return the result
|
||||
return m_Doc->DeleteValue(section, key, value, empty);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_INI(HSQUIRRELVM vm)
|
||||
{
|
||||
Table inins(vm);
|
||||
|
||||
inins.Bind(_SC("Result"),
|
||||
Class< IniResult >(vm, ResultTypename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< CSStr, SQInteger >()
|
||||
.Ctor< const IniResult & >()
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &ResultTypename::Fn)
|
||||
.Func(_SC("_tostring"), &IniResult::ToString)
|
||||
.Func(_SC("cmp"), &IniResult::Cmp)
|
||||
// Properties
|
||||
.Prop(_SC("Valid"), &IniResult::IsValid)
|
||||
.Prop(_SC("Action"), &IniResult::GetAction)
|
||||
.Prop(_SC("Result"), &IniResult::GetResult)
|
||||
// Member Methods
|
||||
.Func(_SC("Check"), &IniResult::Check)
|
||||
);
|
||||
|
||||
inins.Bind(_SC("Entries"),
|
||||
Class< Entries >(vm, EntriesTypename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< const Entries & >()
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &EntriesTypename::Fn)
|
||||
.Func(_SC("_tostring"), &Entries::ToString)
|
||||
.Func(_SC("cmp"), &Entries::Cmp)
|
||||
// Properties
|
||||
.Prop(_SC("Valid"), &Entries::IsValid)
|
||||
.Prop(_SC("Empty"), &Entries::IsEmpty)
|
||||
.Prop(_SC("References"), &Entries::GetRefCount)
|
||||
.Prop(_SC("Size"), &Entries::GetSize)
|
||||
.Prop(_SC("Item"), &Entries::GetItem)
|
||||
.Prop(_SC("Comment"), &Entries::GetComment)
|
||||
.Prop(_SC("Order"), &Entries::GetOrder)
|
||||
// Member Methods
|
||||
.Func(_SC("Reset"), &Entries::Reset)
|
||||
.Func(_SC("Next"), &Entries::Next)
|
||||
.Func(_SC("Prev"), &Entries::Prev)
|
||||
.Func(_SC("Advance"), &Entries::Advance)
|
||||
.Func(_SC("Retreat"), &Entries::Retreat)
|
||||
.Func(_SC("Sort"), &Entries::Sort)
|
||||
.Func(_SC("SortByKeyOrder"), &Entries::SortByKeyOrder)
|
||||
.Func(_SC("SortByLoadOrder"), &Entries::SortByLoadOrder)
|
||||
);
|
||||
|
||||
inins.Bind(_SC("Document"),
|
||||
Class< Document, NoCopy< Document > >(vm, DocumentTypename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< bool >()
|
||||
.Ctor< bool, bool >()
|
||||
.Ctor< bool, bool, bool >()
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &DocumentTypename::Fn)
|
||||
.Func(_SC("_tostring"), &Document::ToString)
|
||||
.Func(_SC("cmp"), &Document::Cmp)
|
||||
// Properties
|
||||
.Prop(_SC("Valid"), &Document::IsValid)
|
||||
.Prop(_SC("Empty"), &Document::IsEmpty)
|
||||
.Prop(_SC("References"), &Document::GetRefCount)
|
||||
.Prop(_SC("Unicode"), &Document::GetUnicode, &Document::SetUnicode)
|
||||
.Prop(_SC("MultiKey"), &Document::GetMultiKey, &Document::SetMultiKey)
|
||||
.Prop(_SC("MultiLine"), &Document::GetMultiLine, &Document::SetMultiLine)
|
||||
.Prop(_SC("Spaces"), &Document::GetSpaces, &Document::SetSpaces)
|
||||
// Member Methods
|
||||
.Func(_SC("Reset"), &Document::Reset)
|
||||
.Func(_SC("LoadFile"), &Document::LoadFile)
|
||||
.Overload< IniResult (Document::*)(CSStr) >(_SC("LoadString"), &Document::LoadData)
|
||||
.Overload< IniResult (Document::*)(CSStr, Int32) >(_SC("LoadString"), &Document::LoadData)
|
||||
.Overload< IniResult (Document::*)(CSStr) >(_SC("SaveFile"), &Document::SaveFile)
|
||||
.Overload< IniResult (Document::*)(CSStr, bool) >(_SC("SaveFile"), &Document::SaveFile)
|
||||
.Func(_SC("SaveData"), &Document::SaveData)
|
||||
.Func(_SC("GetSections"), &Document::GetAllSections)
|
||||
.Func(_SC("GetKeys"), &Document::GetAllKeys)
|
||||
.Func(_SC("GetValues"), &Document::GetAllValues)
|
||||
.Func(_SC("GetSectionSize"), &Document::GetSectionSize)
|
||||
.Func(_SC("HasMultipleKeys"), &Document::HasMultipleKeys)
|
||||
.Func(_SC("GetValue"), &Document::GetValue)
|
||||
.Func(_SC("GetInteger"), &Document::GetInteger)
|
||||
.Func(_SC("GetFloat"), &Document::GetFloat)
|
||||
.Func(_SC("GetBoolean"), &Document::GetBoolean)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr) >(_SC("SetValue"), &Document::SetValue)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("SetValue"), &Document::SetValue)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, CSStr, bool, CSStr) >(_SC("SetValue"), &Document::SetValue)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger) >(_SC("SetInteger"), &Document::SetInteger)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool) >(_SC("SetInteger"), &Document::SetInteger)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool) >(_SC("SetInteger"), &Document::SetInteger)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, SQInteger, bool, bool, CSStr) >(_SC("SetInteger"), &Document::SetInteger)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat) >(_SC("SetFloat"), &Document::SetFloat)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool) >(_SC("SetFloat"), &Document::SetFloat)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, SQFloat, bool, CSStr) >(_SC("SetFloat"), &Document::SetFloat)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool) >(_SC("SetBoolean"), &Document::SetBoolean)
|
||||
.Overload< IniResult (Document::*)(CSStr, CSStr, bool, bool, CSStr) >(_SC("SetBoolean"), &Document::SetBoolean)
|
||||
.Overload< bool (Document::*)(CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
|
||||
.Overload< bool (Document::*)(CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
|
||||
.Overload< bool (Document::*)(CSStr, CSStr, CSStr) >(_SC("DeleteValue"), &Document::DeleteValue)
|
||||
.Overload< bool (Document::*)(CSStr, CSStr, CSStr, bool) >(_SC("DeleteValue"), &Document::DeleteValue)
|
||||
);
|
||||
|
||||
RootTable(vm).Bind(_SC("SqIni"), inins);
|
||||
|
||||
ConstTable(vm).Enum(_SC("SqIniError"), Enumeration(vm)
|
||||
.Const(_SC("Ok"), Int32(SI_OK))
|
||||
.Const(_SC("Updated"), Int32(SI_UPDATED))
|
||||
.Const(_SC("Inserted"), Int32(SI_INSERTED))
|
||||
.Const(_SC("Fail"), Int32(SI_FAIL))
|
||||
.Const(_SC("NoMem"), Int32(SI_NOMEM))
|
||||
.Const(_SC("File"), Int32(SI_FILE))
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
981
module/Library/IO/INI.hpp
Normal file
981
module/Library/IO/INI.hpp
Normal file
@@ -0,0 +1,981 @@
|
||||
#ifndef _LIBRARY_IO_INI_HPP_
|
||||
#define _LIBRARY_IO_INI_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <SimpleIni.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Allows the user to inspect the result of certain operations and act accordingly.
|
||||
*/
|
||||
class IniResult
|
||||
{
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
String m_Action; // The action that was performed.
|
||||
SQInteger m_Result; // The internal result code.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct with no specific action or result.
|
||||
*/
|
||||
IniResult()
|
||||
: m_Action("unknown action"), m_Result(SI_OK)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct with no specific result.
|
||||
*/
|
||||
explicit IniResult(CSStr action)
|
||||
: m_Action(!action ? _SC("") : action), m_Result(SI_OK)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct with no specific action.
|
||||
*/
|
||||
explicit IniResult(SQInteger result)
|
||||
: m_Action("unknown action"), m_Result(result)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct with specific action and result.
|
||||
*/
|
||||
IniResult(CSStr action, SQInteger result)
|
||||
: m_Action(!action ? _SC("") : action), m_Result(result)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
IniResult(const IniResult & o)
|
||||
: m_Action(o.m_Action), m_Result(o.m_Result)
|
||||
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~IniResult()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
IniResult & operator = (const IniResult & o)
|
||||
{
|
||||
m_Action = o.m_Action;
|
||||
m_Result = o.m_Result;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two results.
|
||||
*/
|
||||
bool operator == (const IniResult & o) const
|
||||
{
|
||||
return (m_Result == o.m_Result);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two results.
|
||||
*/
|
||||
bool operator != (const IniResult & o) const
|
||||
{
|
||||
return (m_Result != o.m_Result);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return (m_Result >= 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const IniResult & o) const
|
||||
{
|
||||
if (m_Result == o.m_Result)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (m_Result > o.m_Result)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return m_Action.c_str();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance references a valid INI result.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return (m_Result >= 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated action.
|
||||
*/
|
||||
CSStr GetAction() const
|
||||
{
|
||||
return m_Action.c_str();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the resulted code.
|
||||
*/
|
||||
SQInteger GetResult() const
|
||||
{
|
||||
return m_Result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the resulted code.
|
||||
*/
|
||||
void Check() const;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages a reference counted INI document instance.
|
||||
*/
|
||||
class DocumentRef
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Document;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef CSimpleIniA Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int Counter; // Reference counter type.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the document reference and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Pointer m_Ptr; // The document reader, writer and manager instance.
|
||||
Counter* m_Ref; // Reference count to the managed instance.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grab a strong reference to a document instance.
|
||||
*/
|
||||
void Grab()
|
||||
{
|
||||
if (m_Ptr)
|
||||
{
|
||||
++(*m_Ref);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Drop a strong reference to a document instance.
|
||||
*/
|
||||
void Drop()
|
||||
{
|
||||
if (m_Ptr && --(*m_Ref) == 0)
|
||||
{
|
||||
delete m_Ptr;
|
||||
delete m_Ref;
|
||||
m_Ptr = NULL;
|
||||
m_Ref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
DocumentRef(bool utf8, bool multikey, bool multiline)
|
||||
: m_Ptr(new Type(utf8, multikey, multiline)), m_Ref(new Counter(1))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null).
|
||||
*/
|
||||
DocumentRef()
|
||||
: m_Ptr(NULL), m_Ref(NULL)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
DocumentRef(const DocumentRef & o)
|
||||
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
|
||||
|
||||
{
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
DocumentRef(DocumentRef && o)
|
||||
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
|
||||
|
||||
{
|
||||
o.m_Ptr = NULL;
|
||||
o.m_Ref = NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~DocumentRef()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
DocumentRef & operator = (const DocumentRef & o)
|
||||
{
|
||||
if (m_Ptr != o.m_Ptr)
|
||||
{
|
||||
Drop();
|
||||
m_Ptr = o.m_Ptr;
|
||||
m_Ref = o.m_Ref;
|
||||
Grab();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
DocumentRef & operator = (DocumentRef && o)
|
||||
{
|
||||
if (m_Ptr != o.m_Ptr)
|
||||
{
|
||||
m_Ptr = o.m_Ptr;
|
||||
m_Ref = o.m_Ref;
|
||||
o.m_Ptr = NULL;
|
||||
o.m_Ref = NULL;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two document instances.
|
||||
*/
|
||||
bool operator == (const DocumentRef & o) const
|
||||
{
|
||||
return (m_Ptr == o.m_Ptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two document instances.
|
||||
*/
|
||||
bool operator != (const DocumentRef & o) const
|
||||
{
|
||||
return (m_Ptr != o.m_Ptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance pointer.
|
||||
*/
|
||||
operator Pointer ()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance pointer.
|
||||
*/
|
||||
operator ConstPtr () const
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance reference.
|
||||
*/
|
||||
operator Reference ()
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance reference.
|
||||
*/
|
||||
operator ConstRef () const
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Member operator for dereferencing the managed pointer.
|
||||
*/
|
||||
Pointer operator -> () const
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Indirection operator for obtaining a reference of the managed pointer.
|
||||
*/
|
||||
Reference operator * () const
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of active references to the managed instance.
|
||||
*/
|
||||
Counter Count() const
|
||||
{
|
||||
return (m_Ptr && m_Ref) ? (*m_Ref) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Class that can access and iterate a series of entries in the INI document.
|
||||
*/
|
||||
class Entries
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Document;
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef DocumentRef::Type::TNamesDepend Container;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Container::iterator Iterator;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Entries(const DocumentRef & ini, Container & list)
|
||||
: m_Doc(ini), m_List(), m_Elem()
|
||||
{
|
||||
m_List.swap(list);
|
||||
Reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
DocumentRef m_Doc; // The document that contains the elements.
|
||||
Container m_List; // The list of elements to iterate.
|
||||
Iterator m_Elem; // The currently processed element.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor. (null)
|
||||
*/
|
||||
Entries()
|
||||
: m_Doc(), m_List(), m_Elem(m_List.end())
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
Entries(const Entries & o)
|
||||
: m_Doc(o.m_Doc), m_List(o.m_List), m_Elem()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Entries()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Entries & operator = (const Entries & o)
|
||||
{
|
||||
m_Doc = o.m_Doc;
|
||||
m_List = o.m_List;
|
||||
Reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Entries & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return GetItem();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return whether the current element is valid and can be accessed.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return !(m_List.empty() || m_Elem == m_List.end());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return whether the entry list is empty.
|
||||
*/
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_List.empty();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return the number of active references to this document instance.
|
||||
*/
|
||||
Uint32 GetRefCount() const
|
||||
{
|
||||
return m_Doc.Count();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return the total entries in the list.
|
||||
*/
|
||||
Int32 GetSize() const
|
||||
{
|
||||
return static_cast< Int32 >(m_List.size());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reset the internal iterator to the first element.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
if (m_List.empty())
|
||||
{
|
||||
m_Elem = m_List.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Elem = m_List.begin();
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Go to the next element.
|
||||
*/
|
||||
void Next();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Go to the previous element.
|
||||
*/
|
||||
void Prev();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Advance a certain number of elements.
|
||||
*/
|
||||
void Advance(Int32 n);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retreat a certain number of elements.
|
||||
*/
|
||||
void Retreat(Int32 n);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sort the entries using the default options.
|
||||
*/
|
||||
void Sort()
|
||||
{
|
||||
if (!m_List.empty())
|
||||
{
|
||||
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sort the entries by name of key only.
|
||||
*/
|
||||
void SortByKeyOrder()
|
||||
{
|
||||
if (!m_List.empty())
|
||||
{
|
||||
m_List.sort(DocumentRef::Type::Entry::KeyOrder());
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sort the entries by their load order and then name of key.
|
||||
*/
|
||||
void SortByLoadOrder()
|
||||
{
|
||||
if (!m_List.empty())
|
||||
{
|
||||
m_List.sort(DocumentRef::Type::Entry::LoadOrder());
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the string value of the current element item.
|
||||
*/
|
||||
CSStr GetItem() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the string value of the current element comment.
|
||||
*/
|
||||
CSStr GetComment() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the order of the current element.
|
||||
*/
|
||||
Int32 GetOrder() const;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Class that can read/write and alter the contents of INI files.
|
||||
*/
|
||||
class Document
|
||||
{
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef DocumentRef::Type::TNamesDepend Container;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
Document(const Document & o);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
Document & operator = (const Document & o);
|
||||
|
||||
private:
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
DocumentRef m_Doc; // The main INI document instance.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Document()
|
||||
: m_Doc(false, false, true)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit constructor.
|
||||
*/
|
||||
Document(bool utf8)
|
||||
: m_Doc(utf8, false, true)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit constructor.
|
||||
*/
|
||||
Document(bool utf8, bool multikey)
|
||||
: m_Doc(utf8, multikey, true)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit constructor.
|
||||
*/
|
||||
Document(bool utf8, bool multikey, bool multiline)
|
||||
: m_Doc(utf8, multikey, multiline)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Document()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Document & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return _SC("");
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance references a valid INI document.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return m_Doc;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return the number of active references to this document instance.
|
||||
*/
|
||||
Uint32 GetRefCount() const
|
||||
{
|
||||
return m_Doc.Count();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether any data has been loaded into this document.
|
||||
*/
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_Doc->IsEmpty();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Deallocate all memory stored by this document.
|
||||
*/
|
||||
void Reset() const
|
||||
{
|
||||
m_Doc->Reset();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the INI data is treated as unicode.
|
||||
*/
|
||||
bool GetUnicode() const
|
||||
{
|
||||
return m_Doc->IsUnicode();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether the INI data should be treated as unicode.
|
||||
*/
|
||||
void SetUnicode(bool toggle)
|
||||
{
|
||||
m_Doc->SetUnicode(toggle);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether multiple identical keys be permitted in the file.
|
||||
*/
|
||||
bool GetMultiKey() const
|
||||
{
|
||||
return m_Doc->IsMultiKey();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether multiple identical keys be permitted in the file.
|
||||
*/
|
||||
void SetMultiKey(bool toggle)
|
||||
{
|
||||
m_Doc->SetMultiKey(toggle);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether data values are permitted to span multiple lines in the file.
|
||||
*/
|
||||
bool GetMultiLine() const
|
||||
{
|
||||
return m_Doc->IsMultiLine();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether data values are permitted to span multiple lines in the file.
|
||||
*/
|
||||
void SetMultiLine(bool toggle)
|
||||
{
|
||||
m_Doc->SetMultiLine(toggle);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether spaces are added around the equals sign when writing key/value pairs out.
|
||||
*/
|
||||
bool GetSpaces() const
|
||||
{
|
||||
return m_Doc->UsingSpaces();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether spaces are added around the equals sign when writing key/value pairs out.
|
||||
*/
|
||||
void SetSpaces(bool toggle)
|
||||
{
|
||||
m_Doc->SetSpaces(toggle);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Load an INI file from disk into memory.
|
||||
*/
|
||||
IniResult LoadFile(CSStr filepath);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Load INI file data direct from a string. (LoadString collides with the windows api)
|
||||
*/
|
||||
IniResult LoadData(CSStr source)
|
||||
{
|
||||
return LoadData(source, -1);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Load INI file data direct from a string. (LoadString collides with the windows api)
|
||||
*/
|
||||
IniResult LoadData(CSStr source, Int32 size);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Save an INI file from memory to disk.
|
||||
*/
|
||||
IniResult SaveFile(CSStr filepath)
|
||||
{
|
||||
return SaveFile(filepath, true);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Save an INI file from memory to disk.
|
||||
*/
|
||||
IniResult SaveFile(CSStr filepath, bool signature);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Save the INI data to a string.
|
||||
*/
|
||||
Object SaveData(bool signature);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve all section names.
|
||||
*/
|
||||
Entries GetAllSections() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve all unique key names in a section.
|
||||
*/
|
||||
Entries GetAllKeys(CSStr section) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve all values for a specific key.
|
||||
*/
|
||||
Entries GetAllValues(CSStr section, CSStr key) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Query the number of keys in a specific section.
|
||||
*/
|
||||
Int32 GetSectionSize(CSStr section) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether a certain key has multiple instances.
|
||||
*/
|
||||
bool HasMultipleKeys(CSStr section, CSStr key) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value for a specific key.
|
||||
*/
|
||||
CCStr GetValue(CSStr section, CSStr key, CSStr def) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a numeric value for a specific key.
|
||||
*/
|
||||
SQInteger GetInteger(CSStr section, CSStr key, SQInteger def) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a numeric value for a specific key.
|
||||
*/
|
||||
SQFloat GetFloat(CSStr section, CSStr key, SQFloat def) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a boolean value for a specific key.
|
||||
*/
|
||||
bool GetBoolean(CSStr section, CSStr key, bool def) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a section or value.
|
||||
*/
|
||||
IniResult SetValue(CSStr section, CSStr key, CSStr value)
|
||||
{
|
||||
return SetValue(section, key, value, false, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a section or value.
|
||||
*/
|
||||
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force)
|
||||
{
|
||||
return SetValue(section, key, value, force, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a section or value.
|
||||
*/
|
||||
IniResult SetValue(CSStr section, CSStr key, CSStr value, bool force, CSStr comment);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a numeric value.
|
||||
*/
|
||||
IniResult SetInteger(CSStr section, CSStr key, SQInteger value)
|
||||
{
|
||||
return SetInteger(section, key, value, false, false, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a numeric value.
|
||||
*/
|
||||
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex)
|
||||
{
|
||||
return SetInteger(section, key, value, hex, false, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a numeric value.
|
||||
*/
|
||||
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force)
|
||||
{
|
||||
return SetInteger(section, key, value, hex, force, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a numeric value.
|
||||
*/
|
||||
IniResult SetInteger(CSStr section, CSStr key, SQInteger value, bool hex, bool force, CSStr comment);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a double value.
|
||||
*/
|
||||
IniResult SetFloat(CSStr section, CSStr key, SQFloat value)
|
||||
{
|
||||
return SetFloat(section, key, value, false, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a double value.
|
||||
*/
|
||||
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force)
|
||||
{
|
||||
return SetFloat(section, key, value, force, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a double value.
|
||||
*/
|
||||
IniResult SetFloat(CSStr section, CSStr key, SQFloat value, bool force, CSStr comment);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a double value.
|
||||
*/
|
||||
IniResult SetBoolean(CSStr section, CSStr key, bool value)
|
||||
{
|
||||
return SetBoolean(section, key, value, false, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a double value.
|
||||
*/
|
||||
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force)
|
||||
{
|
||||
return SetBoolean(section, key, value, force, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add or update a boolean value.
|
||||
*/
|
||||
IniResult SetBoolean(CSStr section, CSStr key, bool value, bool force, CSStr comment);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Delete an entire section, or a key from a section.
|
||||
*/
|
||||
bool DeleteValue(CSStr section)
|
||||
{
|
||||
return DeleteValue(section, nullptr, nullptr, false);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Delete an entire section, or a key from a section.
|
||||
*/
|
||||
bool DeleteValue(CSStr section, CSStr key)
|
||||
{
|
||||
return DeleteValue(section, key, nullptr, false);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Delete an entire section, or a key from a section.
|
||||
*/
|
||||
bool DeleteValue(CSStr section, CSStr key, CSStr value)
|
||||
{
|
||||
return DeleteValue(section, key, value, false);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Delete an entire section, or a key from a section.
|
||||
*/
|
||||
bool DeleteValue(CSStr section, CSStr key, CSStr value, bool empty);
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_IO_INI_HPP_
|
20
module/Library/Numeric.cpp
Normal file
20
module/Library/Numeric.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Numeric.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_LongInt(HSQUIRRELVM vm);
|
||||
extern void Register_Math(HSQUIRRELVM vm);
|
||||
extern void Register_Random(HSQUIRRELVM vm);
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Numeric(HSQUIRRELVM vm)
|
||||
{
|
||||
Register_LongInt(vm);
|
||||
Register_Math(vm);
|
||||
Register_Random(vm);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
14
module/Library/Numeric.hpp
Normal file
14
module/Library/Numeric.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LIBRARY_NUMERIC_HPP_
|
||||
#define _LIBRARY_NUMERIC_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_NUMERIC_HPP_
|
197
module/Library/Numeric/LongInt.cpp
Normal file
197
module/Library/Numeric/LongInt.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Numeric/LongInt.hpp"
|
||||
#include "Library/Numeric/Random.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/DynArg.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(TypenameS, _SC("SLongInt"))
|
||||
SQMODE_DECL_TYPENAME(TypenameU, _SC("ULongInt"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LongInt< Int64 >::LongInt(CSStr text)
|
||||
: m_Data(0), m_Text()
|
||||
{
|
||||
m_Data = std::strtoll(text, nullptr, 10);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LongInt< Int64 >::LongInt(CSStr text, Uint32 base)
|
||||
: m_Data(0), m_Text()
|
||||
{
|
||||
m_Data = std::strtoll(text, nullptr, base);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LongInt< Int64 > & LongInt< Int64 >::operator = (CSStr text)
|
||||
{
|
||||
m_Data = std::strtoll(text, nullptr, 10);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr LongInt< Int64 >::ToString()
|
||||
{
|
||||
if (std::snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0)
|
||||
{
|
||||
m_Text[0] = 0;
|
||||
}
|
||||
|
||||
return m_Text;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LongInt< Int64 >::Random()
|
||||
{
|
||||
m_Data = GetRandomInt64();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LongInt< Int64 >::Random(Type n)
|
||||
{
|
||||
m_Data = GetRandomInt64(n);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LongInt< Int64 >::Random(Type m, Type n)
|
||||
{
|
||||
m_Data = GetRandomInt64(m, n);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LongInt< Uint64 >::LongInt(CSStr text)
|
||||
: m_Data(0), m_Text()
|
||||
{
|
||||
m_Data = std::strtoull(text, nullptr, 10);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LongInt< Uint64 >::LongInt(CSStr text, Uint32 base)
|
||||
: m_Data(0), m_Text()
|
||||
{
|
||||
m_Data = std::strtoull(text, nullptr, base);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LongInt< Uint64 > & LongInt< Uint64 >::operator = (CSStr text)
|
||||
{
|
||||
m_Data = std::strtoull(text, nullptr, 10);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr LongInt< Uint64 >::ToString()
|
||||
{
|
||||
if (std::snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0)
|
||||
{
|
||||
m_Text[0] = 0;
|
||||
}
|
||||
|
||||
return m_Text;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LongInt< Uint64 >::Random()
|
||||
{
|
||||
m_Data = GetRandomUint64();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LongInt< Uint64 >::Random(Type n)
|
||||
{
|
||||
m_Data = GetRandomUint64(n);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LongInt< Uint64 >::Random(Type m, Type n)
|
||||
{
|
||||
m_Data = GetRandomUint64(m, n);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_LongInt(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(TypenameS::Str,
|
||||
Class< SLongInt >(vm, TypenameS::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< SLongInt::Type >()
|
||||
.template Ctor< CCStr, SQInteger >()
|
||||
// Properties
|
||||
.Prop(_SC("Str"), &SLongInt::GetCStr, &SLongInt::SetStr)
|
||||
.Prop(_SC("Num"), &SLongInt::GetSNum, &SLongInt::SetNum)
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
|
||||
.SquirrelFunc(_SC("_typename"), &TypenameS::Fn)
|
||||
.Func(_SC("_tostring"), &SLongInt::ToString)
|
||||
// Core Functions
|
||||
.Func(_SC("tointeger"), &SLongInt::ToSqInteger)
|
||||
.Func(_SC("tofloat"), &SLongInt::ToSqFloat)
|
||||
.Func(_SC("tostring"), &SLongInt::ToSqString)
|
||||
.Func(_SC("tobool"), &SLongInt::ToSqBool)
|
||||
.Func(_SC("tochar"), &SLongInt::ToSqChar)
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
|
||||
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
|
||||
.SquirrelFunc(_SC("_mul"), &SqDynArgFwd< SqDynArgMulFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
|
||||
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
|
||||
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< SLongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, SLongInt, ULongInt >)
|
||||
.Func< SLongInt (SLongInt::*)(void) const >(_SC("_unm"), &SLongInt::operator -)
|
||||
// Functions
|
||||
.Func(_SC("GetStr"), &SLongInt::GetCStr)
|
||||
.Func(_SC("SetStr"), &SLongInt::SetStr)
|
||||
.Func(_SC("GetNum"), &SLongInt::GetSNum)
|
||||
.Func(_SC("SetNum"), &SLongInt::SetNum)
|
||||
// Overloads
|
||||
.Overload< void (SLongInt::*)(void) >(_SC("Random"), &SLongInt::Random)
|
||||
.Overload< void (SLongInt::*)(SLongInt::Type) >(_SC("Random"), &SLongInt::Random)
|
||||
.Overload< void (SLongInt::*)(SLongInt::Type, SLongInt::Type) >(_SC("Random"), &SLongInt::Random)
|
||||
);
|
||||
|
||||
RootTable(vm).Bind(TypenameU::Str,
|
||||
Class< ULongInt >(vm, TypenameU::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< ULongInt::Type >()
|
||||
.Ctor< CCStr, SQInteger >()
|
||||
// Properties
|
||||
.Prop(_SC("Str"), &ULongInt::GetCStr, &ULongInt::SetStr)
|
||||
.Prop(_SC("Num"), &ULongInt::GetSNum, &ULongInt::SetNum)
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("cmp"), &SqDynArgFwd< SqDynArgCmpFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
|
||||
.SquirrelFunc(_SC("_typename"), &TypenameU::Fn)
|
||||
.Func(_SC("_tostring"), &ULongInt::ToString)
|
||||
// Core Functions
|
||||
.Func(_SC("tointeger"), &ULongInt::ToSqInteger)
|
||||
.Func(_SC("tofloat"), &ULongInt::ToSqFloat)
|
||||
.Func(_SC("tostring"), &ULongInt::ToSqString)
|
||||
.Func(_SC("tobool"), &ULongInt::ToSqBool)
|
||||
.Func(_SC("tochar"), &ULongInt::ToSqChar)
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_add"), &SqDynArgFwd< SqDynArgAddFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
|
||||
.SquirrelFunc(_SC("_sub"), &SqDynArgFwd< SqDynArgSubFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
|
||||
.SquirrelFunc(_SC("_mul"), &SqDynArgFwd< SqDynArgMulFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
|
||||
.SquirrelFunc(_SC("_div"), &SqDynArgFwd< SqDynArgDivFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
|
||||
.SquirrelFunc(_SC("_modulo"), &SqDynArgFwd< SqDynArgModFn< ULongInt >, SQInteger, SQFloat, bool, std::nullptr_t, CSStr, ULongInt, SLongInt >)
|
||||
.Func< ULongInt (ULongInt::*)(void) const >(_SC("_unm"), &ULongInt::operator -)
|
||||
// Functions
|
||||
.Func(_SC("GetStr"), &ULongInt::GetCStr)
|
||||
.Func(_SC("SetStr"), &ULongInt::SetStr)
|
||||
.Func(_SC("GetNum"), &ULongInt::GetSNum)
|
||||
.Func(_SC("SetNum"), &ULongInt::SetNum)
|
||||
// Overloads
|
||||
.Overload< void (ULongInt::*)(void) >(_SC("Random"), &ULongInt::Random)
|
||||
.Overload< void (ULongInt::*)(ULongInt::Type) >(_SC("Random"), &ULongInt::Random)
|
||||
.Overload< void (ULongInt::*)(ULongInt::Type, ULongInt::Type) >(_SC("Random"), &ULongInt::Random)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
1280
module/Library/Numeric/LongInt.hpp
Normal file
1280
module/Library/Numeric/LongInt.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1231
module/Library/Numeric/Math.cpp
Normal file
1231
module/Library/Numeric/Math.cpp
Normal file
File diff suppressed because it is too large
Load Diff
14
module/Library/Numeric/Math.hpp
Normal file
14
module/Library/Numeric/Math.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LIBRARY_NUMERIC_MATH_HPP_
|
||||
#define _LIBRARY_NUMERIC_MATH_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_NUMERIC_MATH_HPP_
|
444
module/Library/Numeric/Random.cpp
Normal file
444
module/Library/Numeric/Random.cpp
Normal file
@@ -0,0 +1,444 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Numeric/Random.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#ifdef SQMOD_OS_WINDOWS
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static std::unique_ptr< std::mt19937 > RG32_MT19937 =
|
||||
std::unique_ptr< std::mt19937 >(new std::mt19937(GenerateSeed()));
|
||||
|
||||
static std::unique_ptr< std::mt19937_64 > RG64_MT19937 =
|
||||
std::unique_ptr< std::mt19937_64 >(new std::mt19937_64(GenerateSeed()));
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static std::uniform_int_distribution< Int8 > Int8_Dist(std::numeric_limits< Int8 >::min(),
|
||||
std::numeric_limits< Int8 >::max());
|
||||
static std::uniform_int_distribution< Uint8 > Uint8_Dist(std::numeric_limits< Uint8 >::min(),
|
||||
std::numeric_limits< Uint8 >::max());
|
||||
|
||||
static std::uniform_int_distribution< Int16 > Int16_Dist(std::numeric_limits< Int16 >::min(),
|
||||
std::numeric_limits< Int16 >::max());
|
||||
static std::uniform_int_distribution< Uint16 > Uint16_Dist(std::numeric_limits< Uint16 >::min(),
|
||||
std::numeric_limits< Uint16 >::max());
|
||||
|
||||
static std::uniform_int_distribution< Int32 > Int32_Dist(std::numeric_limits< Int32 >::min(),
|
||||
std::numeric_limits< Int32 >::max());
|
||||
static std::uniform_int_distribution< Uint32 > Uint32_Dist(std::numeric_limits< Uint32 >::min(),
|
||||
std::numeric_limits< Uint32 >::max());
|
||||
|
||||
static std::uniform_int_distribution< Int64 > Int64_Dist(std::numeric_limits< Int64 >::min(),
|
||||
std::numeric_limits< Int64 >::max());
|
||||
static std::uniform_int_distribution< Uint64 > Uint64_Dist(std::numeric_limits< Uint64 >::min(),
|
||||
std::numeric_limits< Uint64 >::max());
|
||||
|
||||
static std::uniform_real_distribution<Float32> Float32_Dist(std::numeric_limits< Float32 >::min(),
|
||||
std::numeric_limits< Float32 >::max());
|
||||
static std::uniform_real_distribution<Float64> Float64_Dist(std::numeric_limits< Float64 >::min(),
|
||||
std::numeric_limits< Float64 >::max());
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static std::uniform_int_distribution< String::value_type >
|
||||
String_Dist(std::numeric_limits< String::value_type >::min(),
|
||||
std::numeric_limits< String::value_type >::max());
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SizeT GenerateSeed()
|
||||
{
|
||||
Ulong a = clock();
|
||||
Ulong b = time(NULL);
|
||||
#ifdef SQMOD_OS_WINDOWS
|
||||
Ulong c = _getpid();
|
||||
#else
|
||||
Ulong c = getpid();
|
||||
#endif
|
||||
// Mangle
|
||||
a=a-b; a=a-c; a=a^(c >> 13);
|
||||
b=b-c; b=b-a; b=b^(a << 8);
|
||||
c=c-a; c=c-b; c=c^(b >> 13);
|
||||
a=a-b; a=a-c; a=a^(c >> 12);
|
||||
b=b-c; b=b-a; b=b^(a << 16);
|
||||
c=c-a; c=c-b; c=c^(b >> 5);
|
||||
a=a-b; a=a-c; a=a^(c >> 3);
|
||||
b=b-c; b=b-a; b=b^(a << 10);
|
||||
c=c-a; c=c-b; c=c^(b >> 15);
|
||||
// Return result
|
||||
return c;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SizeT GenerateSeed2()
|
||||
{
|
||||
struct {
|
||||
std::clock_t c;
|
||||
std::time_t t;
|
||||
#ifdef SQMOD_OS_WINDOWS
|
||||
int p;
|
||||
#else
|
||||
pid_t p;
|
||||
#endif
|
||||
} data;
|
||||
data.c = std::clock();
|
||||
data.t = std::time(nullptr);
|
||||
#ifdef SQMOD_OS_WINDOWS
|
||||
data.p = _getpid();
|
||||
#else
|
||||
data.p = getpid();
|
||||
#endif
|
||||
// Mangle and return result
|
||||
return FnvHash(reinterpret_cast< const uint8_t * >(&data), sizeof(data));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReseedRandom()
|
||||
{
|
||||
RG32_MT19937.reset(new std::mt19937(GenerateSeed()));
|
||||
RG64_MT19937.reset(new std::mt19937_64(GenerateSeed()));
|
||||
}
|
||||
|
||||
void ReseedRandom(Uint32 n)
|
||||
{
|
||||
RG32_MT19937.reset(new std::mt19937(n));
|
||||
RG64_MT19937.reset(new std::mt19937_64(n));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReseedRandom32()
|
||||
{
|
||||
RG32_MT19937.reset(new std::mt19937(GenerateSeed()));
|
||||
}
|
||||
|
||||
void ReseedRandom32(Uint32 n)
|
||||
{
|
||||
RG32_MT19937.reset(new std::mt19937(n));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReseedRandom64()
|
||||
{
|
||||
RG64_MT19937.reset(new std::mt19937_64(GenerateSeed()));
|
||||
}
|
||||
|
||||
void ReseedRandom64(Uint32 n)
|
||||
{
|
||||
RG64_MT19937.reset(new std::mt19937_64(n));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int8 GetRandomInt8()
|
||||
{
|
||||
return Int8_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int8 GetRandomInt8(Int8 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int8 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int8 GetRandomInt8(Int8 m, Int8 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int8 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint8 GetRandomUint8()
|
||||
{
|
||||
return Uint8_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint8 GetRandomUint8(Uint8 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Uint8 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint8 GetRandomUint8(Uint8 m, Uint8 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Uint8 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int16 GetRandomInt16()
|
||||
{
|
||||
return Int16_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int16 GetRandomInt16(Int16 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int16 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int16 GetRandomInt16(Int16 m, Int16 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int16 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint16 GetRandomUint16()
|
||||
{
|
||||
return Uint16_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint16 GetRandomUint16(Uint16 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Uint16 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint16 GetRandomUint16(Uint16 m, Uint16 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Uint16 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 GetRandomInt32()
|
||||
{
|
||||
return Int32_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int32 GetRandomInt32(Int32 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int32 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Int32 GetRandomInt32(Int32 m, Int32 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int32 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 GetRandomUint32()
|
||||
{
|
||||
return Int32_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint32 GetRandomUint32(Uint32 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int32 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Uint32 GetRandomUint32(Uint32 m, Uint32 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int32 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 GetRandomInt64()
|
||||
{
|
||||
return Int64_Dist(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Int64 GetRandomInt64(Int64 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int64 >(0, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Int64 GetRandomInt64(Int64 m, Int64 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Int64 >(m, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint64 GetRandomUint64()
|
||||
{
|
||||
return Uint64_Dist(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Uint64 GetRandomUint64(Uint64 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Uint64 >(0, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Uint64 GetRandomUint64(Uint64 m, Uint64 n)
|
||||
{
|
||||
return std::uniform_int_distribution< Uint64 >(m, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 GetRandomFloat32()
|
||||
{
|
||||
return Float32_Dist(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Float32 GetRandomFloat32(Float32 n)
|
||||
{
|
||||
return std::uniform_real_distribution< Float32 >(0, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
Float32 GetRandomFloat32(Float32 m, Float32 n)
|
||||
{
|
||||
return std::uniform_real_distribution< Float32 >(m, n)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float64 GetRandomFloat64()
|
||||
{
|
||||
return Float64_Dist(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Float64 GetRandomFloat64(Float64 n)
|
||||
{
|
||||
return std::uniform_real_distribution< Float64 >(0, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
Float64 GetRandomFloat64(Float64 m, Float64 n)
|
||||
{
|
||||
return std::uniform_real_distribution< Float64 >(m, n)(*RG64_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void GetRandomString(String & str, String::size_type len)
|
||||
{
|
||||
// Reserve the requested size + the null terminator
|
||||
str.reserve(len+1);
|
||||
// Resize to the requested size and fill with 0
|
||||
str.resize(len);
|
||||
// Generate the requested amount of characters
|
||||
for (auto & c : str)
|
||||
c = String_Dist(*RG32_MT19937);
|
||||
// Append the null terminator
|
||||
str.push_back(0);
|
||||
}
|
||||
|
||||
void GetRandomString(String & str, String::size_type len, String::value_type n)
|
||||
{
|
||||
// Reserve the requested size + the null terminator
|
||||
str.reserve(len+1);
|
||||
// Resize to the requested size and fill with 0
|
||||
str.resize(len);
|
||||
// Create the custom distribution
|
||||
std::uniform_int_distribution< String::value_type > dist(1, n);
|
||||
// Generate the requested amount of characters
|
||||
for (auto & c : str)
|
||||
c = dist(*RG32_MT19937);
|
||||
// Append the null terminator
|
||||
str.push_back(0);
|
||||
}
|
||||
|
||||
void GetRandomString(String & str, String::size_type len, String::value_type m, String::value_type n)
|
||||
{
|
||||
// Reserve the requested size + the null terminator
|
||||
str.reserve(len+1);
|
||||
// Resize to the requested size and fill with 0
|
||||
str.resize(len);
|
||||
// Create the custom distribution
|
||||
std::uniform_int_distribution< String::value_type > dist(m, n);
|
||||
// Generate the requested amount of characters
|
||||
for (auto & c : str)
|
||||
c = dist(*RG32_MT19937);
|
||||
// Append the null terminator
|
||||
str.push_back(0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool GetRandomBool()
|
||||
{
|
||||
return std::bernoulli_distribution()(*RG32_MT19937);
|
||||
}
|
||||
|
||||
bool GetRandomBool(SQFloat p)
|
||||
{
|
||||
return std::bernoulli_distribution(p)(*RG32_MT19937);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static String RandomString(Int32 len)
|
||||
{
|
||||
// Is there anything to generate?
|
||||
if (len <= 0)
|
||||
return _SC("");
|
||||
// Prepare the string buffer
|
||||
String str;
|
||||
// Request the random fill
|
||||
GetRandomString(str, len);
|
||||
// Return ownership of the string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static String RandomString(Int32 len, SQChar n)
|
||||
{
|
||||
// Is there anything to generate?
|
||||
if (len <= 0)
|
||||
return _SC("");
|
||||
// Prepare the string buffer
|
||||
String str;
|
||||
// Request the random fill
|
||||
GetRandomString(str, len, n);
|
||||
// Return ownership of the string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static String RandomString(Int32 len, SQChar m, SQChar n)
|
||||
{
|
||||
// Is there anything to generate?
|
||||
if (len <= 0)
|
||||
return _SC("");
|
||||
// Prepare the string buffer
|
||||
String str;
|
||||
// Request the random fill
|
||||
GetRandomString(str, len, m, n);
|
||||
// Return ownership of the string
|
||||
return std::move(str);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Register_Random(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqRand"), Table(vm)
|
||||
.Func(_SC("GenSeed"), &GenerateSeed)
|
||||
.Func(_SC("GenSeed2"), &GenerateSeed2)
|
||||
.Overload< void (*)(void) >(_SC("Reseed"), &ReseedRandom)
|
||||
.Overload< void (*)(Uint32) >(_SC("Reseed"), &ReseedRandom)
|
||||
.Overload< void (*)(void) >(_SC("Reseed32"), &ReseedRandom32)
|
||||
.Overload< void (*)(Uint32) >(_SC("Reseed32"), &ReseedRandom32)
|
||||
.Overload< void (*)(void) >(_SC("Reseed64"), &ReseedRandom64)
|
||||
.Overload< void (*)(Uint32) >(_SC("Reseed64"), &ReseedRandom64)
|
||||
|
||||
#ifdef _SQ64
|
||||
.Overload< SQInteger (*)(void) >(_SC("Integer"), &GetRandomInt64)
|
||||
.Overload< SQInteger (*)(SQInteger) >(_SC("Integer"), &GetRandomInt64)
|
||||
.Overload< SQInteger (*)(SQInteger, SQInteger) >(_SC("Integer"), &GetRandomInt64)
|
||||
#else
|
||||
.Overload< SQInteger (*)(void) >(_SC("Integer"), &GetRandomInt32)
|
||||
.Overload< SQInteger (*)(SQInteger) >(_SC("Integer"), &GetRandomInt32)
|
||||
.Overload< SQInteger (*)(SQInteger, SQInteger) >(_SC("Integer"), &GetRandomInt32)
|
||||
#endif // _SQ64
|
||||
|
||||
#ifdef SQUSEDOUBLE
|
||||
.Overload< SQFloat (*)(void) >(_SC("Float"), &GetRandomFloat64)
|
||||
.Overload< SQFloat (*)(SQFloat) >(_SC("Float"), &GetRandomFloat64)
|
||||
.Overload< SQFloat (*)(SQFloat, SQFloat) >(_SC("Float"), &GetRandomFloat64)
|
||||
#else
|
||||
.Overload< SQFloat (*)(void) >(_SC("Float"), &GetRandomFloat32)
|
||||
.Overload< SQFloat (*)(SQFloat) >(_SC("Float"), &GetRandomFloat32)
|
||||
.Overload< SQFloat (*)(SQFloat, SQFloat) >(_SC("Float"), &GetRandomFloat32)
|
||||
#endif // SQUSEDOUBLE
|
||||
|
||||
.Overload< String (*)(Int32) >(_SC("String"), &RandomString)
|
||||
.Overload< String (*)(Int32, SQChar) >(_SC("String"), &RandomString)
|
||||
.Overload< String (*)(Int32, SQChar, SQChar) >(_SC("String"), &RandomString)
|
||||
.Overload< bool (*)(void) >(_SC("Bool"), &GetRandomBool)
|
||||
.Overload< bool (*)(SQFloat) >(_SC("Bool"), &GetRandomBool)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
164
module/Library/Numeric/Random.hpp
Normal file
164
module/Library/Numeric/Random.hpp
Normal file
@@ -0,0 +1,164 @@
|
||||
#ifndef _LIBRARY_NUMERIC_RANDOM_HPP_
|
||||
#define _LIBRARY_NUMERIC_RANDOM_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Attempt to generate a moderately unique number to be used as a seed for random numbers.
|
||||
*/
|
||||
Uint32 GenerateSeed();
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ReseedRandom();
|
||||
void ReseedRandom(Uint32 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int8 GetRandomInt8();
|
||||
Int8 GetRandomInt8(Int8 n);
|
||||
Int8 GetRandomInt8(Int8 m, Int8 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint8 GetRandomUint8();
|
||||
Uint8 GetRandomUint8(Uint8 n);
|
||||
Uint8 GetRandomUint8(Uint8 m, Uint8 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int16 GetRandomInt16();
|
||||
Int16 GetRandomInt16(Int16 n);
|
||||
Int16 GetRandomInt16(Int16 m, Int16 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint16 GetRandomUint16();
|
||||
Uint16 GetRandomUint16(Uint16 n);
|
||||
Uint16 GetRandomUint16(Uint16 m, Uint16 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 GetRandomInt32();
|
||||
Int32 GetRandomInt32(Int32 n);
|
||||
Int32 GetRandomInt32(Int32 m, Int32 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 GetRandomUint32();
|
||||
Uint32 GetRandomUint32(Uint32 n);
|
||||
Uint32 GetRandomUint32(Uint32 m, Uint32 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int64 GetRandomInt64();
|
||||
Int64 GetRandomInt64(Int64 n);
|
||||
Int64 GetRandomInt64(Int64 m, Int64 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint64 GetRandomUint64();
|
||||
Uint64 GetRandomUint64(Uint64 n);
|
||||
Uint64 GetRandomUint64(Uint64 m, Uint64 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 GetRandomFloat32();
|
||||
Float32 GetRandomFloat32(Float32 n);
|
||||
Float32 GetRandomFloat32(Float32 m, Float32 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float64 GetRandomFloat64();
|
||||
Float64 GetRandomFloat64(Float64 n);
|
||||
Float64 GetRandomFloat64(Float64 m, Float64 n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void GetRandomString(String & str, String::size_type len);
|
||||
void GetRandomString(String & str, String::size_type len, String::value_type n);
|
||||
void GetRandomString(String & str, String::size_type len, String::value_type m, String::value_type n);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool GetRandomBool();
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T> struct RandomVal
|
||||
{ /* ... */ };
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> struct RandomVal< Int8 >
|
||||
{
|
||||
static inline Int8 Get() { return GetRandomInt8(); }
|
||||
static inline Int8 Get(Int8 n) { return GetRandomInt8(n); }
|
||||
static inline Int8 Get(Int8 m, Int8 n) { return GetRandomInt8(m, n); }
|
||||
};
|
||||
|
||||
template <> struct RandomVal< Uint8 >
|
||||
{
|
||||
static inline Uint8 Get() { return GetRandomUint8(); }
|
||||
static inline Uint8 Get(Uint8 n) { return GetRandomUint8(n); }
|
||||
static inline Uint8 Get(Uint8 m, Uint8 n) { return GetRandomUint8(m, n); }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> struct RandomVal< Int16 >
|
||||
{
|
||||
static inline Int16 Get() { return GetRandomInt16(); }
|
||||
static inline Int16 Get(Int16 n) { return GetRandomInt16(n); }
|
||||
static inline Int16 Get(Int16 m, Int16 n) { return GetRandomInt16(m, n); }
|
||||
};
|
||||
|
||||
template <> struct RandomVal< Uint16 >
|
||||
{
|
||||
static inline Uint16 Get() { return GetRandomUint16(); }
|
||||
static inline Uint16 Get(Uint16 n) { return GetRandomUint16(n); }
|
||||
static inline Uint16 Get(Uint16 m, Uint16 n) { return GetRandomUint16(m, n); }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> struct RandomVal< Int32 >
|
||||
{
|
||||
static inline Int32 Get() { return GetRandomInt32(); }
|
||||
static inline Int32 Get(Int32 n) { return GetRandomInt32(n); }
|
||||
static inline Int32 Get(Int32 m, Int32 n) { return GetRandomInt32(m, n); }
|
||||
};
|
||||
|
||||
template <> struct RandomVal< Uint32 >
|
||||
{
|
||||
static inline Uint32 Get() { return GetRandomUint32(); }
|
||||
static inline Uint32 Get(Uint32 n) { return GetRandomUint32(n); }
|
||||
static inline Uint32 Get(Uint32 m, Uint32 n) { return GetRandomUint32(m, n); }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> struct RandomVal< Int64 >
|
||||
{
|
||||
static inline Int64 Get() { return GetRandomInt64(); }
|
||||
static inline Int64 Get(Int64 n) { return GetRandomInt64(n); }
|
||||
static inline Int64 Get(Int64 m, Int64 n) { return GetRandomInt64(m, n); }
|
||||
};
|
||||
|
||||
template <> struct RandomVal< Uint64 >
|
||||
{
|
||||
static inline Uint64 Get() { return GetRandomUint64(); }
|
||||
static inline Uint64 Get(Uint64 n) { return GetRandomUint64(n); }
|
||||
static inline Uint64 Get(Uint64 m, Uint64 n) { return GetRandomUint64(m, n); }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> struct RandomVal< Float32 >
|
||||
{
|
||||
static inline Float32 Get() { return GetRandomFloat32(); }
|
||||
static inline Float32 Get(Float32 n) { return GetRandomFloat32(n); }
|
||||
static inline Float32 Get(Float32 m, Float32 n) { return GetRandomFloat32(m, n); }
|
||||
};
|
||||
|
||||
template <> struct RandomVal< Float64 >
|
||||
{
|
||||
static inline Float64 Get() { return GetRandomFloat64(); }
|
||||
static inline Float64 Get(Float64 n) { return GetRandomFloat64(n); }
|
||||
static inline Float64 Get(Float64 m, Float64 n) { return GetRandomFloat64(m, n); }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> struct RandomVal< bool >
|
||||
{
|
||||
static inline bool Get() { return GetRandomBool(); }
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_NUMERIC_RANDOM_HPP_
|
973
module/Library/String.cpp
Normal file
973
module/Library/String.cpp
Normal file
@@ -0,0 +1,973 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/String.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <algorithm>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqLeftStr(SQChar f, Uint32 w, StackStrF & s)
|
||||
{
|
||||
// Is the specified width valid?
|
||||
if (!w)
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w + 1); // + null terminator
|
||||
// Is the specified string valid?
|
||||
if (!s.mLen)
|
||||
{
|
||||
std::memset(b.Data(), f, w); // Insert only the fill character
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert only the fill character first
|
||||
std::memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
std::strncpy(b.Data(), s.mPtr, s.mLen);
|
||||
}
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), w);
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqLeftOffsetStr(SQChar f, Uint32 w, Uint32 o, StackStrF & s)
|
||||
{
|
||||
// Is the specified width valid?
|
||||
if (!w)
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Is the specified offset within width range?
|
||||
else if (o > w)
|
||||
{
|
||||
STHROWF("Offset is out of bounds");
|
||||
}
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w + 1); // + null terminator
|
||||
// Is the specified string valid?
|
||||
if (!s.mLen)
|
||||
{
|
||||
std::memset(b.Data(), f, w); // Insert only the fill character
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the string length
|
||||
const Uint32 n = ConvTo< Uint32 >::From(s.mLen);
|
||||
// Insert the fill character first
|
||||
std::memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
if (n > (w - o))
|
||||
{
|
||||
std::strncpy(b.Data() + o, s.mPtr, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(b.Data() + o, s.mPtr, n * sizeof(SQChar));
|
||||
}
|
||||
}
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), w);
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqRightStr(SQChar f, Uint32 w, StackStrF & s)
|
||||
{
|
||||
// Is the specified width valid?
|
||||
if (!w)
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w + 1); // + null terminator
|
||||
// Is the specified string valid?
|
||||
if (!s.mLen)
|
||||
{
|
||||
std::memset(b.Data(), f, w); // Insert only the fill character
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the string length
|
||||
const Uint32 n = ConvTo< Uint32 >::From(s.mLen);
|
||||
// Insert the fill character first
|
||||
std::memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
if (n >= w)
|
||||
{
|
||||
std::strncpy(b.Data(), s.mPtr, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::strncpy(b.Data() + (w - n), s.mPtr, n);
|
||||
}
|
||||
}
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), w);
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqRightOffsetStr(SQChar f, Uint32 w, Uint32 o, StackStrF & s)
|
||||
{
|
||||
// Is the specified width valid?
|
||||
if (!w)
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Is the specified offset within width range?
|
||||
else if (o > w)
|
||||
{
|
||||
STHROWF("Offset is out of bounds");
|
||||
}
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w + 1); // + null terminator
|
||||
// Is the specified string valid?
|
||||
if (!s.mLen)
|
||||
{
|
||||
std::memset(b.Data(), f, w); // Insert only the fill character
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the string length
|
||||
const Uint32 n = ConvTo< Uint32 >::From(s.mLen);
|
||||
// Insert the fill character first
|
||||
std::memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
if (n >= w || (n + o) >= w)
|
||||
{
|
||||
std::strncpy(b.Data(), s.mPtr, w - o);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::strncpy(b.Data() + ((w - n) - o), s.mPtr, n);
|
||||
}
|
||||
}
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), w);
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqCenterStr(SQChar f, Uint32 w, StackStrF & s)
|
||||
{
|
||||
// Is the specified width valid?
|
||||
if (!w)
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Allocate a buffer with the requested width
|
||||
Buffer b(w + 1); // + null terminator
|
||||
// Is the specified string valid?
|
||||
if (!s.mLen)
|
||||
{
|
||||
std::memset(b.Data(), f, w); // Insert only the fill character
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the insert position
|
||||
const Int32 p = ((w/2) - (s.mLen/2));
|
||||
// Insert only the fill character first
|
||||
std::memset(b.Data(), f, w);
|
||||
// Overwrite with the specified string
|
||||
std::strncpy(b.Data() + (p < 0 ? 0 : p), s.mPtr, s.mLen);
|
||||
}
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), w);
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Buffer StrJustAlphaNumImpl(CSStr str, Uint32 len)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!len)
|
||||
{
|
||||
return Buffer(); // Default to an empty buffer!
|
||||
}
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(len + 1); // + null terminator
|
||||
// Resulted string size
|
||||
Uint32 n = 0;
|
||||
// Currently processed character
|
||||
SQChar c = 0;
|
||||
// Process characters
|
||||
while ((c = *(str++)) != '\0')
|
||||
{
|
||||
// Is this an alpha-numeric character?
|
||||
if (std::isalnum(c) != 0)
|
||||
{
|
||||
// Save it and move to the next one
|
||||
b.At(n++) = c;
|
||||
}
|
||||
}
|
||||
// End the resulted string
|
||||
b.At(n) = '\0';
|
||||
// Move the cursor to the end
|
||||
b.Move(n);
|
||||
// Return ownership of the buffer
|
||||
return std::move(b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer StrJustAlphaNumB(CSStr str)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!str || *str == '\0')
|
||||
{
|
||||
return Buffer(); // Default to an empty string!
|
||||
}
|
||||
// Attempt to convert and return the result
|
||||
return StrJustAlphaNumImpl(str, std::strlen(str));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr StrJustAlphaNum(CSStr str)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!str || *str == '\0')
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Attempt to convert and return the result
|
||||
return StrJustAlphaNumImpl(str, std::strlen(str)).Get< SQChar >();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqJustAlphaNum(StackStrF & s)
|
||||
{
|
||||
const Buffer b(StrJustAlphaNumImpl(s.mPtr, s.mLen));
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), b.Position());
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Buffer StrToLowercaseImpl(CSStr str, Uint32 len)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!len)
|
||||
{
|
||||
return Buffer(); // Default to an empty buffer!
|
||||
}
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(len + 1); // + null terminator
|
||||
// Resulted string size
|
||||
Uint32 n = 0;
|
||||
// Process characters
|
||||
while (*str != '\0')
|
||||
{
|
||||
// Convert it and move to the next one
|
||||
b.At(n++) = std::tolower(*(str++));
|
||||
}
|
||||
// End the resulted string
|
||||
b.At(n) = '\0';
|
||||
// Move the cursor to the end
|
||||
b.Move(n);
|
||||
// Return ownership of the buffer
|
||||
return std::move(b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer StrToLowercaseB(CSStr str)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!str || *str == '\0')
|
||||
{
|
||||
return Buffer(); // Default to an empty string!
|
||||
}
|
||||
// Attempt to convert and return the result
|
||||
return StrToLowercaseImpl(str, std::strlen(str));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr StrToLowercase(CSStr str)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!str || *str == '\0')
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Attempt to convert and return the result
|
||||
return StrToLowercaseImpl(str, std::strlen(str)).Get< SQChar >();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqToLowercase(StackStrF & s)
|
||||
{
|
||||
const Buffer b(StrToLowercaseImpl(s.mPtr, s.mLen));
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), b.Position());
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Buffer StrToUppercaseImpl(CSStr str, Uint32 len)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!len)
|
||||
{
|
||||
return Buffer(); // Default to an empty buffer!
|
||||
}
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(len + 1); // + null terminator
|
||||
// Resulted string size
|
||||
Uint32 n = 0;
|
||||
// Process characters
|
||||
while (*str != '\0')
|
||||
{
|
||||
// Convert it and move to the next one
|
||||
b.At(n++) = std::toupper(*(str++));
|
||||
}
|
||||
// End the resulted string
|
||||
b.At(n) = '\0';
|
||||
// Move the cursor to the end
|
||||
b.Move(n);
|
||||
// Return ownership of the buffer
|
||||
return std::move(b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer StrToUppercaseB(CSStr str)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!str || *str == '\0')
|
||||
{
|
||||
return Buffer(); // Default to an empty string!
|
||||
}
|
||||
// Attempt to convert and return the result
|
||||
return StrToUppercaseImpl(str, std::strlen(str));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr StrToUppercase(CSStr str)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if(!str || *str == '\0')
|
||||
{
|
||||
return _SC(""); // Default to an empty string!
|
||||
}
|
||||
// Attempt to convert and return the result
|
||||
return StrToUppercaseImpl(str, std::strlen(str)).Get< SQChar >();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static LightObj SqToUppercase(StackStrF & s)
|
||||
{
|
||||
const Buffer b(StrToUppercaseImpl(s.mPtr, s.mLen));
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// Push the string onto the stack
|
||||
sq_pushstring(s.mVM, b.Data(), b.Position());
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Checks if all the characters in the specified string are of the specified class or not.
|
||||
*/
|
||||
template < int (*Fn)(int) > static bool SqAllChars(StackStrF & s)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if (!s.mLen)
|
||||
{
|
||||
// Since there are no other different character then
|
||||
// we count this as all characters being of this type
|
||||
return true;
|
||||
}
|
||||
// Start iterating characters and find the first that doesn't match
|
||||
for (CSStr itr = s.mPtr; *itr != '\0'; ++itr)
|
||||
{
|
||||
// Call the predicate with the current character
|
||||
if (Fn(*itr) == 0)
|
||||
{
|
||||
return false; // This character did not pass the test
|
||||
}
|
||||
}
|
||||
// All characters passed the test
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Find the position of the first character that matches the specified class.
|
||||
*/
|
||||
template < int (*Fn)(int), bool Neg > static LightObj SqFirstChar(StackStrF & s)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if (s.mLen)
|
||||
{
|
||||
// Start iterating characters and find the first that doesn't match
|
||||
for (CSStr itr = s.mPtr; *itr != '\0'; ++itr)
|
||||
{
|
||||
// Call the predicate with the current character
|
||||
if ((Fn(*itr) == 0) == Neg)
|
||||
{
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// This character passed our test, push it's position
|
||||
sq_pushinteger(s.mVM, itr - s.mPtr);
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Since there are no other different character then
|
||||
// we count this as all characters being of this type
|
||||
return LightObj();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Find the position of the last character that matches the specified class.
|
||||
*/
|
||||
template < int (*Fn)(int), bool Neg > static LightObj SqLastChar(StackStrF & s)
|
||||
{
|
||||
// See if we actually have something to search for
|
||||
if (s.mLen)
|
||||
{
|
||||
// Start iterating characters and find the first that doesn't match
|
||||
for (CSStr itr = (s.mPtr + s.mLen) - 1; itr >= s.mPtr; --itr)
|
||||
{
|
||||
// Call the predicate with the current character
|
||||
if ((Fn(*itr) == 0) == Neg)
|
||||
{
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(s.mVM);
|
||||
// This character passed our test, push it's position
|
||||
sq_pushinteger(s.mVM, itr - s.mPtr);
|
||||
// Obtain the object from the stack and return it
|
||||
return std::move(Var< LightObj >(s.mVM, -1).value);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Since there are no other different character then
|
||||
// we count this as all characters being of this type
|
||||
return LightObj();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Split the string into chunks wherever a character matches or not the specified class.
|
||||
*/
|
||||
static SQInteger SplitWhereCharImpl(HSQUIRRELVM vm, int(*fn)(int), bool neg)
|
||||
{
|
||||
static const SQInteger top = sq_gettop(vm);
|
||||
// Is there a value to process?
|
||||
if (top <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing string or value");
|
||||
}
|
||||
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
|
||||
// Create a new array on the stack
|
||||
sq_newarray(vm, 0);
|
||||
|
||||
// See if we actually have something to search for
|
||||
if (!(val.mPtr) || *(val.mPtr) == '\0')
|
||||
{
|
||||
return 1; // Return an empty array
|
||||
}
|
||||
|
||||
// Remember the position of the last found match
|
||||
CSStr last = val.mPtr;
|
||||
|
||||
// Start iterating characters and slice where a match is found
|
||||
for (CSStr itr = val.mPtr; *itr != '\0'; ++itr)
|
||||
{
|
||||
// Call the predicate with the current character
|
||||
if ((fn(*itr) == 0) == neg)
|
||||
{
|
||||
// Are there any characters before this match?
|
||||
if ((itr - last) > 0 && (*last != '\0'))
|
||||
{
|
||||
// Push this chunk of string on the stack
|
||||
sq_pushstring(vm, last, itr - last);
|
||||
// Insert this element into the array on the stack
|
||||
const SQRESULT r = sq_arrayappend(vm, -2);
|
||||
// Did we fail to append the element?
|
||||
if (SQ_FAILED(r))
|
||||
{
|
||||
return r; // We're done here
|
||||
}
|
||||
}
|
||||
// Push this character as an integer on the stack
|
||||
sq_pushinteger(vm, *itr);
|
||||
// Insert this element into the array on the stack
|
||||
const SQRESULT r = sq_arrayappend(vm, -2);
|
||||
// Did we fail to append the element?
|
||||
if (SQ_FAILED(r))
|
||||
{
|
||||
return r; // We're done here
|
||||
}
|
||||
// Update the position of the last found match
|
||||
last = (itr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Push the remaining chunk, if any
|
||||
if (*last != '\0')
|
||||
{
|
||||
// Push this chunk of string on the stack
|
||||
sq_pushstring(vm, last, -1);
|
||||
// Insert this element into the array on the stack
|
||||
const SQRESULT r = sq_arrayappend(vm, -2);
|
||||
// Did we fail to append the element?
|
||||
if (SQ_FAILED(r))
|
||||
{
|
||||
return r; // We're done here
|
||||
}
|
||||
}
|
||||
|
||||
// We have a value to return on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Simple forwarder to minimize templated functions with large body and reduce executable size.
|
||||
*/
|
||||
template < int (*Fn)(int), bool Neg > static SQInteger SplitWhereCharProxy(HSQUIRRELVM vm)
|
||||
{
|
||||
return SplitWhereCharImpl(vm, Fn, Neg);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Checks if the specified character is of the specified class.
|
||||
*/
|
||||
template < int (*Fn)(int) > static bool IsCharOfType(int c)
|
||||
{
|
||||
return (Fn(c) != 0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static bool OnlyDelimiter(CSStr str, SQChar chr)
|
||||
{
|
||||
while (*str != '\0')
|
||||
{
|
||||
// Is this different from the delimiter?
|
||||
if (*(str++) != chr)
|
||||
{
|
||||
// Another character was found
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// No other character was found
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger SqStrExplode(HSQUIRRELVM vm)
|
||||
{
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Was the delimiter character specified?
|
||||
if (top <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, _SC("Missing delimiter character"));
|
||||
}
|
||||
// Was the boolean empty specified?
|
||||
else if (top <= 2)
|
||||
{
|
||||
return sq_throwerror(vm, _SC("Missing boolean empty"));
|
||||
}
|
||||
// Was the string value specified?
|
||||
else if (top <= 3)
|
||||
{
|
||||
return sq_throwerror(vm, _SC("Missing string value"));
|
||||
}
|
||||
// Attempt to generate the string value
|
||||
StackStrF val(vm, 4);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// The delimiter character and boolean empty
|
||||
SQChar delim = 0;
|
||||
bool empty = 0;
|
||||
// Attempt to retrieve the remaining arguments from the stack
|
||||
try
|
||||
{
|
||||
delim = Var< SQChar >(vm, 2).value;
|
||||
empty = Var< bool >(vm, 3).value;
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
return sq_throwerror(vm, e.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return sq_throwerror(vm, _SC("Unable to retrieve arguments"));
|
||||
}
|
||||
// Grab the string value to a shorter name
|
||||
CSStr str = val.mPtr;
|
||||
// Create an empty array on the stack
|
||||
sq_newarray(vm, 0);
|
||||
// See if we actually have something to explode
|
||||
if(!str || *str == '\0')
|
||||
{
|
||||
// Specify that we have an argument on the stack
|
||||
return 1;
|
||||
}
|
||||
// Don't modify the specified string pointer
|
||||
CSStr itr = str, last = str;
|
||||
// The number of delimiter occurrences
|
||||
Uint32 num = 0;
|
||||
// Pre-count how many delimiters of this type exist
|
||||
while (*itr != '\0')
|
||||
{
|
||||
// Is this our delimiter?
|
||||
if (*(itr++) == delim)
|
||||
{
|
||||
// Are we allowed to include empty elements?
|
||||
if (empty || (itr - last) > 1)
|
||||
{
|
||||
// Increase the count
|
||||
++num;
|
||||
}
|
||||
// Update the last delimiter position
|
||||
last = itr;
|
||||
}
|
||||
}
|
||||
// Were there no delimiters found and can we include empty elements?
|
||||
if (num == 0 && !empty && (str[1] == '\0' || OnlyDelimiter(str, delim)))
|
||||
{
|
||||
// Specify that we have an argument on the stack
|
||||
return 1;
|
||||
}
|
||||
// Have we found any delimiters?
|
||||
else if (num == 0)
|
||||
{
|
||||
// Test against strings with only delimiters
|
||||
if (str[1] == '\0' || OnlyDelimiter(str, delim))
|
||||
{
|
||||
sq_pushstring(vm, _SC(""), 0); // Add an empty string
|
||||
}
|
||||
else
|
||||
{
|
||||
sq_pushstring(vm, val.mPtr, val.mLen); // Add the whole string
|
||||
}
|
||||
// Append the string on the stack to the array
|
||||
const SQRESULT r = sq_arrayappend(vm, -2);
|
||||
// Check the result
|
||||
if (SQ_FAILED(r))
|
||||
{
|
||||
return r; // Propagate the error
|
||||
}
|
||||
// Specify that we have an argument on the stack
|
||||
return 1;
|
||||
}
|
||||
// Is there anything after the last delimiter?
|
||||
if (itr != last && *last != delim)
|
||||
{
|
||||
++num; // Add it to the counter
|
||||
}
|
||||
SQRESULT r = SQ_OK;
|
||||
// Pre-allocate an array with the number of found delimiters
|
||||
r = sq_arrayresize(vm, -1, num);
|
||||
// Check the result
|
||||
if (SQ_FAILED(r))
|
||||
{
|
||||
return r; // Propagate the error
|
||||
}
|
||||
// Don't modify the specified string pointer
|
||||
itr = str, last = str;
|
||||
// Reset the counter and use it as the element index
|
||||
num = 0;
|
||||
// Process the string again, this time slicing the actual elements
|
||||
while (*itr != '\0')
|
||||
{
|
||||
// Is this our delimiter?
|
||||
if (*itr++ == delim)
|
||||
{
|
||||
// Are we allowed to include empty elements?
|
||||
if (empty || (itr - last) > 1)
|
||||
{
|
||||
// Push the element index on the stack and advance to the next one
|
||||
sq_pushinteger(vm, num++);
|
||||
// Push the string portion on the stack
|
||||
sq_pushstring(vm, last, itr - last - 1);
|
||||
// Assign the string onto the
|
||||
r = sq_set(vm, -3);
|
||||
// Check the result
|
||||
if (SQ_FAILED(r))
|
||||
{
|
||||
return r; // Propagate the error
|
||||
}
|
||||
}
|
||||
// Update the last delimiter position
|
||||
last = itr;
|
||||
}
|
||||
}
|
||||
// Is there anything after the last delimiter?
|
||||
if (itr != last && *last != delim)
|
||||
{
|
||||
// Push the element index on the stack
|
||||
sq_pushinteger(vm, num);
|
||||
// Add the remaining string as an element
|
||||
sq_pushstring(vm, last, itr - last);
|
||||
// Assign the string onto the
|
||||
r = sq_set(vm, -3);
|
||||
// Check the result
|
||||
if (SQ_FAILED(r))
|
||||
{
|
||||
return r; // Propagate the error
|
||||
}
|
||||
}
|
||||
// Specify that we have an argument on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static CSStr StrImplode(SQChar chr, Array & arr)
|
||||
{
|
||||
// Determine array size
|
||||
const Int32 length = static_cast< Int32 >(arr.Length());
|
||||
// Is there anything to implode?
|
||||
if (length <= 0)
|
||||
{
|
||||
return _SC(""); // Default to an empty string
|
||||
}
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(length * 32);
|
||||
// Process array elements
|
||||
for (SQInteger i = 0; i < length; ++i)
|
||||
{
|
||||
// Retrieve the element value as string
|
||||
SharedPtr< String > str = arr.GetValue< String >(i);
|
||||
// Was there any value retrieved?
|
||||
if (!!str)
|
||||
{
|
||||
// Append the value to the buffer
|
||||
b.AppendS(str->data(), str->size());
|
||||
}
|
||||
// Append the delimiter
|
||||
b.Push(chr);
|
||||
}
|
||||
// Move the cursor back one element
|
||||
b.Retreat(1);
|
||||
// Set that as the null character
|
||||
b.Cursor() = '\0';
|
||||
// Return the string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static CSStr FromArray(Array & arr)
|
||||
{
|
||||
// Determine array size
|
||||
const Int32 length = ConvTo< Int32 >::From(arr.Length());
|
||||
// Obtain a temporary buffer
|
||||
Buffer b(length * sizeof(Int32));
|
||||
// Get array elements as integers
|
||||
arr.GetArray< Int32 >(b.Get< Int32 >(), length);
|
||||
// Overwrite integers with characters
|
||||
for (Int32 n = 0; n < length; ++n)
|
||||
{
|
||||
b.At(n) = ConvTo< SQChar >::From(b.At< Int32 >(n * sizeof(Int32)));
|
||||
}
|
||||
// Terminate the resulted string
|
||||
b.At(length) = '\0';
|
||||
// Return the string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger StdPrintF(HSQUIRRELVM vm)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Send the resulted string to console as a user message
|
||||
LogUsr("%s", val.mPtr);
|
||||
// This function doesn't return anything
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static String StrCharacterSwap(SQInteger a, SQInteger b, StackStrF & val)
|
||||
{
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
STHROWLASTF("Invalid string");
|
||||
}
|
||||
// Is the string empty?
|
||||
else if (!val.mLen)
|
||||
{
|
||||
return String();
|
||||
}
|
||||
// Turn it into a string that we can edit
|
||||
String str(val.mPtr, val.mLen);
|
||||
// Replace all occurences of the specified character
|
||||
std::replace(str.begin(), str.end(),
|
||||
static_cast< String::value_type >(a), static_cast< String::value_type >(b));
|
||||
// Return the new string
|
||||
return str;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_String(HSQUIRRELVM vm)
|
||||
{
|
||||
Table strns(vm);
|
||||
|
||||
strns.Func(_SC("FromArray"), &FromArray)
|
||||
.SquirrelFunc(_SC("Explode"), &SqStrExplode)
|
||||
.Func(_SC("Implode"), &StrImplode)
|
||||
.FmtFunc(_SC("Center"), &SqCenterStr)
|
||||
.FmtFunc(_SC("Left"), &SqLeftStr)
|
||||
.FmtFunc(_SC("Right"), &SqRightStr)
|
||||
.FmtFunc(_SC("LeftEx"), &SqLeftOffsetStr)
|
||||
.FmtFunc(_SC("RightEx"), &SqRightOffsetStr)
|
||||
.FmtFunc(_SC("ToLower"), &SqToLowercase)
|
||||
.FmtFunc(_SC("ToUpper"), &SqToUppercase)
|
||||
.FmtFunc(_SC("CharSwap"), &StrCharacterSwap)
|
||||
.FmtFunc(_SC("Lowercase"), &SqToLowercase)
|
||||
.FmtFunc(_SC("Uppercase"), &SqToUppercase)
|
||||
.FmtFunc(_SC("JustAlnum"), &SqJustAlphaNum)
|
||||
.FmtFunc(_SC("AreAllSpace"), &SqAllChars< std::isspace >)
|
||||
.FmtFunc(_SC("AreAllPrint"), &SqAllChars< std::isprint >)
|
||||
.FmtFunc(_SC("AreAllCntrl"), &SqAllChars< std::iscntrl >)
|
||||
.FmtFunc(_SC("AreAllUpper"), &SqAllChars< std::isupper >)
|
||||
.FmtFunc(_SC("AreAllLower"), &SqAllChars< std::islower >)
|
||||
.FmtFunc(_SC("AreAllAlpha"), &SqAllChars< std::isalpha >)
|
||||
.FmtFunc(_SC("AreAllDigit"), &SqAllChars< std::isdigit >)
|
||||
.FmtFunc(_SC("AreAllPunct"), &SqAllChars< std::ispunct >)
|
||||
.FmtFunc(_SC("AreAllXdigit"), &SqAllChars< std::isxdigit >)
|
||||
.FmtFunc(_SC("AreAllAlnum"), &SqAllChars< std::isalnum >)
|
||||
.FmtFunc(_SC("AreAllGraph"), &SqAllChars< std::isgraph >)
|
||||
.FmtFunc(_SC("AreAllBlank"), &SqAllChars< std::isblank >)
|
||||
.FmtFunc(_SC("FirstSpace"), &SqFirstChar< std::isspace, false >)
|
||||
.FmtFunc(_SC("FirstPrint"), &SqFirstChar< std::isprint, false >)
|
||||
.FmtFunc(_SC("FirstCntrl"), &SqFirstChar< std::iscntrl, false >)
|
||||
.FmtFunc(_SC("FirstUpper"), &SqFirstChar< std::isupper, false >)
|
||||
.FmtFunc(_SC("FirstLower"), &SqFirstChar< std::islower, false >)
|
||||
.FmtFunc(_SC("FirstAlpha"), &SqFirstChar< std::isalpha, false >)
|
||||
.FmtFunc(_SC("FirstDigit"), &SqFirstChar< std::isdigit, false >)
|
||||
.FmtFunc(_SC("FirstPunct"), &SqFirstChar< std::ispunct, false >)
|
||||
.FmtFunc(_SC("FirstXdigit"), &SqFirstChar< std::isxdigit, false >)
|
||||
.FmtFunc(_SC("FirstAlnum"), &SqFirstChar< std::isalnum, false >)
|
||||
.FmtFunc(_SC("FirstGraph"), &SqFirstChar< std::isgraph, false >)
|
||||
.FmtFunc(_SC("FirstBlank"), &SqFirstChar< std::isblank, false >)
|
||||
.FmtFunc(_SC("FirstNotSpace"), &SqFirstChar< std::isspace, true >)
|
||||
.FmtFunc(_SC("FirstNotPrint"), &SqFirstChar< std::isprint, true >)
|
||||
.FmtFunc(_SC("FirstNotCntrl"), &SqFirstChar< std::iscntrl, true >)
|
||||
.FmtFunc(_SC("FirstNotUpper"), &SqFirstChar< std::isupper, true >)
|
||||
.FmtFunc(_SC("FirstNotLower"), &SqFirstChar< std::islower, true >)
|
||||
.FmtFunc(_SC("FirstNotAlpha"), &SqFirstChar< std::isalpha, true >)
|
||||
.FmtFunc(_SC("FirstNotDigit"), &SqFirstChar< std::isdigit, true >)
|
||||
.FmtFunc(_SC("FirstNotPunct"), &SqFirstChar< std::ispunct, true >)
|
||||
.FmtFunc(_SC("FirstNotXdigit"), &SqFirstChar< std::isxdigit, true >)
|
||||
.FmtFunc(_SC("FirstNotAlnum"), &SqFirstChar< std::isalnum, true >)
|
||||
.FmtFunc(_SC("FirstNotGraph"), &SqFirstChar< std::isgraph, true >)
|
||||
.FmtFunc(_SC("FirstNotBlank"), &SqFirstChar< std::isblank, true >)
|
||||
.FmtFunc(_SC("LastSpace"), &SqLastChar< std::isspace, false >)
|
||||
.FmtFunc(_SC("LastPrint"), &SqLastChar< std::isprint, false >)
|
||||
.FmtFunc(_SC("LastCntrl"), &SqLastChar< std::iscntrl, false >)
|
||||
.FmtFunc(_SC("LastUpper"), &SqLastChar< std::isupper, false >)
|
||||
.FmtFunc(_SC("LastLower"), &SqLastChar< std::islower, false >)
|
||||
.FmtFunc(_SC("LastAlpha"), &SqLastChar< std::isalpha, false >)
|
||||
.FmtFunc(_SC("LastDigit"), &SqLastChar< std::isdigit, false >)
|
||||
.FmtFunc(_SC("LastPunct"), &SqLastChar< std::ispunct, false >)
|
||||
.FmtFunc(_SC("LastXdigit"), &SqLastChar< std::isxdigit, false >)
|
||||
.FmtFunc(_SC("LastAlnum"), &SqLastChar< std::isalnum, false >)
|
||||
.FmtFunc(_SC("LastGraph"), &SqLastChar< std::isgraph, false >)
|
||||
.FmtFunc(_SC("LastBlank"), &SqLastChar< std::isblank, false >)
|
||||
.FmtFunc(_SC("LastNotSpace"), &SqLastChar< std::isspace, true >)
|
||||
.FmtFunc(_SC("LastNotPrint"), &SqLastChar< std::isprint, true >)
|
||||
.FmtFunc(_SC("LastNotCntrl"), &SqLastChar< std::iscntrl, true >)
|
||||
.FmtFunc(_SC("LastNotUpper"), &SqLastChar< std::isupper, true >)
|
||||
.FmtFunc(_SC("LastNotLower"), &SqLastChar< std::islower, true >)
|
||||
.FmtFunc(_SC("LastNotAlpha"), &SqLastChar< std::isalpha, true >)
|
||||
.FmtFunc(_SC("LastNotDigit"), &SqLastChar< std::isdigit, true >)
|
||||
.FmtFunc(_SC("LastNotPunct"), &SqLastChar< std::ispunct, true >)
|
||||
.FmtFunc(_SC("LastNotXdigit"), &SqLastChar< std::isxdigit, true >)
|
||||
.FmtFunc(_SC("LastNotAlnum"), &SqLastChar< std::isalnum, true >)
|
||||
.FmtFunc(_SC("LastNotGraph"), &SqLastChar< std::isgraph, true >)
|
||||
.FmtFunc(_SC("LastNotBlank"), &SqLastChar< std::isblank, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereSpace"), &SplitWhereCharProxy< std::isspace, false >)
|
||||
.SquirrelFunc(_SC("SplitWherePrint"), &SplitWhereCharProxy< std::isprint, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereCntrl"), &SplitWhereCharProxy< std::iscntrl, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereUpper"), &SplitWhereCharProxy< std::isupper, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereLower"), &SplitWhereCharProxy< std::islower, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereAlpha"), &SplitWhereCharProxy< std::isalpha, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereDigit"), &SplitWhereCharProxy< std::isdigit, false >)
|
||||
.SquirrelFunc(_SC("SplitWherePunct"), &SplitWhereCharProxy< std::ispunct, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereXdigit"), &SplitWhereCharProxy< std::isxdigit, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereAlnum"), &SplitWhereCharProxy< std::isalnum, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereGraph"), &SplitWhereCharProxy< std::isgraph, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereBlank"), &SplitWhereCharProxy< std::isblank, false >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotSpace"), &SplitWhereCharProxy< std::isspace, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotPrint"), &SplitWhereCharProxy< std::isprint, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotCntrl"), &SplitWhereCharProxy< std::iscntrl, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotUpper"), &SplitWhereCharProxy< std::isupper, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotLower"), &SplitWhereCharProxy< std::islower, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotAlpha"), &SplitWhereCharProxy< std::isalpha, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotDigit"), &SplitWhereCharProxy< std::isdigit, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotPunct"), &SplitWhereCharProxy< std::ispunct, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotXdigit"), &SplitWhereCharProxy< std::isxdigit, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotAlnum"), &SplitWhereCharProxy< std::isalnum, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotGraph"), &SplitWhereCharProxy< std::isgraph, true >)
|
||||
.SquirrelFunc(_SC("SplitWhereNotBlank"), &SplitWhereCharProxy< std::isblank, true >);
|
||||
|
||||
RootTable(vm).Bind(_SC("SqStr"), strns);
|
||||
RootTable(vm).SquirrelFunc(_SC("printf"), &StdPrintF);
|
||||
|
||||
RootTable(vm)
|
||||
.Func(_SC("IsSpace"), &IsCharOfType< std::isspace >)
|
||||
.Func(_SC("IsPrint"), &IsCharOfType< std::isprint >)
|
||||
.Func(_SC("IsCntrl"), &IsCharOfType< std::iscntrl >)
|
||||
.Func(_SC("IsUpper"), &IsCharOfType< std::isupper >)
|
||||
.Func(_SC("IsLower"), &IsCharOfType< std::islower >)
|
||||
.Func(_SC("IsAlpha"), &IsCharOfType< std::isalpha >)
|
||||
.Func(_SC("IsDigit"), &IsCharOfType< std::isdigit >)
|
||||
.Func(_SC("IsPunct"), &IsCharOfType< std::ispunct >)
|
||||
.Func(_SC("IsXdigit"), &IsCharOfType< std::isxdigit >)
|
||||
.Func(_SC("IsAlnum"), &IsCharOfType< std::isalnum >)
|
||||
.Func(_SC("IsGraph"), &IsCharOfType< std::isgraph >)
|
||||
.Func(_SC("IsBlank"), &IsCharOfType< std::isblank >)
|
||||
.Func(_SC("ToLower"), &tolower)
|
||||
.Func(_SC("ToUpper"), &toupper);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
30
module/Library/String.hpp
Normal file
30
module/Library/String.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _LIBRARY_STRING_HPP_
|
||||
#define _LIBRARY_STRING_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Get a new string with only the alpha numeric characters from the specified string.
|
||||
*/
|
||||
CSStr StrJustAlphaNum(CSStr str);
|
||||
Buffer StrJustAlphaNumB(CSStr str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Convert the specified string to lowercase.
|
||||
*/
|
||||
CSStr StrToLowercase(CSStr str);
|
||||
Buffer StrToLowercaseB(CSStr str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Convert the specified string to uppercase.
|
||||
*/
|
||||
CSStr StrToUppercase(CSStr str);
|
||||
Buffer StrToUppercaseB(CSStr str);
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_STRING_HPP_
|
109
module/Library/System.cpp
Normal file
109
module/Library/System.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/System.hpp"
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_SysDir(HSQUIRRELVM vm);
|
||||
extern void Register_SysEnv(HSQUIRRELVM vm);
|
||||
extern void Register_SysPath(HSQUIRRELVM vm);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQInteger SqSysExec(HSQUIRRELVM vm)
|
||||
{
|
||||
// Attempt to retrieve the value from the stack as a string
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Allocate a temp buffer to retrieve chunks from output
|
||||
char buffer[128];
|
||||
// Allocate a buffer which will contain the final output
|
||||
Buffer b(128);
|
||||
// Attempt to open the specified process
|
||||
FILE * pipe = popen(val.mPtr, "r");
|
||||
// The process return status
|
||||
Int32 status = -1;
|
||||
// Did we fail to open the process?
|
||||
if (!pipe)
|
||||
{
|
||||
return sq_throwerror(vm, ToStrF("Unable to open process [%s]", val.mPtr));
|
||||
}
|
||||
// Attempt to read process output
|
||||
try
|
||||
{
|
||||
while (!std::feof(pipe))
|
||||
{
|
||||
if (std::fgets(buffer, 128, pipe) != NULL)
|
||||
{
|
||||
b.AppendS(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Close the process
|
||||
status = pclose(pipe);
|
||||
// Now throw the error
|
||||
return sq_throwerror(vm, ToStrF("Unable read process output [%d]", status));
|
||||
}
|
||||
// Close the process and obtain the exit status
|
||||
status = pclose(pipe);
|
||||
// Remember the top of the stack
|
||||
const Int32 top = sq_gettop(vm);
|
||||
// Create a new table on the stack
|
||||
sq_newtable(vm);
|
||||
// Push the element name
|
||||
sq_pushstring(vm, _SC("Status"), -1);
|
||||
// Push the element value
|
||||
sq_pushinteger(vm, status);
|
||||
// Create the element in the table
|
||||
SQRESULT res = sq_rawset(vm, -3);
|
||||
// Check the result
|
||||
if (SQ_FAILED(res))
|
||||
{
|
||||
// Clean the stack
|
||||
sq_settop(vm, top);
|
||||
// Return the error
|
||||
return res;
|
||||
}
|
||||
// Push the element name
|
||||
sq_pushstring(vm, _SC("Output"), -1);
|
||||
// Push the element value
|
||||
sq_pushstring(vm, b.Get< SQChar >(), b.Position());
|
||||
// Create the element in the table
|
||||
res = sq_rawset(vm, -3);
|
||||
// Check the result
|
||||
if (SQ_FAILED(res))
|
||||
{
|
||||
// Clean the stack
|
||||
sq_settop(vm, top);
|
||||
// Return the error
|
||||
return res;
|
||||
}
|
||||
// Specify that we want to return the table we created
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_System(HSQUIRRELVM vm)
|
||||
{
|
||||
Register_SysDir(vm);
|
||||
Register_SysEnv(vm);
|
||||
Register_SysPath(vm);
|
||||
|
||||
RootTable(vm).SquirrelFunc(_SC("SysExec"), &SqSysExec);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
14
module/Library/System.hpp
Normal file
14
module/Library/System.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LIBRARY_SYSTEM_HPP_
|
||||
#define _LIBRARY_SYSTEM_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_SYSTEM_HPP_
|
126
module/Library/System/Dir.cpp
Normal file
126
module/Library/System/Dir.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/System/Dir.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(TypenameD, _SC("SqSysDir"))
|
||||
SQMODE_DECL_TYPENAME(TypenameF, _SC("SqSysFile"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LightObj SysDir::ReadFile() const
|
||||
{
|
||||
Validate("read current file");
|
||||
// Create a file instance
|
||||
std::unique_ptr< SysFile > mem = std::make_unique< SysFile >();
|
||||
// Turn it into a script object
|
||||
LightObj obj(mem.get());
|
||||
// Will hold the raw object pointer
|
||||
SysFile * ptr = nullptr;
|
||||
// Release it if it was taken over by the script engine
|
||||
if (obj.IsNull())
|
||||
{
|
||||
STHROWF("Failed to create a SqSysFile object.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = mem.release();
|
||||
}
|
||||
// The file handle where it will be opened
|
||||
tinydir_file * handle = ptr->GetOrMake();
|
||||
// Attempt to read the current file
|
||||
if (tinydir_readfile(mHandle.get(), handle) == -1)
|
||||
{
|
||||
STHROWF("Failed to read current file.");
|
||||
}
|
||||
// Return the resulted object
|
||||
return obj;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LightObj SysDir::ReadFileAt(SQInteger i) const
|
||||
{
|
||||
Validate("read scanned file");
|
||||
// Make sure the specified directory index is valid
|
||||
if (i < 0)
|
||||
{
|
||||
STHROWF("File index (" PRINT_INT_FMT " < 0) our of bounds.", i);
|
||||
}
|
||||
if (static_cast< size_t >(i) >= mHandle->n_files)
|
||||
{
|
||||
STHROWF("File index (" PRINT_INT_FMT " >= " PRINT_SZ_FMT ") our of bounds.", i, mHandle->n_files);
|
||||
}
|
||||
// Create a file instance
|
||||
std::unique_ptr< SysFile > mem = std::make_unique< SysFile >();
|
||||
// Turn it into a script object
|
||||
LightObj obj(mem.get());
|
||||
// Will hold the raw object pointer
|
||||
SysFile * ptr = nullptr;
|
||||
// Release it if it was taken over by the script engine
|
||||
if (obj.IsNull())
|
||||
{
|
||||
STHROWF("Failed to create a SqSysFile object.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = mem.release();
|
||||
}
|
||||
// The file handle where it will be opened
|
||||
tinydir_file * handle = ptr->GetOrMake();
|
||||
// Attempt to read the current file
|
||||
if (tinydir_readfile_n(mHandle.get(), handle, i) == -1)
|
||||
{
|
||||
STHROWF("Failed to read file at index (" PRINT_INT_FMT ")", i);
|
||||
}
|
||||
// Return the resulted object
|
||||
return obj;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_SysDir(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(TypenameD::Str,
|
||||
Class< SysDir, NoCopy< SysDir > >(vm, TypenameD::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< StackStrF & >()
|
||||
.Ctor< bool, StackStrF & >()
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &TypenameD::Fn)
|
||||
.Func(_SC("_tostring"), &SysDir::ToString)
|
||||
// Member Properties
|
||||
.Prop(_SC("IsValid"), &SysDir::IsValid)
|
||||
.Prop(_SC("Path"), &SysDir::GetPath)
|
||||
.Prop(_SC("HasNext"), &SysDir::HasNext)
|
||||
.Prop(_SC("FileCount"), &SysDir::FileCount)
|
||||
// Member Methods
|
||||
.FmtFunc(_SC("Open"), &SysDir::Open)
|
||||
.FmtFunc(_SC("OpenSorted"), &SysDir::OpenSorted)
|
||||
.Func(_SC("OpenSubDir"), &SysDir::OpenSubDir)
|
||||
.Func(_SC("Next"), &SysDir::Next)
|
||||
.Func(_SC("Close"), &SysDir::Close)
|
||||
.Func(_SC("ReadFile"), &SysDir::ReadFile)
|
||||
.Func(_SC("ReadFileAt"), &SysDir::ReadFileAt)
|
||||
);
|
||||
RootTable(vm).Bind(TypenameF::Str,
|
||||
Class< SysFile, NoCopy< SysFile > >(vm, TypenameF::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< StackStrF & >()
|
||||
// Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &TypenameF::Fn)
|
||||
.Func(_SC("_tostring"), &SysFile::ToString)
|
||||
// Member Properties
|
||||
.Prop(_SC("IsValid"), &SysFile::IsValid)
|
||||
.Prop(_SC("IsDir"), &SysFile::IsDir)
|
||||
.Prop(_SC("IsReg"), &SysFile::IsReg)
|
||||
.Prop(_SC("Path"), &SysFile::GetPath)
|
||||
.Prop(_SC("Name"), &SysFile::GetName)
|
||||
.Prop(_SC("Extension"), &SysFile::GetExtension)
|
||||
// Member Methods
|
||||
.FmtFunc(_SC("Open"), &SysFile::Open)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
587
module/Library/System/Dir.hpp
Normal file
587
module/Library/System/Dir.hpp
Normal file
@@ -0,0 +1,587 @@
|
||||
#ifndef _LIBRARY_SYSDIR_HPP_
|
||||
#define _LIBRARY_SYSDIR_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <memory>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <tinydir.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
typedef std::unique_ptr< tinydir_dir > TinyDir;
|
||||
typedef std::unique_ptr< tinydir_file > TinyFile;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* This class represents file-system directories in a platform-independent manner.
|
||||
*/
|
||||
class SysDir
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
TinyDir mHandle; /* Handle to the managed directory. */
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Make sure a valid handle is being managed before attempting to use it.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (!mHandle)
|
||||
{
|
||||
STHROWF("Invalid directory handle. Please open a directory first.");
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Make sure a valid handle is being managed before attempting to use it.
|
||||
*/
|
||||
void Validate(CSStr action) const
|
||||
{
|
||||
if (!mHandle)
|
||||
{
|
||||
STHROWF("Cannot %s. Invalid directory handle.", action);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Defaults to a null handle.
|
||||
*/
|
||||
SysDir()
|
||||
: mHandle()
|
||||
{
|
||||
/*...*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Opens the directory at the specified path.
|
||||
*/
|
||||
SysDir(StackStrF & path)
|
||||
: SysDir(false, path)
|
||||
{
|
||||
/*...*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct from an existing file handle.
|
||||
*/
|
||||
explicit SysDir(tinydir_dir * handle)
|
||||
: mHandle(handle)
|
||||
{
|
||||
/*...*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Opens the directory at the specified path.
|
||||
*/
|
||||
SysDir(bool sorted, StackStrF & path)
|
||||
: SysDir()
|
||||
{
|
||||
// Should we open this in sorted mode?
|
||||
if (sorted)
|
||||
{
|
||||
OpenSorted(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
Open(path);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor (disabled).
|
||||
*/
|
||||
SysDir(const SysDir &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
SysDir(SysDir && o)
|
||||
: mHandle(std::forward< TinyDir >(o.mHandle))
|
||||
{
|
||||
/*...*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~SysDir()
|
||||
{
|
||||
// Is there handle being managed?
|
||||
if (mHandle)
|
||||
{
|
||||
tinydir_close(mHandle.get()); // Close it!
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator (disabled).
|
||||
*/
|
||||
SysDir & operator = (const SysDir &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
SysDir & operator = (SysDir && o)
|
||||
{
|
||||
// Avoid self assignment
|
||||
if (this != &o)
|
||||
{
|
||||
// Is there handle being managed?
|
||||
if (mHandle)
|
||||
{
|
||||
tinydir_close(mHandle.get()); // Close it!
|
||||
}
|
||||
// Take ownership of the new handle
|
||||
mHandle = std::move(o.mHandle);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw managed handle.
|
||||
*/
|
||||
tinydir_dir * Get() const
|
||||
{
|
||||
return mHandle.get();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw managed handle and make one if it doesn't exist already.
|
||||
*/
|
||||
tinydir_dir * GetOrMake()
|
||||
{
|
||||
// Do we have a handle already?
|
||||
if (!mHandle)
|
||||
{
|
||||
mHandle = std::make_unique< tinydir_dir >(); // Make one
|
||||
}
|
||||
// Return it like we promised
|
||||
return mHandle.get();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Take ownership of the managed handle.
|
||||
*/
|
||||
tinydir_dir * Release()
|
||||
{
|
||||
return mHandle.release();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Release the managed handle.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
mHandle.reset();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return mHandle ? mHandle->path : _SC("");
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check for the presence of a handle.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return !!mHandle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Open a handle to the directory at the specified path.
|
||||
*/
|
||||
void Open(StackStrF & path)
|
||||
{
|
||||
// Get the string from the script
|
||||
if ((SQ_FAILED(path.Proc(true))))
|
||||
{
|
||||
STHROWF("Unable to extract the specified path.");
|
||||
}
|
||||
// Allocate handle memory, if necessary
|
||||
if (!mHandle)
|
||||
{
|
||||
mHandle = std::make_unique< tinydir_dir >();
|
||||
}
|
||||
// If there was a handle open, we close it
|
||||
// If we just allocated one, we initialize it (win, either way)
|
||||
tinydir_close(mHandle.get());
|
||||
// Attempt to open the specified directory
|
||||
if (tinydir_open(mHandle.get(), path.mPtr) == -1)
|
||||
{
|
||||
// Don't keep a bad handle
|
||||
mHandle.reset();
|
||||
// Now we can throw the exception
|
||||
STHROWLASTF("Failed to open directory: %s", path.mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Open a handle to the directory at the specified path.
|
||||
*/
|
||||
void OpenSorted(StackStrF & path)
|
||||
{
|
||||
// Get the string from the script
|
||||
if ((SQ_FAILED(path.Proc(true))))
|
||||
{
|
||||
STHROWF("Unable to extract the specified path.");
|
||||
}
|
||||
// Allocate handle memory, if necessary
|
||||
if (!mHandle)
|
||||
{
|
||||
mHandle = std::make_unique< tinydir_dir >();
|
||||
}
|
||||
// If there was a handle open, we close it
|
||||
// If we just allocated one, we initialize it (win, either way)
|
||||
tinydir_close(mHandle.get());
|
||||
// Attempt to open the specified directory
|
||||
if (tinydir_open_sorted(mHandle.get(), path.mPtr) == -1)
|
||||
{
|
||||
// Don't keep a bad handle
|
||||
mHandle.reset();
|
||||
// Now we can throw the exception
|
||||
STHROWLASTF("Failed to open directory: %s", path.mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Open a handle to the directory at the specified path.
|
||||
*/
|
||||
SysDir & OpenSubDir(SQInteger i)
|
||||
{
|
||||
Validate("open sub directory");
|
||||
// Discard current error number
|
||||
errno = 0;
|
||||
// Make sure the specified directory index is valid
|
||||
if (i < 0)
|
||||
{
|
||||
STHROWF("Directory index (" PRINT_INT_FMT " < 0) our of bounds.", i);
|
||||
}
|
||||
if (static_cast< size_t >(i) >= mHandle->n_files)
|
||||
{
|
||||
STHROWF("Directory index (" PRINT_INT_FMT " >= " PRINT_SZ_FMT ") our of bounds.", i, mHandle->n_files);
|
||||
}
|
||||
// Make sure there is a directory at the specified index
|
||||
else if (!mHandle->_files[i].is_dir)
|
||||
{
|
||||
STHROWF("The specified index (" PRINT_INT_FMT ") is not a directory.", i);
|
||||
}
|
||||
// Attempt to open the specified sub-directory
|
||||
if (tinydir_open_subdir_n(mHandle.get(), static_cast< size_t >(i)) == -1)
|
||||
{
|
||||
// Don't keep a bad handle
|
||||
mHandle.reset();
|
||||
// Now we can throw the exception
|
||||
STHROWLASTF("Failed to open sub directory (" PRINT_INT_FMT ").", i);
|
||||
}
|
||||
// Return self to allow chaining
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Advance to the next element in the opened directory.
|
||||
*/
|
||||
void Next()
|
||||
{
|
||||
Validate("advance to next element");
|
||||
// See if there is a next element
|
||||
if (!mHandle->has_next)
|
||||
{
|
||||
STHROWF("Nothing left to advance to.");
|
||||
}
|
||||
// Discard current error number
|
||||
errno = 0;
|
||||
// Perform the requested action
|
||||
if (tinydir_next(mHandle.get()) == -1)
|
||||
{
|
||||
// This particular error number means the directory was closed
|
||||
if (errno == EIO) mHandle.reset();
|
||||
// Now the exception can be thrown
|
||||
STHROWLASTF("Failed to advance to the next element");
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Close the currently associated directory handle.
|
||||
*/
|
||||
void Close()
|
||||
{
|
||||
Validate("close directory");
|
||||
// Perform the requested action
|
||||
tinydir_close(mHandle.get());
|
||||
// Release any associated memory
|
||||
mHandle.reset();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the opened path.
|
||||
*/
|
||||
CSStr GetPath() const
|
||||
{
|
||||
Validate("obtain path");
|
||||
// Return the requested information
|
||||
return mHandle->path;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if there's a next element in the opened directory.
|
||||
*/
|
||||
bool HasNext() const
|
||||
{
|
||||
Validate("check for next");
|
||||
// Return the requested information
|
||||
return static_cast< bool >(mHandle->has_next);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of files in the opened directory (only when opened in sorted mode).
|
||||
*/
|
||||
SQInteger FileCount() const
|
||||
{
|
||||
Validate("obtain file count");
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(mHandle->n_files);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Open current file from the specified directory.
|
||||
*/
|
||||
LightObj ReadFile() const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Open current file from the specified directory.
|
||||
*/
|
||||
LightObj ReadFileAt(SQInteger i) const;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* This class represents file-system files in a platform-independent manner.
|
||||
*/
|
||||
class SysFile
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
TinyFile mHandle; /* Handle to the managed file. */
|
||||
|
||||
public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Make sure a valid handle is being managed before attempting to use it.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (!mHandle)
|
||||
{
|
||||
STHROWF("Invalid file handle. Please open a file first.");
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Make sure a valid handle is being managed before attempting to use it.
|
||||
*/
|
||||
void Validate(CSStr action) const
|
||||
{
|
||||
if (!mHandle)
|
||||
{
|
||||
STHROWF("Cannot %s. Invalid file handle.", action);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Defaults to a null handle.
|
||||
*/
|
||||
SysFile()
|
||||
: mHandle()
|
||||
{
|
||||
/*...*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Opens the file at the specified path.
|
||||
*/
|
||||
SysFile(StackStrF & path)
|
||||
: SysFile()
|
||||
{
|
||||
Open(path);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor (disabled).
|
||||
*/
|
||||
SysFile(const SysFile &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
SysFile(SysFile && o)
|
||||
: mHandle(std::forward< TinyFile >(o.mHandle))
|
||||
{
|
||||
/*...*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator (disabled).
|
||||
*/
|
||||
SysFile & operator = (const SysFile &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
SysFile & operator = (SysFile && o)
|
||||
{
|
||||
// Avoid self assignment
|
||||
if (this != &o)
|
||||
{
|
||||
// Take ownership of the new handle
|
||||
mHandle = std::move(o.mHandle);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw managed handle.
|
||||
*/
|
||||
tinydir_file * Get() const
|
||||
{
|
||||
return mHandle.get();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw managed handle and make one if it doesn't exist already.
|
||||
*/
|
||||
tinydir_file * GetOrMake()
|
||||
{
|
||||
// Do we have a handle already?
|
||||
if (!mHandle)
|
||||
{
|
||||
mHandle = std::make_unique< tinydir_file >(); // Make one
|
||||
}
|
||||
// Return it like we promised
|
||||
return mHandle.get();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Take ownership of the managed handle.
|
||||
*/
|
||||
tinydir_file * Release()
|
||||
{
|
||||
return mHandle.release();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Release the managed handle.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
mHandle.reset();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return mHandle ? mHandle->path : _SC("");
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check for the presence of a handle.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return !!mHandle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Open a handle to the file at the specified path.
|
||||
*/
|
||||
void Open(StackStrF & path)
|
||||
{
|
||||
// Get the string from the script
|
||||
if ((SQ_FAILED(path.Proc(true))))
|
||||
{
|
||||
STHROWF("Unable to extract the specified path.");
|
||||
}
|
||||
// Allocate the handle memory
|
||||
mHandle = std::make_unique< tinydir_file >();
|
||||
// Discard current error number
|
||||
errno = 0;
|
||||
// Attempt to open the specified file
|
||||
if (tinydir_file_open(mHandle.get(), path.mPtr) == -1)
|
||||
{
|
||||
// Don't keep a bad handle
|
||||
mHandle.reset();
|
||||
// Now we can throw the exception
|
||||
if (errno != 0)
|
||||
{
|
||||
STHROWF("Failed to open file: %s [%s]", path.mPtr, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
STHROWLASTF("Failed to open file: %s", path.mPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check if the opened element is a directory.
|
||||
*/
|
||||
bool IsDir() const
|
||||
{
|
||||
Validate("check type");
|
||||
// Return the requested information
|
||||
return static_cast< bool >(mHandle->is_dir);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check if the opened element is a regular file.
|
||||
*/
|
||||
bool IsReg() const
|
||||
{
|
||||
Validate("check type");
|
||||
// Return the requested information
|
||||
return static_cast< bool >(mHandle->is_reg);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the path of the opened file.
|
||||
*/
|
||||
CSStr GetPath() const
|
||||
{
|
||||
Validate("retrieve path");
|
||||
// Return the requested information
|
||||
return mHandle->path;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the name of the opened file.
|
||||
*/
|
||||
CSStr GetName() const
|
||||
{
|
||||
Validate("retrieve name");
|
||||
// Return the requested information
|
||||
return mHandle->name;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the extension of the opened file.
|
||||
*/
|
||||
CSStr GetExtension() const
|
||||
{
|
||||
Validate("retrieve extension");
|
||||
// Return the requested information
|
||||
return mHandle->extension != nullptr ? mHandle->extension : _SC("");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_SYSDIR_HPP_
|
1208
module/Library/System/Environment.cpp
Normal file
1208
module/Library/System/Environment.cpp
Normal file
File diff suppressed because it is too large
Load Diff
316
module/Library/System/Environment.hpp
Normal file
316
module/Library/System/Environment.hpp
Normal file
@@ -0,0 +1,316 @@
|
||||
#ifndef _LIBRARY_SYSENV_HPP_
|
||||
#define _LIBRARY_SYSENV_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* This class provides access to environment variables and some general system information.
|
||||
*/
|
||||
struct SysEnv
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor. (disabled)
|
||||
*/
|
||||
SysEnv() = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
SysEnv(const SysEnv &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
SysEnv(SysEnv &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor. (disabled)
|
||||
*/
|
||||
~SysEnv() = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
SysEnv & operator = (const SysEnv &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
SysEnv & operator = (SysEnv &&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns true if an environment variable with the given name is defined.
|
||||
*/
|
||||
static bool Has(CCStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns true if an environment variable with the given name is defined.
|
||||
*/
|
||||
static bool Has(const String & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the value of the environment variable with the given name.
|
||||
* If the environment variable is undefined, returns fallback value instead.
|
||||
*/
|
||||
static void Get(Buffer & b, CCStr name, CCStr fallback);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the value of the environment variable with the given name.
|
||||
*/
|
||||
static Buffer Get(CCStr name)
|
||||
{
|
||||
return Get(name, nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the value of the environment variable with the given name.
|
||||
*/
|
||||
static Buffer Get(const String & name)
|
||||
{
|
||||
return Get(name.c_str(), nullptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the value of the environment variable with the given name.
|
||||
* If the environment variable is undefined, returns fallback value instead.
|
||||
*/
|
||||
static Buffer Get(CCStr name, CCStr fallback);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the value of the environment variable with the given name.
|
||||
* If the environment variable is undefined, returns fallback value instead.
|
||||
*/
|
||||
static Buffer Get(CCStr name, const String & fallback)
|
||||
{
|
||||
return Get(name, fallback.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the value of the environment variable with the given name.
|
||||
* If the environment variable is undefined, returns fallback value instead.
|
||||
*/
|
||||
static Buffer Get(const String & name, CCStr fallback)
|
||||
{
|
||||
return Get(name.c_str(), fallback);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the value of the environment variable with the given name.
|
||||
* If the environment variable is undefined, returns fallback value instead.
|
||||
*/
|
||||
static Buffer Get(const String & name, const String & fallback)
|
||||
{
|
||||
return Get(name.c_str(), fallback.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the environment variable with the given name to the given value.
|
||||
*/
|
||||
static bool Set(CCStr name, CCStr value);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the environment variable with the given name to the given value.
|
||||
*/
|
||||
static bool Set(const String & name, const String & value);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the operating system name.
|
||||
*/
|
||||
static String OSName();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the operating system name in a more "user-friendly" way. This only affects Windows.
|
||||
*/
|
||||
static String OSDisplayName();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the operating system version.
|
||||
*/
|
||||
static String OSVersion();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the operating system architecture.
|
||||
*/
|
||||
static String OSArchitecture();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the node (or host) name.
|
||||
*/
|
||||
static String NodeName();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the number of processors installed in the system. If the number of processors
|
||||
* cannot be determined, returns 1.
|
||||
*/
|
||||
static Uint32 ProcessorCount();
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Make sure that the path in the specified buffer contains a trailing slash.
|
||||
*/
|
||||
static void TerminatePath(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the string.
|
||||
*/
|
||||
static void ExpandVars(Buffer & b, CCStr pos, CCStr end);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the path. Uses the Unix variable style.
|
||||
*/
|
||||
static void ExpandPath(Buffer & b, CCStr pos, CCStr end);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the string.
|
||||
*/
|
||||
static void ExpandVars(Buffer & b, CCStr str);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the string.
|
||||
*/
|
||||
static void ExpandVars(Buffer & b, const String & str);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the string.
|
||||
*/
|
||||
static Buffer ExpandVars(CCStr str);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the string.
|
||||
*/
|
||||
static Buffer ExpandVars(const String & str);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the path. Uses the Unix variable style.
|
||||
*/
|
||||
static void ExpandPath(Buffer & b, CCStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the path. Uses the Unix variable style.
|
||||
*/
|
||||
static void ExpandPath(Buffer & b, const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the path. Uses the Unix variable style.
|
||||
*/
|
||||
static Buffer ExpandPath(CCStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the path. Uses the Unix variable style.
|
||||
*/
|
||||
static Buffer ExpandPath(const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the current working directory within the specified buffer.
|
||||
*/
|
||||
static void WorkingDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the current working directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer WorkingDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's home directory within the specified buffer.
|
||||
*/
|
||||
static void HomeDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's home directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer HomeDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's config directory within the specified buffer.
|
||||
*/
|
||||
static void ConfigHomeDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's config directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer ConfigHomeDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's data directory within the specified buffer.
|
||||
*/
|
||||
static void DataHomeDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's data directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer DataHomeDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's temporary directory within the specified buffer.
|
||||
*/
|
||||
static void TempHomeDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's temporary directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer TempHomeDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's cache directory within the specified buffer.
|
||||
*/
|
||||
static void CacheHomeDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the user's cache directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer CacheHomeDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the temporary directory within the specified buffer.
|
||||
*/
|
||||
static void TempDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the temporary directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer TempDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the systemwide config directory within the specified buffer.
|
||||
*/
|
||||
static void ConfigDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the systemwide config directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer ConfigDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the system directory within the specified buffer.
|
||||
*/
|
||||
static void SystemDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the system directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer SystemDir();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the null directory within the specified buffer.
|
||||
*/
|
||||
static void NullDir(Buffer & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Obtain the null directory within a buffer and return it.
|
||||
*/
|
||||
static Buffer NullDir();
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_SYSENV_HPP_
|
1840
module/Library/System/Path.cpp
Normal file
1840
module/Library/System/Path.cpp
Normal file
File diff suppressed because it is too large
Load Diff
763
module/Library/System/Path.hpp
Normal file
763
module/Library/System/Path.hpp
Normal file
@@ -0,0 +1,763 @@
|
||||
#ifndef _LIBRARY_SYSPATH_HPP_
|
||||
#define _LIBRARY_SYSPATH_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <vector>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the full path of file.
|
||||
*/
|
||||
Buffer GetRealFilePath(CSStr path);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* This class represents filesystem paths in a platform-independent manner.
|
||||
*/
|
||||
class SysPath
|
||||
{
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::vector< String > StrVec; // Directory list.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Styles of directories to expect when parsing or to export.
|
||||
*/
|
||||
enum struct Style
|
||||
{
|
||||
Unix = 0,
|
||||
Windows,
|
||||
Native,
|
||||
Guess,
|
||||
Dynamic
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates an empty relative path.
|
||||
*/
|
||||
SysPath();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates an empty absolute or relative path.
|
||||
*/
|
||||
SysPath(bool absolute);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in native format from a string.
|
||||
*/
|
||||
SysPath(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a string.
|
||||
*/
|
||||
SysPath(CSStr path, Int32 style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a string.
|
||||
*/
|
||||
SysPath(CSStr path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in native format from a string.
|
||||
*/
|
||||
SysPath(const Buffer & path, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a string.
|
||||
*/
|
||||
SysPath(const Buffer & path, Style style, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in native format from a string.
|
||||
*/
|
||||
SysPath(const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a string.
|
||||
*/
|
||||
SysPath(const String & path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a parent path and a file name. The parent path is expected to reference
|
||||
* a directory.
|
||||
*/
|
||||
SysPath(const SysPath & parent, CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a parent path and a file name. The parent path is expected to reference
|
||||
* a directory.
|
||||
*/
|
||||
SysPath(const SysPath & parent, const String & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a parent path and a relative path. The parent path is expected
|
||||
* to reference a directory. The relative path is appended to the parent path.
|
||||
*/
|
||||
SysPath(const SysPath & parent, const SysPath & relative);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
SysPath(const SysPath & o);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
SysPath(SysPath && o);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~SysPath();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
SysPath & operator = (const SysPath & o);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
SysPath & operator = (SysPath && o);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path in native format.
|
||||
*/
|
||||
SysPath & operator = (CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path in native format.
|
||||
*/
|
||||
SysPath & operator = (const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Equality comparison.
|
||||
*/
|
||||
bool operator == (const SysPath & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Inequality comparison.
|
||||
*/
|
||||
bool operator != (const SysPath & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean operator.
|
||||
*/
|
||||
operator bool () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the n'th directory in the directory list. If n == depth(), returns the file name.
|
||||
*/
|
||||
const String & operator [] (Uint32 n) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const SysPath & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
Object ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Swaps the path with another one.
|
||||
*/
|
||||
void Swap(SysPath & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Clears all components.
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path in native format.
|
||||
*/
|
||||
SysPath & Assign(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path.
|
||||
*/
|
||||
SysPath & Assign(CSStr path, Int32 style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path.
|
||||
*/
|
||||
SysPath & Assign(CSStr path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path in native format.
|
||||
*/
|
||||
SysPath & Assign(const Buffer & path, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path.
|
||||
*/
|
||||
SysPath & Assign(const Buffer & path, Style style, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path in native format.
|
||||
*/
|
||||
SysPath & Assign(const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path.
|
||||
*/
|
||||
SysPath & Assign(const String & path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a parent path and a file name. The parent path is expected to reference
|
||||
* a directory.
|
||||
*/
|
||||
SysPath & Assign(const SysPath & parent, CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a parent path and a file name. The parent path is expected to reference
|
||||
* a directory.
|
||||
*/
|
||||
SysPath & Assign(const SysPath & parent, const String & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a parent path and a relative path. The parent path is expected
|
||||
* to reference a directory. The relative path is appended to the parent path.
|
||||
*/
|
||||
SysPath & Assign(const SysPath & parent, const SysPath & relative);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy the components from another path.
|
||||
*/
|
||||
SysPath & Assign(const SysPath & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move the components of another path into this instance.
|
||||
*/
|
||||
SysPath & Assign(SysPath && path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The resulting path always refers to a directory and the filename part is empty.
|
||||
*/
|
||||
SysPath & AssignDir(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The resulting path always refers to a directory and the filename part is empty.
|
||||
*/
|
||||
SysPath & AssignDir(CSStr path, Int32 style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The resulting path always refers to a directory and the filename part is empty.
|
||||
*/
|
||||
SysPath & AssignDir(CSStr path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The resulting path always refers to a directory and the filename part is empty.
|
||||
*/
|
||||
SysPath & AssignDir(const Buffer & path, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The resulting path always refers to a directory and the filename part is empty.
|
||||
*/
|
||||
SysPath & AssignDir(const Buffer & path, Style style, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The resulting path always refers to a directory and the filename part is empty.
|
||||
*/
|
||||
SysPath & AssignDir(const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The resulting path always refers to a directory and the filename part is empty.
|
||||
*/
|
||||
SysPath & AssignDir(const String & path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns a string containing the path in native format.
|
||||
*/
|
||||
Buffer ToBuffer() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns a string containing the path in the given format.
|
||||
*/
|
||||
Buffer ToBuffer(Style style) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns a string containing the path in the given format.
|
||||
*/
|
||||
Object ToStr(Int32 style) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Assigns a string containing a path.
|
||||
*/
|
||||
void FromString(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the path is absolute.
|
||||
*/
|
||||
bool IsAbsolute() const
|
||||
{
|
||||
return m_Absolute;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the path is relative.
|
||||
*/
|
||||
bool IsRelative() const
|
||||
{
|
||||
return !m_Absolute;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the path references a directory.
|
||||
*/
|
||||
bool IsDirectory() const
|
||||
{
|
||||
return m_Name.empty();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the path references a file.
|
||||
*/
|
||||
bool IsFile() const
|
||||
{
|
||||
return !m_Name.empty();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the path Does not contain a drive, directories or file name.
|
||||
*/
|
||||
bool Empty() const
|
||||
{
|
||||
return (m_Dirs.empty() && m_Name.empty() && m_Drive == 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* If the path contains a file name, the file name is appended to the directory list and cleared.
|
||||
*/
|
||||
SysPath & MakeDirectory();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* If the path contains no file name, the last directory becomes the file name.
|
||||
*/
|
||||
SysPath & MakeFile();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes the path refer to its parent.
|
||||
*/
|
||||
SysPath & MakeParent();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes the path absolute if it is relative. The current working directory is taken
|
||||
* as base directory.
|
||||
*/
|
||||
SysPath & MakeAbsolute();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes the path absolute if it is relative. The given path is taken as base.
|
||||
*/
|
||||
SysPath & MakeAbsolute(const SysPath & base);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes the path absolute if it is relative. The given path is taken as base.
|
||||
*/
|
||||
SysPath & MakeAbsolute(SysPath && base);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Appends the given path.
|
||||
*/
|
||||
SysPath & Append(const SysPath & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Appends the given path.
|
||||
*/
|
||||
SysPath & Append(SysPath && path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse the given string and append the resulted path.
|
||||
*/
|
||||
SysPath & Append(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse the given string and append the resulted path.
|
||||
*/
|
||||
SysPath & Append(CSStr path, Int32 style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse the given string and append the resulted path.
|
||||
*/
|
||||
SysPath & Append(CSStr path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse the given string and append the resulted path.
|
||||
*/
|
||||
SysPath & Append(const Buffer & path, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse the given string and append the resulted path.
|
||||
*/
|
||||
SysPath & Append(const Buffer & path, Style style, Int32 size = -1);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse the given string and append the resulted path.
|
||||
*/
|
||||
SysPath & Append(const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse the given string and append the resulted path.
|
||||
*/
|
||||
SysPath & Append(const String & path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the drive letter.
|
||||
*/
|
||||
CharT GetDrive() const
|
||||
{
|
||||
return m_Drive;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modifies the drive letter.
|
||||
*/
|
||||
void SetDrive(CharT drive)
|
||||
{
|
||||
m_Drive = drive;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the number of directories in the directory list.
|
||||
*/
|
||||
Uint32 Depth() const
|
||||
{
|
||||
return m_Dirs.size();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the n'th directory in the directory list. If n == depth(), returns the file name.
|
||||
*/
|
||||
const String & Directory(Uint32 n) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Adds a directory to the directory list.
|
||||
*/
|
||||
SysPath & Push(CSStr dir);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Adds a directory to the directory list.
|
||||
*/
|
||||
SysPath & Push(const String & dir);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Adds a directory to the directory list.
|
||||
*/
|
||||
SysPath & Push(String && dir);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Removes the last directory from the directory list.
|
||||
*/
|
||||
SysPath & PopBack();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Removes the first directory from the directory list.
|
||||
*/
|
||||
SysPath & PopFront();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the specified file name.
|
||||
*/
|
||||
SysPath & SetFilename(CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the specified file name.
|
||||
*/
|
||||
SysPath & SetFilename(const String & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the specified file name.
|
||||
*/
|
||||
SysPath & SetFilename(String && name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieves the file name.
|
||||
*/
|
||||
const String & GetFilename() const
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the specified file name.
|
||||
*/
|
||||
void SqSetFilename(CSStr name)
|
||||
{
|
||||
SetFilename(name);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the basename part of the file name and does not change the extension.
|
||||
*/
|
||||
SysPath & SetBasename(CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the basename part of the file name and does not change the extension.
|
||||
*/
|
||||
SysPath & SetBasename(const String & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the basename part of the file name and does not change the extension.
|
||||
*/
|
||||
SysPath & SetBasename(String && name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the basename (the file name without extension) of the path.
|
||||
*/
|
||||
String GetBasename() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the basename part of the file name and does not change the extension.
|
||||
*/
|
||||
void SqSetBasename(CSStr name)
|
||||
{
|
||||
SetBasename(name);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the file name extension.
|
||||
*/
|
||||
SysPath & SetExtension(CSStr ext);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the file name extension.
|
||||
*/
|
||||
SysPath & SetExtension(const String & ext);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the file name extension.
|
||||
*/
|
||||
String GetExtension() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Sets the file name extension.
|
||||
*/
|
||||
void SqSetExtension(CSStr ext)
|
||||
{
|
||||
SetExtension(ext);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns a pointer to the internal name string where the extension starts.
|
||||
*/
|
||||
CSStr GetExtensionC() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns a path referring to the path's directory.
|
||||
*/
|
||||
SysPath Parent() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Resolves the given path against the current one. If the given path is absolute, it replaces
|
||||
* the current one. Otherwise, the relative path is appended to the current path.
|
||||
*/
|
||||
SysPath & Resolve(const SysPath & path);
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse a path using the unix standards.
|
||||
*/
|
||||
void ParseUnix(CSStr pos, CSStr end);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse a path using the windows standards.
|
||||
*/
|
||||
void ParseWindows(CSStr pos, CSStr end);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse a path and expect combined windows and unix styles.
|
||||
*/
|
||||
void ParseDynamic(CSStr pos, CSStr end);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Parse a path and try to detect it's type automatically.
|
||||
*/
|
||||
void ParseGuess(CSStr pos, CSStr end);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Build a path string using the Unix conventions.
|
||||
*/
|
||||
Buffer BuildUnix() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Build a path string using the Windows conventions.
|
||||
*/
|
||||
Buffer BuildWindows() const;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
StrVec m_Dirs; /* The list of directories that form the path. */
|
||||
String m_Name; /* The file name if one was specified. */
|
||||
CharT m_Drive; /* The drive letter if one was specified. */
|
||||
bool m_Absolute; /* Whether this path is an absolute path. */
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the platform's path name separator, which separates the components (names) in a path.
|
||||
*/
|
||||
static CharT Separator()
|
||||
{
|
||||
#ifdef GMOD_OS_WINDOWS
|
||||
return '\\';
|
||||
#else
|
||||
return '/';
|
||||
#endif // GMOD_OS_WINDOWS
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the platform's path separator, which separates single paths in a list of paths.
|
||||
*/
|
||||
static CharT PathSeparator()
|
||||
{
|
||||
#ifdef GMOD_OS_WINDOWS
|
||||
return ';';
|
||||
#else
|
||||
return ':';
|
||||
#endif // GMOD_OS_WINDOWS
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path referring to a directory.
|
||||
*/
|
||||
static SysPath ForDirectory(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path referring to a directory.
|
||||
*/
|
||||
static SysPath ForDirectory(CSStr path, Int32 style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path referring to a directory.
|
||||
*/
|
||||
static SysPath ForDirectory(CSStr path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path referring to a directory.
|
||||
*/
|
||||
static SysPath ForDirectory(const String & path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path referring to a directory.
|
||||
*/
|
||||
static SysPath ForDirectory(const String & path, Style style);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the path. On Unix, a tilde as first character
|
||||
* in the path is replaced with the path to user's home directory.
|
||||
*/
|
||||
static SysPath Expand(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Expands all environment variables contained in the path.
|
||||
*/
|
||||
static SysPath Expand(const String & path)
|
||||
{
|
||||
return Expand(path.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the user's home directory.
|
||||
*/
|
||||
static SysPath Home();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the user's config directory.
|
||||
*/
|
||||
static SysPath ConfigHome();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the user's data directory.
|
||||
*/
|
||||
static SysPath DataHome();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the user's temp directory.
|
||||
*/
|
||||
static SysPath TempHome();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the user's temp directory.
|
||||
*/
|
||||
static SysPath CacheHome();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the current working directory.
|
||||
*/
|
||||
static SysPath Working();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the temporary directory.
|
||||
*/
|
||||
static SysPath Temp();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the systemwide config directory.
|
||||
*/
|
||||
static SysPath Config();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the system directory.
|
||||
*/
|
||||
static SysPath System();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the name of the null device.
|
||||
*/
|
||||
static SysPath Null();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns the real path to the specified file or directory.
|
||||
*/
|
||||
static SysPath Real(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path from a parent path and a file name. The parent path is expected to reference
|
||||
* a directory.
|
||||
*/
|
||||
static SysPath With(const SysPath & parent, CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in unix format from a string.
|
||||
*/
|
||||
static SysPath MakeUnix(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in windows format from a string.
|
||||
*/
|
||||
static SysPath MakeWindows(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in native format from a string.
|
||||
*/
|
||||
static SysPath MakeNative(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in and guess the format from a string.
|
||||
*/
|
||||
static SysPath MakeGuess(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a path in dynamic format from a string.
|
||||
*/
|
||||
static SysPath MakeDynamic(CSStr path);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes sure all separators from a path are the same.
|
||||
*/
|
||||
static String NormalizePath(SQInteger s, StackStrF & val);
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_SYSPATH_HPP_
|
98
module/Library/Utils.cpp
Normal file
98
module/Library/Utils.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Utils.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
extern void Register_Buffer(HSQUIRRELVM vm);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Probably not the best implementation but should cover all sorts of weird cases.
|
||||
*/
|
||||
static SQInteger SqExtractIPv4(HSQUIRRELVM vm)
|
||||
{
|
||||
// Was the IP address specified?
|
||||
if (sq_gettop(vm) <= 1)
|
||||
{
|
||||
return sq_throwerror(vm, "Missing IP address string");
|
||||
}
|
||||
// Attempt to generate the string value
|
||||
StackStrF val(vm, 2);
|
||||
// Have we failed to retrieve the string?
|
||||
if (SQ_FAILED(val.Proc(true)))
|
||||
{
|
||||
return val.mRes; // Propagate the error!
|
||||
}
|
||||
// Cleansed IP address buffer
|
||||
SQChar address[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
// Counting variables used by loops
|
||||
Uint32 i = 0, j = 0, k = 0;
|
||||
// Replicate the necessary characters from the resulted string
|
||||
for (; (i < static_cast< Uint32 >(val.mLen)) && (j < 16) && (k < 4); ++i)
|
||||
{
|
||||
// Is this a digit?
|
||||
if (std::isdigit(val.mPtr[i]) != 0)
|
||||
{
|
||||
address[j++] = val.mPtr[i]; // Just replicate it
|
||||
}
|
||||
// Is this a delimiter?
|
||||
else if (val.mPtr[i] == '.')
|
||||
{
|
||||
// Add a dummy component if one was not specified
|
||||
if (j == 0 || address[j-1] == '.')
|
||||
{
|
||||
address[j++] = '0';
|
||||
}
|
||||
// Add the actual delimiter
|
||||
address[j++] = '.';
|
||||
// Increase the block counter
|
||||
++k;
|
||||
}
|
||||
}
|
||||
// Complete the address if it wasn't (also count the last block)
|
||||
while (++k < 4)
|
||||
{
|
||||
address[j++] = '0';
|
||||
address[j++] = '.';
|
||||
}
|
||||
// Components of the IP address
|
||||
Uint32 blocks[4] = {0, 0, 0, 0};
|
||||
// Attempt to extract the components of the IP address
|
||||
std::sscanf(address, "%u.%u.%u.%u", &blocks[0], &blocks[1], &blocks[2], &blocks[3]);
|
||||
// Create a new array on the stack to hold the extracted components
|
||||
sq_newarray(vm, 4);
|
||||
// Push the elements into the array
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
// Push the element index
|
||||
sq_pushinteger(vm, i);
|
||||
// Push the element value
|
||||
sq_pushinteger(vm, Clamp(blocks[i], 0U, 255U));
|
||||
// Assign the element
|
||||
const SQRESULT res = sq_set(vm, -3);
|
||||
// See if the assignment failed
|
||||
if (SQ_FAILED(res))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
// Specify that we have a result on the stack
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Utils(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqUtils"), Table(vm)
|
||||
.SquirrelFunc(_SC("ExtractIPv4"), &SqExtractIPv4)
|
||||
);
|
||||
|
||||
Register_Buffer(vm);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
14
module/Library/Utils.hpp
Normal file
14
module/Library/Utils.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _LIBRARY_UTILS_HPP_
|
||||
#define _LIBRARY_UTILS_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_UTILS_HPP_
|
477
module/Library/Utils/Buffer.cpp
Normal file
477
module/Library/Utils/Buffer.cpp
Normal file
@@ -0,0 +1,477 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Library/Utils/Buffer.hpp"
|
||||
#include "Library/Numeric/LongInt.hpp"
|
||||
#include "Base/AABB.hpp"
|
||||
#include "Base/Circle.hpp"
|
||||
#include "Base/Color3.hpp"
|
||||
#include "Base/Color4.hpp"
|
||||
#include "Base/Quaternion.hpp"
|
||||
#include "Base/Sphere.hpp"
|
||||
#include "Base/Vector2.hpp"
|
||||
#include "Base/Vector2i.hpp"
|
||||
#include "Base/Vector3.hpp"
|
||||
#include "Base/Vector4.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstring>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMODE_DECL_TYPENAME(Typename, _SC("SqBuffer"))
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteInt64(const SLongInt & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Int64 >(val.GetNum());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteUint64(const ULongInt & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Uint64 >(val.GetNum());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteString(CSStr val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Is the given string value even valid?
|
||||
if (!val)
|
||||
{
|
||||
STHROWF("Invalid string argument: null");
|
||||
}
|
||||
// Calculate the string length
|
||||
Uint16 length = ConvTo< Uint16 >::From(std::strlen(val));
|
||||
// Change the size endianness to big endian
|
||||
Uint16 size = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8);
|
||||
// Write the size and then the string contents
|
||||
m_Buffer->Push< Uint16 >(size);
|
||||
m_Buffer->AppendS(val, length);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteRawString(CSStr val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Is the given string value even valid?
|
||||
if (!val)
|
||||
{
|
||||
STHROWF("Invalid string argument: null");
|
||||
}
|
||||
// Calculate the string length
|
||||
Uint16 length = ConvTo< Uint16 >::From(std::strlen(val));
|
||||
// Write the the string contents
|
||||
m_Buffer->AppendS(val, length);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteAABB(const AABB & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< AABB >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteCircle(const Circle & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Circle >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteColor3(const Color3 & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Color3 >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteColor4(const Color4 & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Color4 >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteQuaternion(const Quaternion & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Quaternion >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteSphere(const Sphere &val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Sphere >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteVector2(const Vector2 & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Vector2 >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteVector2i(const Vector2i & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Vector2i >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteVector3(const Vector3 & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Vector3 >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqBuffer::WriteVector4(const Vector4 & val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Vector4 >(val);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SLongInt SqBuffer::ReadInt64()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Int64 value = m_Buffer->Cursor< Int64 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Int64 >(1);
|
||||
// Return the requested information
|
||||
return SLongInt(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ULongInt SqBuffer::ReadUint64()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Uint64 value = m_Buffer->Cursor< Uint64 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Uint64 >(1);
|
||||
// Return the requested information
|
||||
return ULongInt(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object SqBuffer::ReadString()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
Uint16 length = m_Buffer->Cursor< Uint16 >();
|
||||
// Convert the length to little endian
|
||||
length = ((length >> 8) & 0xFF) | ((length & 0xFF) << 8);
|
||||
// Validate the obtained length
|
||||
if ((m_Buffer->Position() + sizeof(Uint16) + length) > m_Buffer->Capacity())
|
||||
{
|
||||
STHROWF("String of size (%u) starting at (%u) is out of buffer capacity (%u)",
|
||||
length, m_Buffer->Position() + sizeof(Uint16), m_Buffer->Capacity());
|
||||
}
|
||||
// Advance the buffer to the actual string
|
||||
m_Buffer->Advance< Uint16 >(1);
|
||||
// Remember the current stack size
|
||||
const StackGuard sg;
|
||||
// Attempt to create the string as an object
|
||||
sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), length);
|
||||
// Advance the cursor after the string
|
||||
m_Buffer->Advance(length);
|
||||
// Return the resulted object
|
||||
return Var< Object >(DefaultVM::Get(), -1).value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object SqBuffer::ReadRawString(SQInteger length)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Start with a length of zero
|
||||
Uint32 len = 0;
|
||||
// Should we Identify the string length ourselves?
|
||||
if (length < 0)
|
||||
{
|
||||
// Grab the buffer range to search for
|
||||
CCStr ptr = &m_Buffer->Cursor(), itr = ptr, end = m_Buffer->End();
|
||||
// Attempt to look for a string terminator
|
||||
while (itr != end && *itr != '\0')
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
// If nothing was found, consider the remaining buffer part of the requested string
|
||||
len = static_cast< Uint32 >(ptr - itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = ConvTo< Uint32 >::From(length);
|
||||
}
|
||||
// Validate the obtained length
|
||||
if ((m_Buffer->Position() + len) > m_Buffer->Capacity())
|
||||
{
|
||||
STHROWF("String of size (%u) starting at (%u) is out of buffer capacity (%u)",
|
||||
len, m_Buffer->Position(), m_Buffer->Capacity());
|
||||
}
|
||||
// Remember the current stack size
|
||||
const StackGuard sg;
|
||||
// Attempt to create the string as an object
|
||||
sq_pushstring(DefaultVM::Get(), &m_Buffer->Cursor(), len);
|
||||
// Advance the cursor after the string
|
||||
m_Buffer->Advance(len);
|
||||
// Return the resulted object
|
||||
return Var< Object >(DefaultVM::Get(), -1).value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AABB SqBuffer::ReadAABB()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const AABB & value = m_Buffer->Cursor< AABB >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< AABB >(1);
|
||||
// Return the requested information
|
||||
return AABB(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Circle SqBuffer::ReadCircle()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Circle & value = m_Buffer->Cursor< Circle >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Circle >(1);
|
||||
// Return the requested information
|
||||
return Circle(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3 SqBuffer::ReadColor3()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Color3 & value = m_Buffer->Cursor< Color3 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Color3 >(1);
|
||||
// Return the requested information
|
||||
return Color3(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color4 SqBuffer::ReadColor4()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Color4 & value = m_Buffer->Cursor< Color4 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Color4 >(1);
|
||||
// Return the requested information
|
||||
return Color4(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Quaternion SqBuffer::ReadQuaternion()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Quaternion & value = m_Buffer->Cursor< Quaternion >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Quaternion >(1);
|
||||
// Return the requested information
|
||||
return Quaternion(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Sphere SqBuffer::ReadSphere()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Sphere & value = m_Buffer->Cursor< Sphere >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Sphere >(1);
|
||||
// Return the requested information
|
||||
return Sphere(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2 SqBuffer::ReadVector2()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Vector2 & value = m_Buffer->Cursor< Vector2 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Vector2 >(1);
|
||||
// Return the requested information
|
||||
return Vector2(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2i SqBuffer::ReadVector2i()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Vector2i & value = m_Buffer->Cursor< Vector2i >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Vector2i >(1);
|
||||
// Return the requested information
|
||||
return Vector2i(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector3 SqBuffer::ReadVector3()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Vector3 & value = m_Buffer->Cursor< Vector3 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Vector3 >(1);
|
||||
// Return the requested information
|
||||
return Vector3(value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector4 SqBuffer::ReadVector4()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Vector4 & value = m_Buffer->Cursor< Vector4 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Vector4 >(1);
|
||||
// Return the requested information
|
||||
return Vector4(value);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_Buffer(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(Typename::Str,
|
||||
Class< SqBuffer >(vm, Typename::Str)
|
||||
// Constructors
|
||||
.Ctor()
|
||||
.Ctor< SQInteger >()
|
||||
// Core Meta-methods
|
||||
.SquirrelFunc(_SC("_typename"), &Typename::Fn)
|
||||
// Properties
|
||||
.Prop(_SC("Front"), &SqBuffer::GetFront, &SqBuffer::SetFront)
|
||||
.Prop(_SC("Next"), &SqBuffer::GetNext, &SqBuffer::SetNext)
|
||||
.Prop(_SC("Back"), &SqBuffer::GetBack, &SqBuffer::SetBack)
|
||||
.Prop(_SC("Prev"), &SqBuffer::GetPrev, &SqBuffer::SetPrev)
|
||||
.Prop(_SC("Cursor"), &SqBuffer::GetCursor, &SqBuffer::SetCursor)
|
||||
.Prop(_SC("Before"), &SqBuffer::GetBefore, &SqBuffer::SetBefore)
|
||||
.Prop(_SC("After"), &SqBuffer::GetAfter, &SqBuffer::SetAfter)
|
||||
.Prop(_SC("Max"), &SqBuffer::GetMax)
|
||||
.Prop(_SC("Size"), &SqBuffer::GetSize, &SqBuffer::Adjust)
|
||||
.Prop(_SC("Capacity"), &SqBuffer::GetCapacity, &SqBuffer::Adjust)
|
||||
.Prop(_SC("Position"), &SqBuffer::GetPosition, &SqBuffer::Move)
|
||||
.Prop(_SC("Remaining"), &SqBuffer::GetRemaining)
|
||||
// Member Methods
|
||||
.Func(_SC("Get"), &SqBuffer::Get)
|
||||
.Func(_SC("Set"), &SqBuffer::Set)
|
||||
.Func(_SC("Move"), &SqBuffer::Move)
|
||||
.Func(_SC("Advance"), &SqBuffer::Advance)
|
||||
.Func(_SC("Retreat"), &SqBuffer::Retreat)
|
||||
.Func(_SC("Push"), &SqBuffer::Push)
|
||||
.Func(_SC("Grow"), &SqBuffer::Grow)
|
||||
.Func(_SC("Adjust"), &SqBuffer::Adjust)
|
||||
.Func(_SC("WriteByte"), &SqBuffer::WriteUint8)
|
||||
.Func(_SC("WriteShort"), &SqBuffer::WriteInt16)
|
||||
.Func(_SC("WriteInt"), &SqBuffer::WriteInt32)
|
||||
.Func(_SC("WriteFloat"), &SqBuffer::WriteFloat32)
|
||||
.Func(_SC("WriteInt8"), &SqBuffer::WriteInt8)
|
||||
.Func(_SC("WriteUint8"), &SqBuffer::WriteUint8)
|
||||
.Func(_SC("WriteInt16"), &SqBuffer::WriteInt16)
|
||||
.Func(_SC("WriteUint16"), &SqBuffer::WriteUint16)
|
||||
.Func(_SC("WriteInt32"), &SqBuffer::WriteInt32)
|
||||
.Func(_SC("WriteUint32"), &SqBuffer::WriteUint32)
|
||||
.Func(_SC("WriteInt64"), &SqBuffer::WriteInt64)
|
||||
.Func(_SC("WriteUint64"), &SqBuffer::WriteUint64)
|
||||
.Func(_SC("WriteFloat32"), &SqBuffer::WriteFloat32)
|
||||
.Func(_SC("WriteFloat64"), &SqBuffer::WriteFloat64)
|
||||
.Func(_SC("WriteString"), &SqBuffer::WriteString)
|
||||
.Func(_SC("WriteRawString"), &SqBuffer::WriteRawString)
|
||||
.Func(_SC("WriteAABB"), &SqBuffer::WriteAABB)
|
||||
.Func(_SC("WriteCircle"), &SqBuffer::WriteCircle)
|
||||
.Func(_SC("WriteColor3"), &SqBuffer::WriteColor3)
|
||||
.Func(_SC("WriteColor4"), &SqBuffer::WriteColor4)
|
||||
.Func(_SC("WriteQuaternion"), &SqBuffer::WriteQuaternion)
|
||||
.Func(_SC("WriteSphere"), &SqBuffer::WriteSphere)
|
||||
.Func(_SC("WriteVector2"), &SqBuffer::WriteVector2)
|
||||
.Func(_SC("WriteVector2i"), &SqBuffer::WriteVector2i)
|
||||
.Func(_SC("WriteVector3"), &SqBuffer::WriteVector3)
|
||||
.Func(_SC("WriteVector4"), &SqBuffer::WriteVector4)
|
||||
.Func(_SC("ReadByte"), &SqBuffer::ReadUint8)
|
||||
.Func(_SC("ReadShort"), &SqBuffer::ReadInt16)
|
||||
.Func(_SC("ReadInt"), &SqBuffer::ReadInt32)
|
||||
.Func(_SC("ReadFloat"), &SqBuffer::ReadFloat32)
|
||||
.Func(_SC("ReadInt8"), &SqBuffer::ReadInt8)
|
||||
.Func(_SC("ReadUint8"), &SqBuffer::ReadUint8)
|
||||
.Func(_SC("ReadInt16"), &SqBuffer::ReadInt16)
|
||||
.Func(_SC("ReadUint16"), &SqBuffer::ReadUint16)
|
||||
.Func(_SC("ReadInt32"), &SqBuffer::ReadInt32)
|
||||
.Func(_SC("ReadUint32"), &SqBuffer::ReadUint32)
|
||||
.Func(_SC("ReadInt64"), &SqBuffer::ReadInt64)
|
||||
.Func(_SC("ReadUint64"), &SqBuffer::ReadUint64)
|
||||
.Func(_SC("ReadFloat32"), &SqBuffer::ReadFloat32)
|
||||
.Func(_SC("ReadFloat64"), &SqBuffer::ReadFloat64)
|
||||
.Func(_SC("ReadString"), &SqBuffer::ReadString)
|
||||
.Func(_SC("ReadRawString"), &SqBuffer::ReadRawString)
|
||||
.Func(_SC("ReadAABB"), &SqBuffer::ReadAABB)
|
||||
.Func(_SC("ReadCircle"), &SqBuffer::ReadCircle)
|
||||
.Func(_SC("ReadColor3"), &SqBuffer::ReadColor3)
|
||||
.Func(_SC("ReadColor4"), &SqBuffer::ReadColor4)
|
||||
.Func(_SC("ReadQuaternion"), &SqBuffer::ReadQuaternion)
|
||||
.Func(_SC("ReadSphere"), &SqBuffer::ReadSphere)
|
||||
.Func(_SC("ReadVector2"), &SqBuffer::ReadVector2)
|
||||
.Func(_SC("ReadVector2i"), &SqBuffer::ReadVector2i)
|
||||
.Func(_SC("ReadVector3"), &SqBuffer::ReadVector3)
|
||||
.Func(_SC("ReadVector4"), &SqBuffer::ReadVector4)
|
||||
);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
837
module/Library/Utils/Buffer.hpp
Normal file
837
module/Library/Utils/Buffer.hpp
Normal file
@@ -0,0 +1,837 @@
|
||||
#ifndef _LIBRARY_UTILS_BUFFER_HPP_
|
||||
#define _LIBRARY_UTILS_BUFFER_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Shared.hpp"
|
||||
#include "Base/Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Squirrel wrapper for the shared buffer class.
|
||||
*/
|
||||
class SqBuffer
|
||||
{
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef SharedPtr< Buffer > SRef; // Strong reference type to the managed memory buffer.
|
||||
typedef WeakPtr< Buffer > WRef; // Weak reference type to the managed memory buffer.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SRef m_Buffer; // The managed memory buffer.
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::Value Value; // The type of value used to represent a byte.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value & Reference; // A reference to the stored value type.
|
||||
typedef const Value & ConstRef; // A const reference to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value * Pointer; // A pointer to the stored value type.
|
||||
typedef const Value * ConstPtr; // A const pointer to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::SzType SzType; // The type used to represent size in general.
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Create a memory buffer with the requested size.
|
||||
*/
|
||||
static Object Create(SzType n);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
SqBuffer()
|
||||
: m_Buffer(new Buffer())
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Allocate constructor.
|
||||
*/
|
||||
SqBuffer(SQInteger n)
|
||||
: m_Buffer(new Buffer(ConvTo< SzType >::From(n)))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Allocate constructor.
|
||||
*/
|
||||
SqBuffer(SQInteger n, SQInteger c)
|
||||
: m_Buffer(new Buffer(ConvTo< SzType >::From(n), ConvTo< SzType >::From(c)))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
SqBuffer(ConstPtr p, SQInteger n)
|
||||
: m_Buffer(new Buffer(p, ConvTo< SzType >::From(n)))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
SqBuffer(ConstPtr p, SQInteger n, SQInteger c)
|
||||
: m_Buffer(new Buffer(p, ConvTo< SzType >::From(n), ConvTo< SzType >::From(c)))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reference constructor.
|
||||
*/
|
||||
SqBuffer(const SRef & ref)
|
||||
: m_Buffer(ref)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Buffer constructor.
|
||||
*/
|
||||
SqBuffer(const Buffer & b)
|
||||
: m_Buffer(new Buffer(b))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Buffer constructor.
|
||||
*/
|
||||
SqBuffer(Buffer && b)
|
||||
: m_Buffer(new Buffer(std::move(b)))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
SqBuffer(const SqBuffer & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
SqBuffer(SqBuffer && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~SqBuffer() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
SqBuffer & operator = (const SqBuffer & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
SqBuffer & operator = (SqBuffer && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a reference to the managed memory buffer.
|
||||
*/
|
||||
const SRef & GetRef() const
|
||||
{
|
||||
return m_Buffer;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the managed memory buffer reference.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
// Do we even point to a valid buffer?
|
||||
if (!m_Buffer)
|
||||
{
|
||||
STHROWF("Invalid memory buffer reference");
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the managed memory buffer reference and the buffer itself.
|
||||
*/
|
||||
void ValidateDeeper() const
|
||||
{
|
||||
// Do we even point to a valid buffer?
|
||||
if (!m_Buffer)
|
||||
{
|
||||
STHROWF("Invalid memory buffer reference");
|
||||
}
|
||||
// Validate the buffer itself
|
||||
else if (!(*m_Buffer))
|
||||
{
|
||||
STHROWF("Invalid memory buffer");
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve a certain element type at the specified position.
|
||||
*/
|
||||
Value Get(SQInteger n) const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->At(ConvTo< SzType >::From(n));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify a certain element type at the specified position.
|
||||
*/
|
||||
void Set(SQInteger n, SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->At(ConvTo< SzType >::From(n)) = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the front of the buffer.
|
||||
*/
|
||||
Value GetFront() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->Front();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the front of the buffer.
|
||||
*/
|
||||
void SetFront(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->Front() = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element after the first element in the buffer.
|
||||
*/
|
||||
Value GetNext() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->Next();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element after the first element in the buffer.
|
||||
*/
|
||||
void SetNext(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->Next() = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the back of the buffer.
|
||||
*/
|
||||
Value GetBack() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->Back();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the back of the buffer.
|
||||
*/
|
||||
void SetBack(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->Back() = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element before the last element in the buffer.
|
||||
*/
|
||||
Value GetPrev() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->Prev();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element before the last element in the buffer.
|
||||
*/
|
||||
void SetPrev(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->Prev() = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to the specified number of elements ahead.
|
||||
*/
|
||||
void Advance(SQInteger n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Advance(ConvTo< SzType >::From(n));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to the specified number of elements behind.
|
||||
*/
|
||||
void Retreat(SQInteger n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Retreat(ConvTo< SzType >::From(n));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Reposition the edit cursor to a fixed position within the buffer.
|
||||
*/
|
||||
void Move(SQInteger n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Move(ConvTo< SzType >::From(n));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Append a value to the current cursor location and advance the cursor.
|
||||
*/
|
||||
void Push(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push(ConvTo< Value >::From(v));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element at the cursor position.
|
||||
*/
|
||||
Value GetCursor() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->Cursor();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element at the cursor position.
|
||||
*/
|
||||
void SetCursor(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->Cursor() = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element before the cursor position.
|
||||
*/
|
||||
Value GetBefore() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->Before();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element before the cursor position.
|
||||
*/
|
||||
void SetBefore(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->Before() = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the element after the cursor position.
|
||||
*/
|
||||
Value GetAfter() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
return m_Buffer->After();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the element after the cursor position.
|
||||
*/
|
||||
void SetAfter(SQInteger v)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested element
|
||||
m_Buffer->After() = ConvTo< Value >::From(v);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve maximum elements it can hold for a certain type.
|
||||
*/
|
||||
SzType GetMax() const
|
||||
{
|
||||
return Buffer::Max();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current buffer capacity in element count.
|
||||
*/
|
||||
SzType GetSize() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->CapacityAs< Value >();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current buffer capacity in byte count.
|
||||
*/
|
||||
SzType GetCapacity() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->Capacity();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current position of the cursor in the buffer.
|
||||
*/
|
||||
SzType GetPosition() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->Position();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the amount of unused buffer after the edit cursor.
|
||||
*/
|
||||
SzType GetRemaining() const
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Buffer->Remaining();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grow the size of the internal buffer by the specified amount of bytes.
|
||||
*/
|
||||
void Grow(SQInteger n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return m_Buffer->Grow(ConvTo< SzType >::From(n) * sizeof(Value));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes sure there is enough capacity to hold the specified element count.
|
||||
*/
|
||||
void Adjust(SQInteger n)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Attempt to perform the requested operation
|
||||
try
|
||||
{
|
||||
Buffer bkp(m_Buffer->Adjust(ConvTo< SzType >::From(n) * sizeof(Value)));
|
||||
// Copy the data into the new buffer
|
||||
m_Buffer->Write(0, bkp.Data(), bkp.Capacity());
|
||||
m_Buffer->Move(bkp.Position());
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
STHROWF("%s", e.what()); // Re-package
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a signed 8 bit integer to the buffer.
|
||||
*/
|
||||
void WriteInt8(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Int8 >(ConvTo< Int8 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write an unsigned 8 bit integer to the buffer.
|
||||
*/
|
||||
void WriteUint8(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Uint8 >(ConvTo< Uint8 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a signed 16 bit integer to the buffer.
|
||||
*/
|
||||
void WriteInt16(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Int16 >(ConvTo< Int16 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write an unsigned 16 bit integer to the buffer.
|
||||
*/
|
||||
void WriteUint16(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Uint16 >(ConvTo< Uint16 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a signed 32 bit integer to the buffer.
|
||||
*/
|
||||
void WriteInt32(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Int32 >(ConvTo< Int32 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write an unsigned 32 bit integer to the buffer.
|
||||
*/
|
||||
void WriteUint32(SQInteger val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Uint32 >(ConvTo< Uint32 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a signed 64 bit integer to the buffer.
|
||||
*/
|
||||
void WriteInt64(const SLongInt & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write an unsigned 64 bit integer to the buffer.
|
||||
*/
|
||||
void WriteUint64(const ULongInt & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a 32 bit float to the buffer.
|
||||
*/
|
||||
void WriteFloat32(SQFloat val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Float32 >(ConvTo< Float32 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a 64 bit float to the buffer.
|
||||
*/
|
||||
void WriteFloat64(SQFloat val)
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
m_Buffer->Push< Float64 >(ConvTo< Float64 >::From(val));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a string to the buffer.
|
||||
*/
|
||||
void WriteString(CSStr val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a raw string to the buffer.
|
||||
*/
|
||||
void WriteRawString(CSStr val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a AABB to the buffer.
|
||||
*/
|
||||
void WriteAABB(const AABB & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Circle to the buffer.
|
||||
*/
|
||||
void WriteCircle(const Circle & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Color3 to the buffer.
|
||||
*/
|
||||
void WriteColor3(const Color3 & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Color4 to the buffer.
|
||||
*/
|
||||
void WriteColor4(const Color4 & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Quaternion to the buffer.
|
||||
*/
|
||||
void WriteQuaternion(const Quaternion & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Sphere to the buffer.
|
||||
*/
|
||||
void WriteSphere(const Sphere &val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Vector2 to the buffer.
|
||||
*/
|
||||
void WriteVector2(const Vector2 & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Vector2i to the buffer.
|
||||
*/
|
||||
void WriteVector2i(const Vector2i & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Vector3 to the buffer.
|
||||
*/
|
||||
void WriteVector3(const Vector3 & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a Vector4 to the buffer.
|
||||
*/
|
||||
void WriteVector4(const Vector4 & val);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Write a signed 8 bit integer from the buffer.
|
||||
*/
|
||||
SQInteger ReadInt8()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Int8 value = m_Buffer->Cursor< Int8 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Int8 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQInteger >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read an unsigned 8 bit integer from the buffer.
|
||||
*/
|
||||
SQInteger ReadUint8()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Uint8 value = m_Buffer->Cursor< Uint8 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Uint8 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQInteger >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a signed 16 bit integer from the buffer.
|
||||
*/
|
||||
SQInteger ReadInt16()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Int16 value = m_Buffer->Cursor< Int16 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Int16 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQInteger >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read an unsigned 16 bit integer from the buffer.
|
||||
*/
|
||||
SQInteger ReadUint16()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Uint16 value = m_Buffer->Cursor< Uint16 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Uint16 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQInteger >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a signed 32 bit integer from the buffer.
|
||||
*/
|
||||
SQInteger ReadInt32()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Int32 value = m_Buffer->Cursor< Int32 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Int32 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQInteger >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read an unsigned 32 bit integer from the buffer.
|
||||
*/
|
||||
SQInteger ReadUint32()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Uint32 value = m_Buffer->Cursor< Uint32 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Uint32 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQInteger >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a signed 64 bit integer from the buffer.
|
||||
*/
|
||||
SLongInt ReadInt64();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read an unsigned 64 bit integer from the buffer.
|
||||
*/
|
||||
ULongInt ReadUint64();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a 32 bit float from the buffer.
|
||||
*/
|
||||
SQFloat ReadFloat32()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Float32 value = m_Buffer->Cursor< Float32 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Float32 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQFloat >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a 64 bit float from the buffer.
|
||||
*/
|
||||
SQFloat ReadFloat64()
|
||||
{
|
||||
// Validate the managed buffer reference
|
||||
ValidateDeeper();
|
||||
// Read one element from the buffer
|
||||
const Float64 value = m_Buffer->Cursor< Float64 >();
|
||||
// Advance the buffer cursor
|
||||
m_Buffer->Advance< Float64 >(1);
|
||||
// Return the requested information
|
||||
return ConvTo< SQFloat >::From(value);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a string from the buffer.
|
||||
*/
|
||||
Object ReadString();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a raw string from the buffer.
|
||||
*/
|
||||
Object ReadRawString(SQInteger length);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a AABB from the buffer.
|
||||
*/
|
||||
AABB ReadAABB();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Circle from the buffer.
|
||||
*/
|
||||
Circle ReadCircle();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Color3 from the buffer.
|
||||
*/
|
||||
Color3 ReadColor3();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Color4 from the buffer.
|
||||
*/
|
||||
Color4 ReadColor4();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Quaternion from the buffer.
|
||||
*/
|
||||
Quaternion ReadQuaternion();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Sphere from the buffer.
|
||||
*/
|
||||
Sphere ReadSphere();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Vector2 from the buffer.
|
||||
*/
|
||||
Vector2 ReadVector2();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Vector2i from the buffer.
|
||||
*/
|
||||
Vector2i ReadVector2i();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Vector3 from the buffer.
|
||||
*/
|
||||
Vector3 ReadVector3();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Read a Vector4 from the buffer.
|
||||
*/
|
||||
Vector4 ReadVector4();
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _LIBRARY_UTILS_BUFFER_HPP_
|
Reference in New Issue
Block a user