cleaned all trailing white space from source files.
[sdk] / ecere / src / sys / File.ec
index caa0fe8..e652211 100644 (file)
@@ -1,8 +1,11 @@
 namespace sys;
 
 default:
+#define set _set
 #define uint _uint
 #define File _File
+#define strlen _strlen
+#undef __BLOCKS__
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -38,14 +41,16 @@ default:
 
 #if defined(__WIN32__)
 #define WIN32_LEAN_AND_MEAN
+#define String String_
 #include <windows.h>
+#undef String
 #include <io.h>
 
 BOOL WINAPI GetVolumePathName(LPCTSTR lpszFileName,LPTSTR lpszVolumePathName,DWORD cchBufferLength);
 
 // Missing function...
 /*
-#ifndef WNetGetResourceInformation 
+#ifndef WNetGetResourceInformation
 DWORD APIENTRY WNetGetResourceInformationA(LPNETRESOURCE lpNetResource, LPVOID lpBuffer, LPDWORD lpcbBuffer, LPTSTR* lplpSystem);
 #ifdef UNICODE
 #define WNetGetResourceInformation  WNetGetResourceInformationW
@@ -65,8 +70,10 @@ DWORD APIENTRY WNetGetResourceInformationA(LPNETRESOURCE lpNetResource, LPVOID l
 #endif //#ifndef ECERE_BOOTSTRAP
 private:
 
+#undef set
 #undef uint
 #undef File
+#undef strlen
 
 import "System"
 
@@ -79,6 +86,9 @@ import "dataTypes"
 // IMPLEMENTATION OF THESE IS IN _File.c
 default:
 
+FILE *eC_stdin(void);
+FILE *eC_stdout(void);
+
 uint FILE_GetSize(FILE * input);
 bool FILE_Lock(FILE * input, FILE * output, FileLock type, uint64 start, uint64 length, bool wait);
 void FILE_set_buffered(FILE * input, FILE * output, bool value);
@@ -138,6 +148,43 @@ public class FileSize : uint
    }
 };
 
+public class FileSize64 : uint64
+{
+   int OnCompare(FileSize64 data2)
+   {
+      int result = 0;
+      if(&this && &data2)
+      {
+         if(this > data2)
+            result = 1;
+         else if(this < data2)
+            result = -1;
+      }
+      return result;
+   }
+
+   char * OnGetString(char * string, void * fieldData, bool * needClass)
+   {
+      PrintBigSize(string, this, 2);
+      return string;
+   }
+
+   bool OnGetDataFromString(char * string)
+   {
+      char * end;
+      double value = strtod(string, &end);
+      uint64 multiplier = 1;
+           if(strstr(end, "PB") || strstr(end, "pb")) multiplier = (uint64)1024 * 1024 * 1024 * 1024;
+      else if(strstr(end, "TB") || strstr(end, "tb")) multiplier = (uint64)1024 * 1024 * 1024 * 1024;
+      else if(strstr(end, "GB") || strstr(end, "gb")) multiplier = (uint64)1024 * 1024 * 1024;
+      else if(strstr(end, "MB") || strstr(end, "mb")) multiplier = (uint64)1024 * 1024;
+      else if(strstr(end, "KB") || strstr(end, "kb")) multiplier = 1024;
+
+      this = (uint64)(multiplier * value);
+      return true;
+   }
+};
+
 class FileSystem
 {
    virtual File ::Open(char * archive, char * name, FileOpenMode mode);
@@ -162,7 +209,7 @@ public enum FileOpenMode { read = 1, write, append, readWrite, writeRead, append
 public enum FileSeekMode { start, current, end };
 
 #if !defined(ECERE_BOOTSTRAP)
-static FileDialog fileDialog { text = "Select File" };
+static FileDialog fileDialog { text = $"Select File" };
 #endif
 
 public enum FileLock
@@ -243,8 +290,8 @@ public class File : IOChannel
    {
       Window editData = class::OnEdit(dataBox, obsolete, x + 24, y, w - 48, h, userData);
       Button load
-      { 
-         dataBox, inactive = true, text = "Imp", hotKey = f2,
+      {
+         dataBox, inactive = true, text = $"Import"."Imp", hotKey = f2,
          position = { Max(x + 24, x + w - 24), y }, size = { 24, h };
 
          bool DataBox::NotifyClicked(Button button, int x, int y, Modifiers mods)
@@ -267,8 +314,8 @@ public class File : IOChannel
          }
       };
       Button save
-      { 
-         dataBox, inactive = true, text = "Exp", hotKey = f2,
+      {
+         dataBox, inactive = true, text = $"Export"."Exp", hotKey = f2,
          position = { Max(x + 24, x + w - 48), y }, size = { 24, h };
 
          bool DataBox::NotifyClicked(Button button, int x, int y, Modifiers mods)
@@ -288,10 +335,10 @@ public class File : IOChannel
                   {
                      byte buffer[4096];
                      uint read = input.Read(buffer, 1, sizeof(buffer));
-                     f.Write(buffer, 1, read);                     
+                     f.Write(buffer, 1, read);
                   }
                   delete f;
-               }               
+               }
             }
             return true;
          }
@@ -423,7 +470,7 @@ public:
 
    virtual uint Tell(void)
    {
-      return input ? ftell(input) : ftell(output);
+      return (uint)(input ? ftell(input) : ftell(output));
    }
 
    virtual int Read(void * buffer, uint size, uint count)
@@ -471,7 +518,7 @@ public:
    {
       return input ? feof(input) : true;
    }
-   
+
    virtual bool Truncate(FileSize size)
    {
    #ifdef ECERE_BOOTSTRAP
@@ -482,7 +529,7 @@ public:
       return output ? (_chsize(fileno(output), size) == 0) : false;
    #else
       return output ? (ftruncate(fileno(output), size) == 0) : false;
-   #endif   
+   #endif
    #endif
    }
 
@@ -490,7 +537,7 @@ public:
    {
       return FILE_GetSize(input);
    }
-   
+
    virtual void CloseInput(void)
    {
       if(input)
@@ -527,13 +574,17 @@ public:
    int Printf(char * format, ...)
    {
       int result = 0;
-      char text[MAX_F_STRING];
-      va_list args;
-      va_start(args, format);
-      vsprintf(text, format, args);
-      if(Puts(text))
-         result = strlen(text);
-      va_end(args);
+      if(format)
+      {
+         char text[MAX_F_STRING];
+         va_list args;
+         va_start(args, format);
+         vsnprintf(text, sizeof(text), format, args);
+         text[sizeof(text)-1] = 0;
+         if(Puts(text))
+            result = strlen(text);
+         va_end(args);
+      }
       return result;
    }
 
@@ -579,13 +630,13 @@ public:
          while(c<max-1)
          {
             char ch = 0;
-         
+
             if(/*!Peek() || */ !Getc(&ch))
             {
                result = false;
                break;
             }
