166 lines
2.5 KiB
C++
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);
|
|
}
|