1
0

Merge pull request #2500 from cuberite/FileApiExtend

Extended and fixed the cFile API.
This commit is contained in:
Mattes D 2015-09-27 00:10:50 +02:00
commit 0e3bb7a398
8 changed files with 618 additions and 110 deletions

View File

@ -1008,16 +1008,20 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
Provides helper functions for manipulating and querying the filesystem. Most functions are static,
so they should be called directly on the cFile class itself:
<pre class="prettyprint lang-lua">
cFile:Delete("/usr/bin/virus.exe");
cFile:DeleteFile("/usr/bin/virus.exe");
</pre></p>
]],
Functions =
{
ChangeFileExt = { Params = "FileName, NewExt", Return = "string", Notes = "(STATIC) Returns FileName with its extension changed to NewExt. NewExt may begin with a dot, but needn't, the result is the same in both cases (the first dot, if present, is ignored). FileName may contain path elements, extension is recognized as the last dot after the last path separator in the string." },
Copy = { Params = "SrcFileName, DstFileName", Return = "bool", Notes = "(STATIC) Copies a single file to a new destination. Returns true if successful. Fails if the destination already exists." },
CreateFolder = { Params = "FolderName", Return = "bool", Notes = "(STATIC) Creates a new folder. Returns true if successful." },
Delete = { Params = "FileName", Return = "bool", Notes = "(STATIC) Deletes the specified file. Returns true if successful." },
Exists = { Params = "FileName", Return = "bool", Notes = "(STATIC) Returns true if the specified file exists." },
CreateFolder = { Params = "FolderPath", Return = "bool", Notes = "(STATIC) Creates a new folder. Returns true if successful. Only a single level can be created at a time, use CreateFolderRecursive() to create multiple levels of folders at once." },
CreateFolderRecursive = { Params = "FolderPath", Return = "bool", Notes = "(STATIC) Creates a new folder, creating its parents if needed. Returns true if successful." },
Delete = { Params = "Path", Return = "bool", Notes = "(STATIC) Deletes the specified file or folder. Returns true if successful. Only deletes folders that are empty.<br/><b>NOTE</b>: If you already know if the object is a file or folder, use DeleteFile() or DeleteFolder() explicitly." },
DeleteFile = { Params = "FilePath", Return = "bool", Notes = "(STATIC) Deletes the specified file. Returns true if successful." },
DeleteFolder = { Params = "FolderPath", Return = "bool", Notes = "(STATIC) Deletes the specified file or folder. Returns true if successful. Only deletes folders that are empty." },
DeleteFolderContents = { Params = "FolderPath", Return = "bool", Notes = "(STATIC) Deletes everything from the specified folder, recursively. The specified folder stays intact. Returns true if successful." },
Exists = { Params = "Path", Return = "bool", Notes = "(STATIC) Returns true if the specified file or folder exists.<br/><b>OBSOLETE</b>, use IsFile() or IsFolder() instead" },
GetExecutableExt = { Params = "", Return = "string", Notes = "(STATIC) Returns the customary executable extension (including the dot) used by the current platform (\".exe\" on Windows, empty string on Linux). " },
GetFolderContents = { Params = "FolderName", Return = "array table of strings", Notes = "(STATIC) Returns the contents of the specified folder, as an array table of strings. Each filesystem object is listed. Use the IsFile() and IsFolder() functions to determine the object type." },
GetLastModificationTime = { Params = "Path", Return = "number", Notes = "(STATIC) Returns the last modification time (in current timezone) of the specified file or folder. Returns zero if file not found / not accessible. The returned value is in the same units as values returned by os.time()." },

View File

@ -174,11 +174,9 @@ local function WriteArticles(f)
]]);
for _, extra in ipairs(g_APIDesc.ExtraPages) do
local SrcFileName = g_PluginFolder .. "/" .. extra.FileName;
if (cFile:Exists(SrcFileName)) then
if (cFile:IsFile(SrcFileName)) then
local DstFileName = "API/" .. extra.FileName;
if (cFile:Exists(DstFileName)) then
cFile:Delete(DstFileName);
end
cFile:Copy(SrcFileName, DstFileName);
f:write("<li><a href=\"" .. extra.FileName .. "\">" .. extra.Title .. "</a></li>\n");
else
@ -1112,7 +1110,7 @@ local function ListMissingPages()
local NumLinks = 0;
for PageName, Referrers in pairs(g_TrackedPages) do
NumLinks = NumLinks + 1;
if not(cFile:Exists("API/" .. PageName .. ".html")) then
if not(cFile:IsFile("API/" .. PageName .. ".html")) then
table.insert(MissingPages, {Name = PageName, Refs = Referrers} );
end
end;

