ide,ecere: <wip> fix ear support for emscripten.
[sdk] / ecere / src / sys / EARArchive.ec
index d6630fe..9e28be7 100644 (file)
@@ -7,7 +7,7 @@ namespace sys;
 import "System"
 import "BufferedFile"
 
-#define OFFSET(s, m) ((uint) (&((s *) 0)->m))
+#define OFFSET(s, m) ((uint)(uintptr) (&((s *) 0)->m))
 #define MDWORD(a,b) ((((uint32)((uint16)(b)))<<16)+((uint16)(a)))
 
 #define EAR_RECOGNITION { 'e', 'A', 'R', 228, 11, 12, 3, 0 }
@@ -21,10 +21,10 @@ static class FreeBlock : struct
 };
 
 static struct EARHeader
-{                                               
-   byte recognition[sizeof(earRecognition)] __attribute__((packed));
-   uint version                            __attribute__((packed));
-   FileSize totalSize                      __attribute__((packed));
+{
+   byte recognition[sizeof(earRecognition)];
+   uint version                             __attribute__((packed));
+   FileSize totalSize                       __attribute__((packed));
 };
 
 static enum EAREntryType { ENTRY_FILE = 1, ENTRY_FOLDER = 2 };
@@ -39,20 +39,25 @@ static struct EAREntry
    // null terminated file name follows
 };
 
-static File EAROpenArchive(char * archive, EARHeader header)
+static File EAROpenArchive(const char * archive, EARHeader header)
 {
    File f = null;
    if(archive[0] == ':')
    {
       char moduleName[MAX_LOCATION];
-      char * name = archive + 1;
-#if defined(__ANDROID__)
+      const char * name = archive + 1;
+#if defined(__ANDROID__) || defined(__EMSCRIPTEN__)
       if(!name[0])
          name = ((SubModule)__thisModule.application.modules.first).next.module.name;
 #endif
-
+#if defined(__EMSCRIPTEN__)
+      //sprintf(moduleName, "__%s.ear", name);
+      sprintf(moduleName, "__%s.ear", "HelloForm");
+      f = FileOpen(moduleName, read);
+#else
       if(LocateModule(name, moduleName))
          f = FileOpen(moduleName, read);
+#endif
    }
    else
       f = FileOpen(archive, read);
@@ -62,7 +67,7 @@ static File EAROpenArchive(char * archive, EARHeader header)
 
       // First attempt to treat this as an archive file
       if(f.Read(header, sizeof(EARHeader), 1) == 1 &&
-         !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
+         !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
          return f;
 
       // Then try to see if an archive is at the end of the file
@@ -70,7 +75,7 @@ static File EAROpenArchive(char * archive, EARHeader header)
       f.Read(&archiveSize, sizeof(uint), 1);
       f.Seek(-(int)archiveSize, end);
       if(f.Read(header, sizeof(EARHeader), 1) == 1 &&
-         !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
+         !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
          return f;
 
       delete f;
@@ -78,7 +83,7 @@ static File EAROpenArchive(char * archive, EARHeader header)
    return null;
 }
 
-static FileAttribs EARGetEntry(File f, EAREntry entry, char * name, char * path)
+static FileAttribs EARGetEntry(File f, EAREntry entry, const char * name, char * path)
 {
    uint first = 0, last = 0;
    if(!name[0])
@@ -98,7 +103,7 @@ static FileAttribs EARGetEntry(File f, EAREntry entry, char * name, char * path)
       for(;;)
       {
          char fileName[MAX_FILENAME];
-         
+
          f.Read(entry, sizeof(EAREntry), 1);
          f.Read(fileName, 1, entry.nameLen);
          fileName[entry.nameLen] = '\0';
@@ -159,6 +164,7 @@ class EARArchive : Archive
 
          return end;
       }
+      return 0;
    }
 
    ~EARArchive()
@@ -181,7 +187,7 @@ class EARArchive : Archive
          // Fix the size of the archive
          FileTruncate(path, archiveStart);
       }*/
-      
+
       freeBlocks.Free(null);
    }
 
@@ -191,14 +197,13 @@ class EARArchive : Archive
       return true;
    }
 
