luxos/exp/luxRomImageMaker/romdisk.cpp

166 lines
2.5 KiB
C++

/*
* romdisk.cpp
*
* Created on: Aug 31, 2011
* Author: Tiberiu
*/
#include <vector>
#include <string.h>
#include "app.h"
using namespace std;
RomDisk::RomDisk()
{
FlagsDefault = 0xB68;
Current = &Root;
Root.Flags = FlagsDefault;
Root.Parent = &Root;
}
int RomDisk::IndexOf(char* s)
{
for (int i = 0; i < (int)Current->Children.size(); i++)
if (strcmp(s, Current->Children[i].Name) == 0) return i;
return -1;
}
void RomDisk::SetOutFile (char* s)
{
strcpy(OutputFile, s);
}
void RomDisk::SetFlags (unsigned n)
{
FlagsDefault = n;
}
int RomDisk::ChangeCurrentDirectory (char* n)
{
int len = strlen(n);
if (!len) return -1;
// See if we need to go to root
if (n[0] == '\\')
{
Current = &Root;
n = n+1;
}
// Process every folder in path
while (char* next = strchr(n, '\\'))
{
// mark next entry to parse
*next = 0; next = next+1;
// previous dir?
if (strcmp(n, "..") == 0) Current = Current->Parent;
else {
// Find next node
int index = IndexOf(n);
if (index == -1 && strcmp(n, ".") != 0) return -1; // Invalid path
// Set as current
Current = &Current->Children[index];
}
n = next;
}
return 0;
}
void RomDisk::AddFile (char* name)
{
Node f;
strcpy(f.Name, name);
f.Flags = (FlagsDefault & 0x497) | 1; // File
f.Parent = Current;
Current->Children.push_back(f);
}
void RomDisk::AddDirectory (char* name)
{
Node dir;
strcpy(dir.Name, name);
dir.Flags = (FlagsDefault & 0x497) | 2; // Directory
dir.Parent = Current;
Current->Children.push_back(dir);
}
void RomDisk::prepareBuffer()
{
buffer = malloc(0x10000);
file = fopen(OutputFile, "w");
if (!file) {
perror(OutputFile);
return;
}
}
#define MIN(a,b) ((a > b) ? (b) : (a))
void RomDisk::writeToBuffer(void* data, unsigned size)
{
while (size)
{
unsigned qty = MIN (size, 0x10000);
memcpy(buffer, data, qty);
size -= qty;
fwrite(buffer, sizeof(unsigned char), qty, file);
}
}
long RomDisk::fileSize(char* fn)
{
FILE* f = fopen(fn, "r");
if (!f) {
fprintf(stderr, "Invalid file: %s.\n", fn);
exit (1);
}
fseek(f, 0, SEEK_END);
long size = ftell(f);
fclose(f);
return size;
}
long RomDisk::nodeSize(Node* n)
{
if (n->Flags & 1) return fileSize(n->Name);
return (n->Children.size() * (sizeof(DirectoryEntry)));
}
void RomDisk::writeNode(Node* n)
{
}
void RomDisk::Close()
{
// Init
prepareBuffer();
// Write ramdisk header (magic number)
unsigned MAGIC = 0x51042A0D;
writeToBuffer(&MAGIC, sizeof(unsigned));
// Write root directory entry
writeNode(&Root);
// Cleanup
free(buffer);
fclose(file);
}