mirror of
https://github.com/wiiu-env/homebrew_launcher.git
synced 2024-11-17 18:29:19 +01:00
198 lines
2.8 KiB
C++
198 lines
2.8 KiB
C++
|
#include <stdarg.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "CFile.hpp"
|
||
|
|
||
|
CFile::CFile()
|
||
|
{
|
||
|
iFd = -1;
|
||
|
mem_file = NULL;
|
||
|
filesize = 0;
|
||
|
pos = 0;
|
||
|
}
|
||
|
|
||
|
CFile::CFile(const std::string & filepath, eOpenTypes mode)
|
||
|
{
|
||
|
iFd = -1;
|
||
|
this->open(filepath, mode);
|
||
|
}
|
||
|
|
||
|
CFile::CFile(const u8 * mem, int size)
|
||
|
{
|
||
|
iFd = -1;
|
||
|
this->open(mem, size);
|
||
|
}
|
||
|
|
||
|
CFile::~CFile()
|
||
|
{
|
||
|
this->close();
|
||
|
}
|
||
|
|
||
|
int CFile::open(const std::string & filepath, eOpenTypes mode)
|
||
|
{
|
||
|
this->close();
|
||
|
|
||
|
s32 openMode = 0;
|
||
|
|
||
|
switch(mode)
|
||
|
{
|
||
|
default:
|
||
|
case ReadOnly:
|
||
|
openMode = O_RDONLY;
|
||
|
break;
|
||
|
case WriteOnly:
|
||
|
openMode = O_WRONLY;
|
||
|
break;
|
||
|
case ReadWrite:
|
||
|
openMode = O_RDWR;
|
||
|
break;
|
||
|
case Append:
|
||
|
openMode = O_APPEND | O_WRONLY;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//! Using fopen works only on the first launch as expected
|
||
|
//! on the second launch it causes issues because we don't overwrite
|
||
|
//! the .data sections which is needed for a normal application to re-init
|
||
|
//! this will be added with launching as RPX
|
||
|
iFd = ::open(filepath.c_str(), openMode);
|
||
|
if(iFd < 0)
|
||
|
return iFd;
|
||
|
|
||
|
|
||
|
filesize = ::lseek(iFd, 0, SEEK_END);
|
||
|
::lseek(iFd, 0, SEEK_SET);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int CFile::open(const u8 * mem, int size)
|
||
|
{
|
||
|
this->close();
|
||
|
|
||
|
mem_file = mem;
|
||
|
filesize = size;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void CFile::close()
|
||
|
{
|
||
|
if(iFd >= 0)
|
||
|
::close(iFd);
|
||
|
|
||
|
iFd = -1;
|
||
|
mem_file = NULL;
|
||
|
filesize = 0;
|
||
|
pos = 0;
|
||
|
}
|
||
|
|
||
|
int CFile::read(u8 * ptr, size_t size)
|
||
|
{
|
||
|
if(iFd >= 0)
|
||
|
{
|
||
|
int ret = ::read(iFd, ptr,size);
|
||
|
if(ret > 0)
|
||
|
pos += ret;
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int readsize = size;
|
||
|
|
||
|
if(readsize > (s64) (filesize-pos))
|
||
|
readsize = filesize-pos;
|
||
|
|
||
|
if(readsize <= 0)
|
||
|
return readsize;
|
||
|
|
||
|
if(mem_file != NULL)
|
||
|
{
|
||
|
memcpy(ptr, mem_file+pos, readsize);
|
||
|
pos += readsize;
|
||
|
return readsize;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int CFile::write(const u8 * ptr, size_t size)
|
||
|
{
|
||
|
if(iFd >= 0)
|
||
|
{
|
||
|
size_t done = 0;
|
||
|
while(done < size)
|
||
|
{
|
||
|
int ret = ::write(iFd, ptr, size - done);
|
||
|
if(ret <= 0)
|
||
|
return ret;
|
||
|
|
||
|
ptr += ret;
|
||
|
done += ret;
|
||
|
pos += ret;
|
||
|
}
|
||
|
return done;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int CFile::seek(long int offset, int origin)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
s64 newPos = pos;
|
||
|
|
||
|
if(origin == SEEK_SET)
|
||
|
{
|
||
|
newPos = offset;
|
||
|
}
|
||
|
else if(origin == SEEK_CUR)
|
||
|
{
|
||
|
newPos += offset;
|
||
|
}
|
||
|
else if(origin == SEEK_END)
|
||
|
{
|
||
|
newPos = filesize+offset;
|
||
|
}
|
||
|
|
||
|
if(newPos < 0)
|
||
|
{
|
||
|
pos = 0;
|
||
|
}
|
||
|
else {
|
||
|
pos = newPos;
|
||
|
}
|
||
|
|
||
|
if(iFd >= 0)
|
||
|
ret = ::lseek(iFd, pos, SEEK_SET);
|
||
|
|
||
|
if(mem_file != NULL)
|
||
|
{
|
||
|
if(pos > filesize)
|
||
|
{
|
||
|
pos = filesize;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int CFile::fwrite(const char *format, ...)
|
||
|
{
|
||
|
int result = -1;
|
||
|
char * tmp = NULL;
|
||
|
|
||
|
va_list va;
|
||
|
va_start(va, format);
|
||
|
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
||
|
{
|
||
|
result = this->write((u8 *)tmp, strlen(tmp));
|
||
|
}
|
||
|
va_end(va);
|
||
|
|
||
|
if(tmp)
|
||
|
free(tmp);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|