2017-08-05 13:09:50 +00:00
|
|
|
#include <nx/FacHeader.h>
|
2017-07-06 10:57:33 +00:00
|
|
|
|
2017-07-17 08:21:39 +00:00
|
|
|
nx::FacHeader::FacHeader() :
|
|
|
|
mFsaRights()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2017-07-17 08:21:39 +00:00
|
|
|
clear();
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2017-07-17 08:21:39 +00:00
|
|
|
nx::FacHeader::FacHeader(const FacHeader & other) :
|
|
|
|
mFsaRights()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
*this = other;
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void nx::FacHeader::operator=(const FacHeader & other)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
if (other.getBytes().size())
|
|
|
|
{
|
|
|
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
mFsaRights = other.mFsaRights;
|
|
|
|
mContentOwnerIdPos.offset = other.mContentOwnerIdPos.offset;
|
|
|
|
mContentOwnerIdPos.size = other.mContentOwnerIdPos.size;
|
|
|
|
mSaveDataOwnerIdPos.offset = other.mSaveDataOwnerIdPos.offset;
|
|
|
|
mSaveDataOwnerIdPos.size = other.mSaveDataOwnerIdPos.size;
|
|
|
|
}
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
bool nx::FacHeader::operator==(const FacHeader & other) const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
return (mFsaRights == other.mFsaRights) \
|
|
|
|
&& (mContentOwnerIdPos.offset == other.mContentOwnerIdPos.offset) \
|
|
|
|
&& (mContentOwnerIdPos.size == other.mContentOwnerIdPos.size) \
|
|
|
|
&& (mSaveDataOwnerIdPos.offset == other.mSaveDataOwnerIdPos.offset) \
|
|
|
|
&& (mSaveDataOwnerIdPos.size == other.mSaveDataOwnerIdPos.size);
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
bool nx::FacHeader::operator!=(const FacHeader & other) const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
return !(*this == other);
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void nx::FacHeader::toBytes()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
mRawBinary.alloc(sizeof(sFacHeader));
|
|
|
|
sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
|
2017-07-06 10:57:33 +00:00
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
if (mVersion != fac::kFacFormatVersion)
|
2017-07-17 08:21:39 +00:00
|
|
|
{
|
|
|
|
fnd::Exception(kModuleName, "Unsupported format version");
|
|
|
|
}
|
2018-03-22 05:26:22 +00:00
|
|
|
hdr->version = (mVersion);
|
2017-07-17 08:21:39 +00:00
|
|
|
|
2018-03-22 05:26:22 +00:00
|
|
|
uint64_t flag = 0;
|
2018-06-24 08:18:54 +00:00
|
|
|
for (size_t i = 0; i < mFsaRights.size(); i++)
|
2017-07-17 08:21:39 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
flag |= _BIT((uint64_t)mFsaRights[i]);
|
2017-07-17 08:21:39 +00:00
|
|
|
}
|
2018-03-22 05:26:22 +00:00
|
|
|
hdr->fac_flags = (flag);
|
2017-07-06 10:57:33 +00:00
|
|
|
|
2018-05-26 04:07:42 +00:00
|
|
|
hdr->content_owner_ids.start = (uint32_t)(mContentOwnerIdPos.offset);
|
|
|
|
hdr->content_owner_ids.end = (uint32_t)(mContentOwnerIdPos.offset + mContentOwnerIdPos.size);
|
|
|
|
hdr->save_data_owner_ids.start = (uint32_t)(mSaveDataOwnerIdPos.offset);
|
|
|
|
hdr->save_data_owner_ids.end = (uint32_t)(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size);
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void nx::FacHeader::fromBytes(const byte_t* data, size_t len)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2017-07-15 08:28:01 +00:00
|
|
|
if (len < sizeof(sFacHeader))
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "FAC header too small");
|
|
|
|
}
|
|
|
|
|
2018-06-24 15:01:16 +00:00
|
|
|
// clear internal members
|
|
|
|
clear();
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
mRawBinary.alloc(sizeof(sFacHeader));
|
|
|
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
|
|
|
sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
|
2017-07-06 10:57:33 +00:00
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
if (hdr->version.get() != fac::kFacFormatVersion)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Unsupported FAC format version");
|
|
|
|
}
|
2018-03-22 05:26:22 +00:00
|
|
|
mVersion = hdr->version.get();
|
2017-07-06 10:57:33 +00:00
|
|
|
|
2018-03-22 05:26:22 +00:00
|
|
|
for (uint64_t i = 0; i < 64; i++)
|
2017-07-17 08:21:39 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
if (_HAS_BIT(hdr->fac_flags.get(), i))
|
2017-07-17 08:21:39 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
mFsaRights.addElement((fac::FsAccessFlag)i);
|
2017-07-17 08:21:39 +00:00
|
|
|
}
|
|
|
|
}
|
2018-03-22 05:26:22 +00:00
|
|
|
mContentOwnerIdPos.offset = hdr->content_owner_ids.start.get();
|
|
|
|
mContentOwnerIdPos.size = hdr->content_owner_ids.end.get() > hdr->content_owner_ids.start.get() ? hdr->content_owner_ids.end.get() - hdr->content_owner_ids.start.get() : 0;
|
|
|
|
mSaveDataOwnerIdPos.offset = hdr->save_data_owner_ids.start.get();
|
|
|
|
mSaveDataOwnerIdPos.size = hdr->save_data_owner_ids.end.get() > hdr->save_data_owner_ids.start.get() ? hdr->save_data_owner_ids.end.get() - hdr->save_data_owner_ids.start.get() : 0;
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
const fnd::Vec<byte_t>& nx::FacHeader::getBytes() const
|
|
|
|
{
|
|
|
|
return mRawBinary;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::clear()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2017-07-17 08:21:39 +00:00
|
|
|
mFsaRights.clear();
|
|
|
|
mContentOwnerIdPos.offset = 0;
|
|
|
|
mContentOwnerIdPos.size = 0;
|
|
|
|
mSaveDataOwnerIdPos.offset = 0;
|
|
|
|
mSaveDataOwnerIdPos.size = 0;
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
size_t nx::FacHeader::getFacSize() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
size_t savedata = mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size;
|
|
|
|
size_t content = mContentOwnerIdPos.offset + mContentOwnerIdPos.size;
|
|
|
|
return _MAX(_MAX(savedata, content), sizeof(sFacHeader));
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 05:26:22 +00:00
|
|
|
uint32_t nx::FacHeader::getFormatVersion() const
|
2017-07-17 08:21:39 +00:00
|
|
|
{
|
|
|
|
return mVersion;
|
|
|
|
}
|
|
|
|
|
2018-03-22 05:26:22 +00:00
|
|
|
void nx::FacHeader::setFormatVersion(uint32_t version)
|
2017-07-17 08:21:39 +00:00
|
|
|
{
|
|
|
|
mVersion = version;
|
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
const fnd::List<nx::fac::FsAccessFlag>& nx::FacHeader::getFsaRightsList() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mFsaRights;
|
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void nx::FacHeader::setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2017-07-17 08:21:39 +00:00
|
|
|
mFsaRights.clear();
|
2018-06-24 08:18:54 +00:00
|
|
|
for (size_t i = 0; i < list.size(); i++)
|
2017-07-17 08:21:39 +00:00
|
|
|
{
|
|
|
|
mFsaRights.hasElement(list[i]) ? mFsaRights.addElement(list[i]) : throw fnd::Exception(kModuleName, "FSA right already exists");
|
|
|
|
}
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
const nx::FacHeader::sSection& nx::FacHeader::getContentOwnerIdPos() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
return mContentOwnerIdPos;
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 12:13:52 +00:00
|
|
|
void nx::FacHeader::setContentOwnerIdPos(const sSection& pos)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-25 12:13:52 +00:00
|
|
|
mContentOwnerIdPos = pos;
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
const nx::FacHeader::sSection& nx::FacHeader::getSaveDataOwnerIdPos() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-24 08:18:54 +00:00
|
|
|
return mSaveDataOwnerIdPos;
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 12:13:52 +00:00
|
|
|
void nx::FacHeader::setSaveDataOwnerIdPos(const sSection& pos)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2018-06-25 12:13:52 +00:00
|
|
|
mSaveDataOwnerIdPos = pos;
|
2018-06-24 08:18:54 +00:00
|
|
|
}
|