-            if(ch =='\n') 
+            if(ch =='\n')
                break;
             if(ch !='\r')
                s[c++]=ch;
@@ -629,11 +680,11 @@ public:
             else
                string[c]=ch;
 
-            if(!Getc(&ch)) 
+            if(!Getc(&ch))
             {
                c++;
                result = false;
-               break;            
+               break;
             }
          }
          string[c]=0;
@@ -652,7 +703,7 @@ public:
    {
       char string[32];
       GetString(string, sizeof(string));
-      return strtoul(string, null, 16);
+      return (uint)strtoul(string, null, 16);
    }
 
    float GetFloat(void)
@@ -676,7 +727,7 @@ public:
       set
       {
          FILE_set_buffered(input, output, value);
-      }      
+      }
    }
    property bool eof { get { return Eof(); } }
 
@@ -723,11 +774,13 @@ public:
                break;
             }
          }
+         delete f;
       }
       Seek(0, start);
       return result;
    }
 
+#if 0
    virtual bool Open(char * fileName, FileOpenMode mode)
    {
       bool result = false;
@@ -752,13 +805,14 @@ public:
          //if(!result)
          {
             /* TOFIX:
-            LogErrorCode((mode == Read || mode == ReadWrite) ? 
+            LogErrorCode((mode == Read || mode == ReadWrite) ?
                ERR_FILE_NOT_FOUND : ERR_FILE_WRITE_FAILED, fileName);
             */
          }
       }
       return result;
    }
+#endif
 
    virtual void Close()
    {
@@ -767,10 +821,28 @@ public:
    }
 }
 
