diff --git a/README.md b/README.md index c90c17d..d7e2c0f 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | Chromium Pak | | [`patterns/chromium_pak.hexpat`](patterns/chromium_pak.hexpat) | Chromium pak file | | COFF | `application/x-coff` | [`patterns/coff.hexpat`](patterns/coff.hexpat) | Common Object File Format (COFF) executable | | CPIO | `application/x-cpio` | [`patterns/cpio.hexpat`](patterns/cpio.hexpat) | Old Binary CPIO Format | +| CPIO | | [`patterns/cpio_portable_ascii.hexpat`](patterns/cpio_portable_ascii.hexpat) | Portable ASCII CPIO Format | +| CPIO | | [`patterns/cpio_new_ascii.hexpat`](patterns/cpio_new_ascii.hexpat) | "New" ASCII CPIO Format | | CrashLvl | | [`patterns/Crashlvl.hexpat`](patterns/Crashlvl.hexpat) | Crash Bandicoot - Back in Time (fan game) User created level format | | CREDHIST | | [`patterns/credhist.hexpat`](patterns/credhist.hexpat) | CREDHIST Format | | DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface | diff --git a/patterns/cpio_new_ascii.hexpat b/patterns/cpio_new_ascii.hexpat new file mode 100644 index 0000000..e85085d --- /dev/null +++ b/patterns/cpio_new_ascii.hexpat @@ -0,0 +1,46 @@ +#pragma author gunjambi +#pragma description "New" ASCII CPIO +#pragma magic [ 30 37 30 37 30 31 ] @ 0x00 + +import std.time; +import std.string; + +namespace new_ascii { + fn format_hex_time(str value) { + return std::time::format(std::time::to_utc(std::string::parse_int(value, 16))); + }; + fn parse_hex(str field) { + return std::string::parse_int(field, 16); + }; + + struct Cpio { + char c_magic[6]; + if (c_magic != "070701") { + std::error("Invalid CPIO Magic!"); + } + + char c_ino[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_mode[8]; + char c_uid[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_gid[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_nlink[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_mtime[8] [[format("new_ascii::format_hex_time")]]; + char c_filesize[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_devmajor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_devminor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_rdevmajor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_rdevminor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_namesize[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_check[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + + char filename[c_namesize - 1]; + padding[1]; + if (filename == "TRAILER!!!") + break; + padding[(4 - ((6 + c_namesize) % 4)) % 4]; + + u8 data[c_filesize]; + padding[(4 - (c_filesize % 4)) % 4]; + }; +} +new_ascii::Cpio cpio[while(true)] @ 0x00; diff --git a/patterns/cpio_portable_ascii.hexpat b/patterns/cpio_portable_ascii.hexpat new file mode 100644 index 0000000..50fe9ba --- /dev/null +++ b/patterns/cpio_portable_ascii.hexpat @@ -0,0 +1,41 @@ +#pragma author gunjambi +#pragma description Portable ASCII CPIO +#pragma magic [ 30 37 30 37 30 37 ] @ 0x00 + +import std.time; +import std.string; + +namespace portable_ascii { + fn format_octal_time(str value) { + return std::time::format(std::time::to_utc(std::string::parse_int(value, 8))); + }; + fn parse_octal_string(str field) { + return std::string::parse_int(field, 8); + }; + + struct Cpio { + char c_magic[6]; + if (c_magic != "070707") { + std::error("Invalid CPIO Magic!"); + } + + char c_dev[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_ino[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_mode[6]; + char c_uid[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_gid[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_nlink[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_rdev[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_mtime[11] [[format("portable_ascii::format_octal_time")]]; + char c_namesize[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_filesize[11] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + + char filename[c_namesize - 1]; + padding[1]; + if (filename == "TRAILER!!!") + break; + + u8 data[c_filesize]; + }; +} +portable_ascii::Cpio cpio[while(true)] @ 0x00; diff --git a/tests/patterns/test_data/cpio_new_ascii.hexpat.cpio b/tests/patterns/test_data/cpio_new_ascii.hexpat.cpio new file mode 100644 index 0000000..8d753db Binary files /dev/null and b/tests/patterns/test_data/cpio_new_ascii.hexpat.cpio differ diff --git a/tests/patterns/test_data/cpio_portable_ascii.hexpat.cpio b/tests/patterns/test_data/cpio_portable_ascii.hexpat.cpio new file mode 100644 index 0000000..dfaa037 Binary files /dev/null and b/tests/patterns/test_data/cpio_portable_ascii.hexpat.cpio differ