/* Ofront+ 1.0 -sxtapC -48 */
#include "SYSTEM.oh"

struct Platform__1 {
  INTEGER low, high;
};

typedef
  struct Platform_FileIdentity {
    INTEGER volume, indexhigh, indexlow, mtimehigh, mtimelow;
  } Platform_FileIdentity;

typedef
  struct Platform_LARGE_INTEGER {
    INTEGER low, high;
  } Platform_LARGE_INTEGER;


export BOOLEAN Platform_LittleEndian;
export INTEGER Platform_PID;
export CHAR Platform_CWD[260];
export INTEGER Platform_SeekSet, Platform_SeekCur, Platform_SeekEnd, Platform_StdIn, Platform_StdOut, Platform_StdErr;
static INTEGER Platform_stdOutIsConsole;


export BOOLEAN Platform_Absent (INTEGER e);
export INTEGER Platform_ChDir (CHAR *n, INTEGER n__len);
export INTEGER Platform_CloseFile (INTEGER h);
export BOOLEAN Platform_ConnectionFailed (INTEGER e);
static void Platform_ConvertFromUTF16 (LONGCHAR *in, INTEGER in__len, INTEGER inLen, CHAR *out, INTEGER out__len, INTEGER *outLen);
export void Platform_Delay (INTEGER ms);
export INTEGER Platform_DeleteFile (CHAR *n, INTEGER n__len);
export BOOLEAN Platform_DifferentFilesystems (INTEGER e);
export BOOLEAN Platform_DirExists (CHAR *name, INTEGER name__len);
export INTEGER Platform_Error (void);
export void Platform_ExitOS (INTEGER code);
export BOOLEAN Platform_FileExists (CHAR *name, INTEGER name__len);
export INTEGER Platform_FileSize (INTEGER h, LONGINT *len);
export void Platform_GetAppDir (CHAR *dir, INTEGER dir__len);
export void Platform_GetAppDirW (LONGCHAR *dir, INTEGER dir__len);
export void Platform_GetClock (INTEGER *t, INTEGER *d);
export void Platform_GetEnv (CHAR *var, INTEGER var__len, CHAR *val, INTEGER val__len);
export void Platform_GetEnvW (LONGCHAR *var, INTEGER var__len, LONGCHAR *val, INTEGER val__len);
static INTEGER Platform_GetFilePos (INTEGER h, LONGINT *r);
export void Platform_GetLang (CHAR *lang, INTEGER lang__len);
export void Platform_GetTempPath (CHAR *path, INTEGER path__len);
export INTEGER Platform_Identify (INTEGER h, Platform_FileIdentity *identity);
export INTEGER Platform_IdentifyByName (CHAR *n, INTEGER n__len, Platform_FileIdentity *identity);
export BOOLEAN Platform_Inaccessible (INTEGER e);
export BOOLEAN Platform_IsConsole (INTEGER h);
static BOOLEAN Platform_IsStdOutConsole (void);
export void Platform_MTimeAsClock (Platform_FileIdentity i, INTEGER *t, INTEGER *d);
export INTEGER Platform_MaxNameLength (void);
export INTEGER Platform_MaxPathLength (void);
export INTEGER Platform_NewDir (CHAR *pathname, INTEGER pathname__len);
export INTEGER Platform_NewFile (CHAR *pathname, INTEGER pathname__len, INTEGER *h);
export BOOLEAN Platform_NoSuchDirectory (INTEGER e);
export INTEGER Platform_OSAllocate (INTEGER size);
export void Platform_OSFree (INTEGER address);
export INTEGER Platform_OldRO (CHAR *pathname, INTEGER pathname__len, INTEGER *h);
export INTEGER Platform_OldRW (CHAR *pathname, INTEGER pathname__len, INTEGER *h);
export INTEGER Platform_Read (INTEGER h, INTEGER p, INTEGER l, INTEGER *n);
export INTEGER Platform_ReadBuf (INTEGER h, BYTE *b, INTEGER b__len, INTEGER *n);
export INTEGER Platform_ReadBufW (INTEGER h, LONGCHAR *b, INTEGER b__len, INTEGER *n);
export INTEGER Platform_RenameFile (CHAR *src, INTEGER src__len, CHAR *dest, INTEGER dest__len);
export BOOLEAN Platform_SameFile (Platform_FileIdentity i1, Platform_FileIdentity i2);
export BOOLEAN Platform_SameFileTime (Platform_FileIdentity i1, Platform_FileIdentity i2);
export INTEGER Platform_Seek (INTEGER h, LONGINT offset, INTEGER r);
export void Platform_SetMTime (Platform_FileIdentity *target, Platform_FileIdentity source);
export INTEGER Platform_Sync (INTEGER h);
export INTEGER Platform_System (CHAR *cmd, INTEGER cmd__len);
static void Platform_TestLittleEndian (void);
export INTEGER Platform_Time (void);
export BOOLEAN Platform_TimedOut (INTEGER e);
export BOOLEAN Platform_TooManyFiles (INTEGER e);
export INTEGER Platform_TruncateFile (INTEGER h, LONGINT limit);
export INTEGER Platform_Write (INTEGER h, INTEGER p, INTEGER l);
export INTEGER Platform_WriteW (LONGCHAR *s, INTEGER s__len, INTEGER len);
static void Platform_YMDHMStoClock (INTEGER ye, INTEGER mo, INTEGER da, INTEGER ho, INTEGER mi, INTEGER se, INTEGER *t, INTEGER *d);