-   ArchiveDir OpenDirectory(char * name, FileStats stats, ArchiveAddMode addMode)
+   ArchiveDir OpenDirectory(const char * name, FileStats stats, ArchiveAddMode addMode)
    {
       ArchiveDir result = null;
       EARArchiveDir dir { readOnly = addMode == readOnlyDir };
       if(dir)
       {
          char namePart[MAX_LOCATION] = "", nameRest[MAX_LOCATION];
-         uint position;
 
          dir.archive = this;
 
@@ -229,7 +234,7 @@ class EARArchive : Archive
             rootDir = Position(2*sizeof(uint));
             dir.position = rootDir;
          }
-         
+
          result = dir;
 
          // Open rest of directory...
@@ -303,7 +308,7 @@ class EARArchive : Archive
          if(f.Seek(dirPosition + sizeof(uint), start))
             f.Write(&last, sizeof(uint), 1);
       }
-      
+
       for(; position; position = next)
       {
          EAREntry entry { };
@@ -327,7 +332,7 @@ class EARArchive : Archive
                Defrag(position + sizeof(EAREntry) + entry.nameLen);
          }
          else
-            return 0;
+            return;
       }
 
       // Move all the blocks
@@ -370,13 +375,13 @@ class EARArchive : Archive
       }
    }
 
