Merge pull request #1665 from lioncash/file

IOFile: Minor API changes
master
bunnei 2016-04-14 16:28:15 +07:00
commit aff35d3e58
3 changed files with 38 additions and 48 deletions

@ -824,13 +824,12 @@ size_t WriteStringToFile(bool text_file, const std::string &str, const char *fil
size_t ReadFileToString(bool text_file, const char *filename, std::string &str) size_t ReadFileToString(bool text_file, const char *filename, std::string &str)
{ {
FileUtil::IOFile file(filename, text_file ? "r" : "rb"); IOFile file(filename, text_file ? "r" : "rb");
auto const f = file.GetHandle();
if (!f) if (!file)
return false; return false;
str.resize(static_cast<u32>(GetSize(f))); str.resize(static_cast<u32>(file.GetSize()));
return file.ReadArray(&str[0], str.size()); return file.ReadArray(&str[0], str.size());
} }
@ -877,15 +876,10 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
} }
IOFile::IOFile() IOFile::IOFile()
: m_file(nullptr), m_good(true) {
{} }
IOFile::IOFile(std::FILE* file)
: m_file(file), m_good(true)
{}
IOFile::IOFile(const std::string& filename, const char openmode[]) IOFile::IOFile(const std::string& filename, const char openmode[])
: m_file(nullptr), m_good(true)
{ {
Open(filename, openmode); Open(filename, openmode);
} }
@ -896,7 +890,6 @@ IOFile::~IOFile()
} }
IOFile::IOFile(IOFile&& other) IOFile::IOFile(IOFile&& other)
: m_file(nullptr), m_good(true)
{ {
Swap(other); Swap(other);
} }
@ -935,25 +928,11 @@ bool IOFile::Close()
return m_good; return m_good;
} }
std::FILE* IOFile::ReleaseHandle() u64 IOFile::GetSize() const
{
std::FILE* const ret = m_file;
m_file = nullptr;
return ret;
}
void IOFile::SetHandle(std::FILE* file)
{
Close();
Clear();
m_file = file;
}
u64 IOFile::GetSize()
{ {
if (IsOpen()) if (IsOpen())
return FileUtil::GetSize(m_file); return FileUtil::GetSize(m_file);
else
return 0; return 0;
} }
@ -965,11 +944,11 @@ bool IOFile::Seek(s64 off, int origin)
return m_good; return m_good;
} }
u64 IOFile::Tell() u64 IOFile::Tell() const
{ {
if (IsOpen()) if (IsOpen())
return ftello(m_file); return ftello(m_file);
else
return -1; return -1;
} }

@ -176,7 +176,6 @@ class IOFile : public NonCopyable
{ {
public: public:
IOFile(); IOFile();
explicit IOFile(std::FILE* file);
IOFile(const std::string& filename, const char openmode[]); IOFile(const std::string& filename, const char openmode[]);
~IOFile(); ~IOFile();
@ -192,6 +191,9 @@ public:
template <typename T> template <typename T>
size_t ReadArray(T* data, size_t length) size_t ReadArray(T* data, size_t length)
{ {
static_assert(std::is_standard_layout<T>(), "Given array does not consist of standard layout objects");
static_assert(std::is_trivially_copyable<T>(), "Given array does not consist of trivially copyable objects");
if (!IsOpen()) { if (!IsOpen()) {
m_good = false; m_good = false;
return -1; return -1;
@ -207,9 +209,8 @@ public:
template <typename T> template <typename T>
size_t WriteArray(const T* data, size_t length) size_t WriteArray(const T* data, size_t length)
{ {
static_assert(std::is_standard_layout<T>::value, "Given array does not consist of standard layout objects"); static_assert(std::is_standard_layout<T>(), "Given array does not consist of standard layout objects");
// TODO: gcc 4.8 does not support is_trivially_copyable, but we really should check for it here. static_assert(std::is_trivially_copyable<T>(), "Given array does not consist of trivially copyable objects");
//static_assert(std::is_trivially_copyable<T>::value, "Given array does not consist of trivially copyable objects");
if (!IsOpen()) { if (!IsOpen()) {
m_good = false; m_good = false;
@ -243,25 +244,20 @@ public:
// m_good is set to false when a read, write or other function fails // m_good is set to false when a read, write or other function fails
bool IsGood() const { return m_good; } bool IsGood() const { return m_good; }
operator void*() { return m_good ? m_file : nullptr; } explicit operator bool() const { return IsGood(); }
std::FILE* ReleaseHandle();
std::FILE* GetHandle() { return m_file; }
void SetHandle(std::FILE* file);
bool Seek(s64 off, int origin); bool Seek(s64 off, int origin);
u64 Tell(); u64 Tell() const;
u64 GetSize(); u64 GetSize() const;
bool Resize(u64 size); bool Resize(u64 size);
bool Flush(); bool Flush();
// clear error state // clear error state
void Clear() { m_good = true; std::clearerr(m_file); } void Clear() { m_good = true; std::clearerr(m_file); }
std::FILE* m_file; private:
bool m_good; std::FILE* m_file = nullptr;
bool m_good = true;
}; };
} // namespace } // namespace

@ -586,6 +586,21 @@ TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config,
return info; return info;
} }
#ifdef HAVE_PNG
// Adapter functions to libpng to write/flush to File::IOFile instances.
static void WriteIOFile(png_structp png_ptr, png_bytep data, png_size_t length) {
auto* fp = static_cast<FileUtil::IOFile*>(png_get_io_ptr(png_ptr));
if (!fp->WriteBytes(data, length))
png_error(png_ptr, "Failed to write to output PNG file.");
}
static void FlushIOFile(png_structp png_ptr) {
auto* fp = static_cast<FileUtil::IOFile*>(png_get_io_ptr(png_ptr));
if (!fp->Flush())
png_error(png_ptr, "Failed to flush to output PNG file.");
}
#endif
void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) {
#ifndef HAVE_PNG #ifndef HAVE_PNG
return; return;
@ -629,7 +644,7 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) {
goto finalise; goto finalise;
} }
png_init_io(png_ptr, fp.GetHandle()); png_set_write_fn(png_ptr, static_cast<void*>(&fp), WriteIOFile, FlushIOFile);
// Write header (8 bit color depth) // Write header (8 bit color depth)
png_set_IHDR(png_ptr, info_ptr, texture_config.width, texture_config.height, png_set_IHDR(png_ptr, info_ptr, texture_config.width, texture_config.height,