#include "_windows.h"
#define Platform_ECONNABORTED()  WSAECONNABORTED
#define Platform_ECONNREFUSED()  WSAECONNREFUSED
#define Platform_EHOSTUNREACH()  WSAEHOSTUNREACH
#define Platform_ENETUNREACH()  WSAENETUNREACH
#define Platform_ERRORACCESSDENIED()  ERROR_ACCESS_DENIED
#define Platform_ERRORCALLNOTIMPLEMENTED()  ERROR_CALL_NOT_IMPLEMENTED
#define Platform_ERRORFILENOTFOUND()  ERROR_FILE_NOT_FOUND
#define Platform_ERRORNOTREADY()  ERROR_NOT_READY
#define Platform_ERRORNOTSAMEDEVICE()  ERROR_NOT_SAME_DEVICE
#define Platform_ERRORPATHNOTFOUND()  ERROR_PATH_NOT_FOUND
#define Platform_ERRORSHARINGVIOLATION()  ERROR_SHARING_VIOLATION
#define Platform_ERRORTOOMANYOPENFILES()  ERROR_TOO_MANY_OPEN_FILES
#define Platform_ERRORWRITEPROTECT()  ERROR_WRITE_PROTECT
#define Platform_ETIMEDOUT()  WSAETIMEDOUT
#define Platform_FILEATTRIBUTEDIRECTORY()  (SET)FILE_ATTRIBUTE_DIRECTORY
#define Platform_GetTickCount()  (INTEGER)GetTickCount()
#define Platform_INVALIDFILEATTRIBUTES()  INVALID_FILE_ATTRIBUTES
#define Platform_INVALIDFILESIZE()  INVALID_FILE_SIZE
#define Platform_INVALIDSETFILEPOINTER()  INVALID_SET_FILE_POINTER
#define Platform_InvalidHandleValue()  (-1)
#define Platform_MAXPATH()  MAX_PATH
#define Platform_NOERROR()  NO_ERROR
#define Platform_SystemHalt(code, mod, mod__len, pos)  __HALT(code, mod, pos)
#define Platform_allocate(size)  ((SYSTEM_ADRINT)HeapAlloc(GetProcessHeap(), 0, (size_t)(size)))
#define Platform_bhfiIndexHigh()  (INTEGER)bhfi.nFileIndexHigh
#define Platform_bhfiIndexLow()  (INTEGER)bhfi.nFileIndexLow
#define Platform_bhfiMtimeHigh()  (INTEGER)bhfi.ftLastWriteTime.dwHighDateTime
#define Platform_bhfiMtimeLow()  (INTEGER)bhfi.ftLastWriteTime.dwLowDateTime
#define Platform_bhfiVsn()  (INTEGER)bhfi.dwVolumeSerialNumber
#define Platform_byHandleFileInformation()  BY_HANDLE_FILE_INFORMATION bhfi
#define Platform_cleanupProcess()  CloseHandle(pi.hProcess); CloseHandle(pi.hThread);
#define Platform_closeHandle(h)  (INTEGER)CloseHandle((HANDLE)h)
#define Platform_copyFile(src, src__len, dest, dest__len)  (INTEGER)CopyFile((LPCTSTR)src, (LPCTSTR)dest, FALSE)
#define Platform_createDirectory(lpPathName, lpPathName__len)  CreateDirectory((char*)lpPathName, (LPSECURITY_ATTRIBUTES)0)
#define Platform_createProcess(str, str__len)  (INTEGER)CreateProcess(0, (char*)str, 0,0,0,0,0,0,&si,&pi)
#define Platform_deleteFile(n, n__len)  (INTEGER)DeleteFile((char*)n)
#define Platform_err()  (INTEGER)GetLastError()
#define Platform_exit(code)  ExitProcess((UINT)code)
#define Platform_fileTimeToSysTime()  SYSTEMTIME st; FileTimeToSystemTime(&ft, &st)
#define Platform_flushFileBuffers(h)  (INTEGER)FlushFileBuffers((HANDLE)h)
#define Platform_free(address)  HeapFree(GetProcessHeap(), 0, (void*)address)
#define Platform_getConsoleMode(h, m)  GetConsoleMode((HANDLE)h, (DWORD*)m)
#define Platform_getCurrentDirectory(n, n__len)  GetCurrentDirectory((DWORD)n__len, (char*)n)
#define Platform_getEnvironmentVariable(name, name__len, buf, buf__len)  (INTEGER)GetEnvironmentVariableA((LPSTR)name, (LPSTR)buf, buf__len)
#define Platform_getEnvironmentVariableW(name, name__len, buf, buf__len)  (INTEGER)GetEnvironmentVariableW((LPWSTR)name, (LPWSTR)buf, buf__len)
#define Platform_getExitCodeProcess(exitcode)  GetExitCodeProcess(pi.hProcess, (DWORD*)exitcode);
#define Platform_getFileAttributes(name, name__len)  (INTEGER)GetFileAttributes((LPCTSTR)name)
#define Platform_getFileInformationByHandle(h)  (INTEGER)GetFileInformationByHandle((HANDLE)h, &bhfi)
#define Platform_getFileSize(h, sizehigh)  (INTEGER)GetFileSize((HANDLE)h, (LPDWORD)sizehigh)
#define Platform_getLocalTime()  SYSTEMTIME st; GetLocalTime(&st)
#define Platform_getModuleFileName(hModule, lpFilename, lpFilename__len, nSize)  (INTEGER)GetModuleFileNameA((HMODULE)hModule, (LPTSTR)lpFilename, nSize)
#define Platform_getModuleFileNameW(hModule, lpFilename, lpFilename__len, nSize)  (INTEGER)GetModuleFileNameW((HMODULE)hModule, (LPWSTR)lpFilename, nSize)
#define Platform_getSystemDefaultLangID()  (SHORTINT)GetSystemDefaultLangID()
#define Platform_getTempPath(nBufferLengt, lpBuffer)  (INTEGER)GetTempPathA((DWORD)nBufferLengt, (LPTSTR)lpBuffer)
#define Platform_getpid()  (INTEGER)GetCurrentProcessId()
#define Platform_getstderrhandle()  (SYSTEM_ADRINT)GetStdHandle(STD_ERROR_HANDLE)
#define Platform_getstdinhandle()  (SYSTEM_ADRINT)GetStdHandle(STD_INPUT_HANDLE)
#define Platform_getstdouthandle()  (SYSTEM_ADRINT)GetStdHandle(STD_OUTPUT_HANDLE)
#define Platform_identityToFileTime(i)  FILETIME ft; ft.dwHighDateTime = i.mtimehigh; ft.dwLowDateTime = i.mtimelow
#define Platform_moveFileEx(src, src__len, dest, dest__len)  (INTEGER)MoveFileEx((LPCTSTR)src, (LPCTSTR)dest, MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)
#define Platform_opennew(n, n__len)  (SYSTEM_ADRINT)CreateFile((char*)n, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
#define Platform_openro(n, n__len)  (SYSTEM_ADRINT)CreateFile((char*)n, GENERIC_READ              , FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
#define Platform_openrw(n, n__len)  (SYSTEM_ADRINT)CreateFile((char*)n, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
#define Platform_processInfo()  PROCESS_INFORMATION pi = {0};
#define Platform_readconsole(fd, p, l, n)  (INTEGER)ReadConsoleW ((HANDLE)fd, (void*)(p), (DWORD)l, (DWORD*)n, 0)
#define Platform_readfile(fd, p, l, n)  (INTEGER)ReadFile ((HANDLE)fd, (void*)(p), (DWORD)l, (DWORD*)n, 0)
#define Platform_seekcur()  FILE_CURRENT
#define Platform_seekend()  FILE_END
#define Platform_seekset()  FILE_BEGIN
#define Platform_setCurrentDirectory(n, n__len)  (INTEGER)SetCurrentDirectory((char*)n)
#define Platform_setEndOfFile(h)  (INTEGER)SetEndOfFile((HANDLE)h)
#define Platform_setFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod)  (INTEGER)SetFilePointer((HANDLE)hFile, (LONG)lDistanceToMove, (PLONG)lpDistanceToMoveHigh, (DWORD)dwMoveMethod)
#define Platform_sleep(ms)  Sleep((DWORD)ms)
#define Platform_startupInfo()  STARTUPINFO si = {0}; si.cb = sizeof(si);
#define Platform_sthour()  (INTEGER)st.wHour
#define Platform_stmday()  (INTEGER)st.wDay
#define Platform_stmin()  (INTEGER)st.wMinute
#define Platform_stmon()  (INTEGER)st.wMonth
#define Platform_stsec()  (INTEGER)st.wSecond
#define Platform_styear()  (INTEGER)st.wYear
#define Platform_waitForProcess()  (INTEGER)WaitForSingleObject(pi.hProcess, INFINITE)
#define Platform_writeConsoleW(hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved)  (BOOLEAN)WriteConsoleW((HANDLE)hConsoleOutput, (void *)lpBuffer, (DWORD)nNumberOfCharsToWrite, (LPDWORD)lpNumberOfCharsWritten, (LPVOID)lpReserved)
#define Platform_writeFile(fd, p, l, dummy)  (INTEGER)WriteFile((HANDLE)fd, (void*)(p), (DWORD)l, (LPDWORD)dummy, 0)