@ -1 +1 @@
Subproject commit ee01115ac848116cf58956fa6d031dbbadddba0a
Subproject commit b1e3f972ebf475bfbe1dfc8bccc0240977d11d3e

View File

@ -676,6 +676,18 @@ void cLuaState::Push(int a_Value)
void cLuaState::Push(long a_Value)
{
ASSERT(IsValid());
tolua_pushnumber(m_LuaState, static_cast<lua_Number>(a_Value));
m_NumCurrentFunctionArgs += 1;
}
void cLuaState::Push(UInt32 a_Value)
{
ASSERT(IsValid());

View File

@ -248,6 +248,7 @@ public:
void Push(cLuaUDPEndpoint * a_UDPEndpoint);
void Push(double a_Value);
void Push(int a_Value);
void Push(long a_Value);
void Push(const UInt32 a_Value);
void Push(void * a_Ptr);
void Push(std::chrono::milliseconds a_time);

View File

@ -482,8 +482,258 @@ cPluginLua * cManualBindings::GetLuaPlugin(lua_State * L)
static int tolua_cFile_ChangeFileExt(lua_State * tolua_S)
{
// API signature:
// ChangeFileExt(string, string) -> string
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2, 3) ||
!L.CheckParamEnd(4)
)
{
return 0;
}
// Execute:
AString FileName, NewExt;
ASSERT(L.GetStackValues(2, FileName, NewExt));
L.Push(cFile::ChangeFileExt(FileName, NewExt));
return 1;
}
static int tolua_cFile_Copy(lua_State * tolua_S)
{
// API signature:
// cFile:Copy(string, string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2, 3) ||
!L.CheckParamEnd(4)
)
{
return 0;
}
// Execute:
AString SrcFile, DstFile;
ASSERT(L.GetStackValues(2, SrcFile, DstFile));
L.Push(cFile::Copy(SrcFile, DstFile));
return 1;
}
static int tolua_cFile_CreateFolder(lua_State * tolua_S)
{
// API signature:
// cFile:CreateFolder(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString FolderPath;
ASSERT(L.GetStackValues(2, FolderPath));
L.Push(cFile::CreateFolder(FolderPath));
return 1;
}
static int tolua_cFile_CreateFolderRecursive(lua_State * tolua_S)
{
// API signature:
// cFile:CreateFolderRecursive(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString FolderPath;
ASSERT(L.GetStackValues(2, FolderPath));
L.Push(cFile::CreateFolderRecursive(FolderPath));
return 1;
}
static int tolua_cFile_Delete(lua_State * tolua_S)
{
// API signature:
// cFile:Delete(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::Delete(Path));
return 1;
}
static int tolua_cFile_DeleteFile(lua_State * tolua_S)
{
// API signature:
// cFile:DeleteFile(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::DeleteFile(Path));
return 1;
}
static int tolua_cFile_DeleteFolder(lua_State * tolua_S)
{
// API signature:
// cFile:DeleteFolder(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::DeleteFolder(Path));
return 1;
}
static int tolua_cFile_DeleteFolderContents(lua_State * tolua_S)
{
// API signature:
// cFile:DeleteFolderContents(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::DeleteFolderContents(Path));
return 1;
}
static int tolua_cFile_Exists(lua_State * tolua_S)
{
// API signature:
// cFile:Exists(string) -> bool
// Obsolete, use IsFile() or IsFolder() instead
cLuaState L(tolua_S);
LOGWARNING("cFile:Exists() is obsolete, use cFile:IsFolder() or cFile:IsFile() instead!");
L.LogStackTrace();
// Check params:
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::Exists(Path));
return 1;
}
static int tolua_cFile_GetFolderContents(lua_State * tolua_S)
{
// API signature:
// cFile:GetFolderContents(string) -> {string, string, ...}
// Check params:
cLuaState LuaState(tolua_S);
if (
@ -497,7 +747,7 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S)
// Get params:
AString Folder;
LuaState.GetStackValues(2, Folder);
ASSERT(LuaState.GetStackValues(2, Folder));
// Execute and push result:
LuaState.Push(cFile::GetFolderContents(Folder));
@ -508,8 +758,119 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S)
static int tolua_cFile_GetLastModificationTime(lua_State * tolua_S)
{
// API signature:
// cFile:GetLastModificationTime(string) -> number
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::GetLastModificationTime(Path));
return 1;
}
static int tolua_cFile_GetSize(lua_State * tolua_S)
{
// API signature:
// cFile:GetSize(string) -> number
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::GetSize(Path));
return 1;
}
static int tolua_cFile_IsFile(lua_State * tolua_S)
{
// API signature:
// cFile:IsFile(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::IsFile(Path));
return 1;
}
static int tolua_cFile_IsFolder(lua_State * tolua_S)
{
// API signature:
// cFile:IsFolder(string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2) ||
!L.CheckParamEnd(3)
)
{
return 0;
}
// Execute:
AString Path;
ASSERT(L.GetStackValues(2, Path));
L.Push(cFile::IsFolder(Path));
return 1;
}
static int tolua_cFile_ReadWholeFile(lua_State * tolua_S)
{
// API signature:
// cFile:ReadWholeFile(string) -> string
// Check params:
cLuaState LuaState(tolua_S);
if (
@ -523,7 +884,7 @@ static int tolua_cFile_ReadWholeFile(lua_State * tolua_S)
// Get params:
AString FileName;
LuaState.GetStackValues(2, FileName);
ASSERT(LuaState.GetStackValues(2, FileName));
// Execute and push result:
LuaState.Push(cFile::ReadWholeFile(FileName));
@ -534,6 +895,33 @@ static int tolua_cFile_ReadWholeFile(lua_State * tolua_S)
static int tolua_cFile_Rename(lua_State * tolua_S)
{
// API signature:
// cFile:Rename(string, string) -> bool
// Check params:
cLuaState L(tolua_S);
if (
!L.CheckParamUserTable(1, "cFile") ||
!L.CheckParamString(2, 3) ||
!L.CheckParamEnd(4)
)
{
return 0;
}
// Execute:
AString SrcPath, DstPath;
ASSERT(L.GetStackValues(2, SrcPath, DstPath));
L.Push(cFile::Rename(SrcPath, DstPath));
return 1;
}
static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S)
{
// API function no longer available:
@ -2846,8 +3234,22 @@ void cManualBindings::Bind(lua_State * tolua_S)
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cFile");
tolua_function(tolua_S, "ChangeFileExt", tolua_cFile_ChangeFileExt);
tolua_function(tolua_S, "Copy", tolua_cFile_Copy);
tolua_function(tolua_S, "CreateFolder", tolua_cFile_CreateFolder);
tolua_function(tolua_S, "CreateFolderRecursive", tolua_cFile_CreateFolderRecursive);
tolua_function(tolua_S, "Delete", tolua_cFile_Delete);
tolua_function(tolua_S, "DeleteFile", tolua_cFile_DeleteFile);
tolua_function(tolua_S, "DeleteFolder", tolua_cFile_DeleteFolder);
tolua_function(tolua_S, "DeleteFolderContents", tolua_cFile_DeleteFolderContents);
tolua_function(tolua_S, "Exists", tolua_cFile_Exists);
tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents);
tolua_function(tolua_S, "GetLastModificationTime", tolua_cFile_GetLastModificationTime);
tolua_function(tolua_S, "GetSize", tolua_cFile_GetSize);
tolua_function(tolua_S, "IsFile", tolua_cFile_IsFile);
tolua_function(tolua_S, "IsFolder", tolua_cFile_IsFolder);
tolua_function(tolua_S, "ReadWholeFile", tolua_cFile_ReadWholeFile);
tolua_function(tolua_S, "Rename", tolua_cFile_Rename);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cHopperEntity");

View File

@ -16,11 +16,7 @@
cFile::cFile(void) :
#ifdef USE_STDIO_FILE
m_File(nullptr)
#else
m_File(INVALID_HANDLE_VALUE)
#endif // USE_STDIO_FILE
{
// Nothing needed yet
}
@ -30,11 +26,7 @@ cFile::cFile(void) :
cFile::cFile(const AString & iFileName, eMode iMode) :
#ifdef USE_STDIO_FILE
m_File(nullptr)
#else
m_File(INVALID_HANDLE_VALUE)
#endif // USE_STDIO_FILE
{
Open(iFileName, iMode);
}
@ -78,11 +70,11 @@ bool cFile::Open(const AString & iFileName, eMode iMode)
return false;
}
#ifdef _WIN32
#ifdef _WIN32
m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), Mode, _SH_DENYWR);
#else
#else
m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode);
#endif // _WIN32
#endif // _WIN32
if ((m_File == nullptr) && (iMode == fmReadWrite))
{
@ -91,11 +83,11 @@ bool cFile::Open(const AString & iFileName, eMode iMode)
// So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents.
// Simply re-open for read-writing, erasing existing contents:
#ifdef _WIN32
#ifdef _WIN32
m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+", _SH_DENYWR);
#else
#else
m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+");
#endif // _WIN32
#endif // _WIN32
}
return (m_File != nullptr);
@ -310,7 +302,77 @@ bool cFile::Exists(const AString & a_FileName)
bool cFile::Delete(const AString & a_FileName)
bool cFile::Delete(const AString & a_Path)
{
if (IsFolder(a_Path))
{
return DeleteFolder(a_Path);
}
else
{
return DeleteFile(a_Path);
}
}
bool cFile::DeleteFolder(const AString & a_FolderName)
{
#ifdef _WIN32
return (RemoveDirectoryA(a_FolderName.c_str()) != 0);
#else // _WIN32
return (rmdir(a_FolderName.c_str()) == 0);
#endif // else _WIN32
}
bool cFile::DeleteFolderContents(const AString & a_FolderName)
{
auto Contents = cFile::GetFolderContents(a_FolderName);
for (const auto item: Contents)
{
// Skip "." and ".." altogether:
if ((item == ".") || (item == ".."))
{
continue;
}
// Remove the item:
auto WholePath = a_FolderName + GetPathSeparator() + item;
if (IsFolder(WholePath))
{
if (!DeleteFolderContents(WholePath))
{
return false;
}
if (!DeleteFolder(WholePath))
{
return false;
}
}
else
{
if (!DeleteFile(WholePath))
{
return false;
}
}
} // for item - Contents[]
// All deletes succeeded
return true;
}
bool cFile::DeleteFile(const AString & a_FileName)
{
return (remove(a_FileName.c_str()) == 0);
}
@ -331,7 +393,7 @@ bool cFile::Rename(const AString & a_OrigFileName, const AString & a_NewFileName
bool cFile::Copy(const AString & a_SrcFileName, const AString & a_DstFileName)
{
#ifdef _WIN32
return (CopyFileA(a_SrcFileName.c_str(), a_DstFileName.c_str(), true) != 0);
return (CopyFileA(a_SrcFileName.c_str(), a_DstFileName.c_str(), FALSE) != 0);
#else
// Other OSs don't have a direct CopyFile equivalent, do it the harder way:
std::ifstream src(a_SrcFileName.c_str(), std::ios::binary);
@ -409,6 +471,34 @@ bool cFile::CreateFolder(const AString & a_FolderPath)
bool cFile::CreateFolderRecursive(const AString & a_FolderPath)
{
// Special case: Fail if the path is empty
if (a_FolderPath.empty())
{
return false;
}
// Go through each path element and create the folder:
auto len = a_FolderPath.length();
auto PathSep = GetPathSeparator()[0];
for (decltype(len) i = 0; i < len; i++)
{
if (a_FolderPath[i] == PathSep)
{
CreateFolder(a_FolderPath.substr(0, i));
}
}
CreateFolder(a_FolderPath);
// Check the result by querying whether the final path exists:
return IsFolder(a_FolderPath);
}
AStringVector cFile::GetFolderContents(const AString & a_Folder)
{
AStringVector AllFiles;

View File

@ -32,17 +32,6 @@ For reading entire files into memory, just use the static cFile::ReadWholeFile()
#ifndef _WIN32
#define USE_STDIO_FILE
#endif // _WIN32
// DEBUG:
#define USE_STDIO_FILE
// tolua_begin
class cFile
@ -101,48 +90,64 @@ public:
/** Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error */
int ReadRestOfFile(AString & a_Contents);
// tolua_begin
/** Returns true if the file specified exists */
static bool Exists(const AString & a_FileName);
static bool Exists(const AString & a_FileName); // Exported in ManualBindings.cpp
/** Deletes a file, returns true if successful */
static bool Delete(const AString & a_FileName);
/** Deletes a file or a folder, returns true if successful.
Prefer to use DeleteFile or DeleteFolder, since those don't have the penalty of checking whether a_Path is a folder. */
static bool Delete(const AString & a_Path); // Exported in ManualBindings.cpp
/** Deletes a file, returns true if successful.
Returns false if a_FileName points to a folder. */
static bool DeleteFile(const AString & a_FileName); // Exported in ManualBindings.cpp
/** Deletes a folder, returns true if successful.
Returns false if a_FolderName points to a file. */
static bool DeleteFolder(const AString & a_FolderName); // Exported in ManualBindings.cpp
/** Deletes all content from the specified folder.
The specified folder itself stays intact.
Returns true on success, false on failure. */
static bool DeleteFolderContents(const AString & a_FolderName); // Exported in ManualBindings.cpp
/** Renames a file or folder, returns true if successful. May fail if dest already exists (libc-dependant)! */
static bool Rename(const AString & a_OrigPath, const AString & a_NewPath);
static bool Rename(const AString & a_OrigPath, const AString & a_NewPath); // Exported in ManualBindings.cpp
/** Copies a file, returns true if successful. */
static bool Copy(const AString & a_SrcFileName, const AString & a_DstFileName);
/** Copies a file, returns true if successful.
Overwrites the dest file if it already exists. */
static bool Copy(const AString & a_SrcFileName, const AString & a_DstFileName); // Exported in ManualBindings.cpp
/** Returns true if the specified path is a folder */
static bool IsFolder(const AString & a_Path);
static bool IsFolder(const AString & a_Path); // Exported in ManualBindings.cpp
/** Returns true if the specified path is a regular file */
static bool IsFile(const AString & a_Path);
static bool IsFile(const AString & a_Path); // Exported in ManualBindings.cpp
/** Returns the size of the file, or a negative number on error */
static long GetSize(const AString & a_FileName);
static long GetSize(const AString & a_FileName); // Exported in ManualBindings.cpp
/** Creates a new folder with the specified name. Returns true if successful. Path may be relative or absolute */
static bool CreateFolder(const AString & a_FolderPath);
static bool CreateFolder(const AString & a_FolderPath); // Exported in ManualBindings.cpp
// tolua_end
/** Creates a new folder with the specified name, creating its parents if needed. Path may be relative or absolute.
Returns true if the folder exists at the end of the operation (either created, or already existed).
Supports only paths that use the path separator used by the current platform (MSVC CRT supports slashes for file paths, too, but this function doesn't) */
static bool CreateFolderRecursive(const AString & a_FolderPath); // Exported in ManualBindings.cpp
/** Returns the entire contents of the specified file as a string. Returns empty string on error.
Exported manually in ManualBindings.cpp due to #1914 - ToLua code doesn't work well with binary files. */
static AString ReadWholeFile(const AString & a_FileName);
// tolua_begin
/** Returns the entire contents of the specified file as a string. Returns empty string on error. */
static AString ReadWholeFile(const AString & a_FileName); // Exported in ManualBindings.cpp
/** Returns a_FileName with its extension changed to a_NewExt.
a_FileName may contain path specification. */
static AString ChangeFileExt(const AString & a_FileName, const AString & a_NewExt);
static AString ChangeFileExt(const AString & a_FileName, const AString & a_NewExt); // Exported in ManualBindings.cpp
/** Returns the last modification time (in current timezone) of the specified file.
The value returned is in the same units as the value returned by time() function.
If the file is not found / accessible, zero is returned. */
static unsigned GetLastModificationTime(const AString & a_FileName);
If the file is not found / accessible, zero is returned.
Works for folders, too, when specified without the trailing path separator. */
static unsigned GetLastModificationTime(const AString & a_FileName); // Exported in ManualBindings.cpp
// tolua_begin
/** Returns the path separator used by the current platform.
Note that the platform / CRT may support additional path separators (such as slashes on Windows), these don't get reported. */
@ -162,11 +167,7 @@ public:
void Flush(void);
private:
#ifdef USE_STDIO_FILE
FILE * m_File;
#else
HANDLE m_File;
#endif
} ; // tolua_export