};
static struct EARHeader
-{
+{
byte recognition[sizeof(earRecognition)] __attribute__((packed));
uint version  __attribute__((packed));
FileSize totalSize  __attribute__((packed));
for(;;)
{
char fileName[MAX_FILENAME];
-
+
f.Read(entry, sizeof(EAREntry), 1);
f.Read(fileName, 1, entry.nameLen);
fileName[entry.nameLen] = '\0';
// Fix the size of the archive
FileTruncate(path, archiveStart);
}*/
-
+
freeBlocks.Free(null);
}
rootDir = Position(2*sizeof(uint));
dir.position = rootDir;
}
-
+
result = dir;
// Open rest of directory...
if(f.Seek(dirPosition + sizeof(uint), start))
f.Write(&last, sizeof(uint), 1);
}
-
+
for(; position; position = next)
{
EAREntry entry { };
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)
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;
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);
strcpy(namePart, DIR_SEPS);
// Search for directory
-
+
position = archive.Find(this, namePart, entry);
if(position)
{
archive.f.Read(&dir.first, sizeof(uint), 1);
archive.f.Read(&dir.last, sizeof(uint), 1);
-
+
result = dir;
- }
+ }
}
// If directory doesn't exist already
strcpy(namePart, name);
if(!strcmp(namePart, "/") || !strcmp(namePart, "\\"))
strcpy(namePart, DIR_SEPS);
-
+
position = archive.Find(this, namePart, entry);
if(position)
{
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);
dataSize = 2 * sizeof(uint);
else
dataSize = entry.cSize ? entry.cSize : entry.size;
-
+
newEntry.nameLen = strlen(newName);
if(newEntry.nameLen > entry.nameLen)
{
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);
// 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)
{
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
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
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];
{
if(newPosition) *newPosition = 0;
}
-
+
// archive.f.handle = archive.f;
return true;
}
bool result = false;
switch(mode)
{
- case start:
+ case start:
if(pos <= (int)size)
{
position = pos;
}
break;
}
- return result;
+ return result;
}
uint Tell()
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;
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 });