[libromdata] ISO: Show the Joliet level.
Some checks are pending
Codecov / run (push) Waiting to run

I was considering exporting this from IsoPartition, but the IsoPartition
isn't accessible at this point. We're reading all of the volume
descriptors in checkVolumeDescriptors() anyway, so that sets a local
version of jolietSVDType, which is then checked in loadFieldData().
This commit is contained in:
David Korth 2025-06-08 15:00:39 -04:00
parent 3f1f92b18a
commit 6e7d57282f

View File

@ -88,9 +88,14 @@ public:
// actual sector information. // actual sector information.
unsigned int sector_offset; unsigned int sector_offset;
// UDF version // Joliet level
// TODO: Descriptors? enum class JolietSVDType : uint8_t {
const char *s_udf_version; None = 0,
UCS2_Level1 = 1, // NOTE: UCS-2 BE
UCS2_Level2 = 2, // NOTE: UCS-2 BE
UCS2_Level3 = 3, // NOTE: UCS-2 BE
};
JolietSVDType jolietSVDType;
public: public:
// El Torito boot catalog LBA. (present if non-zero) // El Torito boot catalog LBA. (present if non-zero)
@ -104,6 +109,11 @@ public:
}; };
uint32_t boot_platforms; uint32_t boot_platforms;
public:
// UDF version
// TODO: Descriptors?
const char *s_udf_version;
public: public:
/** /**
* Check additional volume descirptors. * Check additional volume descirptors.
@ -259,9 +269,10 @@ ISOPrivate::ISOPrivate(const IRpFilePtr &file)
: super(file, &romDataInfo) : super(file, &romDataInfo)
, discType(DiscType::Unknown) , discType(DiscType::Unknown)
, sector_offset(0) , sector_offset(0)
, s_udf_version(nullptr) , jolietSVDType(JolietSVDType::None)
, boot_catalog_LBA(0) , boot_catalog_LBA(0)
, boot_platforms(0) , boot_platforms(0)
, s_udf_version(nullptr)
{ {
// Clear the disc header structs. // Clear the disc header structs.
memset(&pvd, 0, sizeof(pvd)); memset(&pvd, 0, sizeof(pvd));
@ -306,6 +317,7 @@ void ISOPrivate::checkVolumeDescriptors(void)
// Found the terminator. // Found the terminator.
foundTerminator = true; foundTerminator = true;
break; break;
case ISO_VDT_BOOT_RECORD: case ISO_VDT_BOOT_RECORD:
if (boot_LBA != 0) if (boot_LBA != 0)
break; break;
@ -315,6 +327,43 @@ void ISOPrivate::checkVolumeDescriptors(void)
boot_LBA = le32_to_cpu(vd.boot.boot_catalog_addr); boot_LBA = le32_to_cpu(vd.boot.boot_catalog_addr);
} }
break; break;
case ISO_VDT_SUPPLEMENTARY: {
if (vd.header.version == ISO_VD_VERSION) {
// Check the escape sequences.
// Escape sequence format: '%', '/', x
const char *const p_end = &vd.pri.svd_escape_sequences[sizeof(vd.pri.svd_escape_sequences)-3];
for (const char *p = vd.pri.svd_escape_sequences; p < p_end && *p != '\0'; p++) {
if (p[0] != '%' || p[1] != '/') {
continue;
}
// Check if this is a valid UCS-2 level seqeunce.
// NOTE: Using the highest level specified.
switch (p[2]) {
case '@':
if (jolietSVDType < JolietSVDType::UCS2_Level1) {
jolietSVDType = JolietSVDType::UCS2_Level1;
}
break;
case 'C':
if (jolietSVDType < JolietSVDType::UCS2_Level2) {
jolietSVDType = JolietSVDType::UCS2_Level2;
}
break;
case 'E':
if (jolietSVDType < JolietSVDType::UCS2_Level3) {
jolietSVDType = JolietSVDType::UCS2_Level3;
}
break;
default:
break;
}
}
}
break;
}
default: default:
break; break;
} }
@ -1047,7 +1096,7 @@ int ISO::loadFieldData(void)
return -EIO; return -EIO;
} }
d->fields.reserve(18); // Maximum of 18 fields. d->fields.reserve(19); // Maximum of 19 fields.
// NOTE: All fields are space-padded. (0x20, ' ') // NOTE: All fields are space-padded. (0x20, ' ')
// TODO: ascii_to_utf8()? // TODO: ascii_to_utf8()?
@ -1093,7 +1142,7 @@ int ISO::loadFieldData(void)
d->fields.addField_string(C_("ISO", "Sector Format"), sector_format); d->fields.addField_string(C_("ISO", "Sector Format"), sector_format);
switch (d->discType) { switch (d->discType) {
case ISOPrivate::DiscType::ISO9660: case ISOPrivate::DiscType::ISO9660: {
// ISO-9660 // ISO-9660
d->fields.setTabName(0, C_("ISO", "ISO-9660 PVD")); d->fields.setTabName(0, C_("ISO", "ISO-9660 PVD"));
@ -1121,7 +1170,17 @@ int ISO::loadFieldData(void)
v_boot_platforms_names, 0, d->boot_platforms); v_boot_platforms_names, 0, d->boot_platforms);
} }
// Joliet SVD
const char *const s_joliet_title = C_("ISO", "Joliet");
if (d->jolietSVDType == ISOPrivate::JolietSVDType::None) {
d->fields.addField_string(s_joliet_title, C_("ISO|JolietSVDType", "Not Present"));
} else {
d->fields.addField_string(s_joliet_title,
fmt::format(FRUN("UCS-2 Level {:d}"), static_cast<uint8_t>(d->jolietSVDType)));
}
break; break;
}
case ISOPrivate::DiscType::HighSierra: case ISOPrivate::DiscType::HighSierra:
// High Sierra // High Sierra