RPM package file: C++11/STL parsing library

An RPM package consists of the lead, the signature (contains digests and signatures), the header (contains the package metadata) and the payload (a compressed archive of the package files).

This structure is shared by all package format versions supported by this Kaitai Struct implementation:

The versions differ mainly in the tags they use: v6 packages store all sizes as 64-bit integers, carry only cryptographic data in the signature and always use the stripped-down cpio archive format (see the payload instance).

The formats before v3, as well as the abandoned rpm5 fork, are not covered by this implementation.

Application

RPM Package Manager

File extension

["rpm", "srpm", "src.rpm", "drpm"]

KS implementation details

License: CC0-1.0
Minimal Kaitai Struct required: 0.11

References

This page hosts a formal specification of RPM package file using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Runtime library

All C++11/STL code generated by Kaitai Struct depends on the Kaitai Struct runtime library for C++/STL. You must add this dependency to your project before you can parse or serialize any data.

For C++, the easiest way is to clone the runtime library sources and build them along with your project.

Code

Using Kaitai Struct in C++/STL usually consists of 3 steps.

  1. We need to create an STL input stream (std::istream). One can open local file for that, or use existing std::string or char* buffer.
    #include <fstream>
    
    std::ifstream is("path/to/local/file.rpm", std::ifstream::binary);
    
    #include <sstream>
    
    std::istringstream is(str);
    
    #include <sstream>
    
    const char buf[] = { ... };
    std::string str(buf, sizeof buf);
    std::istringstream is(str);
    
  2. We need to wrap our input stream into Kaitai stream:
    #include "kaitai/kaitaistream.h"
    
    kaitai::kstream ks(&is);
    
  3. And finally, we can invoke the parsing:
    rpm_t data(&ks);
    

After that, one can get various attributes from the structure by invoking getter methods like:

