2017-07-06 10:57:33 +00:00
|
|
|
#include "FacHeader.h"
|
|
|
|
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
|
|
|
|
nx::FacHeader::FacHeader()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
clearVariables();
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
nx::FacHeader::FacHeader(const FacHeader & other)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
copyFrom(other);
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
nx::FacHeader::FacHeader(const u8 * bytes, size_t len)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2017-07-15 08:28:01 +00:00
|
|
|
importBinary(bytes, len);
|
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
|
|
|
{
|
|
|
|
return isEqual(other);
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
bool nx::FacHeader::operator!=(const FacHeader & other) const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return !isEqual(other);
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::operator=(const FacHeader & other)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
copyFrom(other);
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
const u8 * nx::FacHeader::getBytes() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mBinaryBlob.getBytes();
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
size_t nx::FacHeader::getSize() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mBinaryBlob.getSize();
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::exportBinary()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
mBinaryBlob.alloc(sizeof(sFacHeader));
|
|
|
|
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes();
|
|
|
|
|
|
|
|
hdr->set_version(kFacFormatVersion);
|
|
|
|
hdr->set_fac_flags(mFsaRights);
|
|
|
|
|
|
|
|
calculateOffsets();
|
|
|
|
hdr->content_owner_ids().set_start(mContentOwnerIdPos.offset);
|
|
|
|
hdr->content_owner_ids().set_end(mContentOwnerIdPos.offset + mContentOwnerIdPos.size);
|
|
|
|
hdr->save_data_owner_ids().set_start(mSaveDataOwnerIdPos.offset);
|
|
|
|
hdr->save_data_owner_ids().set_end(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size);
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::importBinary(const u8 * bytes, 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");
|
|
|
|
}
|
|
|
|
|
2017-07-06 10:57:33 +00:00
|
|
|
mBinaryBlob.alloc(sizeof(sFacHeader));
|
|
|
|
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
|
|
|
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes();
|
|
|
|
|
|
|
|
if (hdr->version() != kFacFormatVersion)
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Unsupported FAC format version");
|
|
|
|
}
|
|
|
|
|
|
|
|
mFsaRights = hdr->fac_flags();
|
|
|
|
mContentOwnerIdPos.offset = hdr->content_owner_ids().start();
|
2017-07-15 08:28:01 +00:00
|
|
|
mContentOwnerIdPos.size = hdr->content_owner_ids().end() > hdr->content_owner_ids().start() ? hdr->content_owner_ids().end() - hdr->content_owner_ids().start() : 0;
|
2017-07-06 10:57:33 +00:00
|
|
|
mSaveDataOwnerIdPos.offset = hdr->save_data_owner_ids().start();
|
2017-07-15 08:28:01 +00:00
|
|
|
mSaveDataOwnerIdPos.size = hdr->save_data_owner_ids().end() > hdr->save_data_owner_ids().start() ? hdr->save_data_owner_ids().end() - hdr->save_data_owner_ids().start() : 0;
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::clear()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
2017-07-15 08:28:01 +00:00
|
|
|
clearVariables();
|
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
|
|
|
{
|
2017-07-15 08:28:01 +00:00
|
|
|
size_t savedata = getSaveDataOwnerIdOffset() + getSaveDataOwnerIdSize();
|
|
|
|
size_t content = getContentOwnerIdOffset() + getContentOwnerIdSize();
|
|
|
|
return MAX(MAX(savedata, content), sizeof(sFacHeader));
|
2017-07-06 10:57:33 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
u64 nx::FacHeader::getFsaRights() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mFsaRights;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::setFsaRights(u64 flag)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
mFsaRights = flag;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
size_t nx::FacHeader::getContentOwnerIdOffset() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mContentOwnerIdPos.offset;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
size_t nx::FacHeader::getContentOwnerIdSize() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mContentOwnerIdPos.size;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::setContentOwnerIdSize(size_t size)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
mContentOwnerIdPos.size = size;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
size_t nx::FacHeader::getSaveDataOwnerIdOffset() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mSaveDataOwnerIdPos.offset;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
size_t nx::FacHeader::getSaveDataOwnerIdSize() const
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
return mSaveDataOwnerIdPos.size;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::setSaveDataOwnerIdSize(size_t size)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
mSaveDataOwnerIdPos.size = size;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::clearVariables()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
mFsaRights = 0;
|
|
|
|
mContentOwnerIdPos.offset = 0;
|
|
|
|
mContentOwnerIdPos.size = 0;
|
|
|
|
mSaveDataOwnerIdPos.offset = 0;
|
|
|
|
mSaveDataOwnerIdPos.size = 0;
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::calculateOffsets()
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4);
|
|
|
|
mSaveDataOwnerIdPos.offset = mContentOwnerIdPos.offset + align(mContentOwnerIdPos.size, 4);
|
|
|
|
}
|
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
bool nx::FacHeader::isEqual(const FacHeader & other) const
|
2017-07-06 10:57:33 +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-15 08:28:01 +00:00
|
|
|
void nx::FacHeader::copyFrom(const FacHeader & other)
|
2017-07-06 10:57:33 +00:00
|
|
|
{
|
|
|
|
if (other.getSize())
|
|
|
|
{
|
|
|
|
importBinary(other.getBytes(), other.getSize());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mBinaryBlob.clear();
|
|
|
|
mFsaRights = other.mFsaRights;
|
|
|
|
mContentOwnerIdPos.offset = other.mContentOwnerIdPos.offset;
|
|
|
|
mContentOwnerIdPos.size = other.mContentOwnerIdPos.size;
|
|
|
|
mSaveDataOwnerIdPos.offset = other.mSaveDataOwnerIdPos.offset;
|
|
|
|
mSaveDataOwnerIdPos.size = other.mSaveDataOwnerIdPos.size;
|
|
|
|
}
|
|
|
|
}
|