mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
124 lines
3.4 KiB
C++
124 lines
3.4 KiB
C++
#include "MockOutputPath.h"
|
|
|
|
#include "Utils/ObjStream.h"
|
|
|
|
namespace
|
|
{
|
|
class MockFileBuffer final : public std::streambuf
|
|
{
|
|
public:
|
|
MockFileBuffer()
|
|
: m_pos(0u)
|
|
{
|
|
}
|
|
|
|
std::vector<std::uint8_t> data()
|
|
{
|
|
return std::move(m_data);
|
|
}
|
|
|
|
protected:
|
|
int_type overflow(const int_type b) override
|
|
{
|
|
if (!std::char_traits<char>::eq_int_type(b, std::char_traits<char>::eof()))
|
|
{
|
|
m_data.insert(m_data.begin() + static_cast<decltype(m_data)::difference_type>(m_pos), static_cast<std::uint8_t>(b));
|
|
++m_pos;
|
|
}
|
|
|
|
return b;
|
|
}
|
|
|
|
std::streamsize xsputn(const char* ptr, const std::streamsize count) override
|
|
{
|
|
const auto curSize = m_data.size();
|
|
const auto overrideCount = m_pos < curSize ? std::min(curSize - m_pos, static_cast<size_t>(count)) : 0u;
|
|
const auto insertCount = count - overrideCount;
|
|
|
|
if (overrideCount > 0)
|
|
{
|
|
memcpy(&m_data[m_pos], ptr, overrideCount);
|
|
m_pos += overrideCount;
|
|
ptr += overrideCount;
|
|
}
|
|
|
|
if (insertCount > 0)
|
|
{
|
|
m_data.insert(m_data.begin() + static_cast<decltype(m_data)::difference_type>(m_pos), ptr, ptr + insertCount);
|
|
m_pos += static_cast<size_t>(insertCount);
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
pos_type seekoff(const off_type off, const std::ios_base::seekdir dir, const std::ios_base::openmode mode) override
|
|
{
|
|
if (dir == std::ios::beg)
|
|
return seekpos(off, mode);
|
|
if (dir == std::ios::cur)
|
|
return seekpos(static_cast<pos_type>(m_pos) + off, mode);
|
|
if (off < static_cast<off_type>(m_data.size()))
|
|
return seekpos(static_cast<off_type>(m_data.size()) - off, mode);
|
|
return std::char_traits<char>::eof();
|
|
}
|
|
|
|
pos_type seekpos(const pos_type pos, std::ios_base::openmode) override
|
|
{
|
|
if (pos > m_data.size())
|
|
m_data.resize(static_cast<decltype(m_data)::size_type>(pos));
|
|
m_pos = static_cast<size_t>(pos);
|
|
|
|
return pos;
|
|
}
|
|
|
|
private:
|
|
std::vector<std::uint8_t> m_data;
|
|
std::size_t m_pos;
|
|
};
|
|
|
|
class MockFileWrapper final : public std::ostream
|
|
{
|
|
public:
|
|
MockFileWrapper(std::string name, std::vector<MockOutputFile>& files)
|
|
: std::ostream(&m_buf),
|
|
m_name(std::move(name)),
|
|
m_files(files)
|
|
{
|
|
}
|
|
|
|
~MockFileWrapper() override
|
|
{
|
|
m_files.emplace_back(std::move(m_name), m_buf.data());
|
|
}
|
|
|
|
private:
|
|
MockFileBuffer m_buf;
|
|
std::string m_name;
|
|
std::vector<MockOutputFile>& m_files;
|
|
};
|
|
} // namespace
|
|
|
|
MockOutputFile::MockOutputFile() = default;
|
|
|
|
MockOutputFile::MockOutputFile(std::string name, std::vector<std::uint8_t> data)
|
|
: m_name(std::move(name)),
|
|
m_data(std::move(data))
|
|
{
|
|
}
|
|
|
|
std::unique_ptr<std::ostream> MockOutputPath::Open(const std::string& fileName)
|
|
{
|
|
return std::make_unique<MockFileWrapper>(fileName, m_files);
|
|
}
|
|
|
|
const MockOutputFile* MockOutputPath::GetMockedFile(const std::string& name) const
|
|
{
|
|
for (const auto& file : m_files)
|
|
{
|
|
if (file.m_name == name)
|
|
return &file;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|