-   uint Find(EARArchiveDir directory, char * namePart, EAREntry entry)
+   uint Find(EARArchiveDir directory, const char * namePart, EAREntry entry)
    {
       uint position;
       for(position = directory.first; position; position = entry.next)
       {
          char fileName[MAX_FILENAME];
-      
+
          if(f.Seek(position, start) && f.Read(entry, sizeof(EAREntry), 1))
          {
             if(entry.nameLen > MAX_FILENAME)
@@ -399,12 +404,12 @@ class EARArchive : Archive
    void AddFreeBlock(uint position, uint size)
    {
       FreeBlock block, prevBlock, nextBlock = null;
-      
+
       // Find the previous and next free block
       prevBlock = null;
       for(block = freeBlocks.first; block; block = block.next)
          if(block.end < position)
-            prevBlock = block; 
+            prevBlock = block;
          else
          {
             nextBlock = block;
@@ -493,12 +498,12 @@ class EARArchive : Archive
          size = sizeof(EAREntry) + entry.nameLen + (entry.cSize ? entry.cSize : entry.size);
 
       // Unlink this file
-      if(entry.prev) 
+      if(entry.prev)
       {
          f.Seek(entry.prev + OFFSET(EAREntry, next), start);
          f.Write(&entry.next, sizeof(uint), 1);
       }
-      if(entry.next) 
+      if(entry.next)
       {
          f.Seek(entry.next + OFFSET(EAREntry, prev), start);
          f.Write(&entry.prev, sizeof(uint), 1);
@@ -513,13 +518,12 @@ class EARArchive : Archive
       // bf.handle = f;
    }
 
-   File FileOpen(char * name)
+   File FileOpen(const char * name)
    {
       File result = null;
       EARFile file {};
       if(file)
       {
-         char fileName[MAX_LOCATION];
          EAREntry entry { };
 
          f.Seek(archiveStart + sizeof(EARHeader), start);
@@ -534,7 +538,11 @@ class EARArchive : Archive
                   if(compressed)
                   {
                      if(f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                        uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+                     {
+                        unsigned long destLen = entry.size;
+                        uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                        entry.size = (FileSize)destLen;  // TODO: Support 64 bit file sizes
+                     }
                      delete compressed;
                   }
 
@@ -581,7 +589,11 @@ class EARArchive : Archive
             if(compressed)
             {
                if(f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                  uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+               {
+                  unsigned long destLen = entry.size;
+                  uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                  entry.size = (FileSize)destLen;
+               }
                delete compressed;
             }
 
@@ -602,7 +614,7 @@ class EARArchive : Archive
       return file;
    }
 
-   FileAttribs FileExists(char * fileName)
+   FileAttribs FileExists(const char * fileName)
    {
       FileAttribs result;
       EAREntry entry { };
@@ -615,7 +627,7 @@ class EARArchive : Archive
    {
       uint first, last;
       if(!f.Read(&first, sizeof(uint), 1))
-         return 0;
+         return;
 #ifdef _DEBUG
       if(first > f.GetSize())
       {
@@ -691,13 +703,12 @@ class EARArchiveDir : ArchiveDir
       }
    }
 
-   File FileOpen(char * name)
+   File FileOpen(const char * name)
    {
       File result = null;
       EARFile file {};
       if(file)
       {
-         char fileName[MAX_LOCATION];
          EAREntry entry { };
 
          archive.f.Seek(position, start);
@@ -712,7 +723,11 @@ class EARArchiveDir : ArchiveDir
                   if(compressed)
                   {
                      if(archive.f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                        uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+                     {
+                        unsigned long destLen = entry.size;
+                        uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                        entry.size = (FileSize)destLen;
+                     }
                      delete compressed;
                   }
 
@@ -740,7 +755,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   FileAttribs FileExists(char * fileName)
+   FileAttribs FileExists(const char * fileName)
    {
       FileAttribs result;
       EAREntry entry { };
@@ -749,7 +764,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   ArchiveDir OpenDirectory(char * name, FileStats stats, ArchiveAddMode addMode)
+   ArchiveDir OpenDirectory(const char * name, FileStats stats, ArchiveAddMode addMode)
    {
       ArchiveDir result = null;
       EARArchiveDir dir { readOnly = addMode == readOnlyDir };
@@ -767,7 +782,7 @@ class EARArchiveDir : ArchiveDir
             strcpy(namePart, DIR_SEPS);
 
          // Search for directory
-         
+
          position = archive.Find(this, namePart, entry);
          if(position)
          {
@@ -782,9 +797,9 @@ class EARArchiveDir : ArchiveDir
 
                archive.f.Read(&dir.first, sizeof(uint), 1);
                archive.f.Read(&dir.last, sizeof(uint), 1);
-               
+
                result = dir;
-            }               
+            }
          }
 
          // If directory doesn't exist already
@@ -842,7 +857,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   bool Delete(char * name)
+   bool Delete(const char * name)
    {
       EAREntry entry { };
       uint position;
@@ -851,7 +866,7 @@ class EARArchiveDir : ArchiveDir
       strcpy(namePart, name);
       if(!strcmp(namePart, "/") || !strcmp(namePart, "\\"))
          strcpy(namePart, DIR_SEPS);
-  
+
       position = archive.Find(this, namePart, entry);
       if(position)
       {
@@ -861,7 +876,7 @@ class EARArchiveDir : ArchiveDir
       return false;
    }
 
-   bool Move(char * name, EARArchiveDir to)
+   bool Move(const char * name, EARArchiveDir to)
    {
       bool result = false;
       if(position != to.position)
@@ -883,7 +898,7 @@ class EARArchiveDir : ArchiveDir
                archive.f.Seek(entry.prev + OFFSET(EAREntry, next), start);
                archive.f.Write(&entry.next, sizeof(uint), 1);
             }
-            if(entry.next) 
+            if(entry.next)
             {
                archive.f.Seek(entry.next + OFFSET(EAREntry, prev), start);
                archive.f.Write(&entry.prev, sizeof(uint), 1);
@@ -914,7 +929,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   bool Rename(char * name, char * newName)
+   bool Rename(const char * name, const char * newName)
    {
       bool result = false;
       EAREntry entry { };
@@ -936,7 +951,7 @@ class EARArchiveDir : ArchiveDir
             dataSize = 2 * sizeof(uint);
          else
             dataSize = entry.cSize ? entry.cSize : entry.size;
-      
+
          newEntry.nameLen = strlen(newName);
          if(newEntry.nameLen > entry.nameLen)
          {
@@ -948,12 +963,12 @@ class EARArchiveDir : ArchiveDir
             archive.f.Write(newName, sizeof(char), newEntry.nameLen);
 
             // Fix the links
-            if(entry.prev) 
+            if(entry.prev)
             {
                archive.f.Seek(entry.prev + OFFSET(EAREntry, next), start);
                archive.f.Write(&newPosition, sizeof(uint), 1);
             }
-            if(entry.next) 
+            if(entry.next)
             {
                archive.f.Seek(entry.next + OFFSET(EAREntry, prev), start);
                archive.f.Write(&newPosition, sizeof(uint), 1);
@@ -971,7 +986,7 @@ class EARArchiveDir : ArchiveDir
 
             // There will be free space at the end of an entry with a shorter new name
             if(newEntry.nameLen < entry.nameLen)
-               archive.AddFreeBlock(position + sizeof(EAREntry) + newEntry.nameLen + dataSize, entry.nameLen - newEntry.nameLen);            
+               archive.AddFreeBlock(position + sizeof(EAREntry) + newEntry.nameLen + dataSize, entry.nameLen - newEntry.nameLen);
          }
          if(entry.nameLen != newEntry.nameLen)
          {
@@ -1019,7 +1034,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   bool AddFromFile(char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
+   bool AddFromFile(const char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
    {
       // Search for identical entry
       EAREntry oldEntry;
@@ -1027,7 +1042,7 @@ class EARArchiveDir : ArchiveDir
       return _AddFromFileAtPosition(oldEntry, oldPosition, name, input, stats, addMode, compression, ratio, newPosition);
    }
 
-   bool AddFromFileAtPosition(uint oldPosition, char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
+   bool AddFromFileAtPosition(uint oldPosition, const char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
    {
       EAREntry oldEntry;
       if(oldPosition)
@@ -1038,9 +1053,8 @@ class EARArchiveDir : ArchiveDir
       return _AddFromFileAtPosition(oldEntry, oldPosition, name, input, stats, addMode, compression, ratio, newPosition);
    }
 
-   bool _AddFromFileAtPosition(EAREntry oldEntry, uint oldPosition, char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
+   bool _AddFromFileAtPosition(EAREntry oldEntry, uint oldPosition, const char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
    {
-      bool result = false;
       bool skip = false;
       FileStats oldStats { };
 
@@ -1064,9 +1078,9 @@ class EARArchiveDir : ArchiveDir
             break;
          // Only updates changed files
          case refresh:
-            if(oldPosition && 
-                 (oldEntry.size != stats.size || 
-                  oldEntry.modified != (TimeStamp32)stats.modified || 
+            if(oldPosition &&
+                 (oldEntry.size != stats.size ||
+                  oldEntry.modified != (TimeStamp32)stats.modified ||
                   oldEntry.created != (TimeStamp32)stats.created))
                   archive.Delete(this, oldPosition, oldEntry);
             else
@@ -1076,8 +1090,8 @@ class EARArchiveDir : ArchiveDir
          case update:
             if(oldPosition)
             {
-               if(oldEntry.size != stats.size || 
-                  oldEntry.modified != (TimeStamp32)stats.modified || 
+               if(oldEntry.size != stats.size ||
+                  oldEntry.modified != (TimeStamp32)stats.modified ||
                   oldEntry.created != (TimeStamp32)stats.created)
                   archive.Delete(this, oldPosition, oldEntry);
                else
@@ -1097,11 +1111,11 @@ class EARArchiveDir : ArchiveDir
          entry.prev = last;
          entry.next = 0;
          entry.type = ENTRY_FILE;
-         
+
          entry.size = stats.size;
          entry.created = (TimeStamp32)stats.created;
          entry.modified = (TimeStamp32)stats.modified;
-      
+
          if(compression)
          {
             byte * uncompressed = new byte[entry.size];
@@ -1109,11 +1123,14 @@ class EARArchiveDir : ArchiveDir
             {
                if(input.Read(uncompressed, 1, entry.size) == entry.size)
                {
-                  entry.cSize = entry.size + entry.size / 1000 + 12;
+                  unsigned long destLen = entry.size + entry.size / 1000 + 12;
 
-                  compressed = new byte[entry.cSize];
+                  compressed = new byte[destLen];
                   if(compressed)
-                     compress2(compressed, (uint *)&entry.cSize, uncompressed, entry.size, compression);
+                  {
+                     compress2(compressed, &destLen, uncompressed, entry.size, compression);
+                     entry.cSize = (FileSize)destLen;
+                  }
                }
                delete uncompressed;
             }
@@ -1176,18 +1193,18 @@ class EARArchiveDir : ArchiveDir
 
          last = position;
          if(!first) first = position;
-         if(newPosition) *newPosition = (bool)position;
+         if(newPosition) *newPosition = position;
       }
       else
       {
          if(newPosition) *newPosition = 0;
       }
-               
+
       // archive.f.handle = archive.f;
       return true;
    }
 };
-#endif
+#endif // !defined(ECERE_NOARCHIVE) && !defined(ECERE_VANILLA)
 
 // Directory Description for file listing
 class EARDir : struct
@@ -1241,7 +1258,7 @@ class EARFile : File
       return read;
    }
 
-   int Write(byte * buffer, uint size, uint count)
+   int Write(const byte * buffer, uint size, uint count)
    {
       return 0;
    }
@@ -1271,7 +1288,7 @@ class EARFile : File
       return false;
    }
 
-   bool Puts(char * string)
+   bool Puts(const char * string)
    {
       return false;
    }
@@ -1281,7 +1298,7 @@ class EARFile : File
       bool result = false;
       switch(mode)
       {
-         case start:   
+         case start:
             if(pos <= (int)size)
             {
                position = pos;
@@ -1312,7 +1329,7 @@ class EARFile : File
             }
             break;
       }
-      return result;   
+      return result;
    }
 
    uint Tell()
@@ -1325,7 +1342,7 @@ class EARFile : File
       return position >= size || (f && f.Eof());
    }
 
-   bool GetSize()
+   uint GetSize()
    {
       return size;
    }
@@ -1333,7 +1350,7 @@ class EARFile : File
 
 class EARFileSystem : FileSystem
 {
-   File ::Open(char * archive, char * name, FileOpenMode mode)
+   File ::Open(const char * archive, const char * name, FileOpenMode mode)
    {
       File result = null;
       if(mode == read)
@@ -1370,7 +1387,11 @@ class EARFileSystem : FileSystem
                         if(compressed)
                         {
                            if(f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                              uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+                           {
+                              unsigned long destLen = entry.size;
+                              uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                              entry.size = (FileSize)destLen;
+                           }
                            delete compressed;
                         }
 
@@ -1401,7 +1422,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   FileAttribs ::Exists(char * archive, char * fileName)
+   FileAttribs ::Exists(const char * archive, const char * fileName)
    {
       uint result = 0;
       EARHeader header;
@@ -1415,7 +1436,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   bool ::GetSize(char * archive, char * fileName, FileSize * size)
+   bool ::GetSize(const char * archive, const char * fileName, FileSize * size)
    {
       bool result = false;
       EARHeader header;
@@ -1431,7 +1452,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   bool ::Stats(char * archive, char * fileName, FileStats stats)
+   bool ::Stats(const char * archive, const char * fileName, FileStats stats)
    {
       bool result = false;
       EARHeader header;
@@ -1452,7 +1473,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   void ::FixCase(char * archive, char * name)
+   void ::FixCase(const char * archive, char * name)
    {
    #ifdef __WIN32__
       EARHeader header;
@@ -1468,7 +1489,7 @@ class EARFileSystem : FileSystem
    #endif
    }
 
-   bool ::Find(FileDesc file, char * archive, char * name)
+   bool ::Find(FileDesc file, const char * archive, const char * name)
    {
       bool result = false;
       EARDir d {};
@@ -1499,7 +1520,7 @@ class EARFileSystem : FileSystem
                   file.stats.accessed = file.stats.modified = (TimeStamp)entry.modified;
                   file.stats.created = (TimeStamp)entry.created;
                   file.stats.size = entry.size;
-                  
+
                   strcpy(file.path, d.path);
                   PathCat(file.path, file.name);
                   d.next = entry.next;
@@ -1553,7 +1574,7 @@ class EARFileSystem : FileSystem
    }
 
 #if !defined(ECERE_NOARCHIVE) && !defined(ECERE_VANILLA)
-   Archive ::OpenArchive(char * fileName, ArchiveOpenFlags flags)
+   Archive ::OpenArchive(const char * fileName, ArchiveOpenFlags flags)
    {
       Archive result = null;
       EARArchive archive { writeAccess = flags.writeAccess };
@@ -1574,7 +1595,7 @@ class EARFileSystem : FileSystem
 
                archive.archiveStart = archive.f.Tell();
                if(archive.f.Read(&header, sizeof(EARHeader), 1) == 1 &&
-                  !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
+                  !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
                   opened = true;
 
                if(!opened)
@@ -1583,7 +1604,7 @@ class EARFileSystem : FileSystem
                   archive.archiveStart = archive.f.Tell();
                   archiveSize = archive.f.GetSize();
                   if(archive.f.Read(&header, sizeof(EARHeader), 1) == 1 &&
-                     !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
+                     !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
                      opened = true;
                }
 
@@ -1641,9 +1662,9 @@ class EARFileSystem : FileSystem
                   EAR_RECOGNITION,
                   MDWORD(0, 1)
                };
-                    
+
                archive.f.Seek(0, end);
-         
+
                archive.archiveStart = archive.f.Tell();
                archive.freeBlocks.Add(FreeBlock { start = archive.archiveStart + sizeof(EARHeader), end = MAXDWORD });
 
@@ -1674,8 +1695,8 @@ class EARFileSystem : FileSystem
       }
       return result;
    }
-#endif
-   bool ::QuerySize(char * archive, FileSize * size)
+#endif // !defined(ECERE_NOARCHIVE) && !defined(ECERE_VANILLA)
+   bool ::QuerySize(const char * archive, FileSize * size)
    {
       bool result = false;
       EARHeader header;