data.payload() // => Archive of the package files, compressed using the method specified by
`header_tags::payload_compressor`. If this tag is missing, it's almost
certainly uncompressed (except for some very old v3 packages built by RPM
3.0.3 or earlier, which didn't use the tag because the payload was always
gzipped; RPM 3.0.5 added support for bzip2 payloads and started writing
the tag). However, RPM reads the payload as gzip by default - see
<https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/lib/rpmte.cc#L643-L645>.
Since zlib's gzip reader passes data that is not in gzip format through
unchanged (see
<https://github.com/madler/zlib/blob/da607da739fa6047df13e66a2af6b8bec7c2a498/zlib.h#L1386-L1389>),
this also works for uncompressed payloads.

The archive format is given by `header_tags::payload_format`, which is
`"cpio"` for regular packages. In v4/v3 packages, it's a SVR4 cpio archive
without a checksum (the `070701` variant) - the [v4 format
documentation](https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_v4.md?plain=1#L106-L107)
claims "with a CRC checksum", but that's not true since RPM 2.4.4
(released in 1997).

v6 packages and v4 packages with a file over 4 GiB use a stripped-down
variant of cpio with the magic `07070X`. Its file headers only hold the
index of the file in the file lists of the RPM header, which is the only
place where the file names, sizes and other metadata are stored.

C++11/STL source code to parse RPM package file

rpm.h

#pragma once

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

class rpm_t;

#include "kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include <set>
#include <vector>

#if KAITAI_STRUCT_VERSION < 11000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.11 or later is required"
#endif

/**
 * An RPM package consists of the lead, the signature (contains digests and
 * signatures), the header (contains the package metadata) and the payload (a
 * compressed archive of the package files).
 * 
 * This structure is shared by all package format versions supported by this
 * Kaitai Struct implementation:
 * 
 * * v3, written by RPM 2.1 to 3.x.
 * * v4, written by RPM 4.x, and by RPM 6.x when the `%_rpmformat` macro is set
 *   to 4 - see
 *   <https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/man/rpmbuild-config.5.scd?plain=1#L189-L192>.
 *   For example, Fedora 43 and 44 patch RPM 6.0 to keep producing v4 packages by
 *   default - see
 *   <https://src.fedoraproject.org/rpms/rpm/blob/7099d81c3b5ecf1777a43095be429cb198bcc566/f/rpm-6.0-rpmformat.patch>.
 * * v6, written by upstream RPM 6.0 by default - see
 *   <https://github.com/rpm-software-management/rpm/commit/99d80a22d3d299bdc4418f7e61cd491731626d37>.
 * 
 * The versions differ mainly in the tags they use: v6 packages store all sizes
 * as 64-bit integers, carry only cryptographic data in the signature and always
 * use the stripped-down cpio archive format (see the `payload` instance).
 * 
 * The formats before v3, as well as the abandoned rpm5 fork, are not covered by
 * this implementation.
 * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_v6.md Source
 * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_v4.md Source
 * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_v3.md Source
 * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/signatures_digests.md Source
 * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/large_files.md Source
 * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/tags.md Source
 * \sa https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/pkgformat.html Source
 * \sa https://ftp.osuosl.org/pub/rpm/max-rpm/ Source
 */

class rpm_t : public kaitai::kstruct {

public:
    class dummy_t;
    class header_t;
    class header_index_record_t;
    class header_record_t;
    class header_tags_step_t;
    class lead_t;
    class record_type_bin_t;
    class record_type_string_t;
    class record_type_string_array_t;
    class record_type_uint16_t;
    class record_type_uint32_t;
    class record_type_uint64_t;
    class record_type_uint8_t;
    class rpm_version_t;
    class signature_tags_step_t;

    enum architectures_t {
        ARCHITECTURES_NOT_SET = 0,
        ARCHITECTURES_X86 = 1,
        ARCHITECTURES_ALPHA = 2,
        ARCHITECTURES_SPARC = 3,
        ARCHITECTURES_MIPS = 4,
        ARCHITECTURES_PPC = 5,
        ARCHITECTURES_M68K = 6,
        ARCHITECTURES_SGI = 7,
        ARCHITECTURES_RS6000 = 8,
        ARCHITECTURES_IA64 = 9,
        ARCHITECTURES_SPARC64 = 10,
        ARCHITECTURES_MIPS64 = 11,
        ARCHITECTURES_ARM = 12,
        ARCHITECTURES_M68K_MINT = 13,
        ARCHITECTURES_S390 = 14,
        ARCHITECTURES_S390X = 15,
        ARCHITECTURES_PPC64 = 16,
        ARCHITECTURES_SH = 17,
        ARCHITECTURES_XTENSA = 18,
        ARCHITECTURES_AARCH64 = 19,
        ARCHITECTURES_MIPS_R6 = 20,
        ARCHITECTURES_MIPS64_R6 = 21,
        ARCHITECTURES_RISCV = 22,
        ARCHITECTURES_LOONGARCH64 = 23,
        ARCHITECTURES_E2K = 24,
        ARCHITECTURES_NO_ARCH = 255
    };
    static bool _is_defined_architectures_t(architectures_t v);

private:
    static const std::set<architectures_t> _values_architectures_t;

public:

    enum header_tags_t {
        HEADER_TAGS_SIGNATURES = 62,
        HEADER_TAGS_HEADER_IMMUTABLE = 63,
        HEADER_TAGS_I18N_TABLE = 100,
        HEADER_TAGS_NAME = 1000,
        HEADER_TAGS_VERSION = 1001,
        HEADER_TAGS_RELEASE = 1002,
        HEADER_TAGS_EPOCH = 1003,
        HEADER_TAGS_SUMMARY = 1004,
        HEADER_TAGS_DESCRIPTION = 1005,
        HEADER_TAGS_BUILD_TIME = 1006,
        HEADER_TAGS_BUILD_HOST = 1007,
        HEADER_TAGS_INSTALL_TIME = 1008,
        HEADER_TAGS_SIZE = 1009,
        HEADER_TAGS_DISTRIBUTION = 1010,
        HEADER_TAGS_VENDOR = 1011,
        HEADER_TAGS_GIF_OBSOLETE = 1012,
        HEADER_TAGS_XPM_OBSOLETE = 1013,
        HEADER_TAGS_LICENSE = 1014,
        HEADER_TAGS_PACKAGER = 1015,
        HEADER_TAGS_GROUP = 1016,
        HEADER_TAGS_CHANGELOG_INTERNAL = 1017,
        HEADER_TAGS_SOURCE = 1018,
        HEADER_TAGS_PATCH = 1019,
        HEADER_TAGS_URL = 1020,
        HEADER_TAGS_OS = 1021,
        HEADER_TAGS_ARCH = 1022,
        HEADER_TAGS_PRE_INSTALL_SCRIPTLET = 1023,
        HEADER_TAGS_POST_INSTALL_SCRIPTLET = 1024,
        HEADER_TAGS_PRE_UNINSTALL_SCRIPTLET = 1025,
        HEADER_TAGS_POST_UNINSTALL_SCRIPTLET = 1026,
        HEADER_TAGS_OLD_FILE_NAMES_OBSOLETE = 1027,
        HEADER_TAGS_FILE_SIZES = 1028,
        HEADER_TAGS_FILE_STATES = 1029,
        HEADER_TAGS_FILE_MODES = 1030,
        HEADER_TAGS_FILE_UIDS_INTERNAL = 1031,
        HEADER_TAGS_FILE_GIDS_INTERNAL = 1032,
        HEADER_TAGS_DEVICE_NUMBER = 1033,
        HEADER_TAGS_MTIMES = 1034,
        HEADER_TAGS_FILE_DIGESTS = 1035,
        HEADER_TAGS_LINK_TOS = 1036,
        HEADER_TAGS_FILE_FLAGS = 1037,
        HEADER_TAGS_ROOT_INTERNAL = 1038,
        HEADER_TAGS_FILE_OWNER = 1039,
        HEADER_TAGS_FILE_GROUP = 1040,
        HEADER_TAGS_EXCLUDE_INTERNAL = 1041,
        HEADER_TAGS_EXCLUSIVE_INTERNAL = 1042,
        HEADER_TAGS_ICON_OBSOLETE = 1043,
        HEADER_TAGS_SOURCE_RPM = 1044,
        HEADER_TAGS_FILE_VERIFY_FLAGS = 1045,
        HEADER_TAGS_ARCHIVE_SIZE = 1046,
        HEADER_TAGS_PROVIDE_NAME = 1047,
        HEADER_TAGS_REQUIRE_FLAGS = 1048,
        HEADER_TAGS_REQUIRE_NAME = 1049,
        HEADER_TAGS_REQUIRE_VERSION = 1050,
        HEADER_TAGS_NO_SOURCE = 1051,
        HEADER_TAGS_NO_PATCH = 1052,
        HEADER_TAGS_CONFLICT_FLAGS = 1053,
        HEADER_TAGS_CONFLICT_NAME = 1054,
        HEADER_TAGS_CONFLICT_VERSION = 1055,
        HEADER_TAGS_DEFAULT_PREFIX_INTERNAL = 1056,
        HEADER_TAGS_BUILD_ROOT_INTERNAL = 1057,
        HEADER_TAGS_INSTALL_PREFIX_INTERNAL = 1058,
        HEADER_TAGS_EXCLUDE_ARCH = 1059,
        HEADER_TAGS_EXCLUDE_OS = 1060,
        HEADER_TAGS_EXCLUSIVE_ARCH = 1061,
        HEADER_TAGS_EXCLUSIVE_OS = 1062,
        HEADER_TAGS_AUTOREQPROV_INTERNAL = 1063,
        HEADER_TAGS_RPM_VERSION = 1064,
        HEADER_TAGS_TRIGGER_SCRIPTS = 1065,
        HEADER_TAGS_TRIGGER_NAME = 1066,
        HEADER_TAGS_TRIGGER_VERSION = 1067,
        HEADER_TAGS_TRIGGER_FLAGS = 1068,
        HEADER_TAGS_TRIGGER_INDEX = 1069,
        HEADER_TAGS_VERIFY_SCRIPT = 1079,
        HEADER_TAGS_CHANGELOG_TIME = 1080,
        HEADER_TAGS_CHANGELOG_NAME = 1081,
        HEADER_TAGS_CHANGELOG_TEXT = 1082,
        HEADER_TAGS_BROKEN_MD5_INTERNAL = 1083,
        HEADER_TAGS_PREREQ_INTERNAL = 1084,
        HEADER_TAGS_PRE_INSTALL_INTERPRETER = 1085,
        HEADER_TAGS_POST_INSTALL_INTERPRETER = 1086,
        HEADER_TAGS_PRE_UNINSTALL_INTERPRETER = 1087,
        HEADER_TAGS_POST_UNINSTALL_INTERPRETER = 1088,
        HEADER_TAGS_BUILD_ARCHS = 1089,
        HEADER_TAGS_OBSOLETE_NAME = 1090,
        HEADER_TAGS_VERIFY_SCRIPT_PROG = 1091,
        HEADER_TAGS_TRIGGER_SCRIPT_PROG = 1092,
        HEADER_TAGS_DOC_DIR_INTERNAL = 1093,
        HEADER_TAGS_COOKIE = 1094,
        HEADER_TAGS_FILE_DEVICES = 1095,
        HEADER_TAGS_FILE_INODES = 1096,
        HEADER_TAGS_FILE_LANGS = 1097,
        HEADER_TAGS_PREFIXES = 1098,
        HEADER_TAGS_INSTALL_PREFIXES = 1099,
        HEADER_TAGS_TRIGGER_INSTALL_INTERNAL = 1100,
        HEADER_TAGS_TRIGGER_UNINSTALL_INTERNAL = 1101,
        HEADER_TAGS_TRIGGER_POST_UNINSTALL_INTERNAL = 1102,
        HEADER_TAGS_AUTOREQ_INTERNAL = 1103,
        HEADER_TAGS_AUTOPROV_INTERNAL = 1104,
        HEADER_TAGS_CAPABILITY_INTERNAL = 1105,
        HEADER_TAGS_SOURCE_PACKAGE = 1106,
        HEADER_TAGS_OLD_ORIG_FILENAMES_INTERNAL = 1107,
        HEADER_TAGS_BUILD_PREREQ_INTERNAL = 1108,
        HEADER_TAGS_BUILD_REQUIRES_INTERNAL = 1109,
        HEADER_TAGS_BUILD_CONFLICTS_INTERNAL = 1110,
        HEADER_TAGS_BUILD_MACROS_INTERNAL = 1111,
        HEADER_TAGS_PROVIDE_FLAGS = 1112,
        HEADER_TAGS_PROVIDE_VERSION = 1113,
        HEADER_TAGS_OBSOLETE_FLAGS = 1114,
        HEADER_TAGS_OBSOLETE_VERSION = 1115,
        HEADER_TAGS_DIR_INDEXES = 1116,
        HEADER_TAGS_BASE_NAMES = 1117,
        HEADER_TAGS_DIR_NAMES = 1118,
        HEADER_TAGS_ORIG_DIR_INDEXES = 1119,
        HEADER_TAGS_ORIG_BASE_NAMES = 1120,
        HEADER_TAGS_ORIG_DIR_NAMES = 1121,
        HEADER_TAGS_OPT_FLAGS = 1122,
        HEADER_TAGS_DIST_URL = 1123,
        HEADER_TAGS_PAYLOAD_FORMAT = 1124,
        HEADER_TAGS_PAYLOAD_COMPRESSOR = 1125,
        HEADER_TAGS_PAYLOAD_FLAGS = 1126,
        HEADER_TAGS_INSTALL_COLOR = 1127,
        HEADER_TAGS_INSTALL_TID = 1128,
        HEADER_TAGS_REMOVE_TID_OBSOLETE = 1129,
        HEADER_TAGS_SHA1_RHN_INTERNAL = 1130,
        HEADER_TAGS_RHN_PLATFORM_INTERNAL = 1131,
        HEADER_TAGS_PLATFORM = 1132,
        HEADER_TAGS_PATCHES_NAME_OBSOLETE = 1133,
        HEADER_TAGS_PATCHES_FLAGS_OBSOLETE = 1134,
        HEADER_TAGS_PATCHES_VERSION_OBSOLETE = 1135,
        HEADER_TAGS_CACHE_CTIME_INTERNAL = 1136,
        HEADER_TAGS_CACHE_PKG_PATH_INTERNAL = 1137,
        HEADER_TAGS_CACHE_PKG_SIZE_INTERNAL = 1138,
        HEADER_TAGS_CACHE_PKG_MTIME_INTERNAL = 1139,
        HEADER_TAGS_FILE_COLORS = 1140,
        HEADER_TAGS_FILE_CLASS = 1141,
        HEADER_TAGS_CLASS_DICT = 1142,
        HEADER_TAGS_FILE_DEPENDS_IDX = 1143,
        HEADER_TAGS_FILE_DEPENDS_NUM = 1144,
        HEADER_TAGS_DEPENDS_DICT = 1145,
        HEADER_TAGS_SOURCE_SIG_MD5 = 1146,
        HEADER_TAGS_FILE_CONTEXTS_OBSOLETE = 1147,
        HEADER_TAGS_FS_CONTEXTS_OBSOLETE = 1148,
        HEADER_TAGS_RE_CONTEXTS_OBSOLETE = 1149,
        HEADER_TAGS_POLICIES = 1150,
        HEADER_TAGS_PRE_TRANS = 1151,
        HEADER_TAGS_POST_TRANS = 1152,
        HEADER_TAGS_PRE_TRANS_PROG = 1153,
        HEADER_TAGS_POST_TRANS_PROG = 1154,
        HEADER_TAGS_DIST_TAG = 1155,
        HEADER_TAGS_OLD_SUGGESTS_NAME_OBSOLETE = 1156,
        HEADER_TAGS_OLD_SUGGESTS_VERSION_OBSOLETE = 1157,
        HEADER_TAGS_OLD_SUGGESTS_FLAGS_OBSOLETE = 1158,
        HEADER_TAGS_OLD_ENHANCES_NAME_OBSOLETE = 1159,
        HEADER_TAGS_OLD_ENHANCES_VERSION_OBSOLETE = 1160,
        HEADER_TAGS_OLD_ENHANCES_FLAGS_OBSOLETE = 1161,
        HEADER_TAGS_PRIORITY_UNIMPLEMENTED = 1162,
        HEADER_TAGS_CVSID_UNIMPLEMENTED = 1163,
        HEADER_TAGS_BLINK_PKGID_UNIMPLEMENTED = 1164,
        HEADER_TAGS_BLINK_HDRID_UNIMPLEMENTED = 1165,
        HEADER_TAGS_BLINK_NEVRA_UNIMPLEMENTED = 1166,
        HEADER_TAGS_FLINK_PKGID_UNIMPLEMENTED = 1167,
        HEADER_TAGS_FLINK_HDRID_UNIMPLEMENTED = 1168,
        HEADER_TAGS_FLINK_NEVRA_UNIMPLEMENTED = 1169,
        HEADER_TAGS_PACKAGE_ORIGIN_UNIMPLEMENTED = 1170,
        HEADER_TAGS_TRIGGER_PRE_INSTALL_INTERNAL = 1171,
        HEADER_TAGS_BUILD_SUGGESTS_UNIMPLEMENTED = 1172,
        HEADER_TAGS_BUILD_ENHANCES_UNIMPLEMENTED = 1173,
        HEADER_TAGS_SCRIPT_STATES_UNIMPLEMENTED = 1174,
        HEADER_TAGS_SCRIPT_METRICS_UNIMPLEMENTED = 1175,
        HEADER_TAGS_BUILD_CPU_CLOCK_UNIMPLEMENTED = 1176,
        HEADER_TAGS_FILE_DIGEST_ALGOS_UNIMPLEMENTED = 1177,
        HEADER_TAGS_VARIANTS_UNIMPLEMENTED = 1178,
        HEADER_TAGS_XMAJOR_UNIMPLEMENTED = 1179,
        HEADER_TAGS_XMINOR_UNIMPLEMENTED = 1180,
        HEADER_TAGS_REPO_TAG_UNIMPLEMENTED = 1181,
        HEADER_TAGS_KEYWORDS_UNIMPLEMENTED = 1182,
        HEADER_TAGS_BUILD_PLATFORMS_UNIMPLEMENTED = 1183,
        HEADER_TAGS_PACKAGE_COLOR_UNIMPLEMENTED = 1184,
        HEADER_TAGS_PACKAGE_PREF_COLOR_UNIMPLEMENTED = 1185,
        HEADER_TAGS_XATTRS_DICT_UNIMPLEMENTED = 1186,
        HEADER_TAGS_FILEX_ATTRSX_UNIMPLEMENTED = 1187,
        HEADER_TAGS_DEP_ATTRS_DICT_UNIMPLEMENTED = 1188,
        HEADER_TAGS_CONFLICT_ATTRSX_UNIMPLEMENTED = 1189,
        HEADER_TAGS_OBSOLETE_ATTRSX_UNIMPLEMENTED = 1190,
        HEADER_TAGS_PROVIDE_ATTRSX_UNIMPLEMENTED = 1191,
        HEADER_TAGS_REQUIRE_ATTRSX_UNIMPLEMENTED = 1192,
        HEADER_TAGS_BUILD_PROVIDES_UNIMPLEMENTED = 1193,
        HEADER_TAGS_BUILD_OBSOLETES_UNIMPLEMENTED = 1194,
        HEADER_TAGS_DB_INSTANCE = 1195,
        HEADER_TAGS_NVRA = 1196,
        HEADER_TAGS_FILE_NAMES = 5000,
        HEADER_TAGS_FILE_PROVIDE = 5001,
        HEADER_TAGS_FILE_REQUIRE = 5002,
        HEADER_TAGS_FS_NAMES_UNIMPLEMENTED = 5003,
        HEADER_TAGS_FS_SIZES_UNIMPLEMENTED = 5004,
        HEADER_TAGS_TRIGGER_CONDS = 5005,
        HEADER_TAGS_TRIGGER_TYPE = 5006,
        HEADER_TAGS_ORIG_FILE_NAMES = 5007,
        HEADER_TAGS_LONG_FILE_SIZES = 5008,
        HEADER_TAGS_LONG_SIZE = 5009,
        HEADER_TAGS_FILE_CAPS = 5010,
        HEADER_TAGS_FILE_DIGEST_ALGO = 5011,
        HEADER_TAGS_BUG_URL = 5012,
        HEADER_TAGS_EVR = 5013,
        HEADER_TAGS_NVR = 5014,
        HEADER_TAGS_NEVR = 5015,
        HEADER_TAGS_NEVRA = 5016,
        HEADER_TAGS_HEADER_COLOR = 5017,
        HEADER_TAGS_VERBOSE = 5018,
        HEADER_TAGS_EPOCH_NUM = 5019,
        HEADER_TAGS_PRE_INSTALL_FLAGS = 5020,
        HEADER_TAGS_POST_INSTALL_FLAGS = 5021,
        HEADER_TAGS_PRE_UNINSTALL_FLAGS = 5022,
        HEADER_TAGS_POST_UNINSTALL_FLAGS = 5023,
        HEADER_TAGS_PRE_TRANS_FLAGS = 5024,
        HEADER_TAGS_POST_TRANS_FLAGS = 5025,
        HEADER_TAGS_VERIFY_SCRIPT_FLAGS = 5026,
        HEADER_TAGS_TRIGGER_SCRIPT_FLAGS = 5027,
        HEADER_TAGS_COLLECTIONS_UNIMPLEMENTED = 5029,
        HEADER_TAGS_POLICY_NAMES = 5030,
        HEADER_TAGS_POLICY_TYPES = 5031,
        HEADER_TAGS_POLICY_TYPES_INDEXES = 5032,
        HEADER_TAGS_POLICY_FLAGS = 5033,
        HEADER_TAGS_VCS = 5034,
        HEADER_TAGS_ORDER_NAME = 5035,
        HEADER_TAGS_ORDER_VERSION = 5036,
        HEADER_TAGS_ORDER_FLAGS = 5037,
        HEADER_TAGS_MSSF_MANIFEST_UNIMPLEMENTED = 5038,
        HEADER_TAGS_MSSF_DOMAIN_UNIMPLEMENTED = 5039,
        HEADER_TAGS_INST_FILE_NAMES = 5040,
        HEADER_TAGS_REQUIRE_NEVRS = 5041,
        HEADER_TAGS_PROVIDE_NEVRS = 5042,
        HEADER_TAGS_OBSOLETE_NEVRS = 5043,
        HEADER_TAGS_CONFLICT_NEVRS = 5044,
        HEADER_TAGS_FILE_NLINKS = 5045,
        HEADER_TAGS_RECOMMEND_NAME = 5046,
        HEADER_TAGS_RECOMMEND_VERSION = 5047,
        HEADER_TAGS_RECOMMEND_FLAGS = 5048,
        HEADER_TAGS_SUGGEST_NAME = 5049,
        HEADER_TAGS_SUGGEST_VERSION = 5050,
        HEADER_TAGS_SUGGEST_FLAGS = 5051,
        HEADER_TAGS_SUPPLEMENT_NAME = 5052,
        HEADER_TAGS_SUPPLEMENT_VERSION = 5053,
        HEADER_TAGS_SUPPLEMENT_FLAGS = 5054,
        HEADER_TAGS_ENHANCE_NAME = 5055,
        HEADER_TAGS_ENHANCE_VERSION = 5056,
        HEADER_TAGS_ENHANCE_FLAGS = 5057,
        HEADER_TAGS_RECOMMEND_NEVRS = 5058,
        HEADER_TAGS_SUGGEST_NEVRS = 5059,
        HEADER_TAGS_SUPPLEMENT_NEVRS = 5060,
        HEADER_TAGS_ENHANCE_NEVRS = 5061,
        HEADER_TAGS_ENCODING = 5062,
        HEADER_TAGS_FILE_TRIGGER_INSTALL_INTERNAL = 5063,
        HEADER_TAGS_FILE_TRIGGER_UNINSTALL_INTERNAL = 5064,
        HEADER_TAGS_FILE_TRIGGER_POST_UNINSTALL_INTERNAL = 5065,
        HEADER_TAGS_FILE_TRIGGER_SCRIPTS = 5066,
        HEADER_TAGS_FILE_TRIGGER_SCRIPT_PROG = 5067,
        HEADER_TAGS_FILE_TRIGGER_SCRIPT_FLAGS = 5068,
        HEADER_TAGS_FILE_TRIGGER_NAME = 5069,
        HEADER_TAGS_FILE_TRIGGER_INDEX = 5070,
        HEADER_TAGS_FILE_TRIGGER_VERSION = 5071,
        HEADER_TAGS_FILE_TRIGGER_FLAGS = 5072,
        HEADER_TAGS_TRANS_FILE_TRIGGER_INSTALL_INTERNAL = 5073,
        HEADER_TAGS_TRANS_FILE_TRIGGER_UNINSTALL_INTERNAL = 5074,
        HEADER_TAGS_TRANS_FILE_TRIGGER_POST_UNINSTALL_INTERNAL = 5075,
        HEADER_TAGS_TRANS_FILE_TRIGGER_SCRIPTS = 5076,
        HEADER_TAGS_TRANS_FILE_TRIGGER_SCRIPT_PROG = 5077,
        HEADER_TAGS_TRANS_FILE_TRIGGER_SCRIPT_FLAGS = 5078,
        HEADER_TAGS_TRANS_FILE_TRIGGER_NAME = 5079,
        HEADER_TAGS_TRANS_FILE_TRIGGER_INDEX = 5080,
        HEADER_TAGS_TRANS_FILE_TRIGGER_VERSION = 5081,
        HEADER_TAGS_TRANS_FILE_TRIGGER_FLAGS = 5082,
        HEADER_TAGS_REMOVE_PATH_POSTFIXES_INTERNAL = 5083,
        HEADER_TAGS_FILE_TRIGGER_PRIORITIES = 5084,
        HEADER_TAGS_TRANS_FILE_TRIGGER_PRIORITIES = 5085,
        HEADER_TAGS_FILE_TRIGGER_CONDS = 5086,
        HEADER_TAGS_FILE_TRIGGER_TYPE = 5087,
        HEADER_TAGS_TRANS_FILE_TRIGGER_CONDS = 5088,
        HEADER_TAGS_TRANS_FILE_TRIGGER_TYPE = 5089,
        HEADER_TAGS_FILE_SIGNATURES = 5090,
        HEADER_TAGS_FILE_SIGNATURE_LENGTH = 5091,
        HEADER_TAGS_PAYLOAD_SHA256 = 5092,
        HEADER_TAGS_PAYLOAD_SHA256_ALGO_OBSOLETE = 5093,
        HEADER_TAGS_AUTO_INSTALLED_UNIMPLEMENTED = 5094,
        HEADER_TAGS_IDENTITY_UNIMPLEMENTED = 5095,
        HEADER_TAGS_MODULARITY_LABEL = 5096,
        HEADER_TAGS_PAYLOAD_SHA256_ALT = 5097,
        HEADER_TAGS_ARCH_SUFFIX = 5098,
        HEADER_TAGS_SPEC = 5099,
        HEADER_TAGS_TRANSLATION_URL = 5100,
        HEADER_TAGS_UPSTREAM_RELEASES = 5101,
        HEADER_TAGS_SOURCE_LICENSE_INTERNAL = 5102,
        HEADER_TAGS_PRE_UNTRANS = 5103,
        HEADER_TAGS_POST_UNTRANS = 5104,
        HEADER_TAGS_PRE_UNTRANS_PROG = 5105,
        HEADER_TAGS_POST_UNTRANS_PROG = 5106,
        HEADER_TAGS_PRE_UNTRANS_FLAGS = 5107,
        HEADER_TAGS_POST_UNTRANS_FLAGS = 5108,
        HEADER_TAGS_SYS_USERS = 5109,
        HEADER_TAGS_BUILD_SYSTEM_INTERNAL = 5110,
        HEADER_TAGS_BUILD_OPTION_INTERNAL = 5111,
        HEADER_TAGS_PAYLOAD_SIZE = 5112,
        HEADER_TAGS_PAYLOAD_SIZE_ALT = 5113,
        HEADER_TAGS_RPM_FORMAT = 5114,
        HEADER_TAGS_FILE_MIME_INDEX = 5115,
        HEADER_TAGS_MIME_DICT = 5116,
        HEADER_TAGS_FILE_MIMES = 5117,
        HEADER_TAGS_PACKAGE_DIGESTS = 5118,
        HEADER_TAGS_PACKAGE_DIGEST_ALGOS = 5119,
        HEADER_TAGS_SOURCE_NEVR = 5120,
        HEADER_TAGS_PAYLOAD_SHA512 = 5121,
        HEADER_TAGS_PAYLOAD_SHA512_ALT = 5122,
        HEADER_TAGS_PAYLOAD_SHA3_256 = 5123,
        HEADER_TAGS_PAYLOAD_SHA3_256_ALT = 5124
    };
    static bool _is_defined_header_tags_t(header_tags_t v);

private:
    static const std::set<header_tags_t> _values_header_tags_t;

public:

    enum operating_systems_t {
        OPERATING_SYSTEMS_NOT_SET = 0,
        OPERATING_SYSTEMS_LINUX = 1,
        OPERATING_SYSTEMS_IRIX = 2,
        OPERATING_SYSTEMS_NO_OS = 255
    };
    static bool _is_defined_operating_systems_t(operating_systems_t v);

private:
    static const std::set<operating_systems_t> _values_operating_systems_t;

public:

    enum record_types_t {
        RECORD_TYPES_CHAR = 1,
        RECORD_TYPES_UINT8 = 2,
        RECORD_TYPES_UINT16 = 3,
        RECORD_TYPES_UINT32 = 4,
        RECORD_TYPES_UINT64 = 5,
        RECORD_TYPES_STRING = 6,
        RECORD_TYPES_BIN = 7,
        RECORD_TYPES_STRING_ARRAY = 8,
        RECORD_TYPES_I18N_STRING = 9
    };
    static bool _is_defined_record_types_t(record_types_t v);

private:
    static const std::set<record_types_t> _values_record_types_t;

public:

    enum rpm_types_t {
        RPM_TYPES_BINARY = 0,
        RPM_TYPES_SOURCE = 1
    };
    static bool _is_defined_rpm_types_t(rpm_types_t v);

private:
    static const std::set<rpm_types_t> _values_rpm_types_t;

public:

    enum signature_tags_t {
        SIGNATURE_TAGS_SIGNATURES = 62,
        SIGNATURE_TAGS_HEADER_IMMUTABLE = 63,
        SIGNATURE_TAGS_I18N_TABLE = 100,
        SIGNATURE_TAGS_BAD_SHA1_1_OBSOLETE = 264,
        SIGNATURE_TAGS_BAD_SHA1_2_OBSOLETE = 265,
        SIGNATURE_TAGS_DSA = 267,
        SIGNATURE_TAGS_RSA = 268,
        SIGNATURE_TAGS_SHA1 = 269,
        SIGNATURE_TAGS_LONG_SIZE = 270,
        SIGNATURE_TAGS_LONG_ARCHIVE_SIZE = 271,
        SIGNATURE_TAGS_SHA256 = 273,
        SIGNATURE_TAGS_FILE_SIGNATURES = 274,
        SIGNATURE_TAGS_FILE_SIGNATURE_LENGTH = 275,
        SIGNATURE_TAGS_VERITY_SIGNATURES = 276,
        SIGNATURE_TAGS_VERITY_SIGNATURE_ALGO = 277,
        SIGNATURE_TAGS_OPENPGP = 278,
        SIGNATURE_TAGS_SHA3_256 = 279,
        SIGNATURE_TAGS_RESERVED = 999,
        SIGNATURE_TAGS_SIZE = 1000,
        SIGNATURE_TAGS_LE_MD5_1_OBSOLETE = 1001,
        SIGNATURE_TAGS_PGP = 1002,
        SIGNATURE_TAGS_LE_MD5_2_OBSOLETE = 1003,
        SIGNATURE_TAGS_MD5 = 1004,
        SIGNATURE_TAGS_GPG = 1005,
        SIGNATURE_TAGS_PGP5_OBSOLETE = 1006,
        SIGNATURE_TAGS_PAYLOAD_SIZE = 1007,
        SIGNATURE_TAGS_RESERVED_SPACE = 1008
    };
    static bool _is_defined_signature_tags_t(signature_tags_t v);

private:
    static const std::set<signature_tags_t> _values_signature_tags_t;

public:

    rpm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, rpm_t* p__root = nullptr);

private:
    void _read();
    void _clean_up();

public:
    ~rpm_t();

    class dummy_t : public kaitai::kstruct {

    public:

        dummy_t(kaitai::kstream* p__io, rpm_t::header_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~dummy_t();

    private:
        rpm_t* m__root;
        rpm_t::header_t* m__parent;

    public:
        rpm_t* _root() const { return m__root; }
        rpm_t::header_t* _parent() const { return m__parent; }
    };

    /**
     * header structure used for both the "header" and "signature", but some tag
     * values have different meanings in signature and header (hence they use
     * different enums)
     */

    class header_t : public kaitai::kstruct {

    public:

        header_t(bool p_is_signature, kaitai::kstream* p__io, rpm_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~header_t();

    private:
        bool f_is_header;
        bool m_is_header;

    public:
        bool is_header();

    private:
        std::unique_ptr<header_record_t> m_header_record;
        std::unique_ptr<std::vector<std::unique_ptr<header_index_record_t>>> m_index_records;
        std::unique_ptr<dummy_t> m_storage_section;
        bool m_is_signature;
        rpm_t* m__root;
        rpm_t* m__parent;
        std::string m__raw_storage_section;
        std::unique_ptr<kaitai::kstream> m__io__raw_storage_section;

    public:
        header_record_t* header_record() const { return m_header_record.get(); }
        std::vector<std::unique_ptr<header_index_record_t>>* index_records() const { return m_index_records.get(); }
        dummy_t* storage_section() const { return m_storage_section.get(); }
        bool is_signature() const { return m_is_signature; }
        rpm_t* _root() const { return m__root; }
        rpm_t* _parent() const { return m__parent; }
        std::string _raw_storage_section() const { return m__raw_storage_section; }
        kaitai::kstream* _io__raw_storage_section() const { return m__io__raw_storage_section.get(); }
    };

    class header_index_record_t : public kaitai::kstruct {

    public:

        header_index_record_t(kaitai::kstream* p__io, rpm_t::header_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~header_index_record_t();

    private:
        bool f_body;
        std::unique_ptr<kaitai::kstruct> m_body;
        bool n_body;

    public:
        bool _is_null_body() { body(); return n_body; };

    private:

    public:
        kaitai::kstruct* body();

    private:
        bool f_header_tag;
        header_tags_t m_header_tag;
        bool n_header_tag;

    public:
        bool _is_null_header_tag() { header_tag(); return n_header_tag; };

    private:

    public:
        header_tags_t header_tag();

    private:
        bool f_len_value;
        uint32_t m_len_value;
        bool n_len_value;

    public:
        bool _is_null_len_value() { len_value(); return n_len_value; };

    private:

    public:
        uint32_t len_value();

    private:
        bool f_num_values;
        uint32_t m_num_values;
        bool n_num_values;

    public:
        bool _is_null_num_values() { num_values(); return n_num_values; };

    private:

    public:
        uint32_t num_values();

    private:
        bool f_signature_tag;
        signature_tags_t m_signature_tag;
        bool n_signature_tag;

    public:
        bool _is_null_signature_tag() { signature_tag(); return n_signature_tag; };

    private:

    public:
        signature_tags_t signature_tag();

    private:
        uint32_t m_tag_raw;
        record_types_t m_record_type;
        uint32_t m_ofs_body;
        uint32_t m_count;
        rpm_t* m__root;
        rpm_t::header_t* m__parent;

    public:

        /**
         * prefer to access `signature_tag` and `header_tag` instead
         */
        uint32_t tag_raw() const { return m_tag_raw; }
        record_types_t record_type() const { return m_record_type; }
        uint32_t ofs_body() const { return m_ofs_body; }

        /**
         * internal; access `num_values` and `len_value` instead
         */
        uint32_t count() const { return m_count; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_t* _parent() const { return m__parent; }
    };

    class header_record_t : public kaitai::kstruct {

    public:

        header_record_t(kaitai::kstream* p__io, rpm_t::header_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~header_record_t();

    private:
        std::string m_magic;
        std::string m_reserved;
        uint32_t m_num_index_records;
        uint32_t m_len_storage_section;
        rpm_t* m__root;
        rpm_t::header_t* m__parent;

    public:
        std::string magic() const { return m_magic; }
        std::string reserved() const { return m_reserved; }
        uint32_t num_index_records() const { return m_num_index_records; }

        /**
         * Size of the storage area for the data
         * pointed to by the Index Records.
         */
        uint32_t len_storage_section() const { return m_len_storage_section; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_t* _parent() const { return m__parent; }
    };

    /**
     * Like `signature_tags_step`, but looks for `header_tags::payload_size`,
     * which is where v6 packages store the payload size.
     */

    class header_tags_step_t : public kaitai::kstruct {

    public:

        header_tags_step_t(int32_t p_idx, int32_t p_prev_payload_size_tag_idx, kaitai::kstream* p__io, rpm_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~header_tags_step_t();

    private:
        bool f_payload_size_tag_idx;
        int32_t m_payload_size_tag_idx;

    public:
        int32_t payload_size_tag_idx();

    private:
        int32_t m_idx;
        int32_t m_prev_payload_size_tag_idx;
        rpm_t* m__root;
        rpm_t* m__parent;

    public:
        int32_t idx() const { return m_idx; }
        int32_t prev_payload_size_tag_idx() const { return m_prev_payload_size_tag_idx; }
        rpm_t* _root() const { return m__root; }
        rpm_t* _parent() const { return m__parent; }
    };

    /**
     * In 2021, Panu Matilainen (an RPM developer) [described this
     * structure](https://github.com/kaitai-io/kaitai_struct_formats/pull/469#discussion_r718288192)
     * as follows:
     * 
     * > The lead as a structure is 25 years obsolete, the data there is
     * > meaningless. Seriously. Except to check for the magic to detect that
     * > it's an rpm file in the first place, just ignore everything in it.
     * > Literally everything.
     * 
     * RPM 4.19 and older rejected packages that didn't meet the `valid`
     * constraints specified here, while RPM 4.20 and later only check the
     * `magic` - see
     * <https://github.com/rpm-software-management/rpm/commit/b3449a0774487a091bbe59e821b4004b06d4fa66>.
     * Nevertheless, RPM still writes values that pass these checks for backwards
     * compatibility, so any `.rpm` file should pass.
     * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_lead.md Source
     */

    class lead_t : public kaitai::kstruct {

    public:

        lead_t(kaitai::kstream* p__io, rpm_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~lead_t();

    private:
        std::string m_magic;
        std::unique_ptr<rpm_version_t> m_version;
        rpm_types_t m_type;
        architectures_t m_architecture;
        std::string m_package_name;
        operating_systems_t m_os;
        uint16_t m_signature_type;
        std::string m_reserved;
        rpm_t* m__root;
        rpm_t* m__parent;

    public:
        std::string magic() const { return m_magic; }
        rpm_version_t* version() const { return m_version.get(); }
        rpm_types_t type() const { return m_type; }
        architectures_t architecture() const { return m_architecture; }
        std::string package_name() const { return m_package_name; }
        operating_systems_t os() const { return m_os; }

        /**
         * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/lib/rpmlead.cc#L20-L21 Source
         */
        uint16_t signature_type() const { return m_signature_type; }
        std::string reserved() const { return m_reserved; }
        rpm_t* _root() const { return m__root; }
        rpm_t* _parent() const { return m__parent; }
    };

    class record_type_bin_t : public kaitai::kstruct {

    public:

        record_type_bin_t(uint32_t p_len_value, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~record_type_bin_t();

    private:
        std::unique_ptr<std::vector<std::string>> m_values;
        uint32_t m_len_value;
        rpm_t* m__root;
        rpm_t::header_index_record_t* m__parent;

    public:
        std::vector<std::string>* values() const { return m_values.get(); }
        uint32_t len_value() const { return m_len_value; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_index_record_t* _parent() const { return m__parent; }
    };

    class record_type_string_t : public kaitai::kstruct {

    public:

        record_type_string_t(kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~record_type_string_t();

    private:
        std::unique_ptr<std::vector<std::string>> m_values;
        rpm_t* m__root;
        rpm_t::header_index_record_t* m__parent;

    public:
        std::vector<std::string>* values() const { return m_values.get(); }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_index_record_t* _parent() const { return m__parent; }
    };

    class record_type_string_array_t : public kaitai::kstruct {

    public:

        record_type_string_array_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~record_type_string_array_t();

    private:
        std::unique_ptr<std::vector<std::string>> m_values;
        uint32_t m_num_values;
        rpm_t* m__root;
        rpm_t::header_index_record_t* m__parent;

    public:
        std::vector<std::string>* values() const { return m_values.get(); }
        uint32_t num_values() const { return m_num_values; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_index_record_t* _parent() const { return m__parent; }
    };

    class record_type_uint16_t : public kaitai::kstruct {

    public:

        record_type_uint16_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~record_type_uint16_t();

    private:
        std::unique_ptr<std::vector<uint16_t>> m_values;
        uint32_t m_num_values;
        rpm_t* m__root;
        rpm_t::header_index_record_t* m__parent;

    public:
        std::vector<uint16_t>* values() const { return m_values.get(); }
        uint32_t num_values() const { return m_num_values; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_index_record_t* _parent() const { return m__parent; }
    };

    class record_type_uint32_t : public kaitai::kstruct {

    public:

        record_type_uint32_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~record_type_uint32_t();

    private:
        std::unique_ptr<std::vector<uint32_t>> m_values;
        uint32_t m_num_values;
        rpm_t* m__root;
        rpm_t::header_index_record_t* m__parent;

    public:
        std::vector<uint32_t>* values() const { return m_values.get(); }
        uint32_t num_values() const { return m_num_values; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_index_record_t* _parent() const { return m__parent; }
    };

    class record_type_uint64_t : public kaitai::kstruct {

    public:

        record_type_uint64_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~record_type_uint64_t();

    private:
        std::unique_ptr<std::vector<uint64_t>> m_values;
        uint32_t m_num_values;
        rpm_t* m__root;
        rpm_t::header_index_record_t* m__parent;

    public:
        std::vector<uint64_t>* values() const { return m_values.get(); }
        uint32_t num_values() const { return m_num_values; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_index_record_t* _parent() const { return m__parent; }
    };

    class record_type_uint8_t : public kaitai::kstruct {

    public:

        record_type_uint8_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~record_type_uint8_t();

    private:
        std::unique_ptr<std::vector<uint8_t>> m_values;
        uint32_t m_num_values;
        rpm_t* m__root;
        rpm_t::header_index_record_t* m__parent;

    public:
        std::vector<uint8_t>* values() const { return m_values.get(); }
        uint32_t num_values() const { return m_num_values; }
        rpm_t* _root() const { return m__root; }
        rpm_t::header_index_record_t* _parent() const { return m__parent; }
    };

    class rpm_version_t : public kaitai::kstruct {

    public:

        rpm_version_t(kaitai::kstream* p__io, rpm_t::lead_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~rpm_version_t();

    private:
        uint8_t m_major;
        uint8_t m_minor;
        rpm_t* m__root;
        rpm_t::lead_t* m__parent;

    public:

        /**
         * 3 in v3 and v4 packages, 4 in v6 packages.
         * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/lib/rpmlead.cc#L51-L52 Source
         */
        uint8_t major() const { return m_major; }
        uint8_t minor() const { return m_minor; }
        rpm_t* _root() const { return m__root; }
        rpm_t::lead_t* _parent() const { return m__parent; }
    };

    /**
     * Finds the first `signature_tags::size` and `signature_tags::long_size`
     * index record. Since Kaitai Struct doesn't have a built-in way to search an
     * array directly, each step receives the indexes found so far via
     * parameters.
     */

    class signature_tags_step_t : public kaitai::kstruct {

    public:

        signature_tags_step_t(int32_t p_idx, int32_t p_prev_size_tag_idx, int32_t p_prev_long_size_tag_idx, kaitai::kstream* p__io, rpm_t* p__parent = nullptr, rpm_t* p__root = nullptr);

    private:
        void _read();
        void _clean_up();

    public:
        ~signature_tags_step_t();

    private:
        bool f_long_size_tag_idx;
        int32_t m_long_size_tag_idx;

    public:
        int32_t long_size_tag_idx();

    private:
        bool f_size_tag_idx;
        int32_t m_size_tag_idx;

    public:
        int32_t size_tag_idx();

    private:
        int32_t m_idx;
        int32_t m_prev_size_tag_idx;
        int32_t m_prev_long_size_tag_idx;
        rpm_t* m__root;
        rpm_t* m__parent;

    public:
        int32_t idx() const { return m_idx; }
        int32_t prev_size_tag_idx() const { return m_prev_size_tag_idx; }
        int32_t prev_long_size_tag_idx() const { return m_prev_long_size_tag_idx; }
        rpm_t* _root() const { return m__root; }
        rpm_t* _parent() const { return m__parent; }
    };

private:
    bool f_has_header_payload_size_tag;
    bool m_has_header_payload_size_tag;

public:
    bool has_header_payload_size_tag();

private:
    bool f_has_payload;
    bool m_has_payload;

public:
    bool has_payload();

private:
    bool f_has_signature_long_size_tag;
    bool m_has_signature_long_size_tag;

public:
    bool has_signature_long_size_tag();

private:
    bool f_has_signature_size_tag;
    bool m_has_signature_size_tag;

public:
    bool has_signature_size_tag();

private:
    bool f_header_payload_size_tag;
    header_index_record_t* m_header_payload_size_tag;
    bool n_header_payload_size_tag;

public:
    bool _is_null_header_payload_size_tag() { header_payload_size_tag(); return n_header_payload_size_tag; };

private:

public:
    header_index_record_t* header_payload_size_tag();

private:
    bool f_len_header;
    int32_t m_len_header;

public:
    int32_t len_header();

private:
    bool f_len_payload;
    int32_t m_len_payload;
    bool n_len_payload;

public:
    bool _is_null_len_payload() { len_payload(); return n_len_payload; };

private:

public:

    /**
     * Size of the (compressed) payload in bytes. v6 packages store it in
     * `header_tags::payload_size`, v4/v3 packages in `signature_tags::size`
     * (which also includes the size of the header).
     * 
     * If the header and payload together or the uncompressed payload reach
     * 4 GiB, v4 packages use `signature_tags::long_size` instead - see
     * <https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/lib/signature.cc#L182-L212>.
     * 
     * RPM never writes both (so this is just a hypothetical scenario), but if
     * both are present, `signature_tags::long_size` takes precedence over
     * `signature_tags::size`, just like in RPM's `printSize()` function:
     * <https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/lib/signature.cc#L36-L43>
     */
    int32_t len_payload();

private:
    bool f_ofs_header;
    int32_t m_ofs_header;

public:
    int32_t ofs_header();

private:
    bool f_ofs_payload;
    int32_t m_ofs_payload;

public:
    int32_t ofs_payload();

private:
    bool f_payload;
    std::string m_payload;
    bool n_payload;

public:
    bool _is_null_payload() { payload(); return n_payload; };

private:

public:

    /**
     * Archive of the package files, compressed using the method specified by
     * `header_tags::payload_compressor`. If this tag is missing, it's almost
     * certainly uncompressed (except for some very old v3 packages built by RPM
     * 3.0.3 or earlier, which didn't use the tag because the payload was always
     * gzipped; RPM 3.0.5 added support for bzip2 payloads and started writing
     * the tag). However, RPM reads the payload as gzip by default - see
     * <https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/lib/rpmte.cc#L643-L645>.
     * Since zlib's gzip reader passes data that is not in gzip format through
     * unchanged (see
     * <https://github.com/madler/zlib/blob/da607da739fa6047df13e66a2af6b8bec7c2a498/zlib.h#L1386-L1389>),
     * this also works for uncompressed payloads.
     * 
     * The archive format is given by `header_tags::payload_format`, which is
     * `"cpio"` for regular packages. In v4/v3 packages, it's a SVR4 cpio archive
     * without a checksum (the `070701` variant) - the [v4 format
     * documentation](https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_v4.md?plain=1#L106-L107)
     * claims "with a CRC checksum", but that's not true since RPM 2.4.4
     * (released in 1997).
     * 
     * v6 packages and v4 packages with a file over 4 GiB use a stripped-down
     * variant of cpio with the magic `07070X`. Its file headers only hold the
     * index of the file in the file lists of the RPM header, which is the only
     * place where the file names, sizes and other metadata are stored.
     * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_v6.md#payload Source
     * \sa https://github.com/rpm-software-management/rpm/blob/ec9ea8c43808c346da4b6cb454cdc58aef8e506a/docs/manual/format_v4.md#payload Source
     */
    std::string payload();

private:
    bool f_signature_long_size_tag;
    header_index_record_t* m_signature_long_size_tag;
    bool n_signature_long_size_tag;

public:
    bool _is_null_signature_long_size_tag() { signature_long_size_tag(); return n_signature_long_size_tag; };

private:

public:
    header_index_record_t* signature_long_size_tag();

private:
    bool f_signature_size_tag;
    header_index_record_t* m_signature_size_tag;
    bool n_signature_size_tag;

public:
    bool _is_null_signature_size_tag() { signature_size_tag(); return n_signature_size_tag; };

private:

public:
    header_index_record_t* signature_size_tag();

private:
    std::unique_ptr<lead_t> m_lead;
    std::unique_ptr<header_t> m_signature;
    std::string m_signature_padding;
    std::string m__unnamed3;
    bool n__unnamed3;

public:
    bool _is_null__unnamed3() { _unnamed3(); return n__unnamed3; };

private:
    std::unique_ptr<header_t> m_header;
    std::string m__unnamed5;
    bool n__unnamed5;

public:
    bool _is_null__unnamed5() { _unnamed5(); return n__unnamed5; };

private:
    std::unique_ptr<std::vector<std::unique_ptr<signature_tags_step_t>>> m_signature_tags_steps;
    std::unique_ptr<std::vector<std::unique_ptr<header_tags_step_t>>> m_header_tags_steps;
    rpm_t* m__root;
    kaitai::kstruct* m__parent;

public:
    lead_t* lead() const { return m_lead.get(); }
    header_t* signature() const { return m_signature.get(); }
    std::string signature_padding() const { return m_signature_padding; }
    std::string _unnamed3() const { return m__unnamed3; }
    header_t* header() const { return m_header.get(); }
    std::string _unnamed5() const { return m__unnamed5; }
    std::vector<std::unique_ptr<signature_tags_step_t>>* signature_tags_steps() const { return m_signature_tags_steps.get(); }
    std::vector<std::unique_ptr<header_tags_step_t>>* header_tags_steps() const { return m_header_tags_steps.get(); }
    rpm_t* _root() const { return m__root; }
    kaitai::kstruct* _parent() const { return m__parent; }
};

rpm.cpp

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "rpm.h"
#include "kaitai/exceptions.h"
const std::set<rpm_t::architectures_t> rpm_t::_values_architectures_t{
    rpm_t::ARCHITECTURES_NOT_SET,
    rpm_t::ARCHITECTURES_X86,
    rpm_t::ARCHITECTURES_ALPHA,
    rpm_t::ARCHITECTURES_SPARC,
    rpm_t::ARCHITECTURES_MIPS,
    rpm_t::ARCHITECTURES_PPC,
    rpm_t::ARCHITECTURES_M68K,
    rpm_t::ARCHITECTURES_SGI,
    rpm_t::ARCHITECTURES_RS6000,
    rpm_t::ARCHITECTURES_IA64,
    rpm_t::ARCHITECTURES_SPARC64,
    rpm_t::ARCHITECTURES_MIPS64,
    rpm_t::ARCHITECTURES_ARM,
    rpm_t::ARCHITECTURES_M68K_MINT,
    rpm_t::ARCHITECTURES_S390,
    rpm_t::ARCHITECTURES_S390X,
    rpm_t::ARCHITECTURES_PPC64,
    rpm_t::ARCHITECTURES_SH,
    rpm_t::ARCHITECTURES_XTENSA,
    rpm_t::ARCHITECTURES_AARCH64,
    rpm_t::ARCHITECTURES_MIPS_R6,
    rpm_t::ARCHITECTURES_MIPS64_R6,
    rpm_t::ARCHITECTURES_RISCV,
    rpm_t::ARCHITECTURES_LOONGARCH64,
    rpm_t::ARCHITECTURES_E2K,
    rpm_t::ARCHITECTURES_NO_ARCH,
};
bool rpm_t::_is_defined_architectures_t(rpm_t::architectures_t v) {
    return rpm_t::_values_architectures_t.find(v) != rpm_t::_values_architectures_t.end();
}
const std::set<rpm_t::header_tags_t> rpm_t::_values_header_tags_t{
    rpm_t::HEADER_TAGS_SIGNATURES,
    rpm_t::HEADER_TAGS_HEADER_IMMUTABLE,
    rpm_t::HEADER_TAGS_I18N_TABLE,
    rpm_t::HEADER_TAGS_NAME,
    rpm_t::HEADER_TAGS_VERSION,
    rpm_t::HEADER_TAGS_RELEASE,
    rpm_t::HEADER_TAGS_EPOCH,
    rpm_t::HEADER_TAGS_SUMMARY,
    rpm_t::HEADER_TAGS_DESCRIPTION,
    rpm_t::HEADER_TAGS_BUILD_TIME,
    rpm_t::HEADER_TAGS_BUILD_HOST,
    rpm_t::HEADER_TAGS_INSTALL_TIME,
    rpm_t::HEADER_TAGS_SIZE,
    rpm_t::HEADER_TAGS_DISTRIBUTION,
    rpm_t::HEADER_TAGS_VENDOR,
    rpm_t::HEADER_TAGS_GIF_OBSOLETE,
    rpm_t::HEADER_TAGS_XPM_OBSOLETE,
    rpm_t::HEADER_TAGS_LICENSE,
    rpm_t::HEADER_TAGS_PACKAGER,
    rpm_t::HEADER_TAGS_GROUP,
    rpm_t::HEADER_TAGS_CHANGELOG_INTERNAL,
    rpm_t::HEADER_TAGS_SOURCE,
    rpm_t::HEADER_TAGS_PATCH,
    rpm_t::HEADER_TAGS_URL,
    rpm_t::HEADER_TAGS_OS,
    rpm_t::HEADER_TAGS_ARCH,
    rpm_t::HEADER_TAGS_PRE_INSTALL_SCRIPTLET,
    rpm_t::HEADER_TAGS_POST_INSTALL_SCRIPTLET,
    rpm_t::HEADER_TAGS_PRE_UNINSTALL_SCRIPTLET,
    rpm_t::HEADER_TAGS_POST_UNINSTALL_SCRIPTLET,
    rpm_t::HEADER_TAGS_OLD_FILE_NAMES_OBSOLETE,
    rpm_t::HEADER_TAGS_FILE_SIZES,
    rpm_t::HEADER_TAGS_FILE_STATES,
    rpm_t::HEADER_TAGS_FILE_MODES,
    rpm_t::HEADER_TAGS_FILE_UIDS_INTERNAL,
    rpm_t::HEADER_TAGS_FILE_GIDS_INTERNAL,
    rpm_t::HEADER_TAGS_DEVICE_NUMBER,
    rpm_t::HEADER_TAGS_MTIMES,
    rpm_t::HEADER_TAGS_FILE_DIGESTS,
    rpm_t::HEADER_TAGS_LINK_TOS,
    rpm_t::HEADER_TAGS_FILE_FLAGS,
    rpm_t::HEADER_TAGS_ROOT_INTERNAL,
    rpm_t::HEADER_TAGS_FILE_OWNER,
    rpm_t::HEADER_TAGS_FILE_GROUP,
    rpm_t::HEADER_TAGS_EXCLUDE_INTERNAL,
    rpm_t::HEADER_TAGS_EXCLUSIVE_INTERNAL,
    rpm_t::HEADER_TAGS_ICON_OBSOLETE,
    rpm_t::HEADER_TAGS_SOURCE_RPM,
    rpm_t::HEADER_TAGS_FILE_VERIFY_FLAGS,
    rpm_t::HEADER_TAGS_ARCHIVE_SIZE,
    rpm_t::HEADER_TAGS_PROVIDE_NAME,
    rpm_t::HEADER_TAGS_REQUIRE_FLAGS,
    rpm_t::HEADER_TAGS_REQUIRE_NAME,
    rpm_t::HEADER_TAGS_REQUIRE_VERSION,
    rpm_t::HEADER_TAGS_NO_SOURCE,
    rpm_t::HEADER_TAGS_NO_PATCH,
    rpm_t::HEADER_TAGS_CONFLICT_FLAGS,
    rpm_t::HEADER_TAGS_CONFLICT_NAME,
    rpm_t::HEADER_TAGS_CONFLICT_VERSION,
    rpm_t::HEADER_TAGS_DEFAULT_PREFIX_INTERNAL,
    rpm_t::HEADER_TAGS_BUILD_ROOT_INTERNAL,
    rpm_t::HEADER_TAGS_INSTALL_PREFIX_INTERNAL,
    rpm_t::HEADER_TAGS_EXCLUDE_ARCH,
    rpm_t::HEADER_TAGS_EXCLUDE_OS,
    rpm_t::HEADER_TAGS_EXCLUSIVE_ARCH,
    rpm_t::HEADER_TAGS_EXCLUSIVE_OS,
    rpm_t::HEADER_TAGS_AUTOREQPROV_INTERNAL,
    rpm_t::HEADER_TAGS_RPM_VERSION,
    rpm_t::HEADER_TAGS_TRIGGER_SCRIPTS,
    rpm_t::HEADER_TAGS_TRIGGER_NAME,
    rpm_t::HEADER_TAGS_TRIGGER_VERSION,
    rpm_t::HEADER_TAGS_TRIGGER_FLAGS,
    rpm_t::HEADER_TAGS_TRIGGER_INDEX,
    rpm_t::HEADER_TAGS_VERIFY_SCRIPT,
    rpm_t::HEADER_TAGS_CHANGELOG_TIME,
    rpm_t::HEADER_TAGS_CHANGELOG_NAME,
    rpm_t::HEADER_TAGS_CHANGELOG_TEXT,
    rpm_t::HEADER_TAGS_BROKEN_MD5_INTERNAL,
    rpm_t::HEADER_TAGS_PREREQ_INTERNAL,
    rpm_t::HEADER_TAGS_PRE_INSTALL_INTERPRETER,
    rpm_t::HEADER_TAGS_POST_INSTALL_INTERPRETER,
    rpm_t::HEADER_TAGS_PRE_UNINSTALL_INTERPRETER,
    rpm_t::HEADER_TAGS_POST_UNINSTALL_INTERPRETER,
    rpm_t::HEADER_TAGS_BUILD_ARCHS,
    rpm_t::HEADER_TAGS_OBSOLETE_NAME,
    rpm_t::HEADER_TAGS_VERIFY_SCRIPT_PROG,
    rpm_t::HEADER_TAGS_TRIGGER_SCRIPT_PROG,
    rpm_t::HEADER_TAGS_DOC_DIR_INTERNAL,
    rpm_t::HEADER_TAGS_COOKIE,
    rpm_t::HEADER_TAGS_FILE_DEVICES,
    rpm_t::HEADER_TAGS_FILE_INODES,
    rpm_t::HEADER_TAGS_FILE_LANGS,
    rpm_t::HEADER_TAGS_PREFIXES,
    rpm_t::HEADER_TAGS_INSTALL_PREFIXES,
    rpm_t::HEADER_TAGS_TRIGGER_INSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_TRIGGER_UNINSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_TRIGGER_POST_UNINSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_AUTOREQ_INTERNAL,
    rpm_t::HEADER_TAGS_AUTOPROV_INTERNAL,
    rpm_t::HEADER_TAGS_CAPABILITY_INTERNAL,
    rpm_t::HEADER_TAGS_SOURCE_PACKAGE,
    rpm_t::HEADER_TAGS_OLD_ORIG_FILENAMES_INTERNAL,
    rpm_t::HEADER_TAGS_BUILD_PREREQ_INTERNAL,
    rpm_t::HEADER_TAGS_BUILD_REQUIRES_INTERNAL,
    rpm_t::HEADER_TAGS_BUILD_CONFLICTS_INTERNAL,
    rpm_t::HEADER_TAGS_BUILD_MACROS_INTERNAL,
    rpm_t::HEADER_TAGS_PROVIDE_FLAGS,
    rpm_t::HEADER_TAGS_PROVIDE_VERSION,
    rpm_t::HEADER_TAGS_OBSOLETE_FLAGS,
    rpm_t::HEADER_TAGS_OBSOLETE_VERSION,
    rpm_t::HEADER_TAGS_DIR_INDEXES,
    rpm_t::HEADER_TAGS_BASE_NAMES,
    rpm_t::HEADER_TAGS_DIR_NAMES,
    rpm_t::HEADER_TAGS_ORIG_DIR_INDEXES,
    rpm_t::HEADER_TAGS_ORIG_BASE_NAMES,
    rpm_t::HEADER_TAGS_ORIG_DIR_NAMES,
    rpm_t::HEADER_TAGS_OPT_FLAGS,
    rpm_t::HEADER_TAGS_DIST_URL,
    rpm_t::HEADER_TAGS_PAYLOAD_FORMAT,
    rpm_t::HEADER_TAGS_PAYLOAD_COMPRESSOR,
    rpm_t::HEADER_TAGS_PAYLOAD_FLAGS,
    rpm_t::HEADER_TAGS_INSTALL_COLOR,
    rpm_t::HEADER_TAGS_INSTALL_TID,
    rpm_t::HEADER_TAGS_REMOVE_TID_OBSOLETE,
    rpm_t::HEADER_TAGS_SHA1_RHN_INTERNAL,
    rpm_t::HEADER_TAGS_RHN_PLATFORM_INTERNAL,
    rpm_t::HEADER_TAGS_PLATFORM,
    rpm_t::HEADER_TAGS_PATCHES_NAME_OBSOLETE,
    rpm_t::HEADER_TAGS_PATCHES_FLAGS_OBSOLETE,
    rpm_t::HEADER_TAGS_PATCHES_VERSION_OBSOLETE,
    rpm_t::HEADER_TAGS_CACHE_CTIME_INTERNAL,
    rpm_t::HEADER_TAGS_CACHE_PKG_PATH_INTERNAL,
    rpm_t::HEADER_TAGS_CACHE_PKG_SIZE_INTERNAL,
    rpm_t::HEADER_TAGS_CACHE_PKG_MTIME_INTERNAL,
    rpm_t::HEADER_TAGS_FILE_COLORS,
    rpm_t::HEADER_TAGS_FILE_CLASS,
    rpm_t::HEADER_TAGS_CLASS_DICT,
    rpm_t::HEADER_TAGS_FILE_DEPENDS_IDX,
    rpm_t::HEADER_TAGS_FILE_DEPENDS_NUM,
    rpm_t::HEADER_TAGS_DEPENDS_DICT,
    rpm_t::HEADER_TAGS_SOURCE_SIG_MD5,
    rpm_t::HEADER_TAGS_FILE_CONTEXTS_OBSOLETE,
    rpm_t::HEADER_TAGS_FS_CONTEXTS_OBSOLETE,
    rpm_t::HEADER_TAGS_RE_CONTEXTS_OBSOLETE,
    rpm_t::HEADER_TAGS_POLICIES,
    rpm_t::HEADER_TAGS_PRE_TRANS,
    rpm_t::HEADER_TAGS_POST_TRANS,
    rpm_t::HEADER_TAGS_PRE_TRANS_PROG,
    rpm_t::HEADER_TAGS_POST_TRANS_PROG,
    rpm_t::HEADER_TAGS_DIST_TAG,
    rpm_t::HEADER_TAGS_OLD_SUGGESTS_NAME_OBSOLETE,
    rpm_t::HEADER_TAGS_OLD_SUGGESTS_VERSION_OBSOLETE,
    rpm_t::HEADER_TAGS_OLD_SUGGESTS_FLAGS_OBSOLETE,
    rpm_t::HEADER_TAGS_OLD_ENHANCES_NAME_OBSOLETE,
    rpm_t::HEADER_TAGS_OLD_ENHANCES_VERSION_OBSOLETE,
    rpm_t::HEADER_TAGS_OLD_ENHANCES_FLAGS_OBSOLETE,
    rpm_t::HEADER_TAGS_PRIORITY_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_CVSID_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BLINK_PKGID_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BLINK_HDRID_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BLINK_NEVRA_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_FLINK_PKGID_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_FLINK_HDRID_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_FLINK_NEVRA_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_PACKAGE_ORIGIN_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_TRIGGER_PRE_INSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_BUILD_SUGGESTS_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BUILD_ENHANCES_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_SCRIPT_STATES_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_SCRIPT_METRICS_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BUILD_CPU_CLOCK_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_FILE_DIGEST_ALGOS_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_VARIANTS_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_XMAJOR_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_XMINOR_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_REPO_TAG_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_KEYWORDS_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BUILD_PLATFORMS_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_PACKAGE_COLOR_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_PACKAGE_PREF_COLOR_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_XATTRS_DICT_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_FILEX_ATTRSX_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_DEP_ATTRS_DICT_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_CONFLICT_ATTRSX_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_OBSOLETE_ATTRSX_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_PROVIDE_ATTRSX_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_REQUIRE_ATTRSX_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BUILD_PROVIDES_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_BUILD_OBSOLETES_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_DB_INSTANCE,
    rpm_t::HEADER_TAGS_NVRA,
    rpm_t::HEADER_TAGS_FILE_NAMES,
    rpm_t::HEADER_TAGS_FILE_PROVIDE,
    rpm_t::HEADER_TAGS_FILE_REQUIRE,
    rpm_t::HEADER_TAGS_FS_NAMES_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_FS_SIZES_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_TRIGGER_CONDS,
    rpm_t::HEADER_TAGS_TRIGGER_TYPE,
    rpm_t::HEADER_TAGS_ORIG_FILE_NAMES,
    rpm_t::HEADER_TAGS_LONG_FILE_SIZES,
    rpm_t::HEADER_TAGS_LONG_SIZE,
    rpm_t::HEADER_TAGS_FILE_CAPS,
    rpm_t::HEADER_TAGS_FILE_DIGEST_ALGO,
    rpm_t::HEADER_TAGS_BUG_URL,
    rpm_t::HEADER_TAGS_EVR,
    rpm_t::HEADER_TAGS_NVR,
    rpm_t::HEADER_TAGS_NEVR,
    rpm_t::HEADER_TAGS_NEVRA,
    rpm_t::HEADER_TAGS_HEADER_COLOR,
    rpm_t::HEADER_TAGS_VERBOSE,
    rpm_t::HEADER_TAGS_EPOCH_NUM,
    rpm_t::HEADER_TAGS_PRE_INSTALL_FLAGS,
    rpm_t::HEADER_TAGS_POST_INSTALL_FLAGS,
    rpm_t::HEADER_TAGS_PRE_UNINSTALL_FLAGS,
    rpm_t::HEADER_TAGS_POST_UNINSTALL_FLAGS,
    rpm_t::HEADER_TAGS_PRE_TRANS_FLAGS,
    rpm_t::HEADER_TAGS_POST_TRANS_FLAGS,
    rpm_t::HEADER_TAGS_VERIFY_SCRIPT_FLAGS,
    rpm_t::HEADER_TAGS_TRIGGER_SCRIPT_FLAGS,
    rpm_t::HEADER_TAGS_COLLECTIONS_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_POLICY_NAMES,
    rpm_t::HEADER_TAGS_POLICY_TYPES,
    rpm_t::HEADER_TAGS_POLICY_TYPES_INDEXES,
    rpm_t::HEADER_TAGS_POLICY_FLAGS,
    rpm_t::HEADER_TAGS_VCS,
    rpm_t::HEADER_TAGS_ORDER_NAME,
    rpm_t::HEADER_TAGS_ORDER_VERSION,
    rpm_t::HEADER_TAGS_ORDER_FLAGS,
    rpm_t::HEADER_TAGS_MSSF_MANIFEST_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_MSSF_DOMAIN_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_INST_FILE_NAMES,
    rpm_t::HEADER_TAGS_REQUIRE_NEVRS,
    rpm_t::HEADER_TAGS_PROVIDE_NEVRS,
    rpm_t::HEADER_TAGS_OBSOLETE_NEVRS,
    rpm_t::HEADER_TAGS_CONFLICT_NEVRS,
    rpm_t::HEADER_TAGS_FILE_NLINKS,
    rpm_t::HEADER_TAGS_RECOMMEND_NAME,
    rpm_t::HEADER_TAGS_RECOMMEND_VERSION,
    rpm_t::HEADER_TAGS_RECOMMEND_FLAGS,
    rpm_t::HEADER_TAGS_SUGGEST_NAME,
    rpm_t::HEADER_TAGS_SUGGEST_VERSION,
    rpm_t::HEADER_TAGS_SUGGEST_FLAGS,
    rpm_t::HEADER_TAGS_SUPPLEMENT_NAME,
    rpm_t::HEADER_TAGS_SUPPLEMENT_VERSION,
    rpm_t::HEADER_TAGS_SUPPLEMENT_FLAGS,
    rpm_t::HEADER_TAGS_ENHANCE_NAME,
    rpm_t::HEADER_TAGS_ENHANCE_VERSION,
    rpm_t::HEADER_TAGS_ENHANCE_FLAGS,
    rpm_t::HEADER_TAGS_RECOMMEND_NEVRS,
    rpm_t::HEADER_TAGS_SUGGEST_NEVRS,
    rpm_t::HEADER_TAGS_SUPPLEMENT_NEVRS,
    rpm_t::HEADER_TAGS_ENHANCE_NEVRS,
    rpm_t::HEADER_TAGS_ENCODING,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_INSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_UNINSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_POST_UNINSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_SCRIPTS,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_SCRIPT_PROG,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_SCRIPT_FLAGS,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_NAME,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_INDEX,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_VERSION,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_FLAGS,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_INSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_UNINSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_POST_UNINSTALL_INTERNAL,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_SCRIPTS,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_SCRIPT_PROG,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_SCRIPT_FLAGS,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_NAME,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_INDEX,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_VERSION,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_FLAGS,
    rpm_t::HEADER_TAGS_REMOVE_PATH_POSTFIXES_INTERNAL,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_PRIORITIES,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_PRIORITIES,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_CONDS,
    rpm_t::HEADER_TAGS_FILE_TRIGGER_TYPE,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_CONDS,
    rpm_t::HEADER_TAGS_TRANS_FILE_TRIGGER_TYPE,
    rpm_t::HEADER_TAGS_FILE_SIGNATURES,
    rpm_t::HEADER_TAGS_FILE_SIGNATURE_LENGTH,
    rpm_t::HEADER_TAGS_PAYLOAD_SHA256,
    rpm_t::HEADER_TAGS_PAYLOAD_SHA256_ALGO_OBSOLETE,
    rpm_t::HEADER_TAGS_AUTO_INSTALLED_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_IDENTITY_UNIMPLEMENTED,
    rpm_t::HEADER_TAGS_MODULARITY_LABEL,
    rpm_t::HEADER_TAGS_PAYLOAD_SHA256_ALT,
    rpm_t::HEADER_TAGS_ARCH_SUFFIX,
    rpm_t::HEADER_TAGS_SPEC,
    rpm_t::HEADER_TAGS_TRANSLATION_URL,
    rpm_t::HEADER_TAGS_UPSTREAM_RELEASES,
    rpm_t::HEADER_TAGS_SOURCE_LICENSE_INTERNAL,
    rpm_t::HEADER_TAGS_PRE_UNTRANS,
    rpm_t::HEADER_TAGS_POST_UNTRANS,
    rpm_t::HEADER_TAGS_PRE_UNTRANS_PROG,
    rpm_t::HEADER_TAGS_POST_UNTRANS_PROG,
    rpm_t::HEADER_TAGS_PRE_UNTRANS_FLAGS,
    rpm_t::HEADER_TAGS_POST_UNTRANS_FLAGS,
    rpm_t::HEADER_TAGS_SYS_USERS,
    rpm_t::HEADER_TAGS_BUILD_SYSTEM_INTERNAL,
    rpm_t::HEADER_TAGS_BUILD_OPTION_INTERNAL,
    rpm_t::HEADER_TAGS_PAYLOAD_SIZE,
    rpm_t::HEADER_TAGS_PAYLOAD_SIZE_ALT,
    rpm_t::HEADER_TAGS_RPM_FORMAT,
    rpm_t::HEADER_TAGS_FILE_MIME_INDEX,
    rpm_t::HEADER_TAGS_MIME_DICT,
    rpm_t::HEADER_TAGS_FILE_MIMES,
    rpm_t::HEADER_TAGS_PACKAGE_DIGESTS,
    rpm_t::HEADER_TAGS_PACKAGE_DIGEST_ALGOS,
    rpm_t::HEADER_TAGS_SOURCE_NEVR,
    rpm_t::HEADER_TAGS_PAYLOAD_SHA512,
    rpm_t::HEADER_TAGS_PAYLOAD_SHA512_ALT,
    rpm_t::HEADER_TAGS_PAYLOAD_SHA3_256,
    rpm_t::HEADER_TAGS_PAYLOAD_SHA3_256_ALT,
};
bool rpm_t::_is_defined_header_tags_t(rpm_t::header_tags_t v) {
    return rpm_t::_values_header_tags_t.find(v) != rpm_t::_values_header_tags_t.end();
}
const std::set<rpm_t::operating_systems_t> rpm_t::_values_operating_systems_t{
    rpm_t::OPERATING_SYSTEMS_NOT_SET,
    rpm_t::OPERATING_SYSTEMS_LINUX,
    rpm_t::OPERATING_SYSTEMS_IRIX,
    rpm_t::OPERATING_SYSTEMS_NO_OS,
};
bool rpm_t::_is_defined_operating_systems_t(rpm_t::operating_systems_t v) {
    return rpm_t::_values_operating_systems_t.find(v) != rpm_t::_values_operating_systems_t.end();
}
const std::set<rpm_t::record_types_t> rpm_t::_values_record_types_t{
    rpm_t::RECORD_TYPES_CHAR,
    rpm_t::RECORD_TYPES_UINT8,
    rpm_t::RECORD_TYPES_UINT16,
    rpm_t::RECORD_TYPES_UINT32,
    rpm_t::RECORD_TYPES_UINT64,
    rpm_t::RECORD_TYPES_STRING,
    rpm_t::RECORD_TYPES_BIN,
    rpm_t::RECORD_TYPES_STRING_ARRAY,
    rpm_t::RECORD_TYPES_I18N_STRING,
};
bool rpm_t::_is_defined_record_types_t(rpm_t::record_types_t v) {
    return rpm_t::_values_record_types_t.find(v) != rpm_t::_values_record_types_t.end();
}
const std::set<rpm_t::rpm_types_t> rpm_t::_values_rpm_types_t{
    rpm_t::RPM_TYPES_BINARY,
    rpm_t::RPM_TYPES_SOURCE,
};
bool rpm_t::_is_defined_rpm_types_t(rpm_t::rpm_types_t v) {
    return rpm_t::_values_rpm_types_t.find(v) != rpm_t::_values_rpm_types_t.end();
}
const std::set<rpm_t::signature_tags_t> rpm_t::_values_signature_tags_t{
    rpm_t::SIGNATURE_TAGS_SIGNATURES,
    rpm_t::SIGNATURE_TAGS_HEADER_IMMUTABLE,
    rpm_t::SIGNATURE_TAGS_I18N_TABLE,
    rpm_t::SIGNATURE_TAGS_BAD_SHA1_1_OBSOLETE,
    rpm_t::SIGNATURE_TAGS_BAD_SHA1_2_OBSOLETE,
    rpm_t::SIGNATURE_TAGS_DSA,
    rpm_t::SIGNATURE_TAGS_RSA,
    rpm_t::SIGNATURE_TAGS_SHA1,
    rpm_t::SIGNATURE_TAGS_LONG_SIZE,
    rpm_t::SIGNATURE_TAGS_LONG_ARCHIVE_SIZE,
    rpm_t::SIGNATURE_TAGS_SHA256,
    rpm_t::SIGNATURE_TAGS_FILE_SIGNATURES,
    rpm_t::SIGNATURE_TAGS_FILE_SIGNATURE_LENGTH,
    rpm_t::SIGNATURE_TAGS_VERITY_SIGNATURES,
    rpm_t::SIGNATURE_TAGS_VERITY_SIGNATURE_ALGO,
    rpm_t::SIGNATURE_TAGS_OPENPGP,
    rpm_t::SIGNATURE_TAGS_SHA3_256,
    rpm_t::SIGNATURE_TAGS_RESERVED,
    rpm_t::SIGNATURE_TAGS_SIZE,
    rpm_t::SIGNATURE_TAGS_LE_MD5_1_OBSOLETE,
    rpm_t::SIGNATURE_TAGS_PGP,
    rpm_t::SIGNATURE_TAGS_LE_MD5_2_OBSOLETE,
    rpm_t::SIGNATURE_TAGS_MD5,
    rpm_t::SIGNATURE_TAGS_GPG,
    rpm_t::SIGNATURE_TAGS_PGP5_OBSOLETE,
    rpm_t::SIGNATURE_TAGS_PAYLOAD_SIZE,
    rpm_t::SIGNATURE_TAGS_RESERVED_SPACE,
};
bool rpm_t::_is_defined_signature_tags_t(rpm_t::signature_tags_t v) {
    return rpm_t::_values_signature_tags_t.find(v) != rpm_t::_values_signature_tags_t.end();
}

rpm_t::rpm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root ? p__root : this;
    m_lead = nullptr;
    m_signature = nullptr;
    m_header = nullptr;
    m_signature_tags_steps = nullptr;
    m_header_tags_steps = nullptr;
    f_has_header_payload_size_tag = false;
    f_has_payload = false;
    f_has_signature_long_size_tag = false;
    f_has_signature_size_tag = false;
    f_header_payload_size_tag = false;
    f_len_header = false;
    f_len_payload = false;
    f_ofs_header = false;
    f_ofs_payload = false;
    f_payload = false;
    f_signature_long_size_tag = false;
    f_signature_size_tag = false;
    _read();
}

void rpm_t::_read() {
    m_lead = std::unique_ptr<lead_t>(new lead_t(m__io, this, m__root));
    m_signature = std::unique_ptr<header_t>(new header_t(true, m__io, this, m__root));
    m_signature_padding = m__io->read_bytes(kaitai::kstream::mod(-(_io()->pos()), 8));
    n__unnamed3 = true;
    if (ofs_header() < 0) {
        n__unnamed3 = false;
        m__unnamed3 = m__io->read_bytes(0);
    }
    m_header = std::unique_ptr<header_t>(new header_t(false, m__io, this, m__root));
    n__unnamed5 = true;
    if (ofs_payload() < 0) {
        n__unnamed5 = false;
        m__unnamed5 = m__io->read_bytes(0);
    }
    m_signature_tags_steps = std::unique_ptr<std::vector<std::unique_ptr<signature_tags_step_t>>>(new std::vector<std::unique_ptr<signature_tags_step_t>>());
    const int l_signature_tags_steps = signature()->header_record()->num_index_records();
    for (int i = 0; i < l_signature_tags_steps; i++) {
        m_signature_tags_steps->push_back(std::move(std::unique_ptr<signature_tags_step_t>(new signature_tags_step_t(i, ((i != 0) ? (signature_tags_steps()->at(i - 1)->size_tag_idx()) : (-1)), ((i != 0) ? (signature_tags_steps()->at(i - 1)->long_size_tag_idx()) : (-1)), m__io, this, m__root))));
    }
    m_header_tags_steps = std::unique_ptr<std::vector<std::unique_ptr<header_tags_step_t>>>(new std::vector<std::unique_ptr<header_tags_step_t>>());
    const int l_header_tags_steps = header()->header_record()->num_index_records();
    for (int i = 0; i < l_header_tags_steps; i++) {
        m_header_tags_steps->push_back(std::move(std::unique_ptr<header_tags_step_t>(new header_tags_step_t(i, ((i != 0) ? (header_tags_steps()->at(i - 1)->payload_size_tag_idx()) : (-1)), m__io, this, m__root))));
    }
}

rpm_t::~rpm_t() {
    _clean_up();
}

void rpm_t::_clean_up() {
    if (!n__unnamed3) {
    }
    if (!n__unnamed5) {
    }
    if (f_payload && !n_payload) {
    }
}

rpm_t::dummy_t::dummy_t(kaitai::kstream* p__io, rpm_t::header_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void rpm_t::dummy_t::_read() {
}

rpm_t::dummy_t::~dummy_t() {
    _clean_up();
}

void rpm_t::dummy_t::_clean_up() {
}

rpm_t::header_t::header_t(bool p_is_signature, kaitai::kstream* p__io, rpm_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_is_signature = p_is_signature;
    m_header_record = nullptr;
    m_index_records = nullptr;
    m_storage_section = nullptr;
    m__io__raw_storage_section = nullptr;
    f_is_header = false;
    _read();
}

void rpm_t::header_t::_read() {
    m_header_record = std::unique_ptr<header_record_t>(new header_record_t(m__io, this, m__root));
    m_index_records = std::unique_ptr<std::vector<std::unique_ptr<header_index_record_t>>>(new std::vector<std::unique_ptr<header_index_record_t>>());
    const int l_index_records = header_record()->num_index_records();
    for (int i = 0; i < l_index_records; i++) {
        m_index_records->push_back(std::move(std::unique_ptr<header_index_record_t>(new header_index_record_t(m__io, this, m__root))));
    }
    m__raw_storage_section = m__io->read_bytes(header_record()->len_storage_section());
    m__io__raw_storage_section = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_storage_section));
    m_storage_section = std::unique_ptr<dummy_t>(new dummy_t(m__io__raw_storage_section.get(), this, m__root));
}

rpm_t::header_t::~header_t() {
    _clean_up();
}

void rpm_t::header_t::_clean_up() {
}

bool rpm_t::header_t::is_header() {
    if (f_is_header)
        return m_is_header;
    f_is_header = true;
    m_is_header = !(is_signature());
    return m_is_header;
}

rpm_t::header_index_record_t::header_index_record_t(kaitai::kstream* p__io, rpm_t::header_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    f_body = false;
    f_header_tag = false;
    f_len_value = false;
    f_num_values = false;
    f_signature_tag = false;
    _read();
}

void rpm_t::header_index_record_t::_read() {
    m_tag_raw = m__io->read_u4be();
    m_record_type = static_cast<rpm_t::record_types_t>(m__io->read_u4be());
    if (!rpm_t::_is_defined_record_types_t(m_record_type)) {
        throw kaitai::validation_not_in_enum_error<rpm_t::record_types_t>(m_record_type, m__io, std::string("/types/header_index_record/seq/1"));
    }
    m_ofs_body = m__io->read_u4be();
    m_count = m__io->read_u4be();
}

rpm_t::header_index_record_t::~header_index_record_t() {
    _clean_up();
}

void rpm_t::header_index_record_t::_clean_up() {
    if (f_body && !n_body) {
    }
}

kaitai::kstruct* rpm_t::header_index_record_t::body() {
    if (f_body)
        return m_body.get();
    f_body = true;
    kaitai::kstream *io = _parent()->storage_section()->_io();
    std::streampos _pos = io->pos();
    io->seek(ofs_body());
    n_body = true;
    switch (record_type()) {
    case rpm_t::RECORD_TYPES_BIN: {
        n_body = false;
        m_body = std::unique_ptr<record_type_bin_t>(new record_type_bin_t(len_value(), io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_CHAR: {
        n_body = false;
        m_body = std::unique_ptr<record_type_uint8_t>(new record_type_uint8_t(num_values(), io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_I18N_STRING: {
        n_body = false;
        m_body = std::unique_ptr<record_type_string_array_t>(new record_type_string_array_t(num_values(), io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_STRING: {
        n_body = false;
        m_body = std::unique_ptr<record_type_string_t>(new record_type_string_t(io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_STRING_ARRAY: {
        n_body = false;
        m_body = std::unique_ptr<record_type_string_array_t>(new record_type_string_array_t(num_values(), io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_UINT16: {
        n_body = false;
        m_body = std::unique_ptr<record_type_uint16_t>(new record_type_uint16_t(num_values(), io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_UINT32: {
        n_body = false;
        m_body = std::unique_ptr<record_type_uint32_t>(new record_type_uint32_t(num_values(), io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_UINT64: {
        n_body = false;
        m_body = std::unique_ptr<record_type_uint64_t>(new record_type_uint64_t(num_values(), io, this, m__root));
        break;
    }
    case rpm_t::RECORD_TYPES_UINT8: {
        n_body = false;
        m_body = std::unique_ptr<record_type_uint8_t>(new record_type_uint8_t(num_values(), io, this, m__root));
        break;
    }
    }
    io->seek(_pos);
    return m_body.get();
}

rpm_t::header_tags_t rpm_t::header_index_record_t::header_tag() {
    if (f_header_tag)
        return m_header_tag;
    f_header_tag = true;
    n_header_tag = true;
    if (_parent()->is_header()) {
        n_header_tag = false;
        m_header_tag = static_cast<rpm_t::header_tags_t>(tag_raw());
    }
    return m_header_tag;
}

uint32_t rpm_t::header_index_record_t::len_value() {
    if (f_len_value)
        return m_len_value;
    f_len_value = true;
    n_len_value = true;
    if (record_type() == rpm_t::RECORD_TYPES_BIN) {
        n_len_value = false;
        m_len_value = count();
    }
    return m_len_value;
}

uint32_t rpm_t::header_index_record_t::num_values() {
    if (f_num_values)
        return m_num_values;
    f_num_values = true;
    n_num_values = true;
    if (record_type() != rpm_t::RECORD_TYPES_BIN) {
        n_num_values = false;
        m_num_values = count();
    }
    return m_num_values;
}

rpm_t::signature_tags_t rpm_t::header_index_record_t::signature_tag() {
    if (f_signature_tag)
        return m_signature_tag;
    f_signature_tag = true;
    n_signature_tag = true;
    if (_parent()->is_signature()) {
        n_signature_tag = false;
        m_signature_tag = static_cast<rpm_t::signature_tags_t>(tag_raw());
    }
    return m_signature_tag;
}

rpm_t::header_record_t::header_record_t(kaitai::kstream* p__io, rpm_t::header_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void rpm_t::header_record_t::_read() {
    m_magic = m__io->read_bytes(4);
    if (!(m_magic == std::string("\x8E\xAD\xE8\x01", 4))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x8E\xAD\xE8\x01", 4), m_magic, m__io, std::string("/types/header_record/seq/0"));
    }
    m_reserved = m__io->read_bytes(4);
    if (!(m_reserved == std::string("\x00\x00\x00\x00", 4))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\x00\x00\x00\x00", 4), m_reserved, m__io, std::string("/types/header_record/seq/1"));
    }
    m_num_index_records = m__io->read_u4be();
    if (!(m_num_index_records >= 1)) {
        throw kaitai::validation_less_than_error<uint32_t>(1, m_num_index_records, m__io, std::string("/types/header_record/seq/2"));
    }
    if (!(m_num_index_records <= ((_parent()->is_signature()) ? (32) : (65535)))) {
        throw kaitai::validation_greater_than_error<uint32_t>(((_parent()->is_signature()) ? (32) : (65535)), m_num_index_records, m__io, std::string("/types/header_record/seq/2"));
    }
    m_len_storage_section = m__io->read_u4be();
    if (!(m_len_storage_section <= ((_parent()->is_signature()) ? ((64 * 1024) * 1024) : (268435455)))) {
        throw kaitai::validation_greater_than_error<uint32_t>(((_parent()->is_signature()) ? ((64 * 1024) * 1024) : (268435455)), m_len_storage_section, m__io, std::string("/types/header_record/seq/3"));
    }
}

rpm_t::header_record_t::~header_record_t() {
    _clean_up();
}

void rpm_t::header_record_t::_clean_up() {
}

rpm_t::header_tags_step_t::header_tags_step_t(int32_t p_idx, int32_t p_prev_payload_size_tag_idx, kaitai::kstream* p__io, rpm_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_idx = p_idx;
    m_prev_payload_size_tag_idx = p_prev_payload_size_tag_idx;
    f_payload_size_tag_idx = false;
    _read();
}

void rpm_t::header_tags_step_t::_read() {
}

rpm_t::header_tags_step_t::~header_tags_step_t() {
    _clean_up();
}

void rpm_t::header_tags_step_t::_clean_up() {
}

int32_t rpm_t::header_tags_step_t::payload_size_tag_idx() {
    if (f_payload_size_tag_idx)
        return m_payload_size_tag_idx;
    f_payload_size_tag_idx = true;
    m_payload_size_tag_idx = ((prev_payload_size_tag_idx() != -1) ? (prev_payload_size_tag_idx()) : ((( ((_parent()->header()->index_records()->at(idx())->header_tag() == rpm_t::HEADER_TAGS_PAYLOAD_SIZE) && (_parent()->header()->index_records()->at(idx())->record_type() == rpm_t::RECORD_TYPES_UINT64) && (_parent()->header()->index_records()->at(idx())->num_values() >= 1)) ) ? (idx()) : (-1))));
    return m_payload_size_tag_idx;
}

rpm_t::lead_t::lead_t(kaitai::kstream* p__io, rpm_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_version = nullptr;
    _read();
}

void rpm_t::lead_t::_read() {
    m_magic = m__io->read_bytes(4);
    if (!(m_magic == std::string("\xED\xAB\xEE\xDB", 4))) {
        throw kaitai::validation_not_equal_error<std::string>(std::string("\xED\xAB\xEE\xDB", 4), m_magic, m__io, std::string("/types/lead/seq/0"));
    }
    m_version = std::unique_ptr<rpm_version_t>(new rpm_version_t(m__io, this, m__root));
    m_type = static_cast<rpm_t::rpm_types_t>(m__io->read_u2be());
    m_architecture = static_cast<rpm_t::architectures_t>(m__io->read_u2be());
    m_package_name = kaitai::kstream::bytes_to_str(kaitai::kstream::bytes_terminate(m__io->read_bytes(66), 0, false), "UTF-8");
    m_os = static_cast<rpm_t::operating_systems_t>(m__io->read_u2be());
    m_signature_type = m__io->read_u2be();
    if (!(m_signature_type == 5)) {
        throw kaitai::validation_not_equal_error<uint16_t>(5, m_signature_type, m__io, std::string("/types/lead/seq/6"));
    }
    m_reserved = m__io->read_bytes(16);
}

rpm_t::lead_t::~lead_t() {
    _clean_up();
}

void rpm_t::lead_t::_clean_up() {
}

rpm_t::record_type_bin_t::record_type_bin_t(uint32_t p_len_value, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_len_value = p_len_value;
    m_values = nullptr;
    _read();
}

void rpm_t::record_type_bin_t::_read() {
    m_values = std::unique_ptr<std::vector<std::string>>(new std::vector<std::string>());
    const int l_values = 1;
    for (int i = 0; i < l_values; i++) {
        m_values->push_back(std::move(m__io->read_bytes(len_value())));
    }
}

rpm_t::record_type_bin_t::~record_type_bin_t() {
    _clean_up();
}

void rpm_t::record_type_bin_t::_clean_up() {
}

rpm_t::record_type_string_t::record_type_string_t(kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_values = nullptr;
    _read();
}

void rpm_t::record_type_string_t::_read() {
    m_values = std::unique_ptr<std::vector<std::string>>(new std::vector<std::string>());
    const int l_values = 1;
    for (int i = 0; i < l_values; i++) {
        m_values->push_back(std::move(kaitai::kstream::bytes_to_str(m__io->read_bytes_term(0, false, true, true), "UTF-8")));
    }
}

rpm_t::record_type_string_t::~record_type_string_t() {
    _clean_up();
}

void rpm_t::record_type_string_t::_clean_up() {
}

rpm_t::record_type_string_array_t::record_type_string_array_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_num_values = p_num_values;
    m_values = nullptr;
    _read();
}

void rpm_t::record_type_string_array_t::_read() {
    m_values = std::unique_ptr<std::vector<std::string>>(new std::vector<std::string>());
    const int l_values = num_values();
    for (int i = 0; i < l_values; i++) {
        m_values->push_back(std::move(kaitai::kstream::bytes_to_str(m__io->read_bytes_term(0, false, true, true), "UTF-8")));
    }
}

rpm_t::record_type_string_array_t::~record_type_string_array_t() {
    _clean_up();
}

void rpm_t::record_type_string_array_t::_clean_up() {
}

rpm_t::record_type_uint16_t::record_type_uint16_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_num_values = p_num_values;
    m_values = nullptr;
    _read();
}

void rpm_t::record_type_uint16_t::_read() {
    m_values = std::unique_ptr<std::vector<uint16_t>>(new std::vector<uint16_t>());
    const int l_values = num_values();
    for (int i = 0; i < l_values; i++) {
        m_values->push_back(std::move(m__io->read_u2be()));
    }
}

rpm_t::record_type_uint16_t::~record_type_uint16_t() {
    _clean_up();
}

void rpm_t::record_type_uint16_t::_clean_up() {
}

rpm_t::record_type_uint32_t::record_type_uint32_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_num_values = p_num_values;
    m_values = nullptr;
    _read();
}

void rpm_t::record_type_uint32_t::_read() {
    m_values = std::unique_ptr<std::vector<uint32_t>>(new std::vector<uint32_t>());
    const int l_values = num_values();
    for (int i = 0; i < l_values; i++) {
        m_values->push_back(std::move(m__io->read_u4be()));
    }
}

rpm_t::record_type_uint32_t::~record_type_uint32_t() {
    _clean_up();
}

void rpm_t::record_type_uint32_t::_clean_up() {
}

rpm_t::record_type_uint64_t::record_type_uint64_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_num_values = p_num_values;
    m_values = nullptr;
    _read();
}

void rpm_t::record_type_uint64_t::_read() {
    m_values = std::unique_ptr<std::vector<uint64_t>>(new std::vector<uint64_t>());
    const int l_values = num_values();
    for (int i = 0; i < l_values; i++) {
        m_values->push_back(std::move(m__io->read_u8be()));
    }
}

rpm_t::record_type_uint64_t::~record_type_uint64_t() {
    _clean_up();
}

void rpm_t::record_type_uint64_t::_clean_up() {
}

rpm_t::record_type_uint8_t::record_type_uint8_t(uint32_t p_num_values, kaitai::kstream* p__io, rpm_t::header_index_record_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_num_values = p_num_values;
    m_values = nullptr;
    _read();
}

void rpm_t::record_type_uint8_t::_read() {
    m_values = std::unique_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>());
    const int l_values = num_values();
    for (int i = 0; i < l_values; i++) {
        m_values->push_back(std::move(m__io->read_u1()));
    }
}

rpm_t::record_type_uint8_t::~record_type_uint8_t() {
    _clean_up();
}

void rpm_t::record_type_uint8_t::_clean_up() {
}

rpm_t::rpm_version_t::rpm_version_t(kaitai::kstream* p__io, rpm_t::lead_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void rpm_t::rpm_version_t::_read() {
    m_major = m__io->read_u1();
    if (!(m_major >= 3)) {
        throw kaitai::validation_less_than_error<uint8_t>(3, m_major, m__io, std::string("/types/rpm_version/seq/0"));
    }
    if (!(m_major <= 4)) {
        throw kaitai::validation_greater_than_error<uint8_t>(4, m_major, m__io, std::string("/types/rpm_version/seq/0"));
    }
    m_minor = m__io->read_u1();
}

rpm_t::rpm_version_t::~rpm_version_t() {
    _clean_up();
}

void rpm_t::rpm_version_t::_clean_up() {
}

rpm_t::signature_tags_step_t::signature_tags_step_t(int32_t p_idx, int32_t p_prev_size_tag_idx, int32_t p_prev_long_size_tag_idx, kaitai::kstream* p__io, rpm_t* p__parent, rpm_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_idx = p_idx;
    m_prev_size_tag_idx = p_prev_size_tag_idx;
    m_prev_long_size_tag_idx = p_prev_long_size_tag_idx;
    f_long_size_tag_idx = false;
    f_size_tag_idx = false;
    _read();
}

void rpm_t::signature_tags_step_t::_read() {
}

rpm_t::signature_tags_step_t::~signature_tags_step_t() {
    _clean_up();
}

void rpm_t::signature_tags_step_t::_clean_up() {
}

int32_t rpm_t::signature_tags_step_t::long_size_tag_idx() {
    if (f_long_size_tag_idx)
        return m_long_size_tag_idx;
    f_long_size_tag_idx = true;
    m_long_size_tag_idx = ((prev_long_size_tag_idx() != -1) ? (prev_long_size_tag_idx()) : ((( ((_parent()->signature()->index_records()->at(idx())->signature_tag() == rpm_t::SIGNATURE_TAGS_LONG_SIZE) && (_parent()->signature()->index_records()->at(idx())->record_type() == rpm_t::RECORD_TYPES_UINT64) && (_parent()->signature()->index_records()->at(idx())->num_values() >= 1)) ) ? (idx()) : (-1))));
    return m_long_size_tag_idx;
}

int32_t rpm_t::signature_tags_step_t::size_tag_idx() {
    if (f_size_tag_idx)
        return m_size_tag_idx;
    f_size_tag_idx = true;
    m_size_tag_idx = ((prev_size_tag_idx() != -1) ? (prev_size_tag_idx()) : ((( ((_parent()->signature()->index_records()->at(idx())->signature_tag() == rpm_t::SIGNATURE_TAGS_SIZE) && (_parent()->signature()->index_records()->at(idx())->record_type() == rpm_t::RECORD_TYPES_UINT32) && (_parent()->signature()->index_records()->at(idx())->num_values() >= 1)) ) ? (idx()) : (-1))));
    return m_size_tag_idx;
}

bool rpm_t::has_header_payload_size_tag() {
    if (f_has_header_payload_size_tag)
        return m_has_header_payload_size_tag;
    f_has_header_payload_size_tag = true;
    m_has_header_payload_size_tag = header_tags_steps()->back()->payload_size_tag_idx() != -1;
    return m_has_header_payload_size_tag;
}

bool rpm_t::has_payload() {
    if (f_has_payload)
        return m_has_payload;
    f_has_payload = true;
    m_has_payload =  ((has_header_payload_size_tag()) || (has_signature_long_size_tag()) || (has_signature_size_tag())) ;
    return m_has_payload;
}

bool rpm_t::has_signature_long_size_tag() {
    if (f_has_signature_long_size_tag)
        return m_has_signature_long_size_tag;
    f_has_signature_long_size_tag = true;
    m_has_signature_long_size_tag = signature_tags_steps()->back()->long_size_tag_idx() != -1;
    return m_has_signature_long_size_tag;
}

bool rpm_t::has_signature_size_tag() {
    if (f_has_signature_size_tag)
        return m_has_signature_size_tag;
    f_has_signature_size_tag = true;
    m_has_signature_size_tag = signature_tags_steps()->back()->size_tag_idx() != -1;
    return m_has_signature_size_tag;
}

rpm_t::header_index_record_t* rpm_t::header_payload_size_tag() {
    if (f_header_payload_size_tag)
        return m_header_payload_size_tag;
    f_header_payload_size_tag = true;
    n_header_payload_size_tag = true;
    if (has_header_payload_size_tag()) {
        n_header_payload_size_tag = false;
        m_header_payload_size_tag = header()->index_records()->at(header_tags_steps()->back()->payload_size_tag_idx()).get();
    }
    return m_header_payload_size_tag;
}

int32_t rpm_t::len_header() {
    if (f_len_header)
        return m_len_header;
    f_len_header = true;
    m_len_header = ofs_payload() - ofs_header();
    return m_len_header;
}

int32_t rpm_t::len_payload() {
    if (f_len_payload)
        return m_len_payload;
    f_len_payload = true;
    n_len_payload = true;
    if (has_payload()) {
        n_len_payload = false;
        m_len_payload = ((has_header_payload_size_tag()) ? (static_cast<rpm_t::record_type_uint64_t*>(header_payload_size_tag()->body())->values()->at(0)) : (((has_signature_long_size_tag()) ? (static_cast<rpm_t::record_type_uint64_t*>(signature_long_size_tag()->body())->values()->at(0) - len_header()) : (static_cast<rpm_t::record_type_uint32_t*>(signature_size_tag()->body())->values()->at(0) - len_header()))));
    }
    return m_len_payload;
}

int32_t rpm_t::ofs_header() {
    if (f_ofs_header)
        return m_ofs_header;
    f_ofs_header = true;
    m_ofs_header = _io()->pos();
    return m_ofs_header;
}

int32_t rpm_t::ofs_payload() {
    if (f_ofs_payload)
        return m_ofs_payload;
    f_ofs_payload = true;
    m_ofs_payload = _io()->pos();
    return m_ofs_payload;
}

std::string rpm_t::payload() {
    if (f_payload)
        return m_payload;
    f_payload = true;
    n_payload = true;
    if (has_payload()) {
        n_payload = false;
        std::streampos _pos = m__io->pos();
        m__io->seek(ofs_payload());
        m_payload = m__io->read_bytes(len_payload());
        m__io->seek(_pos);
    }
    return m_payload;
}

rpm_t::header_index_record_t* rpm_t::signature_long_size_tag() {
    if (f_signature_long_size_tag)
        return m_signature_long_size_tag;
    f_signature_long_size_tag = true;
    n_signature_long_size_tag = true;
    if (has_signature_long_size_tag()) {
        n_signature_long_size_tag = false;
        m_signature_long_size_tag = signature()->index_records()->at(signature_tags_steps()->back()->long_size_tag_idx()).get();
    }
    return m_signature_long_size_tag;
}

rpm_t::header_index_record_t* rpm_t::signature_size_tag() {
    if (f_signature_size_tag)
        return m_signature_size_tag;
    f_signature_size_tag = true;
    n_signature_size_tag = true;
    if (has_signature_size_tag()) {
        n_signature_size_tag = false;
        m_signature_size_tag = signature()->index_records()->at(signature_tags_steps()->back()->size_tag_idx()).get();
    }
    return m_signature_size_tag;
}