1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00
SqMod/module/Library/IO/Stream.cpp
2021-03-09 00:40:16 +02:00

348 lines
15 KiB
C++

// ------------------------------------------------------------------------------------------------
#include "Library/IO/Stream.hpp"
// ------------------------------------------------------------------------------------------------
#include <sqratConst.h>
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
SQMOD_DECL_TYPENAME(StringStreamTn, _SC("SqStringStream"))
SQMOD_DECL_TYPENAME(FileStreamTn, _SC("SqFileStream"))
SQMOD_DECL_TYPENAME(OStringStreamTn, _SC("SqOStringStream"))
SQMOD_DECL_TYPENAME(OFileStreamTn, _SC("SqOFileStream"))
SQMOD_DECL_TYPENAME(IStringStreamTn, _SC("SqIStringStream"))
SQMOD_DECL_TYPENAME(IFileStreamTn, _SC("SqIFileStream"))
// ------------------------------------------------------------------------------------------------
SQMOD_DECL_TYPENAME(CInStreamTn, _SC("SqCInStream"))
SQMOD_DECL_TYPENAME(COutStreamTn, _SC("SqCOutStream"))
SQMOD_DECL_TYPENAME(CErrStreamTn, _SC("SqCErrStream"))
SQMOD_DECL_TYPENAME(CLogStreamTn, _SC("SqCLogStream"))
// ------------------------------------------------------------------------------------------------
static LightObj FileToString(StackStrF & name)
{
// Open file
std::ifstream t(name.mPtr);
String str;
// Pre-allocate buffer
t.seekg(0, std::ios::end);
str.reserve(t.tellg());
t.seekg(0, std::ios::beg);
// Read contents
str.assign((std::istreambuf_iterator< SQChar >(t)), std::istreambuf_iterator< SQChar >());
// Transform to object
return LightObj(str.data(), static_cast< SQInteger >(str.size()));
}
// ------------------------------------------------------------------------------------------------
static void StringToFile(StackStrF & name, StackStrF & str)
{
// Open file
std::ofstream out(name.mPtr);
// Write contents
out.write(str.mPtr, static_cast< std::streamsize >(str.mLen));
// Close file
out.close();
}
// ------------------------------------------------------------------------------------------------
using StringStream = SqStream< std::stringstream >;
using FileStream = SqStream< std::fstream >;
using OStringStream = SqStream< std::ostringstream >;
using OFileStream = SqStream< std::ofstream >;
using IStringStream = SqStream< std::istringstream >;
using IFileStream = SqStream< std::ifstream >;
// ------------------------------------------------------------------------------------------------
using CInStream = SqStream< SqGlobalStream< CInTag > >;
using COutStream = SqStream< SqGlobalStream< COutTag > >;
using CErrStream = SqStream< SqGlobalStream< CErrTag > >;
using CLogStream = SqStream< SqGlobalStream< CLogTag > >;
/* ================================================================================================
* Utility used to reduce code duplication when registering streams.
*/
template < class T > struct RegisterStream
{
/* --------------------------------------------------------------------------------------------
* Class object to be registered.
*/
Class< T, NoCopy< T > > mCls;
/* --------------------------------------------------------------------------------------------
* Base constructor.
*/
RegisterStream(HSQUIRRELVM vm, const SQChar * tn)
: mCls(vm, tn)
{
}
/* --------------------------------------------------------------------------------------------
* Base members.
*/
template < class Tn > RegisterStream & Base()
{
mCls
// Core Meta-methods
.SquirrelFunc(_SC("_typename"), &Tn::Fn)
// Properties
.Prop(_SC("Flags"), &T::GetFlags, &T::SetFlags)
.Prop(_SC("Width"), &T::GetWidth, &T::SetWidth)
.Prop(_SC("Precision"), &T::GetPrecision, &T::SetPrecision)
.Prop(_SC("Good"), &T::Good)
.Prop(_SC("EOF"), &T::EOF_)
.Prop(_SC("Fail"), &T::Fail)
.Prop(_SC("Bad"), &T::Bad)
.Prop(_SC("Fill"), &T::GetFill, &T::SetFill)
.Prop(_SC("State"), &T::GetState, &T::SetState)
.Prop(_SC("Exceptions"), &T::GetExceptions, &T::SetExceptions)
// Member Methods
.Func(_SC("UnSetF"), &T::UnSetF)
.Func(_SC("SetWidth"), &T::SetWidth)
.Func(_SC("SetPrecision"), &T::SetPrecision)
.Func(_SC("SetFill"), &T::SetFill)
.Func(_SC("AdjustBuffer"), &T::AdjustBuffer)
.Func(_SC("ReclaimBuffer"), &T::ReclaimBuffer)
// Member Overloads
.Overload(_SC("SetF"), &T::SetF)
.Overload(_SC("SetF"), &T::SetF_)
.Overload(_SC("Clear"), &T::Clear)
.Overload(_SC("Clear"), &T::ClearEx)
;
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Output members.
*/
RegisterStream & Output()
{
mCls
// Member Methods
.Func(_SC("TellP"), &T::TellP)
.Func(_SC("Put"), &T::Put)
.Func(_SC("Flush"), &T::Flush)
.FmtFunc(_SC("Write"), &T::WriteString)
.Func(_SC("WriteBuffer"), &T::WriteBuffer)
// Member Overloads
.Overload(_SC("SeekP"), &T::SeekP)
.Overload(_SC("SeekP"), &T::SeekP_)
;
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Input members.
*/
RegisterStream & Input()
{
mCls
// Properties
.Prop(_SC("GCount"), &T::GCount)
// Member Methods
.Func(_SC("TellG"), &T::TellG)
.Func(_SC("Peek"), &T::Peek)
.Func(_SC("UnGet"), &T::UnGet)
.Func(_SC("PutBack"), &T::PutBack)
.Func(_SC("Read"), &T::ReadString)
.Func(_SC("ReadBuffer"), &T::ReadBuffer)
.Func(_SC("ReadSome"), &T::ReadSomeString)
.Func(_SC("ReadSomeBuffer"), &T::ReadSomeBuffer)
// Member Overloads
.Overload(_SC("SeekG"), &T::SeekG)
.Overload(_SC("SeekG"), &T::SeekG_)
.Overload(_SC("Get"), &T::GetString0)
.Overload(_SC("Get"), &T::GetString1)
.Overload(_SC("Get"), &T::GetString2)
.Overload(_SC("GetBuffer"), &T::GetBuffer1)
.Overload(_SC("GetBuffer"), &T::GetBuffer2)
.Overload(_SC("GetLine"), &T::GetLineString1)
.Overload(_SC("GetLine"), &T::GetLineString2)
.Overload(_SC("GetLineBuffer"), &T::GetLineBuffer1)
.Overload(_SC("GetLineBuffer"), &T::GetLineBuffer2)
.Overload(_SC("Ignore"), &T::Ignore0)
.Overload(_SC("Ignore"), &T::Ignore1)
.Overload(_SC("Ignore"), &T::Ignore2)
;
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* String type members.
*/
RegisterStream & StringType()
{
mCls
// Constructors
.template Ctor()
.template Ctor< StackStrF & >()
.template Ctor< SQInteger, StackStrF & >()
// Properties
.Prop(_SC("Str"), &T::GetStr, &T::SetStr)
;
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* File type members.
*/
RegisterStream & FileType()
{
mCls
// Constructors
.template Ctor< StackStrF & >()
.template Ctor< SQInteger, StackStrF & >()
// Properties
.Prop(_SC("IsOpen"), &T::IsOpen)
// Member Methods
.Func(_SC("Close"), &T::Close)
// Member Overloads
.Overload(_SC("Open"), &T::Open)
.Overload(_SC("Open"), &T::Open_)
;
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Global stream type members.
*/
RegisterStream & GlobalType()
{
mCls
// Constructors
.template Ctor()
;
// Allow chaining
return *this;
}
/* --------------------------------------------------------------------------------------------
* Bind the class object to a table.
*/
void Bind(Table & ns, const SQChar * name)
{
ns.Bind(name, mCls);
}
};
// ================================================================================================
void Register_Stream(HSQUIRRELVM vm)
{
Table sns(vm);
// --------------------------------------------------------------------------------------------
RegisterStream< StringStream >(vm, StringStreamTn::Str)
.Base< StringStreamTn >()
.Output()
.Input()
.StringType()
.Bind(sns, "String");
// --------------------------------------------------------------------------------------------
RegisterStream< FileStream >(vm, FileStreamTn::Str)
.Base< FileStreamTn >()
.Output()
.Input()
.FileType()
.Bind(sns, "File");
// --------------------------------------------------------------------------------------------
RegisterStream< OStringStream >(vm, OStringStreamTn::Str)
.Base< OStringStreamTn >()
.Output()
.StringType()
.Bind(sns, "OutputString");
// --------------------------------------------------------------------------------------------
RegisterStream< OFileStream >(vm, OFileStreamTn::Str)
.Base< OFileStreamTn >()
.Output()
.FileType()
.Bind(sns, "OutputFile");
// --------------------------------------------------------------------------------------------
RegisterStream< IStringStream >(vm, IStringStreamTn::Str)
.Base< IStringStreamTn >()
.Input()
.StringType()
.Bind(sns, "InputString");
// --------------------------------------------------------------------------------------------
RegisterStream< IFileStream >(vm, IFileStreamTn::Str)
.Base< IFileStreamTn >()
.Input()
.FileType()
.Bind(sns, "InputFile");
// --------------------------------------------------------------------------------------------
sns.FmtFunc(_SC("FileToString"), FileToString);
sns.FmtFunc(_SC("StringToFile"), StringToFile);
// --------------------------------------------------------------------------------------------
/* This feature is implemented but not enabled because it's rather pointless */
//RegisterStream< CInStream >(vm, CInStreamTn::Str)
// .Base< CInStreamTn >()
// .Input()
// .GlobalType()
// .Bind(sns, "CIn");
// --------------------------------------------------------------------------------------------
//RegisterStream< COutStream >(vm, COutStreamTn::Str)
// .Base< COutStreamTn >()
// .Output()
// .GlobalType()
// .Bind(sns, "COut");
// --------------------------------------------------------------------------------------------
//RegisterStream< CErrStream >(vm, CErrStreamTn::Str)
// .Base< CErrStreamTn >()
// .Output()
// .GlobalType()
// .Bind(sns, "CErr");
// --------------------------------------------------------------------------------------------
//RegisterStream< CLogStream >(vm, CLogStreamTn::Str)
// .Base< CLogStreamTn >()
// .Output()
// .GlobalType()
// .Bind(sns, "CLog");
// --------------------------------------------------------------------------------------------
RootTable(vm).Bind(_SC("SqStream"), sns);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqIoState"), Enumeration(vm)
.Const(_SC("GoodBit"), SQInteger(std::ios_base::goodbit))
.Const(_SC("BadBit"), SQInteger(std::ios_base::badbit))
.Const(_SC("FailBit"), SQInteger(std::ios_base::failbit))
.Const(_SC("EofBit"), SQInteger(std::ios_base::eofbit))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqFmtFlags"), Enumeration(vm)
.Const(_SC("Dec"), SQInteger(std::ios_base::dec))
.Const(_SC("Oct"), SQInteger(std::ios_base::oct))
.Const(_SC("Hex"), SQInteger(std::ios_base::hex))
.Const(_SC("BaseField"), SQInteger(std::ios_base::basefield))
.Const(_SC("Left"), SQInteger(std::ios_base::left))
.Const(_SC("Right"), SQInteger(std::ios_base::right))
.Const(_SC("Internal"), SQInteger(std::ios_base::internal))
.Const(_SC("AdjustField"), SQInteger(std::ios_base::adjustfield))
.Const(_SC("Scientific"), SQInteger(std::ios_base::scientific))
.Const(_SC("Fixed"), SQInteger(std::ios_base::fixed))
.Const(_SC("FloatField"), SQInteger(std::ios_base::floatfield))
.Const(_SC("BoolAlpha"), SQInteger(std::ios_base::boolalpha))
.Const(_SC("ShowBase"), SQInteger(std::ios_base::showbase))
.Const(_SC("ShowPoint"), SQInteger(std::ios_base::showpoint))
.Const(_SC("ShowPos"), SQInteger(std::ios_base::showpos))
.Const(_SC("SkipWS"), SQInteger(std::ios_base::skipws))
.Const(_SC("UnitBuf"), SQInteger(std::ios_base::unitbuf))
.Const(_SC("UpperCase"), SQInteger(std::ios_base::uppercase))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqOpenMode"), Enumeration(vm)
.Const(_SC("App"), SQInteger(std::ios_base::app))
.Const(_SC("Ate"), SQInteger(std::ios_base::ate))
.Const(_SC("AtEnd"), SQInteger(std::ios_base::ate))
.Const(_SC("Binary"), SQInteger(std::ios_base::binary))
.Const(_SC("In"), SQInteger(std::ios_base::in))
.Const(_SC("Out"), SQInteger(std::ios_base::out))
.Const(_SC("Trunc"), SQInteger(std::ios_base::trunc))
);
// --------------------------------------------------------------------------------------------
ConstTable(vm).Enum(_SC("SqSeekDir"), Enumeration(vm)
.Const(_SC("Beg"), SQInteger(std::ios_base::beg))
.Const(_SC("Beginning"), SQInteger(std::ios_base::beg))
.Const(_SC("Cur"), SQInteger(std::ios_base::cur))
.Const(_SC("Current"), SQInteger(std::ios_base::cur))
.Const(_SC("End"), SQInteger(std::ios_base::end))
);
}
} // Namespace:: SqMod