activegs-ios/kegs/Src/bigfile.cpp

185 lines
3.2 KiB
C++

//
// bigfile.cpp
// ActiveGS_Karateka
//
// Created by Olivier Goguel on 14/12/2017.
//
#include "bigfile.h"
#if KARATEKA_BIGFILE
#define ONLY_BIG
#endif
#define BIG 0x8000
struct CBigFile
{
const char* filename;
off_t seek_pos;
const char* buffer;
int size;
bool opened;
int code;
};
#if KARATEKA_BIGFILE
extern "C" const char karateka_bin[];
extern "C" const char karateka_activegsxml[];
CBigFile files[] ={
"karateka.bin", 0, karateka_bin,143360,false,0xEA,
"karateka.activegsxml", 0, karateka_activegsxml,5260,false,0XEA,
NULL,0,NULL,0,false
};
#else
CBigFile files[] ={
NULL,0,NULL,0,false
};
#endif
/*
off_t seek_pos = -1;
const char* buffer = NULL;
int file_size = -1;
*/
static const char* getfile(const char* p)
{
int l = strlen(p);
while(l>=0)
{
if (p[l]=='/')
return p+l+1;
l--;
}
return p;
}
int big_open(const char *_pathname, int _flags, mode_t _mode)
{
const char* file = getfile(_pathname);
if (file[0]=='*')
{
#if KARATEKA_BIGFILE
int l = 0;
while(files[l].filename != NULL)
{
if (!strcmp(file+1,files[l].filename))
{
if (files[l].opened)
{
printf("already opened %s",_pathname);
// return -1;
}
files[l].opened = true;
files[l].seek_pos = 0;
return BIG+l;
}
l++;
}
return -1;
#else
return open(_pathname+1,_flags,_mode);
#endif
}
else
{
#ifdef ONLY_BIG
printf("missing file %s\n",_pathname);
return -1;
#else
return open(_pathname,_flags,_mode);
#endif
}
}
off_t big_lseek(int _fd, off_t _offset, int _whence)
{
if ( ( _fd & BIG ) == 0 )
{
#ifdef ONLY_BIG
return 0;
#else
return lseek(_fd, _offset, _whence);
#endif
}
else
{
CBigFile& file = files[_fd &~BIG];
if (_whence == SEEK_SET)
file.seek_pos = _offset;
else
if (_whence == SEEK_END)
file.seek_pos = file.size-1;
return file.seek_pos;
}
}
ssize_t big_read(int _fd, void *_buf, size_t _count)
{
if ( ( _fd & BIG ) == 0 )
{
#ifdef ONLY_BIG
return 0;
#else
return read(_fd, _buf, _count);
#endif
}
else
{
CBigFile& file = files[_fd &~BIG];
if (_count + file.seek_pos > file.size)
_count = file.size - file.seek_pos;
memcpy(_buf,file.buffer+file.seek_pos,_count);
char *decode = (char*)_buf;
for(int i=0;i<_count;i++)
decode[i] ^= file.code;
file.seek_pos += _count;
return _count;
}
}
ssize_t big_write(int _fd, void* _buf, size_t _count)
{
if ( ( _fd & BIG ) == 0 )
{
return _count;
}
else {
return write(_fd, _buf, _count);
}
}
int big_close(int _fd)
{
if ( ( _fd & BIG ) == 0 )
{
CBigFile& file = files[_fd &~BIG];
if (!file.opened)
{
printf("nothing to close");
return -1;
}
file.opened=false;
}
else
close(_fd);
return 0;
}