MWCC/command_line/CmdLine/Src/CLBrowser.c

216 lines
5.3 KiB
C

#include "cmdline.h"
typedef struct {
UInt16 fileID;
char *filepath;
} S43;
typedef struct {
UInt16 fileID;
char unused[12];
UInt16 filename_length;
char filepath[1];
} S49;
typedef struct {
char magic_word[4];
char version;
char big_endian;
char padding[16];
UInt16 file_data_count;
UInt32 browse_data_offset;
UInt32 browse_data_length;
UInt32 file_data_offset;
UInt32 file_data_length;
} T53;
static void GetBrowseTableInfoAndLock(OSHandle *browsetable, S43 **scan, SInt32 *num, SInt32 *size) {
UInt32 tsize;
OS_GetHandleSize(browsetable, &tsize);
if (scan)
*scan = OS_LockHandle(browsetable);
if (num)
*num = tsize / sizeof(S43);
if (size)
*size = tsize;
}
int Browser_Initialize(OSHandle *browsetableptr) {
int err = OS_NewHandle(0, browsetableptr);
if (err) {
CLReportOSError(63, err, "allocate", "browse file table");
return 0;
} else {
return 1;
}
}
static int Destroy(OSHandle *browsetable) {
S43 *scan;
SInt32 num;
GetBrowseTableInfoAndLock(browsetable, &scan, &num, NULL);
while (num--) {
xfree(scan->filepath);
scan++;
}
OS_UnlockHandle(browsetable);
return 1;
}
int Browser_Terminate(OSHandle *browsetableptr) {
if (!Destroy(browsetableptr)) {
return 0;
} else {
OS_FreeHandle(browsetableptr);
return 1;
}
}
int Browser_SearchFile(OSHandle *browsetable, const char *fullpath, SInt16 *ID) {
S43 *scan;
SInt32 cnt;
SInt32 idx;
SInt32 size;
Boolean found = 0;
OS_ASSERT(114, OS_IsFullPath(fullpath));
OS_ASSERT(115, browsetable!=NULL);
GetBrowseTableInfoAndLock(browsetable, &scan, &cnt, &size);
for (idx = 0; idx < cnt; idx++) {
if (OS_EqualPath(fullpath, scan->filepath)) {
found = 1;
break;
}
scan++;
}
if (found)
*ID = scan->fileID;
else
*ID = 0;
OS_UnlockHandle(browsetable);
return found;
}
int Browser_SearchAndAddFile(OSHandle *browsetable, const char *fullpath, SInt16 *ID) {
S43 *scan;
SInt32 cnt;
SInt32 size;
char *pathptr;
if (!Browser_SearchFile(browsetable, fullpath, ID)) {
pathptr = xstrdup(fullpath);
GetBrowseTableInfoAndLock(browsetable, &scan, &cnt, &size);
OS_UnlockHandle(browsetable);
if (OS_ResizeHandle(browsetable, sizeof(S43) * (cnt + 1))) {
fprintf(stderr, "\n*** Out of memory\n");
exit(-23);
}
scan = (S43 *) (((char *) OS_LockHandle(browsetable)) + size);
scan->filepath = pathptr;
scan->fileID = cnt + 1;
OS_UnlockHandle(browsetable);
*ID = scan->fileID;
return -1;
} else {
return 1;
}
}
static SInt32 CalcDiskSpaceRequirements(S43 *mem, int num) {
SInt32 space = 0;
while (num--) {
space += 0x10;
space += (strlen(mem->filepath) + 7) & ~7;
mem++;
}
return space;
}
static int ConvertMemToDisk(S43 *mem, S49 *disk, int num) {
int slen;
int blen;
while (num--) {
disk->fileID = mem->fileID;
memset(disk->unused, 0, sizeof(disk->unused));
slen = strlen(mem->filepath);
blen = (slen + 7) & ~7;
disk->filename_length = slen;
memset(disk->filepath, 0, blen);
strncpy(disk->filepath, mem->filepath, slen);
disk = (S49 *) (((unsigned char *) disk) + 0x10 + blen);
mem++;
}
return 1;
}
int Browser_PackBrowseFile(Handle browsedata, OSHandle *browsetable, OSHandle *browsefileptr) {
OSHandle h;
char *ptr;
T53 header;
S43 *scan;
SInt32 entries;
UInt32 datasize;
UInt32 tableoffs;
UInt32 tablesize;
UInt32 totalsize;
SInt32 a_long = 1;
int err;
void *bptr;
OS_ASSERT(253, browsedata!=NULL);
OS_ASSERT(254, browsetable!=NULL);
datasize = GetHandleSize(browsedata);
tableoffs = (datasize + sizeof(header) + 7) & ~7;
GetBrowseTableInfoAndLock(browsetable, &scan, &entries, NULL);
tablesize = CalcDiskSpaceRequirements(scan, entries);
OS_UnlockHandle(browsetable);
totalsize = tablesize + tableoffs;
memcpy(header.magic_word, "DubL", 4);
header.version = 1;
header.big_endian = *((char *) &a_long) == 0;
memset(header.padding, 0, sizeof(header.padding));
header.browse_data_offset = sizeof(header);
header.browse_data_length = datasize;
header.file_data_offset = tableoffs;
header.file_data_length = tablesize;
header.file_data_count = entries;
err = OS_NewHandle(totalsize, &h);
*browsefileptr = h;
if (err) {
fprintf(stderr, "\n*** Out of memory\n");
exit(-23);
}
ptr = OS_LockHandle(&h);
memcpy(ptr, &header, sizeof(header));
HLock(browsedata);
memcpy(&ptr[sizeof(header)], *browsedata, datasize);
// an 'add' for this is swapped around and i cannot fucking figure out why
memset(&ptr[sizeof(header) + datasize], 0, tableoffs - sizeof(header) - datasize);
HUnlock(browsedata);
GetBrowseTableInfoAndLock(browsetable, &scan, &entries, NULL);
ConvertMemToDisk(scan, bptr = ptr + tableoffs, entries);
memset((char *) bptr + tablesize, 0, totalsize - tableoffs - tablesize);
OS_UnlockHandle(browsetable);
OS_UnlockHandle(&h);
return 1;
}