/************************************************************************** @file fdt.d Copyright (c) 2005 Derek Parnell This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for damages of any kind arising from the use of this software. Permission is hereby granted to anyone to use this software for any purpose, including commercial applications, and to alter it and/or redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment within documentation of said product would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any distribution of the source. 4. Derivative works are permitted, but they must carry this notice in full and credit the original source. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @version Initial version, January 2005 @author Derek Parnell MODIFIED VERSION. The dependency from util.str and / -> \ conversion have been removed. **************************************************************************/ module utils.Fdt; private import std.stdio; version(unix) version = Unix; version(Unix) version = Posix; version(linux) version = Posix; version(darwin) version = Posix; private { import std.utf; import std.file; version(Windows) { import std.c.windows.windows; } else version(linux) { import std.c.linux.linux; alias std.c.linux.linux posix; } else version(darwin) { import std.c.darwin.darwin; alias std.c.darwin.darwin posix; } else version(Unix) { import std.c.unix; alias std.c.unix posix; } version(Posix) { import std.string; alias posix.open open; alias posix.fstat fstat; alias posix.close close; } } public { /+debug(1) { private import std.stdio; static this() { writefln(__FILE__ ~ " build #%d", auto_build_number); } }+/ // --------- classes ---------------- version(Windows) { class FileDateTime { FILETIME mDT; bool mSet; this(FILETIME pInitValue) {mSet = true; mDT = pInitValue; } this() {mSet = false; mDT.dwHighDateTime = 0; mDT.dwLowDateTime = 0;} this(char[] pFileName) { this = GetFileTime(pFileName); } int opCmp(FileDateTime pOther) { return Compare(pOther); } int Compare(FileDateTime pOther, bool pExact = false) { SYSTEMTIME lATime; SYSTEMTIME lBTime; int lResult; if (mSet == false) lResult = -1; else if (pOther.mSet == false) lResult = 1; else { FileTimeToSystemTime(&mDT, &lATime); FileTimeToSystemTime(&pOther.mDT, &lBTime); if (lATime.wYear > lBTime.wYear) lResult = 2; else if (lATime.wYear < lBTime.wYear) lResult = -2; else if (lATime.wMonth > lBTime.wMonth) lResult = 3; else if (lATime.wMonth < lBTime.wMonth) lResult = -3; else if (lATime.wDay > lBTime.wDay) lResult = 4; else if (lATime.wDay < lBTime.wDay) lResult = -4; else if (lATime.wHour > lBTime.wHour) lResult = 5; else if (lATime.wHour < lBTime.wHour) lResult = -5; else if (lATime.wMinute > lBTime.wMinute) lResult = 6; else if (lATime.wMinute < lBTime.wMinute) lResult = -6; else if (lATime.wSecond > lBTime.wSecond) lResult = 7; else if (lATime.wSecond < lBTime.wSecond) lResult = -7; else if (pExact) { if (lATime.wMilliseconds > lBTime.wMilliseconds) lResult = 8; else if (lATime.wMilliseconds < lBTime.wMilliseconds) lResult = -8; else lResult = 0; } } return lResult; } // Format the date-time into human readable text. char[] toString(bool pExact = false) { TIME_ZONE_INFORMATION lTimeZone; SYSTEMTIME lSystemTime; SYSTEMTIME lLocalTime; FILETIME lLocalDT; if ( mSet == false ) return "not recorded"; else { // Convert the file's time into the user's local timezone. if (std.file.useWfuncs) { FileTimeToSystemTime(&mDT, &lSystemTime); GetTimeZoneInformation(&lTimeZone); SystemTimeToTzSpecificLocalTime(&lTimeZone, &lSystemTime, &lLocalTime); } else { FileTimeToLocalFileTime(&mDT, &lLocalDT); FileTimeToSystemTime(&lLocalDT, &lLocalTime); } // Return a standardized string form of the date-time. // CCYY/MM/DD hh:mm:ss if (pExact) return std.string.format("%04d/%02d/%02d %02d:%02d:%02d.%04d" ,lLocalTime.wYear, lLocalTime.wMonth, lLocalTime.wDay, lLocalTime.wHour, lLocalTime.wMinute, lLocalTime.wSecond ,lLocalTime.wMilliseconds ); else return std.string.format("%04d/%02d/%02d %02d:%02d:%02d" ,lLocalTime.wYear, lLocalTime.wMonth, lLocalTime.wDay, lLocalTime.wHour, lLocalTime.wMinute, lLocalTime.wSecond ); } } } } version(Posix){ class FileDateTime { ulong mDT; bool mSet; this(ulong pInitValue) { mSet = true; mDT = pInitValue; } this() { mSet = false; mDT = 0;} this(char[] pFileName) { mSet = true; this = GetFileTime(pFileName); } int opCmp(FileDateTime pOther) { if (mSet == false) return -1; if (pOther.mSet == false) return 1; if (mDT > pOther.mDT) return 1; if (mDT < pOther.mDT) return -1; return 0; } char[] toString() { if ( mSet == false ) return "not recorded"; else return std.string.format("%d", mDT); } } } } version(Windows) { FileDateTime GetFileTime (char[] pFileName) { return GetFileTime( toUTF16(pFileName) ); } FileDateTime GetFileTime (dchar[] pFileName) { return GetFileTime( toUTF16(pFileName) ); } FileDateTime GetFileTime (wchar[] pFileName) body { FileDateTime lFileTime; WIN32_FIND_DATAW lFileInfoW; WIN32_FIND_DATA lFileInfoA; FILETIME lWriteTime; char[] lASCII_FileName; HANDLE lFH; if (std.file.useWfuncs) { lFH = FindFirstFileW ((pFileName ~ cast(wchar[])"\0").ptr, &lFileInfoW); if(lFH != INVALID_HANDLE_VALUE) { lWriteTime = lFileInfoW.ftLastWriteTime; } } else { lASCII_FileName = std.utf.toUTF8(pFileName ~ cast(wchar[])"\0"); lFH = FindFirstFileA (lASCII_FileName.ptr, &lFileInfoA); if(lFH != INVALID_HANDLE_VALUE) { lWriteTime = lFileInfoA.ftLastWriteTime; } } if(lFH != INVALID_HANDLE_VALUE) { lFileTime = new FileDateTime(lWriteTime); FindClose(lFH); } else { lFileTime = new FileDateTime(); } return lFileTime; } } version(Posix) { /* seconds between timebase and last modification - zero if it doesn't exist. */ FileDateTime GetFileTime(wchar[] pFileName) { return GetFileTime( toUTF8(pFileName) ); } FileDateTime GetFileTime(dchar[] pFileName) { return GetFileTime( toUTF8(pFileName) ); } FileDateTime GetFileTime(char[] pFileName) body { FileDateTime lDateTime; int lFileHandle; struct_stat lFileInfo; char *lFileName; lFileName = std.string.toStringz(pFileName); lFileHandle = open(lFileName, O_RDONLY); if (lFileHandle != -1) { if(fstat(lFileHandle, &lFileInfo) == 0 ) lDateTime = new FileDateTime(lFileInfo.st_mtime); else lDateTime = new FileDateTime(); close(lFileHandle); } else lDateTime = new FileDateTime(); return lDateTime; } }