Play-/Source/discimages/ChdImageStream.cpp
Jean-Philip Desjardins 178a466139
Some checks failed
Build Windows / build_windows (x86_32, Visual Studio 16 2019, installer32.nsi, win32_msvc2019, Win32) (push) Has been cancelled
Build Windows / build_windows (x86_64, Visual Studio 16 2019, installer64.nsi, win64_msvc2019_64, x64) (push) Has been cancelled
Build Android / build_android (apk) (push) Has been cancelled
Build Android / build_android (libretro) (push) Has been cancelled
Build iOS / build_ios (push) Has been cancelled
Build JavaScript / build_js (push) Has been cancelled
Build Linux / build_linux (push) Has been cancelled
Build Linux ARM32 / build_linux_arm32 (push) Has been cancelled
Build Linux ARM64 / build_linux_arm64 (push) Has been cancelled
Build macOS / build_macos (push) Has been cancelled
Build Windows Psf / build_windows_psf (off, x86_64, Visual Studio 16 2019, installer64.nsi, x64) (push) Has been cancelled
Build Windows Psf / build_windows_psf (on, x86_64, Visual Studio 16 2019, installer64.nsi, x64) (push) Has been cancelled
Check Format / run_clangformat (push) Has been cancelled
ChdImageStream: Fix image size computation.
2025-01-07 10:06:48 -05:00

86 lines
2 KiB
C++

#include "ChdImageStream.h"
#include <cstring>
#include <cassert>
#include <stdexcept>
#include "maybe_unused.h"
#include <libchdr/chd.h>
#include "ChdStreamSupport.h"
//Should probably take a shared_ptr instead of raw
CChdImageStream::CChdImageStream(std::unique_ptr<Framework::CStream> baseStream)
: m_baseStream(std::move(baseStream))
{
m_file = ChdStreamSupport::CreateFileFromStream(m_baseStream.get());
chd_error result = chd_open_core_file(m_file, CHD_OPEN_READ, nullptr, &m_chd);
if(result != CHDERR_NONE)
{
throw std::runtime_error("Failed to open CHD file.");
}
auto header = chd_get_header(m_chd);
m_unitCount = header->unitcount;
m_unitSize = header->unitbytes;
m_hunkSize = header->hunkbytes;
m_hunkBuffer.resize(m_hunkSize);
}
CChdImageStream::~CChdImageStream()
{
chd_close(m_chd);
}
uint32 CChdImageStream::GetUnitSize() const
{
return m_unitSize;
}
void CChdImageStream::Seek(int64 position, Framework::STREAM_SEEK_DIRECTION origin)
{
switch(origin)
{
case Framework::STREAM_SEEK_CUR:
m_position += position;
break;
case Framework::STREAM_SEEK_SET:
m_position = position;
break;
case Framework::STREAM_SEEK_END:
m_position = GetTotalSize() + position;
break;
}
}
uint64 CChdImageStream::Tell()
{
return m_position;
}
bool CChdImageStream::IsEOF()
{
return m_position >= GetTotalSize();
}
uint64 CChdImageStream::Read(void* buffer, uint64 size)
{
uint32 hunkPosition = m_position % m_hunkSize;
assert((hunkPosition + size) <= m_hunkSize);
uint32 hunkIdx = m_position / m_hunkSize;
if(hunkIdx != m_hunkBufferIdx)
{
FRAMEWORK_MAYBE_UNUSED chd_error error = chd_read(m_chd, hunkIdx, m_hunkBuffer.data());
assert(error == CHDERR_NONE);
m_hunkBufferIdx = hunkIdx;
}
memcpy(buffer, m_hunkBuffer.data() + hunkPosition, size);
m_position += size;
return size;
}
uint64 CChdImageStream::Write(const void* buffer, uint64 size)
{
throw std::runtime_error("Not supported.");
}
uint64 CChdImageStream::GetTotalSize() const
{
return m_unitCount * static_cast<uint64>(m_unitSize);
}