/*============================================================================*/

BOOLEAN Platform_TooManyFiles (INTEGER e)
{
  return e == Platform_ERRORTOOMANYOPENFILES();
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_NoSuchDirectory (INTEGER e)
{
  return e == Platform_ERRORPATHNOTFOUND();
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_DifferentFilesystems (INTEGER e)
{
  return e == Platform_ERRORNOTSAMEDEVICE();
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_Inaccessible (INTEGER e)
{
  return ((e == Platform_ERRORACCESSDENIED() || e == Platform_ERRORWRITEPROTECT()) || e == Platform_ERRORNOTREADY()) || e == Platform_ERRORSHARINGVIOLATION();
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_Absent (INTEGER e)
{
  return e == Platform_ERRORFILENOTFOUND() || e == Platform_ERRORPATHNOTFOUND();
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_TimedOut (INTEGER e)
{
  return e == Platform_ETIMEDOUT();
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_ConnectionFailed (INTEGER e)
{
  return ((e == Platform_ECONNREFUSED() || e == Platform_ECONNABORTED()) || e == Platform_ENETUNREACH()) || e == Platform_EHOSTUNREACH();
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_OSAllocate (INTEGER size)
{
  if (size > 0) {
    return Platform_allocate(size);
  }
  Platform_SystemHalt(-25, (CHAR*)"Platform", 9, 126);
  return 0;
}

/*----------------------------------------------------------------------------*/
void Platform_OSFree (INTEGER address)
{
  Platform_free(address);
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_IsConsole (INTEGER h)
{
  INTEGER mode;
  return Platform_getConsoleMode(h, &mode);
}

/*----------------------------------------------------------------------------*/
static BOOLEAN Platform_IsStdOutConsole (void)
{
  INTEGER mode;
  if (Platform_stdOutIsConsole < 0) {
    if (Platform_getConsoleMode(Platform_StdOut, &mode)) {
      Platform_stdOutIsConsole = 1;
    } else {
      Platform_stdOutIsConsole = 0;
    }
  }
  return Platform_stdOutIsConsole != 0;
}

void Platform_GetEnv (CHAR *var, INTEGER var__len, CHAR *val, INTEGER val__len)
{
  INTEGER res;
  res = Platform_getEnvironmentVariable(var, var__len, (void*)val, val__len);
  if (res < 0 || res > val__len) {
    val[0] = 0x00;
  }
}

/*----------------------------------------------------------------------------*/
void Platform_GetEnvW (LONGCHAR *var, INTEGER var__len, LONGCHAR *val, INTEGER val__len)
{
  INTEGER res;
  res = Platform_getEnvironmentVariableW(var, var__len, (void*)val, val__len);
  if (res < 0 || res > val__len) {
    val[0] = 0x00;
  }
}

/*----------------------------------------------------------------------------*/
void Platform_GetLang (CHAR *lang, INTEGER lang__len)
{
  SHORTINT langId, n;
  langId = Platform_getSystemDefaultLangID();
  n = (SHORTINT)__MASK((INTEGER)langId, -256);
  if ((INTEGER)n == 25) {
    __STRCOPYCC((CHAR*)"ru", lang, lang__len, (CHAR*)"Platform", 47359);
  } else if ((INTEGER)n == 34) {
    __STRCOPYCC((CHAR*)"ua", lang, lang__len, (CHAR*)"Platform", 47615);
  } else if ((INTEGER)n == 38) {
    __STRCOPYCC((CHAR*)"lv", lang, lang__len, (CHAR*)"Platform", 47871);
  } else if ((INTEGER)langId == 4096) {
    __STRCOPYCC((CHAR*)"eo", lang, lang__len, (CHAR*)"Platform", 48127);
  } else {
    __STRCOPYCC((CHAR*)"en", lang, lang__len, (CHAR*)"Platform", 48383);
  }
}

/*----------------------------------------------------------------------------*/
static void Platform_YMDHMStoClock (INTEGER ye, INTEGER mo, INTEGER da, INTEGER ho, INTEGER mi, INTEGER se, INTEGER *t, INTEGER *d)
{
  *d = (__ASHL(__MOD(ye, 100), 9, INTEGER) + __ASHL(mo + 1, 5, INTEGER)) + da;
  *t = (__ASHL(ho, 12, INTEGER) + __ASHL(mi, 6, INTEGER)) + se;
}

void Platform_GetClock (INTEGER *t, INTEGER *d)
{
  Platform_getLocalTime();
  Platform_YMDHMStoClock(Platform_styear(), Platform_stmon(), Platform_stmday(), Platform_sthour(), Platform_stmin(), Platform_stsec(), t, d);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_Time (void)
{
  return __MODF(Platform_GetTickCount(), 2147483647);
}

/*----------------------------------------------------------------------------*/
void Platform_Delay (INTEGER ms)
{
  while (ms > 30000) {
    Platform_sleep(30000);
    ms = ms - 30000;
  }
  if (ms > 0) {
    Platform_sleep(ms);
  }
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_System (CHAR *cmd, INTEGER cmd__len)
{
  INTEGER result;
  result = 127;
  Platform_startupInfo();
  Platform_processInfo();
  if (Platform_createProcess(cmd, cmd__len) != 0) {
    if (Platform_waitForProcess() == 0) {
      Platform_getExitCodeProcess(&result);
    }
    Platform_cleanupProcess();
  }
  return __ASHL(result, 8, INTEGER);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_Error (void)
{
  return Platform_err();
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_MaxNameLength (void)
{
  return Platform_MAXPATH();
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_MaxPathLength (void)
{
  return Platform_MAXPATH();
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_OldRO (CHAR *pathname, INTEGER pathname__len, INTEGER *h)
{
  INTEGER fd;
  fd = Platform_openro(pathname, pathname__len);
  if (fd == Platform_InvalidHandleValue()) {
    return Platform_err();
  } else {
    *h = fd;
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 73799);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_OldRW (CHAR *pathname, INTEGER pathname__len, INTEGER *h)
{
  INTEGER fd;
  fd = Platform_openrw(pathname, pathname__len);
  if (fd == Platform_InvalidHandleValue()) {
    return Platform_err();
  } else {
    *h = fd;
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 75591);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_NewFile (CHAR *pathname, INTEGER pathname__len, INTEGER *h)
{
  INTEGER fd;
  fd = Platform_opennew(pathname, pathname__len);
  if (fd == Platform_InvalidHandleValue()) {
    return Platform_err();
  } else {
    *h = fd;
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 77383);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_NewDir (CHAR *pathname, INTEGER pathname__len)
{
  if (Platform_createDirectory(pathname, pathname__len) == 0) {
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 78658);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_CloseFile (INTEGER h)
{
  if (Platform_closeHandle(h) == 0) {
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 80695);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_Identify (INTEGER h, Platform_FileIdentity *identity)
{
  Platform_byHandleFileInformation();
  if (Platform_getFileInformationByHandle(h) == 0) {
    return Platform_err();
  }
  (*identity).volume = Platform_bhfiVsn();
  (*identity).indexhigh = Platform_bhfiIndexHigh();
  (*identity).indexlow = Platform_bhfiIndexLow();
  (*identity).mtimehigh = Platform_bhfiMtimeHigh();
  (*identity).mtimelow = Platform_bhfiMtimeLow();
  return 0;
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_IdentifyByName (CHAR *n, INTEGER n__len, Platform_FileIdentity *identity)
{
  INTEGER h, e, i;
  e = Platform_OldRO((void*)n, n__len, &h);
  if (e != 0) {
    return e;
  }
  e = Platform_Identify(h, identity);
  i = Platform_CloseFile(h);
  return e;
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_SameFile (Platform_FileIdentity i1, Platform_FileIdentity i2)
{
  return (i1.indexhigh == i2.indexhigh && i1.indexlow == i2.indexlow) && i1.volume == i2.volume;
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_SameFileTime (Platform_FileIdentity i1, Platform_FileIdentity i2)
{
  return i1.mtimehigh == i2.mtimehigh && i1.mtimelow == i2.mtimelow;
}

/*----------------------------------------------------------------------------*/
void Platform_SetMTime (Platform_FileIdentity *target, Platform_FileIdentity source)
{
  (*target).mtimehigh = source.mtimehigh;
  (*target).mtimelow = source.mtimelow;
}

/*----------------------------------------------------------------------------*/
void Platform_MTimeAsClock (Platform_FileIdentity i, INTEGER *t, INTEGER *d)
{
  Platform_identityToFileTime(i);
  Platform_fileTimeToSysTime();
  Platform_YMDHMStoClock(Platform_styear(), Platform_stmon(), Platform_stmday(), Platform_sthour(), Platform_stmin(), Platform_stsec(), t, d);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_FileSize (INTEGER h, LONGINT *len)
{
  struct Platform__1 size;
  INTEGER error;
  size.low = Platform_getFileSize(h, &size.high);
  if (size.low == Platform_INVALIDFILESIZE()) {
    error = Platform_err();
    if (error != Platform_NOERROR()) {
      return error;
    }
  }
  *len = __VAL(LONGINT, size);
  return 0;
}

/*----------------------------------------------------------------------------*/
void Platform_GetTempPath (CHAR *path, INTEGER path__len)
{
  if (Platform_getTempPath(path__len, &path[0]) == 0) {
    __STRCOPYCC((CHAR*)"C:\\Windows\\Temp\\", path, path__len, (CHAR*)"Platform", 101704);
  }
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_Read (INTEGER h, INTEGER p, INTEGER l, INTEGER *n)
{
  INTEGER result;
  *n = 0;
  result = Platform_readfile(h, p, l, n);
  if (result == 0) {
    *n = 0;
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 105527);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_ReadBuf (INTEGER h, BYTE *b, INTEGER b__len, INTEGER *n)
{
  INTEGER result;
  *n = 0;
  result = Platform_readfile(h, (SYSTEM_ADRINT)b, b__len, n);
  if (result == 0) {
    *n = 0;
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 107575);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_ReadBufW (INTEGER h, LONGCHAR *b, INTEGER b__len, INTEGER *n)
{
  INTEGER result;
  *n = 0;
  result = Platform_readconsole(h, (SYSTEM_ADRINT)b, b__len, n);
  if (result == 0) {
    *n = 0;
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 109623);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_Write (INTEGER h, INTEGER p, INTEGER l)
{
  INTEGER dummy;
  if (Platform_writeFile(h, p, l, &dummy) == 0) {
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 113474);
}

/*----------------------------------------------------------------------------*/
static void Platform_ConvertFromUTF16 (LONGCHAR *in, INTEGER in__len, INTEGER inLen, CHAR *out, INTEGER out__len, INTEGER *outLen)
{
  INTEGER i, j, val, lim;
  BOOLEAN ok;
  i = 0;
  j = 0;
  lim = out__len - 1;
  ok = 1;
  if (inLen < 0) {
    inLen = in__len;
  }
  while (((ok && i != inLen) && in[i] != 0x00) && j < lim) {
    val = (INTEGER)in[i];
    i += 1;
    if (val < 128) {
      out[j] = (CHAR)val;
      j += 1;
    } else if (val < 2048 && j < lim - 1) {
      out[j] = (CHAR)(__ASHR(val, 6, INTEGER) + 192);
      j += 1;
      out[j] = (CHAR)(__MASK(val, -64) + 128);
      j += 1;
    } else if (j < lim - 2) {
      out[j] = (CHAR)(__ASHR(val, 12, INTEGER) + 224);
      j += 1;
      out[j] = (CHAR)(__MASK(__ASHR(val, 6, INTEGER), -64) + 128);
      j += 1;
      out[j] = (CHAR)(__MASK(val, -64) + 128);
      j += 1;
    } else {
      ok = 0;
    }
  }
  out[j] = 0x00;
  *outLen = j;
  if (i != inLen && in[i] != 0x00) {
    ok = 0;
  }
}

INTEGER Platform_WriteW (LONGCHAR *s, INTEGER s__len, INTEGER len)
{
  INTEGER dummy, error;
  CHAR u[40960];
  INTEGER ulen, written;
  if (Platform_IsStdOutConsole() && Platform_writeConsoleW(Platform_StdOut, (SYSTEM_ADRINT)&s[0], len, &written, 0)) {
    error = 0;
  } else {
    Platform_ConvertFromUTF16((void*)s, s__len, len, (void*)u, 40960, &ulen);
    if (Platform_writeFile(Platform_StdOut, (SYSTEM_ADRINT)u, ulen, &dummy) == 0) {
      error = Platform_err();
    } else {
      error = 0;
    }
  }
  return error;
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_Sync (INTEGER h)
{
  if (Platform_flushFileBuffers(h) == 0) {
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 125756);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_Seek (INTEGER h, LONGINT offset, INTEGER r)
{
  Platform_LARGE_INTEGER pos;
  INTEGER error;
  pos = __VAL(Platform_LARGE_INTEGER, offset);
  if (Platform_setFilePointer(h, pos.low, &pos.high, r) == Platform_INVALIDSETFILEPOINTER()) {
    error = Platform_err();
    if (error != Platform_NOERROR()) {
      return error;
    }
  }
  return 0;
}

/*----------------------------------------------------------------------------*/
static INTEGER Platform_GetFilePos (INTEGER h, LONGINT *r)
{
  Platform_LARGE_INTEGER pos;
  INTEGER error;
  pos.high = 0;
  pos.low = Platform_setFilePointer(h, 0, &pos.high, Platform_seekcur());
  if (pos.low == Platform_INVALIDSETFILEPOINTER()) {
    error = Platform_err();
    if (error != Platform_NOERROR()) {
      return error;
    }
  }
  *r = __VAL(LONGINT, pos);
  return 0;
}

INTEGER Platform_TruncateFile (INTEGER h, LONGINT limit)
{
  Platform_LARGE_INTEGER pos;
  LONGINT oldpos;
  INTEGER error;
  error = Platform_GetFilePos(h, &oldpos);
  if (error != 0) {
    return error;
  }
  pos = __VAL(Platform_LARGE_INTEGER, limit);
  if (Platform_setFilePointer(h, pos.low, &pos.high, Platform_seekset()) == Platform_INVALIDSETFILEPOINTER()) {
    error = Platform_err();
    if (error != Platform_NOERROR()) {
      return error;
    }
  }
  if (Platform_setEndOfFile(h) == 0) {
    return Platform_err();
  }
  pos = __VAL(Platform_LARGE_INTEGER, oldpos);
  if (Platform_setFilePointer(h, pos.low, &pos.high, Platform_seekset()) == Platform_INVALIDSETFILEPOINTER()) {
    error = Platform_err();
    if (error != Platform_NOERROR()) {
      return error;
    }
  }
  return 0;
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_DeleteFile (CHAR *n, INTEGER n__len)
{
  if (Platform_deleteFile(n, n__len) == 0) {
    return Platform_err();
  } else {
    return 0;
  }
  __RETCHK((CHAR*)"Platform", 141110);
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_ChDir (CHAR *n, INTEGER n__len)
{
  INTEGER r;
  r = Platform_setCurrentDirectory(n, n__len);
  if (r == 0) {
    return Platform_err();
  }
  Platform_getCurrentDirectory((void*)Platform_CWD, 260);
  return 0;
}

/*----------------------------------------------------------------------------*/
void Platform_GetAppDir (CHAR *dir, INTEGER dir__len)
{
  INTEGER i;
  dir[dir__len - 1] = 0x00;
  i = Platform_getModuleFileName(0, dir, dir__len, dir__len - 1);
  if (i < dir__len) {
    while (i > 0 && dir[i] != '\\') {
      i -= 1;
    }
    if (i > 0) {
      dir[i + 1] = 0x00;
    }
  }
}

/*----------------------------------------------------------------------------*/
void Platform_GetAppDirW (LONGCHAR *dir, INTEGER dir__len)
{
  INTEGER i;
  dir[dir__len - 1] = 0x00;
  i = Platform_getModuleFileNameW(0, dir, dir__len, dir__len - 1);
  if (i < dir__len) {
    while (i > 0 && dir[i] != '\\') {
      i -= 1;
    }
    if (i > 0) {
      dir[i + 1] = 0x00;
    }
  }
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_FileExists (CHAR *name, INTEGER name__len)
{
  INTEGER dwAttrib;
  dwAttrib = Platform_getFileAttributes(name, name__len);
  return dwAttrib != Platform_INVALIDFILEATTRIBUTES() && ((SET)dwAttrib & Platform_FILEATTRIBUTEDIRECTORY()) == 0x0;
}

/*----------------------------------------------------------------------------*/
BOOLEAN Platform_DirExists (CHAR *name, INTEGER name__len)
{
  INTEGER dwAttrib;
  dwAttrib = Platform_getFileAttributes(name, name__len);
  return dwAttrib != Platform_INVALIDFILEATTRIBUTES() && ((SET)dwAttrib & Platform_FILEATTRIBUTEDIRECTORY()) != 0x0;
}

/*----------------------------------------------------------------------------*/
INTEGER Platform_RenameFile (CHAR *src, INTEGER src__len, CHAR *dest, INTEGER dest__len)
{
  Platform_FileIdentity src_id, dest_id;
  INTEGER error;
  if (Platform_moveFileEx(src, src__len, dest, dest__len) != 0) {
    return 0;
  }
  error = Platform_err();
  if (error != Platform_ERRORCALLNOTIMPLEMENTED() && error != Platform_ERRORNOTSAMEDEVICE()) {
    return error;
  }
  if (Platform_FileExists((void*)dest, dest__len) && (((Platform_FileExists((void*)src, src__len) && Platform_IdentifyByName((void*)src, src__len, &src_id) == 0) && Platform_IdentifyByName((void*)dest, dest__len, &dest_id) == 0) && Platform_SameFile(src_id, dest_id))) {
    return 0;
  }
  if (Platform_copyFile(src, src__len, dest, dest__len) == 0) {
    return Platform_err();
  }
  return Platform_DeleteFile((void*)src, src__len);
}

/*----------------------------------------------------------------------------*/
void Platform_ExitOS (INTEGER code)
{
  Platform_exit(code);
}

/*----------------------------------------------------------------------------*/
static void Platform_TestLittleEndian (void)
{
  INTEGER i;
  i = 1;
  __GET((SYSTEM_ADRINT)&i, Platform_LittleEndian, BOOLEAN);
}


export void *Platform__init (void)
{
  __DEFMOD;
  __REGMOD("Platform", 0);
/* BEGIN */
  Platform_TestLittleEndian();
  Platform_CWD[0] = 0x00;
  Platform_getCurrentDirectory((void*)Platform_CWD, 260);
  Platform_PID = Platform_getpid();
  Platform_SeekSet = Platform_seekset();
  Platform_SeekCur = Platform_seekcur();
  Platform_SeekEnd = Platform_seekend();
  Platform_StdIn = Platform_getstdinhandle();
  Platform_StdOut = Platform_getstdouthandle();
  Platform_StdErr = Platform_getstderrhandle();
  Platform_stdOutIsConsole = -1;
  __ENDMOD;
}
