1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-01 02:23:32 +02:00
VVVVVV/desktop_version/src/BinaryBlob.cpp
Misa e481c75404 Use SDL stdlib funcs for free/malloc/strcmp
It's always good to have less of a dependency on a libc.
2020-08-14 09:51:19 -04:00

197 lines
3.8 KiB
C++

#include "BinaryBlob.h"
#include <physfs.h> /* FIXME: Abstract to FileSystemUtils! */
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include "UtilityClass.h"
binaryBlob::binaryBlob()
{
numberofHeaders = 0;
SDL_memset(m_headers, 0, sizeof(m_headers));
SDL_memset(m_memblocks, 0, sizeof(m_memblocks));
}
#ifdef VVV_COMPILEMUSIC
void binaryBlob::AddFileToBinaryBlob(const char* _path)
{
long size;
char * memblock;
FILE *file = fopen(_path, "rb");
if (file != NULL)
{
fseek(file, 0, SEEK_END);
size = ftell(file);
fseek(file, 0, SEEK_SET);
memblock = (char*) SDL_malloc(size);
fread(memblock, 1, size, file);
fclose(file);
printf("The complete file size: %li\n", size);
m_memblocks[numberofHeaders] = memblock;
for (int i = 0; _path[i]; i += 1)
{
m_headers[numberofHeaders].name[i] = _path[i];
}
m_headers[numberofHeaders].valid = true;
m_headers[numberofHeaders].size = size;
numberofHeaders += 1;
}
else
{
printf("Unable to open file\n");
}
}
void binaryBlob::writeBinaryBlob(const char* _name)
{
FILE *file = fopen(_name, "wb");
if (file != NULL)
{
fwrite((char*) &m_headers, 1, sizeof(m_headers), file);
for (int i = 0; i < numberofHeaders; i += 1)
{
fwrite(m_memblocks[i], 1, m_headers[i].size, file);
}
fclose(file);
}
else
{
printf("Unable to open new file for writing. Feels bad.\n");
}
}
#endif
bool binaryBlob::unPackBinary(const char* name)
{
PHYSFS_sint64 size;
PHYSFS_File *handle = PHYSFS_openRead(name);
if (handle == NULL)
{
printf("Unable to open file %s\n", name);
return false;
}
size = PHYSFS_fileLength(handle);
PHYSFS_readBytes(handle, &m_headers, sizeof(m_headers));
int offset = 0 + (sizeof(m_headers));
for (size_t i = 0; i < SDL_arraysize(m_headers); i += 1)
{
/* Name can be stupid, just needs to be terminated */
m_headers[i].name[47] = '\0';
if (m_headers[i].valid & ~0x1 || !m_headers[i].valid)
{
m_headers[i].valid = false;
continue; /* Must be EXACTLY 1 or 0 */
}
if (m_headers[i].size < 1)
{
m_headers[i].valid = false;
continue; /* Must be nonzero and positive */
}
if ((offset + m_headers[i].size) > size)
{
m_headers[i].valid = false;
continue; /* Bogus size value */
}
PHYSFS_seek(handle, offset);
m_memblocks[i] = (char*) SDL_malloc(m_headers[i].size);
if (m_memblocks[i] == NULL)
{
exit(1); /* Oh god we're out of memory, just bail */
}
PHYSFS_readBytes(handle, m_memblocks[i], m_headers[i].size);
offset += m_headers[i].size;
}
PHYSFS_close(handle);
printf("The complete reloaded file size: %lli\n", size);
for (size_t i = 0; i < SDL_arraysize(m_headers); i += 1)
{
if (m_headers[i].valid == false)
{
break;
}
printf("%s unpacked\n", m_headers[i].name);
}
return true;
}
void binaryBlob::clear()
{
for (size_t i = 0; i < SDL_arraysize(m_headers); i += 1)
{
if (m_headers[i].valid)
{
SDL_free(m_memblocks[i]);
m_headers[i].valid = false;
}
}
}
int binaryBlob::getIndex(const char* _name)
{
for (size_t i = 0; i < SDL_arraysize(m_headers); i += 1)
{
if (SDL_strcmp(_name, m_headers[i].name) == 0 && m_headers[i].valid)
{
return i;
}
}
return -1;
}
int binaryBlob::getSize(int _index)
{
if (!INBOUNDS_ARR(_index, m_headers))
{
puts("getSize() out-of-bounds!");
return 0;
}
return m_headers[_index].size;
}
char* binaryBlob::getAddress(int _index)
{
if (!INBOUNDS_ARR(_index, m_memblocks))
{
puts("getAddress() out-of-bounds!");
return NULL;
}
return m_memblocks[_index];
}
std::vector<int> binaryBlob::getExtra()
{
std::vector<int> result;
for (size_t i = 0; i < SDL_arraysize(m_headers); i += 1)
{
if (m_headers[i].valid
#define FOREACH_TRACK(track_name) && SDL_strcmp(m_headers[i].name, track_name) != 0
TRACK_NAMES
#undef FOREACH_TRACK
) {
result.push_back(i);
}
}
return result;
}