+#if defined(__WIN32__)
+default extern intptr_t stdinHandle;
+default extern intptr_t stdoutHandle;
+#endif
+
 public class ConsoleFile : File
 {
-   input = stdin;
-   output = stdout;
+   input = eC_stdin();
+   output = eC_stdout();
+
+#if defined(__WIN32__)
+   void CloseInput()
+   {
+      CloseHandle((HANDLE)stdinHandle);
+   }
+   /*
+   void CloseOutput()
+   {
+      CloseHandle((HANDLE)stdoutHandle);
+   }*/
+#endif
+
    ~ConsoleFile()
    {
       input = null;
@@ -828,7 +900,7 @@ default void TimeStampToWin32FileTime(TimeStamp t, FILETIME * fileTime)
    // TIME_ZONE_INFORMATION tz = { 0 };
    SYSTEMTIME st, lt;
    DateTime tm;
-   
+
    tm = t;
 
    st.wYear = (short)tm.year;
@@ -888,7 +960,7 @@ public File FileOpen(char * fileName, FileOpenMode mode)
          result = EARFileSystem::Open(archiveName, archiveFile, mode);
       }
 #if !defined(ECERE_VANILLA) && !defined(ECERE_NONET)
-      else if(strstr(fileName, "http://") == fileName)
+      else if(strstr(fileName, "http://") == fileName || strstr(fileName, "https://"))
       {
          result = FileOpenURL(fileName);
       }
@@ -897,7 +969,7 @@ public File FileOpen(char * fileName, FileOpenMode mode)
 #endif
       if(strstr(fileName, "File://") == fileName)
       {
-         result = (File)strtoul(fileName+7, null, 16);
+         result = (File)(uintptr)strtoull(fileName+7, null, 16);
          if(result)
          {
             if(result._class && eClass_IsDerived(result._class, class(File)))
@@ -915,10 +987,30 @@ public File FileOpen(char * fileName, FileOpenMode mode)
          File file = File {};
          if(file)
          {
-            if(file.Open(fileName, mode))
-               result = file;
+            FILE_FileOpen(fileName, mode, &file.input, &file.output);
+
+            //file.mode = mode;
+            if(!file.input && !file.output);
             else
+            {
+               openCount++;
+               result = file;
+               // TESTING ENABLING FILE BUFFERING BY DEFAULT... DOCUMENT ANY ISSUE
+               /*
+               if(file.input)
+                  setvbuf(file.input, null, _IONBF, 0);
+               else
+                  setvbuf(file.output, null, _IONBF, 0);
+               */
+            }
+            if(!result)
+            {
                delete file;
+               /* TOFIX:
+               LogErrorCode((mode == Read || mode == ReadWrite) ?
+                  ERR_FILE_NOT_FOUND : ERR_FILE_WRITE_FAILED, fileName);
+               */
+            }
          }
       }
    }
@@ -1021,7 +1113,7 @@ public bool FileSetTime(char * fileName, TimeStamp created, TimeStamp accessed,
       if(hFile != INVALID_HANDLE_VALUE)
       {
          FILETIME c, a, m;
-      
+
          TimeStampToWin32FileTime(created, &c);
          TimeStampToWin32FileTime(accessed, &a);
          TimeStampToWin32FileTime(modified, &m);
@@ -1035,7 +1127,7 @@ public bool FileSetTime(char * fileName, TimeStamp created, TimeStamp accessed,
             mm = Win32FileTimeToTimeStamp(&m);
          }
          */
-                  
+
          if(SetFileTime(hFile, &c, &a, &m))
             result = true;
 
@@ -1091,14 +1183,15 @@ static FileDesc FileFind(char * path, char * extensions)
       else
       {
          Dir d;
-      
+
          if((d = file.dir = Dir {}))
          {
 #if defined(__WIN32__)
             if(!strcmp(path, "/"))
             {
                int c;
-               d.fHandle = (void *)0xFFFFFFFF; //GetLogicalDrives();
+               uint drives = 0xFFFFFFFF;
+               d.fHandle = (HANDLE)drives; //GetLogicalDrives();
                for(c = 0; c<26; c++)
                   if(((uint)d.fHandle) & (1<<c))
                   {
@@ -1122,10 +1215,10 @@ static FileDesc FileFind(char * path, char * extensions)
                         case DRIVE_REMOTE:    file.stats.attribs.isRemote = true; break;
                         case DRIVE_CDROM:     file.stats.attribs.isCDROM = true; break;
                      }
-                     *((uint *)&d.fHandle) ^= (1<<c);
+                     drives ^= (1<<c);
                      if(driveType == DRIVE_NO_ROOT_DIR) continue;
-                  
-                     if(driveType != DRIVE_REMOVABLE && driveType != DRIVE_REMOTE && 
+
+                     if(driveType != DRIVE_REMOVABLE && driveType != DRIVE_REMOTE &&
                         GetVolumeInformation(_wfilePath, _wvolume, MAX_FILENAME - 1, null, null, null, null, 0))
                      {
                         file.path[2] = '\0';
@@ -1140,6 +1233,7 @@ static FileDesc FileFind(char * path, char * extensions)
                      result = file;
                      break;
                   }
+               d.fHandle = (HANDLE) drives;
                d.resource = 0;
             }
             else if(path[0] != '\\' || path[1] != '\\' || strstr(path+2, "\\"))
@@ -1172,6 +1266,7 @@ static FileDesc FileFind(char * path, char * extensions)
                   file.stats.attribs.isSystem    = (winFile.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)    ? true : false;
                   file.stats.attribs.isTemporary = (winFile.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) ? true : false;
                   file.stats.attribs.isDirectory = (winFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false;
+                  file.stats.attribs.isFile = !(winFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
                   strcpy(d.name, path);
 
                   file.stats.accessed = Win32FileTimeToTimeStamp(&winFile.ftLastAccessTime);
@@ -1261,7 +1356,7 @@ static FileDesc FileFind(char * path, char * extensions)
 
                      size = 512 * sizeof(NETRESOURCE);
                      resources = (NETRESOURCE *)new0 byte[size];
-                  
+
                      // Entire Network
                      WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, &buffer[c], &handle);
                      while(true)
@@ -1312,17 +1407,19 @@ static FileDesc FileFind(char * path, char * extensions)
                if(path[0])
                {
                   strcpy(file.path, path);
-                  strcat(file.path, DIR_SEPS);
+                  if(path[1])
+                     strcat(file.path, DIR_SEPS);
                }
                strcpy(file.name,de->d_name);
                strcat(file.path, file.name);
-               stat(file.path, &s);
-               file.stats.attribs = (s.st_mode&S_IFDIR) ? FileAttribs { isDirectory = true } : FileAttribs { isFile = true };
-               file.stats.size = s.st_size;
-               file.stats.accessed = s.st_atime;
-               file.stats.modified = s.st_mtime;
-               file.stats.created = s.st_ctime;
-          
+               if(!stat(file.path, &s))
+               {
+                  file.stats.attribs = (s.st_mode&S_IFDIR) ? FileAttribs { isDirectory = true } : FileAttribs { isFile = true };
+                  file.stats.size = (FileSize)s.st_size;
+                  file.stats.accessed = s.st_atime;
+                  file.stats.modified = s.st_mtime;
+                  file.stats.created = s.st_ctime;
+               }
                strcpy(d.name, path);
 
                result = file;
@@ -1407,9 +1504,10 @@ private class FileDesc : struct
             if(!strcmp(d.name, "/"))
             {
                int c;
+               uint drives = (uint)d.fHandle;
                for(c = 0; c<26; c++)
                {
-                  if(((uint)d.fHandle) & (1<<c))
+                  if(drives & (1<<c))
                   {
                      char volume[MAX_FILENAME] = "";
                      int driveType;
@@ -1424,7 +1522,7 @@ private class FileDesc : struct
                      _wpath[2] = path[2] = '\\';
                      _wpath[3] = path[3] = 0;
                      driveType = GetDriveType(_wpath);
-                     *((uint *)&d.fHandle) ^= (1<<c);
+                     drives ^= (1<<c);
 
                      switch(driveType)
                      {
@@ -1447,7 +1545,7 @@ private class FileDesc : struct
                         _wpath[3] = 0;
                      }
 
-                     if(driveType != DRIVE_REMOVABLE && driveType != DRIVE_REMOTE && 
+                     if(driveType != DRIVE_REMOVABLE && driveType != DRIVE_REMOTE &&
                         GetVolumeInformation(_wpath, _wvolume, MAX_FILENAME - 1, null, null, null, null, 0))
                      {
                         UTF16toUTF8Buffer(_wvolume, volume, MAX_FILENAME);
@@ -1463,6 +1561,7 @@ private class FileDesc : struct
                      break;
                   }
                }
+               d.fHandle = (HANDLE) drives;
                break;
             }
             else if(d.name[0] != '\\' || d.name[1] != '\\' || strstr(d.name+2, "\\"))
@@ -1478,6 +1577,7 @@ private class FileDesc : struct
                   stats.attribs.isSystem    = (winFile.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)    ? true : false;
                   stats.attribs.isTemporary = (winFile.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) ? true : false;
                   stats.attribs.isDirectory = (winFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false;
+                  stats.attribs.isFile      = !(winFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
                   stats.size = winFile.nFileSizeLow;
 
                   stats.accessed = Win32FileTimeToTimeStamp(&winFile.ftLastAccessTime);
@@ -1539,7 +1639,7 @@ private class FileDesc : struct
                               break;
                            countInGroup = 0xFFFFFFFF;
                            resources = (NETRESOURCE *)renew0 resources byte[size];
-                           
+
                         }
                         WNetCloseEnum(handle);
                         d.numResources = countInGroup;
@@ -1565,7 +1665,7 @@ private class FileDesc : struct
                      }
                      else
                      {
-                        if(d.resources) 
+                        if(d.resources)
                            delete d.resources;
                      }
                   }
@@ -1586,16 +1686,18 @@ private class FileDesc : struct
             {
                strcpy(name,de->d_name);
                strcpy(path, d.name);
-               if(d.name[0] && d.name[0])
+               if(d.name[0] && d.name[1])
                   strcat(path, DIR_SEPS);
                strcat(path, name);
-               stat(path, &s);
-               stats.attribs = FileAttribs { };
-               if(s.st_mode & S_IFDIR) stats.attribs.isDirectory = true;
-               stats.size = s.st_size;
-               stats.accessed = s.st_atime;
-               stats.modified = s.st_mtime;
-               stats.created = s.st_ctime;
+               if(!stat(path, &s))
+               {
+                  stats.attribs = FileAttribs { };
+                  stats.attribs = (s.st_mode&S_IFDIR) ? FileAttribs { isDirectory = true } : FileAttribs { isFile = true };
+                  stats.size = (FileSize)s.st_size;
+                  stats.accessed = s.st_atime;
+                  stats.modified = s.st_mtime;
+                  stats.created = s.st_ctime;
+               }
                result = this;
             }
             else
@@ -1676,7 +1778,7 @@ public File CreateTemporaryFile(char * tempFileName, char * template)
    //strcpy(buffer, template);
    strcat(buffer, "XXXXXX");
    // mktemp(buffer);
-   fd = mkstemp(buffer);   
+   fd = mkstemp(buffer);
    strcpy(tempFileName, buffer);
    f = { };
    f.output = f.input = fdopen(fd, "r+");
@@ -1685,7 +1787,7 @@ public File CreateTemporaryFile(char * tempFileName, char * template)
    GetTempPathA(MAX_LOCATION, tempPath);     // TODO: Patch this whole thing to support Unicode temp path
    GetTempFileNameA(tempPath, template, 0, tempFileName);
    f = FileOpen(tempFileName, readWrite);
-#endif   
+#endif
    return f;
 #endif
 }
@@ -1713,3 +1815,48 @@ public void CreateTemporaryDir(char * tempFileName, char * template)
 #endif
 #endif
 }
+
+public void MakeSlashPath(char * p)
+{
+   FileFixCase(p);
+#ifdef WIN32
+   ChangeCh(p, '\\', '/');
+#endif
+}
+
+public void MakeSystemPath(char * p)
+{
+   FileFixCase(p);
+}
+
+public char * CopySystemPath(char * p)
+{
+   char * d = CopyString(p);
+   if(d)
+      MakeSystemPath(d);
+   return d;
+}
+
+public char * CopyUnixPath(char * p)
+{
+   char * d = CopyString(p);
+   if(d)
+      MakeSlashPath(d);
+   return d;
+}
+
+public char * GetSystemPathBuffer(char * d, char * p)
+{
+   if(d != p)
+      strcpy(d, p ? p : "");
+   MakeSystemPath(d);
+   return d;
+}
+
+public char * GetSlashPathBuffer(char * d, char * p)
+{
+   if(d != p)
+      strcpy(d, p ? p : "");
+   MakeSlashPath(d);
+   return d;
+}