/* Copyright 2017 R. Thomas
 * Copyright 2017 Quarkslab
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "LIEF/PE/Structures.hpp"
#include "LIEF/PE/EnumToString.hpp"

#include "frozen.hpp"

namespace LIEF {
namespace PE {

const char* to_string(PE_TYPE e) {
  CONST_MAP(PE_TYPE, const char*, 2) enumStrings {
    { PE_TYPE::PE32,     "PE32" },
    { PE_TYPE::PE32_PLUS,"PE32_PLUS" },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}

const char* to_string(DATA_DIRECTORY e) {
  CONST_MAP(DATA_DIRECTORY, const char*, 15) enumStrings {
    { DATA_DIRECTORY::EXPORT_TABLE,            "EXPORT_TABLE" },
    { DATA_DIRECTORY::IMPORT_TABLE,            "IMPORT_TABLE" },
    { DATA_DIRECTORY::RESOURCE_TABLE,          "RESOURCE_TABLE" },
    { DATA_DIRECTORY::EXCEPTION_TABLE,         "EXCEPTION_TABLE" },
    { DATA_DIRECTORY::CERTIFICATE_TABLE,       "CERTIFICATE_TABLE" },
    { DATA_DIRECTORY::BASE_RELOCATION_TABLE,   "BASE_RELOCATION_TABLE" },
    { DATA_DIRECTORY::DEBUG,                   "DEBUG" },
    { DATA_DIRECTORY::ARCHITECTURE,            "ARCHITECTURE" },
    { DATA_DIRECTORY::GLOBAL_PTR,              "GLOBAL_PTR" },
    { DATA_DIRECTORY::TLS_TABLE,               "TLS_TABLE" },
    { DATA_DIRECTORY::LOAD_CONFIG_TABLE,       "LOAD_CONFIG_TABLE" },
    { DATA_DIRECTORY::BOUND_IMPORT,            "BOUND_IMPORT" },
    { DATA_DIRECTORY::IAT,                     "IAT" },
    { DATA_DIRECTORY::DELAY_IMPORT_DESCRIPTOR, "DELAY_IMPORT_DESCRIPTOR" },
    { DATA_DIRECTORY::CLR_RUNTIME_HEADER,      "CLR_RUNTIME_HEADER" }
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(MACHINE_TYPES e) {
  CONST_MAP(MACHINE_TYPES, const char*, 25) enumStrings {
    { MACHINE_TYPES::MT_Invalid,                   "INVALID" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_UNKNOWN,   "UNKNOWN" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_AM33,      "AM33" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_AMD64,     "AMD64" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_ARM,       "ARM" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_ARMNT,     "ARMNT" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_EBC,       "EBC" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_I386,      "I386" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_IA64,      "IA64" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_M32R,      "M32R" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_MIPS16,    "MIPS16" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_MIPSFPU,   "MIPSFPU" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_MIPSFPU16, "MIPSFPU16" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_POWERPC,   "POWERPC" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_POWERPCFP, "POWERPCFP" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_R4000,     "R4000" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_RISCV32,   "RISCV32" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_RISCV64,   "RISCV64" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_RISCV128,  "RISCV128" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_SH3,       "SH3" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_SH3DSP,    "SH3DSP" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_SH4,       "SH4" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_SH5,       "SH5" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_THUMB,     "THUMB" },
    { MACHINE_TYPES::IMAGE_FILE_MACHINE_WCEMIPSV2, "WCEMIPSV2" }
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}



const char* to_string(HEADER_CHARACTERISTICS e) {
  CONST_MAP(HEADER_CHARACTERISTICS, const char*, 15) enumStrings {
    { HEADER_CHARACTERISTICS::IMAGE_FILE_RELOCS_STRIPPED,         "RELOCS_STRIPPED" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_EXECUTABLE_IMAGE,        "EXECUTABLE_IMAGE" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_LINE_NUMS_STRIPPED,      "LINE_NUMS_STRIPPED" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_LOCAL_SYMS_STRIPPED,     "LOCAL_SYMS_STRIPPED" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_AGGRESSIVE_WS_TRIM,      "AGGRESSIVE_WS_TRIM" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_LARGE_ADDRESS_AWARE,     "LARGE_ADDRESS_AWARE" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_BYTES_REVERSED_LO,       "BYTES_REVERSED_LO" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_32BIT_MACHINE,           "CHARA_32BIT_MACHINE" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_DEBUG_STRIPPED,          "DEBUG_STRIPPED" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, "REMOVABLE_RUN_FROM_SWAP" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_NET_RUN_FROM_SWAP,       "NET_RUN_FROM_SWAP" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_SYSTEM,                  "SYSTEM" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_DLL,                     "DLL" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_UP_SYSTEM_ONLY,          "UP_SYSTEM_ONLY" },
    { HEADER_CHARACTERISTICS::IMAGE_FILE_BYTES_REVERSED_HI,       "BYTES_REVERSED_HI" }
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(SUBSYSTEM e) {
  CONST_MAP(SUBSYSTEM, const char*, 14) enumStrings {
    { SUBSYSTEM::IMAGE_SUBSYSTEM_UNKNOWN,                  "UNKNOWN" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_NATIVE,                   "NATIVE" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_WINDOWS_GUI,              "WINDOWS_GUI" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_WINDOWS_CUI,              "WINDOWS_CUI" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_OS2_CUI,                  "OS2_CUI" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_POSIX_CUI,                "POSIX_CUI" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_NATIVE_WINDOWS,           "NATIVE_WINDOWS" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI,           "WINDOWS_CE_GUI" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_EFI_APPLICATION,          "EFI_APPLICATION" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER,  "EFI_BOOT_SERVICE_DRIVER" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER,       "EFI_RUNTIME_DRIVER" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_EFI_ROM,                  "EFI_ROM" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_XBOX,                     "XBOX" },
    { SUBSYSTEM::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION, "WINDOWS_BOOT_APPLICATION" },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(DLL_CHARACTERISTICS e) {
  CONST_MAP(DLL_CHARACTERISTICS, const char*, 11) enumStrings {
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA,       "HIGH_ENTROPY_VA" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE,          "DYNAMIC_BASE" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY,       "FORCE_INTEGRITY" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_NX_COMPAT,             "NX_COMPAT" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION,          "NO_ISOLATION" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_NO_SEH,                "NO_SEH" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_NO_BIND,               "NO_BIND" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_APPCONTAINER,          "APPCONTAINER" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER,            "WDM_DRIVER" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_GUARD_CF,              "GUARD_CF" },
    { DLL_CHARACTERISTICS::IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE, "TERMINAL_SERVER_AWARE" },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(SECTION_CHARACTERISTICS e) {
  CONST_MAP(SECTION_CHARACTERISTICS, const char*, 35) enumStrings {
      { SECTION_CHARACTERISTICS::IMAGE_SCN_TYPE_NO_PAD,            "TYPE_NO_PAD" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_CNT_CODE,               "CNT_CODE" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_CNT_INITIALIZED_DATA,   "CNT_INITIALIZED_DATA" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_CNT_UNINITIALIZED_DATA, "CNT_UNINITIALIZED_DATA" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_LNK_OTHER,              "LNK_OTHER" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_LNK_INFO,               "LNK_INFO" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_LNK_REMOVE,             "LNK_REMOVE" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_LNK_COMDAT,             "LNK_COMDAT" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_GPREL,                  "GPREL" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_PURGEABLE,          "MEM_PURGEABLE" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_16BIT,              "MEM_16BIT" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_LOCKED,             "MEM_LOCKED" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_PRELOAD,            "MEM_PRELOAD" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_1BYTES,           "ALIGN_1BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_2BYTES,           "ALIGN_2BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_4BYTES,           "ALIGN_4BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_8BYTES,           "ALIGN_8BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_16BYTES,          "ALIGN_16BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_32BYTES,          "ALIGN_32BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_64BYTES,          "ALIGN_64BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_128BYTES,         "ALIGN_128BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_256BYTES,         "ALIGN_256BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_512BYTES,         "ALIGN_512BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_1024BYTES,        "ALIGN_1024BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_2048BYTES,        "ALIGN_2048BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_4096BYTES,        "ALIGN_4096BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_ALIGN_8192BYTES,        "ALIGN_8192BYTES" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_LNK_NRELOC_OVFL,        "LNK_NRELOC_OVFL" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_DISCARDABLE,        "MEM_DISCARDABLE" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_NOT_CACHED,         "MEM_NOT_CACHED" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_NOT_PAGED,          "MEM_NOT_PAGED" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_SHARED,             "MEM_SHARED" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_EXECUTE,            "MEM_EXECUTE" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_READ,               "MEM_READ" },
      { SECTION_CHARACTERISTICS::IMAGE_SCN_MEM_WRITE,              "MEM_WRITE" }
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(PE_SECTION_TYPES e) {
  CONST_MAP(PE_SECTION_TYPES, const char*, 10) enumStrings {
    { PE_SECTION_TYPES::TEXT,       "TEXT"       },
    { PE_SECTION_TYPES::TLS,        "TLS_"       },
    { PE_SECTION_TYPES::IMPORT,     "IDATA"      },
    { PE_SECTION_TYPES::DATA,       "DATA"       },
    { PE_SECTION_TYPES::BSS,        "BSS"        },
    { PE_SECTION_TYPES::RESOURCE,   "RESOURCE"   },
    { PE_SECTION_TYPES::RELOCATION, "RELOCATION" },
    { PE_SECTION_TYPES::EXPORT,     "EXPORT"     },
    { PE_SECTION_TYPES::DEBUG,      "DEBUG"      },
    { PE_SECTION_TYPES::UNKNOWN,    "UNKNOWN"    },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}

const char* to_string(SYMBOL_BASE_TYPES e) {
  CONST_MAP(SYMBOL_BASE_TYPES, const char*, 16) enumStrings {
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_NULL,   "NULL"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_VOID,   "VOID"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_CHAR,   "CHAR"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_SHORT,  "SHORT"  },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_INT,    "INT"    },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_LONG,   "LONG"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_FLOAT,  "FLOAT"  },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_DOUBLE, "DOUBLE" },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_STRUCT, "STRUCT" },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_UNION,  "UNION"  },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_ENUM,   "ENUM"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_MOE,    "MOE"    },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_BYTE,   "BYTE"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_WORD,   "WORD"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_UINT,   "UINT"   },
    { SYMBOL_BASE_TYPES::IMAGE_SYM_TYPE_DWORD,  "DWORD"  },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}

const char* to_string(SYMBOL_COMPLEX_TYPES e) {
  CONST_MAP(SYMBOL_COMPLEX_TYPES, const char*, 5) enumStrings {
    { SYMBOL_COMPLEX_TYPES::IMAGE_SYM_DTYPE_NULL,     "NULL"               },
    { SYMBOL_COMPLEX_TYPES::IMAGE_SYM_DTYPE_POINTER,  "POINTER"            },
    { SYMBOL_COMPLEX_TYPES::IMAGE_SYM_DTYPE_FUNCTION, "FUNCTION"           },
    { SYMBOL_COMPLEX_TYPES::IMAGE_SYM_DTYPE_ARRAY,    "ARRAY"              },
    { SYMBOL_COMPLEX_TYPES::SCT_COMPLEX_TYPE_SHIFT,   "COMPLEX_TYPE_SHIFT" },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(SYMBOL_SECTION_NUMBER e) {
  CONST_MAP(SYMBOL_SECTION_NUMBER, const char*, 3) enumStrings {
    { SYMBOL_SECTION_NUMBER::IMAGE_SYM_DEBUG,     "DEBUG"     },
    { SYMBOL_SECTION_NUMBER::IMAGE_SYM_ABSOLUTE,  "ABSOLUTE"  },
    { SYMBOL_SECTION_NUMBER::IMAGE_SYM_UNDEFINED, "UNDEFINED" },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(SYMBOL_STORAGE_CLASS e) {
  CONST_MAP(SYMBOL_STORAGE_CLASS, const char*, 24) enumStrings {
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_END_OF_FUNCTION,  "END_OF_FUNCTION"  },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_NULL,             "NULL"             },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_AUTOMATIC,        "AUTOMATIC"        },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_EXTERNAL,         "EXTERNAL"         },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_STATIC,           "STATIC"           },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_REGISTER,         "REGISTER"         },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_EXTERNAL_DEF,     "EXTERNAL_DEF"     },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_LABEL,            "LABEL"            },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_UNDEFINED_LABEL,  "UNDEFINED_LABEL"  },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT, "MEMBER_OF_STRUCT" },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_UNION_TAG,        "UNION_TAG"        },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_TYPE_DEFINITION,  "TYPE_DEFINITION"  },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_UNDEFINED_STATIC, "UDEFINED_STATIC"  },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_ENUM_TAG,         "ENUM_TAG"         },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_MEMBER_OF_ENUM,   "MEMBER_OF_ENUM"   },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_REGISTER_PARAM,   "REGISTER_PARAM"   },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_BIT_FIELD,        "BIT_FIELD"        },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_BLOCK,            "BLOCK"            },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_FUNCTION,         "FUNCTION"         },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_END_OF_STRUCT,    "END_OF_STRUCT"    },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_FILE,             "FILE"             },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_SECTION,          "SECTION"          },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_WEAK_EXTERNAL,    "WEAK_EXTERNAL"    },
    { SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_CLR_TOKEN,        "CLR_TOKEN"        },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(RELOCATIONS_I386 e) {
  CONST_MAP(RELOCATIONS_I386, const char*, 11) enumStrings {
    { RELOCATIONS_I386::IMAGE_REL_I386_ABSOLUTE,  "ABSOLUTE" },
    { RELOCATIONS_I386::IMAGE_REL_I386_DIR16,     "DIR16"    },
    { RELOCATIONS_I386::IMAGE_REL_I386_REL16,     "REL16"    },
    { RELOCATIONS_I386::IMAGE_REL_I386_DIR32,     "DIR32"    },
    { RELOCATIONS_I386::IMAGE_REL_I386_DIR32NB,   "DIR32NB"  },
    { RELOCATIONS_I386::IMAGE_REL_I386_SEG12,     "SEG12"    },
    { RELOCATIONS_I386::IMAGE_REL_I386_SECTION,   "SECTION"  },
    { RELOCATIONS_I386::IMAGE_REL_I386_SECREL,    "SECREL"   },
    { RELOCATIONS_I386::IMAGE_REL_I386_TOKEN,     "TOKEN"    },
    { RELOCATIONS_I386::IMAGE_REL_I386_SECREL7,   "SECREL7"  },
    { RELOCATIONS_I386::IMAGE_REL_I386_REL32,     "REL32"    },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}



const char* to_string(RELOCATIONS_AMD64 e) {
  CONST_MAP(RELOCATIONS_AMD64, const char*, 17) enumStrings {
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_ABSOLUTE, "ABSOLUTE" },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_ADDR64,   "ADDR64"   },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_ADDR32,   "ADDR32"   },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_ADDR32NB, "ADDR32NB" },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_REL32,    "REL32"    },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_REL32_1,  "REL32_1"  },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_REL32_2,  "REL32_2"  },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_REL32_3,  "REL32_3"  },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_REL32_4,  "REL32_4"  },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_REL32_5,  "REL32_5"  },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_SECTION,  "SECTION"  },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_SECREL,   "SECREL"   },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_SECREL7,  "SECREL7"  },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_TOKEN,    "TOKEN"    },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_SREL32,   "SREL32"   },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_PAIR,     "PAIR"     },
    { RELOCATIONS_AMD64::IMAGE_REL_AMD64_SSPAN32,  "SSPAN32"  },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}



const char* to_string(RELOCATIONS_ARM e) {
  CONST_MAP(RELOCATIONS_ARM, const char*, 15) enumStrings {
    { RELOCATIONS_ARM::IMAGE_REL_ARM_ABSOLUTE,  "ABSOLUTE"  },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_ADDR32,    "ADDR32"    },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_ADDR32NB,  "ADDR32NB"  },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_BRANCH24,  "BRANCH24"  },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_BRANCH11,  "BRANCH11"  },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_TOKEN,     "TOKEN"     },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_BLX24,     "BLX24"     },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_BLX11,     "BLX11"     },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_SECTION,   "SECTION"   },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_SECREL,    "SECREL"    },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_MOV32A,    "MOV32A"    },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_MOV32T,    "MOV32T"    },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_BRANCH20T, "BRANCH20T" },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_BRANCH24T, "BRANCH24T" },
    { RELOCATIONS_ARM::IMAGE_REL_ARM_BLX23T,    "BLX23T"    },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(RELOCATIONS_BASE_TYPES e) {
  CONST_MAP(RELOCATIONS_BASE_TYPES, const char*, 12) enumStrings {
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ABSOLUTE,       "ABSOLUTE"  },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGH,           "HIGH"      },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_LOW,            "LOW"       },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHLOW,        "HIGHLOW"   },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHADJ,        "HIGHADJ"   },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_MIPS_JMPADDR,   "JMPADDR"   },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_SECTION,        "SECTION"   },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_REL,            "REL"       },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_MIPS_JMPADDR16, "JMPADDR16" },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_IA64_IMM64,     "IMM64"     },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_DIR64,          "DIR64"     },
    { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGH3ADJ,       "HIGH3ADJ"  }
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}



const char* to_string(DEBUG_TYPES e) {
  CONST_MAP(DEBUG_TYPES, const char*, 16) enumStrings {
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_UNKNOWN,       "UNKNOWN"    },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_COFF,          "COFF"       },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_CODEVIEW,      "CODEVIEW"   },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_FPO,           "FPO"        },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_MISC,          "MISC"       },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_EXCEPTION,     "EXCEPTION"  },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_FIXUP,         "FIXUP"      },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_OMAP_TO_SRC,   "SRC"        },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_OMAP_FROM_SRC, "SRC"        },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_BORLAND,       "BORLAND"    },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_CLSID,         "CLSID"      },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_VC_FEATURE,    "VC_FEATURE" },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_POGO,          "POGO"       },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_ILTCG,         "ILTCG"      },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_MPX,           "MPX"        },
    { DEBUG_TYPES::IMAGE_DEBUG_TYPE_REPRO,         "REPRO"      },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(RESOURCE_TYPES e) {
  CONST_MAP(RESOURCE_TYPES, const char*, 21) enumStrings {
    { RESOURCE_TYPES::CURSOR,       "CURSOR"       },
    { RESOURCE_TYPES::BITMAP,       "BITMAP"       },
    { RESOURCE_TYPES::ICON,         "ICON"         },
    { RESOURCE_TYPES::MENU,         "MENU"         },
    { RESOURCE_TYPES::DIALOG,       "DIALOG"       },
    { RESOURCE_TYPES::STRING,       "STRING"       },
    { RESOURCE_TYPES::FONTDIR,      "FONTDIR"      },
    { RESOURCE_TYPES::FONT,         "FONT"         },
    { RESOURCE_TYPES::ACCELERATOR,  "ACCELERATOR"  },
    { RESOURCE_TYPES::RCDATA,       "RCDATA"       },
    { RESOURCE_TYPES::MESSAGETABLE, "MESSAGETABLE" },
    { RESOURCE_TYPES::GROUP_CURSOR, "GROUP_CURSOR" },
    { RESOURCE_TYPES::GROUP_ICON,   "GROUP_ICON"   },
    { RESOURCE_TYPES::VERSION,      "VERSION"      },
    { RESOURCE_TYPES::DLGINCLUDE,   "DLGINCLUDE"   },
    { RESOURCE_TYPES::PLUGPLAY,     "PLUGPLAY"     },
    { RESOURCE_TYPES::VXD,          "VXD"          },
    { RESOURCE_TYPES::ANICURSOR,    "ANICURSOR"    },
    { RESOURCE_TYPES::ANIICON,      "ANIICON"      },
    { RESOURCE_TYPES::HTML,         "HTML"         },
    { RESOURCE_TYPES::MANIFEST,     "MANIFEST"     },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}

const char* to_string(RESOURCE_LANGS e) {
  CONST_MAP(RESOURCE_LANGS, const char*, 103) enumStrings {
    { RESOURCE_LANGS::LANG_NEUTRAL,        "NEUTRAL" },
    { RESOURCE_LANGS::LANG_INVARIANT,      "INVARIANT" },
    { RESOURCE_LANGS::LANG_AFRIKAANS,      "AFRIKAANS" },
    { RESOURCE_LANGS::LANG_ALBANIAN,       "ALBANIAN" },
    { RESOURCE_LANGS::LANG_ARABIC,         "ARABIC" },
    { RESOURCE_LANGS::LANG_ARMENIAN,       "ARMENIAN" },
    { RESOURCE_LANGS::LANG_ASSAMESE,       "ASSAMESE" },
    { RESOURCE_LANGS::LANG_AZERI,          "AZERI" },
    { RESOURCE_LANGS::LANG_BASQUE,         "BASQUE" },
    { RESOURCE_LANGS::LANG_BELARUSIAN,     "BELARUSIAN" },
    { RESOURCE_LANGS::LANG_BANGLA,         "BANGLA" },
    { RESOURCE_LANGS::LANG_BULGARIAN,      "BULGARIAN" },
    { RESOURCE_LANGS::LANG_CATALAN,        "CATALAN" },
    { RESOURCE_LANGS::LANG_CHINESE,        "CHINESE" },
    { RESOURCE_LANGS::LANG_CROATIAN,       "CROATIAN" },
    { RESOURCE_LANGS::LANG_BOSNIAN,        "BOSNIAN" },
    { RESOURCE_LANGS::LANG_CZECH,          "CZECH" },
    { RESOURCE_LANGS::LANG_DANISH,         "DANISH" },
    { RESOURCE_LANGS::LANG_DIVEHI,         "DIVEHI" },
    { RESOURCE_LANGS::LANG_DUTCH,          "DUTCH" },
    { RESOURCE_LANGS::LANG_ENGLISH,        "ENGLISH" },
    { RESOURCE_LANGS::LANG_ESTONIAN,       "ESTONIAN" },
    { RESOURCE_LANGS::LANG_FAEROESE,       "FAEROESE" },
    { RESOURCE_LANGS::LANG_FARSI,          "FARSI" },
    { RESOURCE_LANGS::LANG_FINNISH,        "FINNISH" },
    { RESOURCE_LANGS::LANG_FRENCH,         "FRENCH" },
    { RESOURCE_LANGS::LANG_GALICIAN,       "GALICIAN" },
    { RESOURCE_LANGS::LANG_GEORGIAN,       "GEORGIAN" },
    { RESOURCE_LANGS::LANG_GERMAN,         "GERMAN" },
    { RESOURCE_LANGS::LANG_GREEK,          "GREEK" },
    { RESOURCE_LANGS::LANG_GUJARATI,       "GUJARATI" },
    { RESOURCE_LANGS::LANG_HEBREW,         "HEBREW" },
    { RESOURCE_LANGS::LANG_HINDI,          "HINDI" },
    { RESOURCE_LANGS::LANG_HUNGARIAN,      "HUNGARIAN" },
    { RESOURCE_LANGS::LANG_ICELANDIC,      "ICELANDIC" },
    { RESOURCE_LANGS::LANG_INDONESIAN,     "INDONESIAN" },
    { RESOURCE_LANGS::LANG_ITALIAN,        "ITALIAN" },
    { RESOURCE_LANGS::LANG_JAPANESE,       "JAPANESE" },
    { RESOURCE_LANGS::LANG_KANNADA,        "KANNADA" },
    { RESOURCE_LANGS::LANG_KASHMIRI,       "KASHMIRI" },
    { RESOURCE_LANGS::LANG_KAZAK,          "KAZAK" },
    { RESOURCE_LANGS::LANG_KONKANI,        "KONKANI" },
    { RESOURCE_LANGS::LANG_KOREAN,         "KOREAN" },
    { RESOURCE_LANGS::LANG_KYRGYZ,         "KYRGYZ" },
    { RESOURCE_LANGS::LANG_LATVIAN,        "LATVIAN" },
    { RESOURCE_LANGS::LANG_LITHUANIAN,     "LITHUANIAN" },
    { RESOURCE_LANGS::LANG_MACEDONIAN,     "MACEDONIAN" },
    { RESOURCE_LANGS::LANG_MALAY,          "MALAY" },
    { RESOURCE_LANGS::LANG_MALAYALAM,      "MALAYALAM" },
    { RESOURCE_LANGS::LANG_MANIPURI,       "MANIPURI" },
    { RESOURCE_LANGS::LANG_MARATHI,        "MARATHI" },
    { RESOURCE_LANGS::LANG_MONGOLIAN,      "MONGOLIAN" },
    { RESOURCE_LANGS::LANG_NEPALI,         "NEPALI" },
    { RESOURCE_LANGS::LANG_NORWEGIAN,      "NORWEGIAN" },
    { RESOURCE_LANGS::LANG_ORIYA,          "ORIYA" },
    { RESOURCE_LANGS::LANG_POLISH,         "POLISH" },
    { RESOURCE_LANGS::LANG_PORTUGUESE,     "PORTUGUESE" },
    { RESOURCE_LANGS::LANG_PUNJABI,        "PUNJABI" },
    { RESOURCE_LANGS::LANG_ROMANIAN,       "ROMANIAN" },
    { RESOURCE_LANGS::LANG_RUSSIAN,        "RUSSIAN" },
    { RESOURCE_LANGS::LANG_SANSKRIT,       "SANSKRIT" },
    { RESOURCE_LANGS::LANG_SERBIAN,        "SERBIAN" },
    { RESOURCE_LANGS::LANG_SINDHI,         "SINDHI" },
    { RESOURCE_LANGS::LANG_SLOVAK,         "SLOVAK" },
    { RESOURCE_LANGS::LANG_SLOVENIAN,      "SLOVENIAN" },
    { RESOURCE_LANGS::LANG_SPANISH,        "SPANISH" },
    { RESOURCE_LANGS::LANG_SWAHILI,        "SWAHILI" },
    { RESOURCE_LANGS::LANG_SWEDISH,        "SWEDISH" },
    { RESOURCE_LANGS::LANG_SYRIAC,         "SYRIAC" },
    { RESOURCE_LANGS::LANG_TAMIL,          "TAMIL" },
    { RESOURCE_LANGS::LANG_TATAR,          "TATAR" },
    { RESOURCE_LANGS::LANG_TELUGU,         "TELUGU" },
    { RESOURCE_LANGS::LANG_THAI,           "THAI" },
    { RESOURCE_LANGS::LANG_TURKISH,        "TURKISH" },
    { RESOURCE_LANGS::LANG_UKRAINIAN,      "UKRAINIAN" },
    { RESOURCE_LANGS::LANG_URDU,           "URDU" },
    { RESOURCE_LANGS::LANG_UZBEK,          "UZBEK" },
    { RESOURCE_LANGS::LANG_VIETNAMESE,     "VIETNAMESE" },
    { RESOURCE_LANGS::LANG_GAELIC,         "GAELIC" },
    { RESOURCE_LANGS::LANG_MALTESE,        "MALTESE" },
    { RESOURCE_LANGS::LANG_MAORI,          "MAORI" },
    { RESOURCE_LANGS::LANG_RHAETO_ROMANCE, "RHAETO_ROMANCE" },
    { RESOURCE_LANGS::LANG_SAMI,           "SAMI" },
    { RESOURCE_LANGS::LANG_SORBIAN,        "SORBIAN" },
    { RESOURCE_LANGS::LANG_SUTU,           "SUTU" },
    { RESOURCE_LANGS::LANG_TSONGA,         "TSONGA" },
    { RESOURCE_LANGS::LANG_TSWANA,         "TSWANA" },
    { RESOURCE_LANGS::LANG_VENDA,          "VENDA" },
    { RESOURCE_LANGS::LANG_XHOSA,          "XHOSA" },
    { RESOURCE_LANGS::LANG_ZULU,           "ZULU" },
    { RESOURCE_LANGS::LANG_ESPERANTO,      "ESPERANTO" },
    { RESOURCE_LANGS::LANG_WALON,          "WALON" },
    { RESOURCE_LANGS::LANG_CORNISH,        "CORNISH" },
    { RESOURCE_LANGS::LANG_WELSH,          "WELSH" },
    { RESOURCE_LANGS::LANG_BRETON,         "BRETON" },
    { RESOURCE_LANGS::LANG_INUKTITUT,      "INUKTITUT" },
    { RESOURCE_LANGS::LANG_IRISH,          "IRISH" },
    { RESOURCE_LANGS::LANG_LOWER_SORBIAN,  "LOWER_SORBIAN" },
    { RESOURCE_LANGS::LANG_PULAR,          "PULAR" },
    { RESOURCE_LANGS::LANG_QUECHUA,        "QUECHUA" },
    { RESOURCE_LANGS::LANG_TAMAZIGHT,      "TAMAZIGHT" },
    { RESOURCE_LANGS::LANG_TIGRINYA,       "TIGRINYA" },
    { RESOURCE_LANGS::LANG_VALENCIAN,      "VALENCIAN" },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}

const char* to_string(RESOURCE_SUBLANGS e) {
  CONST_MAP(RESOURCE_SUBLANGS, const char*, 229) enumStrings {
  { RESOURCE_SUBLANGS::SUBLANG_AFRIKAANS_SOUTH_AFRICA, "AFRIKAANS_SOUTH_AFRICA" },
  { RESOURCE_SUBLANGS::SUBLANG_ALBANIAN_ALBANIA, "ALBANIAN_ALBANIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ALSATIAN_FRANCE, "ALSATIAN_FRANCE" },
  { RESOURCE_SUBLANGS::SUBLANG_AMHARIC_ETHIOPIA, "AMHARIC_ETHIOPIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_ALGERIA, "ARABIC_ALGERIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_BAHRAIN, "ARABIC_BAHRAIN" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_EGYPT, "ARABIC_EGYPT" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_IRAQ, "ARABIC_IRAQ" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_JORDAN, "ARABIC_JORDAN" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_KUWAIT, "ARABIC_KUWAIT" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_LEBANON, "ARABIC_LEBANON" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_LIBYA, "ARABIC_LIBYA" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_MOROCCO, "ARABIC_MOROCCO" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_OMAN, "ARABIC_OMAN" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_QATAR, "ARABIC_QATAR" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_SAUDI_ARABIA, "ARABIC_SAUDI_ARABIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_SYRIA, "ARABIC_SYRIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_TUNISIA, "ARABIC_TUNISIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_UAE, "ARABIC_UAE" },
  { RESOURCE_SUBLANGS::SUBLANG_ARABIC_YEMEN, "ARABIC_YEMEN" },
  { RESOURCE_SUBLANGS::SUBLANG_ARMENIAN_ARMENIA, "ARMENIAN_ARMENIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ASSAMESE_INDIA, "ASSAMESE_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_AZERI_CYRILLIC, "AZERI_CYRILLIC" },
  { RESOURCE_SUBLANGS::SUBLANG_AZERI_LATIN, "AZERI_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_BASHKIR_RUSSIA, "BASHKIR_RUSSIA" },
  { RESOURCE_SUBLANGS::SUBLANG_BASQUE_BASQUE, "BASQUE_BASQUE" },
  { RESOURCE_SUBLANGS::SUBLANG_BELARUSIAN_BELARUS, "BELARUSIAN_BELARUS" },
  { RESOURCE_SUBLANGS::SUBLANG_BANGLA_BANGLADESH, "BANGLA_BANGLADESH" },
  { RESOURCE_SUBLANGS::SUBLANG_BANGLA_INDIA, "BANGLA_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC, "BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC" },
  { RESOURCE_SUBLANGS::SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN, "BOSNIAN_BOSNIA_HERZEGOVINA_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_BRETON_FRANCE, "BRETON_FRANCE" },
  { RESOURCE_SUBLANGS::SUBLANG_BULGARIAN_BULGARIA, "BULGARIAN_BULGARIA" },
  { RESOURCE_SUBLANGS::SUBLANG_CATALAN_CATALAN, "CATALAN_CATALAN" },
  { RESOURCE_SUBLANGS::SUBLANG_CHINESE_HONGKONG, "CHINESE_HONGKONG" },
  { RESOURCE_SUBLANGS::SUBLANG_CHINESE_MACAU, "CHINESE_MACAU" },
  { RESOURCE_SUBLANGS::SUBLANG_CHINESE_SIMPLIFIED, "CHINESE_SIMPLIFIED" },
  { RESOURCE_SUBLANGS::SUBLANG_CHINESE_SINGAPORE, "CHINESE_SINGAPORE" },
  { RESOURCE_SUBLANGS::SUBLANG_CHINESE_TRADITIONAL, "CHINESE_TRADITIONAL" },
  { RESOURCE_SUBLANGS::SUBLANG_CORSICAN_FRANCE, "CORSICAN_FRANCE" },
  { RESOURCE_SUBLANGS::SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN, "CROATIAN_BOSNIA_HERZEGOVINA_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_CROATIAN_CROATIA, "CROATIAN_CROATIA" },
  { RESOURCE_SUBLANGS::SUBLANG_CUSTOM_DEFAULT, "CUSTOM_DEFAULT" },
  { RESOURCE_SUBLANGS::SUBLANG_CUSTOM_UNSPECIFIED, "CUSTOM_UNSPECIFIED" },
  { RESOURCE_SUBLANGS::SUBLANG_CZECH_CZECH_REPUBLIC, "CZECH_CZECH_REPUBLIC" },
  { RESOURCE_SUBLANGS::SUBLANG_DANISH_DENMARK, "DANISH_DENMARK" },
  { RESOURCE_SUBLANGS::SUBLANG_DARI_AFGHANISTAN, "DARI_AFGHANISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_DEFAULT, "DEFAULT" },
  { RESOURCE_SUBLANGS::SUBLANG_DIVEHI_MALDIVES, "DIVEHI_MALDIVES" },
  { RESOURCE_SUBLANGS::SUBLANG_DUTCH_BELGIAN, "DUTCH_BELGIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_DUTCH, "DUTCH" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_AUS, "ENGLISH_AUS" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_BELIZE, "ENGLISH_BELIZE" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_CAN, "ENGLISH_CAN" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_CARIBBEAN, "ENGLISH_CARIBBEAN" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_EIRE, "ENGLISH_EIRE" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_INDIA, "ENGLISH_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_JAMAICA, "ENGLISH_JAMAICA" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_MALAYSIA, "ENGLISH_MALAYSIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_NZ, "ENGLISH_NZ" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_PHILIPPINES, "ENGLISH_PHILIPPINES" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_SINGAPORE, "ENGLISH_SINGAPORE" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_SOUTH_AFRICA, "ENGLISH_SOUTH_AFRICA" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_TRINIDAD, "ENGLISH_TRINIDAD" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_UK, "ENGLISH_UK" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_US, "ENGLISH_US" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_ZIMBABWE, "ENGLISH_ZIMBABWE" },
  { RESOURCE_SUBLANGS::SUBLANG_ENGLISH_IRELAND, "ENGLISH_IRELAND" },
  { RESOURCE_SUBLANGS::SUBLANG_ESTONIAN_ESTONIA, "ESTONIAN_ESTONIA" },
  { RESOURCE_SUBLANGS::SUBLANG_FAEROESE_FAROE_ISLANDS, "FAEROESE_FAROE_ISLANDS" },
  { RESOURCE_SUBLANGS::SUBLANG_FILIPINO_PHILIPPINES, "FILIPINO_PHILIPPINES" },
  { RESOURCE_SUBLANGS::SUBLANG_FINNISH_FINLAND, "FINNISH_FINLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_FRENCH_BELGIAN, "FRENCH_BELGIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_FRENCH_CANADIAN, "FRENCH_CANADIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_FRENCH_LUXEMBOURG, "FRENCH_LUXEMBOURG" },
  { RESOURCE_SUBLANGS::SUBLANG_FRENCH_MONACO, "FRENCH_MONACO" },
  { RESOURCE_SUBLANGS::SUBLANG_FRENCH_SWISS, "FRENCH_SWISS" },
  { RESOURCE_SUBLANGS::SUBLANG_FRENCH, "FRENCH" },
  { RESOURCE_SUBLANGS::SUBLANG_FRISIAN_NETHERLANDS, "FRISIAN_NETHERLANDS" },
  { RESOURCE_SUBLANGS::SUBLANG_GALICIAN_GALICIAN, "GALICIAN_GALICIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_GEORGIAN_GEORGIA, "GEORGIAN_GEORGIA" },
  { RESOURCE_SUBLANGS::SUBLANG_GERMAN_AUSTRIAN, "GERMAN_AUSTRIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_GERMAN_LIECHTENSTEIN, "GERMAN_LIECHTENSTEIN" },
  { RESOURCE_SUBLANGS::SUBLANG_GERMAN_LUXEMBOURG, "GERMAN_LUXEMBOURG" },
  { RESOURCE_SUBLANGS::SUBLANG_GERMAN_SWISS, "GERMAN_SWISS" },
  { RESOURCE_SUBLANGS::SUBLANG_GERMAN, "GERMAN" },
  { RESOURCE_SUBLANGS::SUBLANG_GREEK_GREECE, "GREEK_GREECE" },
  { RESOURCE_SUBLANGS::SUBLANG_GREENLANDIC_GREENLAND, "GREENLANDIC_GREENLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_GUJARATI_INDIA, "GUJARATI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_HAUSA_NIGERIA_LATIN, "HAUSA_NIGERIA_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_HEBREW_ISRAEL, "HEBREW_ISRAEL" },
  { RESOURCE_SUBLANGS::SUBLANG_HINDI_INDIA, "HINDI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_HUNGARIAN_HUNGARY, "HUNGARIAN_HUNGARY" },
  { RESOURCE_SUBLANGS::SUBLANG_ICELANDIC_ICELAND, "ICELANDIC_ICELAND" },
  { RESOURCE_SUBLANGS::SUBLANG_IGBO_NIGERIA, "IGBO_NIGERIA" },
  { RESOURCE_SUBLANGS::SUBLANG_INDONESIAN_INDONESIA, "INDONESIAN_INDONESIA" },
  { RESOURCE_SUBLANGS::SUBLANG_INUKTITUT_CANADA_LATIN, "INUKTITUT_CANADA_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_INUKTITUT_CANADA, "INUKTITUT_CANADA" },
  { RESOURCE_SUBLANGS::SUBLANG_IRISH_IRELAND, "IRISH_IRELAND" },
  { RESOURCE_SUBLANGS::SUBLANG_ITALIAN_SWISS, "ITALIAN_SWISS" },
  { RESOURCE_SUBLANGS::SUBLANG_ITALIAN, "ITALIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_JAPANESE_JAPAN, "JAPANESE_JAPAN" },
  { RESOURCE_SUBLANGS::SUBLANG_KANNADA_INDIA, "KANNADA_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_KASHMIRI_INDIA, "KASHMIRI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_KASHMIRI_SASIA, "KASHMIRI_SASIA" },
  { RESOURCE_SUBLANGS::SUBLANG_KAZAK_KAZAKHSTAN, "KAZAK_KAZAKHSTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_KHMER_CAMBODIA, "KHMER_CAMBODIA" },
  { RESOURCE_SUBLANGS::SUBLANG_KICHE_GUATEMALA, "KICHE_GUATEMALA" },
  { RESOURCE_SUBLANGS::SUBLANG_KINYARWANDA_RWANDA, "KINYARWANDA_RWANDA" },
  { RESOURCE_SUBLANGS::SUBLANG_KONKANI_INDIA, "KONKANI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_KOREAN, "KOREAN" },
  { RESOURCE_SUBLANGS::SUBLANG_KYRGYZ_KYRGYZSTAN, "KYRGYZ_KYRGYZSTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_LAO_LAO, "LAO_LAO" },
  { RESOURCE_SUBLANGS::SUBLANG_LATVIAN_LATVIA, "LATVIAN_LATVIA" },
  { RESOURCE_SUBLANGS::SUBLANG_LITHUANIAN_CLASSIC, "LITHUANIAN_CLASSIC" },
  { RESOURCE_SUBLANGS::SUBLANG_LITHUANIAN, "LITHUANIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_LOWER_SORBIAN_GERMANY, "LOWER_SORBIAN_GERMANY" },
  { RESOURCE_SUBLANGS::SUBLANG_LUXEMBOURGISH_LUXEMBOURG, "LUXEMBOURGISH_LUXEMBOURG" },
  { RESOURCE_SUBLANGS::SUBLANG_MACEDONIAN_MACEDONIA, "MACEDONIAN_MACEDONIA" },
  { RESOURCE_SUBLANGS::SUBLANG_MALAY_BRUNEI_DARUSSALAM, "MALAY_BRUNEI_DARUSSALAM" },
  { RESOURCE_SUBLANGS::SUBLANG_MALAY_MALAYSIA, "MALAY_MALAYSIA" },
  { RESOURCE_SUBLANGS::SUBLANG_MALAYALAM_INDIA, "MALAYALAM_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_MALTESE_MALTA, "MALTESE_MALTA" },
  { RESOURCE_SUBLANGS::SUBLANG_MAORI_NEW_ZEALAND, "MAORI_NEW_ZEALAND" },
  { RESOURCE_SUBLANGS::SUBLANG_MAPUDUNGUN_CHILE, "MAPUDUNGUN_CHILE" },
  { RESOURCE_SUBLANGS::SUBLANG_MARATHI_INDIA, "MARATHI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_MOHAWK_MOHAWK, "MOHAWK_MOHAWK" },
  { RESOURCE_SUBLANGS::SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA, "MONGOLIAN_CYRILLIC_MONGOLIA" },
  { RESOURCE_SUBLANGS::SUBLANG_MONGOLIAN_PRC, "MONGOLIAN_PRC" },
  { RESOURCE_SUBLANGS::SUBLANG_NEPALI_INDIA, "NEPALI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_NEPALI_NEPAL, "NEPALI_NEPAL" },
  { RESOURCE_SUBLANGS::SUBLANG_NEUTRAL, "NEUTRAL" },
  { RESOURCE_SUBLANGS::SUBLANG_NORWEGIAN_BOKMAL, "NORWEGIAN_BOKMAL" },
  { RESOURCE_SUBLANGS::SUBLANG_NORWEGIAN_NYNORSK, "NORWEGIAN_NYNORSK" },
  { RESOURCE_SUBLANGS::SUBLANG_OCCITAN_FRANCE, "OCCITAN_FRANCE" },
  { RESOURCE_SUBLANGS::SUBLANG_ORIYA_INDIA, "ORIYA_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_PASHTO_AFGHANISTAN, "PASHTO_AFGHANISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_PERSIAN_IRAN, "PERSIAN_IRAN" },
  { RESOURCE_SUBLANGS::SUBLANG_POLISH_POLAND, "POLISH_POLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_PORTUGUESE_BRAZILIAN, "PORTUGUESE_BRAZILIAN" },
  { RESOURCE_SUBLANGS::SUBLANG_PORTUGUESE, "PORTUGUESE" },
  { RESOURCE_SUBLANGS::SUBLANG_PUNJABI_INDIA, "PUNJABI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_QUECHUA_BOLIVIA, "QUECHUA_BOLIVIA" },
  { RESOURCE_SUBLANGS::SUBLANG_QUECHUA_ECUADOR, "QUECHUA_ECUADOR" },
  { RESOURCE_SUBLANGS::SUBLANG_QUECHUA_PERU, "QUECHUA_PERU" },
  { RESOURCE_SUBLANGS::SUBLANG_ROMANIAN_ROMANIA, "ROMANIAN_ROMANIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ROMANSH_SWITZERLAND, "ROMANSH_SWITZERLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_RUSSIAN_RUSSIA, "RUSSIAN_RUSSIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_INARI_FINLAND, "SAMI_INARI_FINLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_LULE_NORWAY, "SAMI_LULE_NORWAY" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_LULE_SWEDEN, "SAMI_LULE_SWEDEN" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_NORTHERN_FINLAND, "SAMI_NORTHERN_FINLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_NORTHERN_NORWAY, "SAMI_NORTHERN_NORWAY" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_NORTHERN_SWEDEN, "SAMI_NORTHERN_SWEDEN" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_SKOLT_FINLAND, "SAMI_SKOLT_FINLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_SOUTHERN_NORWAY, "SAMI_SOUTHERN_NORWAY" },
  { RESOURCE_SUBLANGS::SUBLANG_SAMI_SOUTHERN_SWEDEN, "SAMI_SOUTHERN_SWEDEN" },
  { RESOURCE_SUBLANGS::SUBLANG_SANSKRIT_INDIA, "SANSKRIT_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC, "SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC" },
  { RESOURCE_SUBLANGS::SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN, "SERBIAN_BOSNIA_HERZEGOVINA_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_SERBIAN_CROATIA, "SERBIAN_CROATIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SERBIAN_CYRILLIC, "SERBIAN_CYRILLIC" },
  { RESOURCE_SUBLANGS::SUBLANG_SERBIAN_LATIN, "SERBIAN_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_SINDHI_AFGHANISTAN, "SINDHI_AFGHANISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_SINDHI_INDIA, "SINDHI_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SINDHI_PAKISTAN, "SINDHI_PAKISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_SINHALESE_SRI_LANKA, "SINHALESE_SRI_LANKA" },
  { RESOURCE_SUBLANGS::SUBLANG_SLOVAK_SLOVAKIA, "SLOVAK_SLOVAKIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SLOVENIAN_SLOVENIA, "SLOVENIAN_SLOVENIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA, "SOTHO_NORTHERN_SOUTH_AFRICA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_ARGENTINA, "SPANISH_ARGENTINA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_BOLIVIA, "SPANISH_BOLIVIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_CHILE, "SPANISH_CHILE" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_COLOMBIA, "SPANISH_COLOMBIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_COSTA_RICA, "SPANISH_COSTA_RICA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_DOMINICAN_REPUBLIC, "SPANISH_DOMINICAN_REPUBLIC" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_ECUADOR, "SPANISH_ECUADOR" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_EL_SALVADOR, "SPANISH_EL_SALVADOR" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_GUATEMALA, "SPANISH_GUATEMALA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_HONDURAS, "SPANISH_HONDURAS" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_MEXICAN, "SPANISH_MEXICAN" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_MODERN, "SPANISH_MODERN" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_NICARAGUA, "SPANISH_NICARAGUA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_PANAMA, "SPANISH_PANAMA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_PARAGUAY, "SPANISH_PARAGUAY" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_PERU, "SPANISH_PERU" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_PUERTO_RICO, "SPANISH_PUERTO_RICO" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_URUGUAY, "SPANISH_URUGUAY" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_US, "SPANISH_US" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH_VENEZUELA, "SPANISH_VENEZUELA" },
  { RESOURCE_SUBLANGS::SUBLANG_SPANISH, "SPANISH" },
  { RESOURCE_SUBLANGS::SUBLANG_SWAHILI_KENYA, "SWAHILI_KENYA" },
  { RESOURCE_SUBLANGS::SUBLANG_SWEDISH_FINLAND, "SWEDISH_FINLAND" },
  { RESOURCE_SUBLANGS::SUBLANG_SWEDISH, "SWEDISH" },
  { RESOURCE_SUBLANGS::SUBLANG_SYRIAC_SYRIA, "SYRIAC_SYRIA" },
  { RESOURCE_SUBLANGS::SUBLANG_SYS_DEFAULT, "SYS_DEFAULT" },
  { RESOURCE_SUBLANGS::SUBLANG_TAJIK_TAJIKISTAN, "TAJIK_TAJIKISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_TAMAZIGHT_ALGERIA_LATIN, "TAMAZIGHT_ALGERIA_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_TAMIL_INDIA, "TAMIL_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_TATAR_RUSSIA, "TATAR_RUSSIA" },
  { RESOURCE_SUBLANGS::SUBLANG_TELUGU_INDIA, "TELUGU_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_THAI_THAILAND, "THAI_THAILAND" },
  { RESOURCE_SUBLANGS::SUBLANG_TIBETAN_PRC, "TIBETAN_PRC" },
  { RESOURCE_SUBLANGS::SUBLANG_TIGRIGNA_ERITREA, "TIGRIGNA_ERITREA" },
  { RESOURCE_SUBLANGS::SUBLANG_TSWANA_SOUTH_AFRICA, "TSWANA_SOUTH_AFRICA" },
  { RESOURCE_SUBLANGS::SUBLANG_TURKISH_TURKEY, "TURKISH_TURKEY" },
  { RESOURCE_SUBLANGS::SUBLANG_TURKMEN_TURKMENISTAN, "TURKMEN_TURKMENISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_UI_CUSTOM_DEFAULT, "UI_CUSTOM_DEFAULT" },
  { RESOURCE_SUBLANGS::SUBLANG_UIGHUR_PRC, "UIGHUR_PRC" },
  { RESOURCE_SUBLANGS::SUBLANG_UKRAINIAN_UKRAINE, "UKRAINIAN_UKRAINE" },
  { RESOURCE_SUBLANGS::SUBLANG_UPPER_SORBIAN_GERMANY, "UPPER_SORBIAN_GERMANY" },
  { RESOURCE_SUBLANGS::SUBLANG_URDU_INDIA, "URDU_INDIA" },
  { RESOURCE_SUBLANGS::SUBLANG_URDU_PAKISTAN, "URDU_PAKISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_UZBEK_CYRILLIC, "UZBEK_CYRILLIC" },
  { RESOURCE_SUBLANGS::SUBLANG_UZBEK_LATIN, "UZBEK_LATIN" },
  { RESOURCE_SUBLANGS::SUBLANG_VIETNAMESE_VIETNAM, "VIETNAMESE_VIETNAM" },
  { RESOURCE_SUBLANGS::SUBLANG_WELSH_UNITED_KINGDOM, "WELSH_UNITED_KINGDOM" },
  { RESOURCE_SUBLANGS::SUBLANG_WOLOF_SENEGAL, "WOLOF_SENEGAL" },
  { RESOURCE_SUBLANGS::SUBLANG_XHOSA_SOUTH_AFRICA, "XHOSA_SOUTH_AFRICA" },
  { RESOURCE_SUBLANGS::SUBLANG_YAKUT_RUSSIA, "YAKUT_RUSSIA" },
  { RESOURCE_SUBLANGS::SUBLANG_YI_PRC, "YI_PRC" },
  { RESOURCE_SUBLANGS::SUBLANG_YORUBA_NIGERIA, "YORUBA_NIGERIA" },
  { RESOURCE_SUBLANGS::SUBLANG_ZULU_SOUTH_AFRICA, "ZULU_SOUTH_AFRICA" },
  { RESOURCE_SUBLANGS::SUBLANG_PUNJABI_PAKISTAN, "PUNJABI_PAKISTAN" },
  { RESOURCE_SUBLANGS::SUBLANG_TSWANA_BOTSWANA, "TSWANA_BOTSWANA" },
  { RESOURCE_SUBLANGS::SUBLANG_TAMIL_SRI_LANKA, "TAMIL_SRI_LANKA" },
  { RESOURCE_SUBLANGS::SUBLANG_TIGRINYA_ETHIOPIA, "TIGRINYA_ETHIOPIA" },
  { RESOURCE_SUBLANGS::SUBLANG_TIGRINYA_ERITREA, "TIGRINYA_ERITREA" },
  { RESOURCE_SUBLANGS::SUBLANG_VALENCIAN_VALENCIA, "VALENCIAN_VALENCIA" },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}

const char* to_string(EXTENDED_WINDOW_STYLES e) {
  CONST_MAP(EXTENDED_WINDOW_STYLES, const char*, 19) enumStrings {
    { EXTENDED_WINDOW_STYLES::WS_EX_DLGMODALFRAME,  "DLGMODALFRAME"  },
    { EXTENDED_WINDOW_STYLES::WS_EX_NOPARENTNOTIFY, "NOPARENTNOTIFY" },
    { EXTENDED_WINDOW_STYLES::WS_EX_TOPMOST,        "TOPMOST"        },
    { EXTENDED_WINDOW_STYLES::WS_EX_ACCEPTFILES,    "ACCEPTFILES"    },
    { EXTENDED_WINDOW_STYLES::WS_EX_TRANSPARENT,    "TRANSPARENT"    },
    { EXTENDED_WINDOW_STYLES::WS_EX_MDICHILD,       "MDICHILD"       },
    { EXTENDED_WINDOW_STYLES::WS_EX_TOOLWINDOW,     "TOOLWINDOW"     },
    { EXTENDED_WINDOW_STYLES::WS_EX_WINDOWEDGE,     "WINDOWEDGE"     },
    { EXTENDED_WINDOW_STYLES::WS_EX_CLIENTEDGE,     "CLIENTEDGE"     },
    { EXTENDED_WINDOW_STYLES::WS_EX_CONTEXTHELP,    "CONTEXTHELP"    },
    { EXTENDED_WINDOW_STYLES::WS_EX_RIGHT,          "RIGHT"          },
    { EXTENDED_WINDOW_STYLES::WS_EX_LEFT,           "LEFT"           },
    { EXTENDED_WINDOW_STYLES::WS_EX_RTLREADING,     "RTLREADING"     },
    { EXTENDED_WINDOW_STYLES::WS_EX_LTRREADING,     "LTRREADING"     },
    { EXTENDED_WINDOW_STYLES::WS_EX_LEFTSCROLLBAR,  "LEFTSCROLLBAR"  },
    { EXTENDED_WINDOW_STYLES::WS_EX_RIGHTSCROLLBAR, "RIGHTSCROLLBAR" },
    { EXTENDED_WINDOW_STYLES::WS_EX_CONTROLPARENT,  "CONTROLPARENT"  },
    { EXTENDED_WINDOW_STYLES::WS_EX_STATICEDGE,     "STATICEDGE"     },
    { EXTENDED_WINDOW_STYLES::WS_EX_APPWINDOW,      "APPWINDOW"      },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(WINDOW_STYLES e) {
  CONST_MAP(WINDOW_STYLES, const char*, 20) enumStrings {
    { WINDOW_STYLES::WS_OVERLAPPED,   "OVERLAPPED"   },
    { WINDOW_STYLES::WS_POPUP,        "POPUP"        },
    { WINDOW_STYLES::WS_CHILD,        "CHILD"        },
    { WINDOW_STYLES::WS_MINIMIZE,     "MINIMIZE"     },
    { WINDOW_STYLES::WS_VISIBLE,      "VISIBLE"      },
    { WINDOW_STYLES::WS_DISABLED,     "DISABLED"     },
    { WINDOW_STYLES::WS_CLIPSIBLINGS, "CLIPSIBLINGS" },
    { WINDOW_STYLES::WS_CLIPCHILDREN, "CLIPCHILDREN" },
    { WINDOW_STYLES::WS_MAXIMIZE,     "MAXIMIZE"     },
    { WINDOW_STYLES::WS_CAPTION,      "CAPTION"      },
    { WINDOW_STYLES::WS_BORDER,       "BORDER"       },
    { WINDOW_STYLES::WS_DLGFRAME,     "DLGFRAME"     },
    { WINDOW_STYLES::WS_VSCROLL,      "VSCROLL"      },
    { WINDOW_STYLES::WS_HSCROLL,      "HSCROLL"      },
    { WINDOW_STYLES::WS_SYSMENU,      "SYSMENU"      },
    { WINDOW_STYLES::WS_THICKFRAME,   "THICKFRAME"   },
    { WINDOW_STYLES::WS_GROUP,        "GROUP"        },
    { WINDOW_STYLES::WS_TABSTOP,      "TABSTOP"      },
    { WINDOW_STYLES::WS_MINIMIZEBOX,  "MINIMIZEBOX"  },
    { WINDOW_STYLES::WS_MAXIMIZEBOX,  "MAXIMIZEBOX"  },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(DIALOG_BOX_STYLES e) {
  CONST_MAP(DIALOG_BOX_STYLES, const char*, 15) enumStrings {
    { DIALOG_BOX_STYLES::DS_ABSALIGN,      "ABSALIGN"      },
    { DIALOG_BOX_STYLES::DS_SYSMODAL,      "SYSMODAL"      },
    { DIALOG_BOX_STYLES::DS_LOCALEDIT,     "LOCALEDIT"     },
    { DIALOG_BOX_STYLES::DS_SETFONT,       "SETFONT"       },
    { DIALOG_BOX_STYLES::DS_MODALFRAME,    "MODALFRAME"    },
    { DIALOG_BOX_STYLES::DS_NOIDLEMSG,     "NOIDLEMSG"     },
    { DIALOG_BOX_STYLES::DS_SETFOREGROUND, "SETFOREGROUND" },
    { DIALOG_BOX_STYLES::DS_3DLOOK,        "D3DLOOK"       },
    { DIALOG_BOX_STYLES::DS_FIXEDSYS,      "FIXEDSYS"      },
    { DIALOG_BOX_STYLES::DS_NOFAILCREATE,  "NOFAILCREATE"  },
    { DIALOG_BOX_STYLES::DS_CONTROL,       "CONTROL"       },
    { DIALOG_BOX_STYLES::DS_CENTER,        "CENTER"        },
    { DIALOG_BOX_STYLES::DS_CENTERMOUSE,   "CENTERMOUSE"   },
    { DIALOG_BOX_STYLES::DS_CONTEXTHELP,   "CONTEXTHELP"   },
    { DIALOG_BOX_STYLES::DS_SHELLFONT,     "SHELLFONT"     },
  };

  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(FIXED_VERSION_OS e) {
  CONST_MAP(FIXED_VERSION_OS, const char*, 14) enumStrings {
    { FIXED_VERSION_OS::VOS_UNKNOWN,       "UNKNOWN"       },
    { FIXED_VERSION_OS::VOS_DOS,           "DOS"           },
    { FIXED_VERSION_OS::VOS_NT,            "NT"            },
    { FIXED_VERSION_OS::VOS__WINDOWS16,    "WINDOWS16"     },
    { FIXED_VERSION_OS::VOS__WINDOWS32,    "WINDOWS32"     },
    { FIXED_VERSION_OS::VOS_OS216,         "OS216"         },
    { FIXED_VERSION_OS::VOS_OS232,         "OS232"         },
    { FIXED_VERSION_OS::VOS__PM16,         "PM16"          },
    { FIXED_VERSION_OS::VOS__PM32,         "PM32"          },
    { FIXED_VERSION_OS::VOS_DOS_WINDOWS16, "DOS_WINDOWS16" },
    { FIXED_VERSION_OS::VOS_DOS_WINDOWS32, "DOS_WINDOWS32" },
    { FIXED_VERSION_OS::VOS_NT_WINDOWS32,  "NT_WINDOWS32"  },
    { FIXED_VERSION_OS::VOS_OS216_PM16,    "OS216_PM16"    },
    { FIXED_VERSION_OS::VOS_OS232_PM32,    "OS232_PM32"    },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(FIXED_VERSION_FILE_FLAGS e) {
  CONST_MAP(FIXED_VERSION_FILE_FLAGS, const char*, 6) enumStrings {
    { FIXED_VERSION_FILE_FLAGS::VS_FF_DEBUG,        "DEBUG"        },
    { FIXED_VERSION_FILE_FLAGS::VS_FF_INFOINFERRED, "INFOINFERRED" },
    { FIXED_VERSION_FILE_FLAGS::VS_FF_PATCHED,      "PATCHED"      },
    { FIXED_VERSION_FILE_FLAGS::VS_FF_PRERELEASE,   "PRERELEASE"   },
    { FIXED_VERSION_FILE_FLAGS::VS_FF_PRIVATEBUILD, "PRIVATEBUILD" },
    { FIXED_VERSION_FILE_FLAGS::VS_FF_SPECIALBUILD, "SPECIALBUILD" },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(FIXED_VERSION_FILE_TYPES e) {
  CONST_MAP(FIXED_VERSION_FILE_TYPES, const char*, 7) enumStrings {
    { FIXED_VERSION_FILE_TYPES::VFT_APP,        "APP"        },
    { FIXED_VERSION_FILE_TYPES::VFT_DLL,        "DLL"        },
    { FIXED_VERSION_FILE_TYPES::VFT_DRV,        "DRV"        },
    { FIXED_VERSION_FILE_TYPES::VFT_FONT,       "FONT"       },
    { FIXED_VERSION_FILE_TYPES::VFT_STATIC_LIB, "STATIC_LIB" },
    { FIXED_VERSION_FILE_TYPES::VFT_UNKNOWN,    "UNKNOWN"    },
    { FIXED_VERSION_FILE_TYPES::VFT_VXD,        "VXD"        },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(FIXED_VERSION_FILE_SUB_TYPES e) {
  CONST_MAP(FIXED_VERSION_FILE_SUB_TYPES, const char*, 15) enumStrings {
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_COMM,              "DRV_COMM"              },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_DISPLAY,           "DRV_DISPLAY"           },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_INSTALLABLE,       "DRV_INSTALLABLE"       },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_KEYBOARD,          "DRV_KEYBOARD"          },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_LANGUAGE,          "DRV_LANGUAGE"          },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_MOUSE,             "DRV_MOUSE"             },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_NETWORK,           "DRV_NETWORK"           },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_PRINTER,           "DRV_PRINTER"           },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_SOUND,             "DRV_SOUND"             },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_SYSTEM,            "DRV_SYSTEM"            },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_DRV_VERSIONED_PRINTER, "DRV_VERSIONED_PRINTER" },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_FONT_RASTER,           "FONT_RASTER"           },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_FONT_TRUETYPE,         "FONT_TRUETYPE"         },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_FONT_VECTOR,           "FONT_VECTOR"           },
    { FIXED_VERSION_FILE_SUB_TYPES::VFT2_UNKNOWN,               "UNKNOWN"               },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}

const char* to_string(CODE_PAGES e) {
  CONST_MAP(CODE_PAGES, const char*, 140) enumStrings {
    { CODE_PAGES::CP_IBM037,                  "IBM037"},
    { CODE_PAGES::CP_IBM437,                  "IBM437"},
    { CODE_PAGES::CP_IBM500,                  "IBM500"},
    { CODE_PAGES::CP_ASMO_708,                "ASMO_708"},
    { CODE_PAGES::CP_DOS_720,                 "DOS_720"},
    { CODE_PAGES::CP_IBM737,                  "IBM737"},
    { CODE_PAGES::CP_IBM775,                  "IBM775"},
    { CODE_PAGES::CP_IBM850,                  "IBM850"},
    { CODE_PAGES::CP_IBM852,                  "IBM852"},
    { CODE_PAGES::CP_IBM855,                  "IBM855"},
    { CODE_PAGES::CP_IBM857,                  "IBM857"},
    { CODE_PAGES::CP_IBM00858,                "IBM00858"},
    { CODE_PAGES::CP_IBM860,                  "IBM860"},
    { CODE_PAGES::CP_IBM861,                  "IBM861"},
    { CODE_PAGES::CP_DOS_862,                 "DOS_862"},
    { CODE_PAGES::CP_IBM863,                  "IBM863"},
    { CODE_PAGES::CP_IBM864,                  "IBM864"},
    { CODE_PAGES::CP_IBM865,                  "IBM865"},
    { CODE_PAGES::CP_CP866,                   "CP866"},
    { CODE_PAGES::CP_IBM869,                  "IBM869"},
    { CODE_PAGES::CP_IBM870,                  "IBM870"},
    { CODE_PAGES::CP_WINDOWS_874,             "WINDOWS_874"},
    { CODE_PAGES::CP_CP875,                   "CP875"},
    { CODE_PAGES::CP_SHIFT_JIS,               "SHIFT_JIS"},
    { CODE_PAGES::CP_GB2312,                  "GB2312"},
    { CODE_PAGES::CP_KS_C_5601_1987,          "KS_C_5601_1987"},
    { CODE_PAGES::CP_BIG5,                    "BIG5"},
    { CODE_PAGES::CP_IBM1026,                 "IBM1026"},
    { CODE_PAGES::CP_IBM01047,                "IBM01047"},
    { CODE_PAGES::CP_IBM01140,                "IBM01140"},
    { CODE_PAGES::CP_IBM01141,                "IBM01141"},
    { CODE_PAGES::CP_IBM01142,                "IBM01142"},
    { CODE_PAGES::CP_IBM01143,                "IBM01143"},
    { CODE_PAGES::CP_IBM01144,                "IBM01144"},
    { CODE_PAGES::CP_IBM01145,                "IBM01145"},
    { CODE_PAGES::CP_IBM01146,                "IBM01146"},
    { CODE_PAGES::CP_IBM01147,                "IBM01147"},
    { CODE_PAGES::CP_IBM01148,                "IBM01148"},
    { CODE_PAGES::CP_IBM01149,                "IBM01149"},
    { CODE_PAGES::CP_UTF_16,                  "UTF_16"},
    { CODE_PAGES::CP_UNICODEFFFE,             "UNICODEFFFE"},
    { CODE_PAGES::CP_WINDOWS_1250,            "WINDOWS_1250"},
    { CODE_PAGES::CP_WINDOWS_1251,            "WINDOWS_1251"},
    { CODE_PAGES::CP_WINDOWS_1252,            "WINDOWS_1252"},
    { CODE_PAGES::CP_WINDOWS_1253,            "WINDOWS_1253"},
    { CODE_PAGES::CP_WINDOWS_1254,            "WINDOWS_1254"},
    { CODE_PAGES::CP_WINDOWS_1255,            "WINDOWS_1255"},
    { CODE_PAGES::CP_WINDOWS_1256,            "WINDOWS_1256"},
    { CODE_PAGES::CP_WINDOWS_1257,            "WINDOWS_1257"},
    { CODE_PAGES::CP_WINDOWS_1258,            "WINDOWS_1258"},
    { CODE_PAGES::CP_JOHAB,                   "JOHAB"},
    { CODE_PAGES::CP_MACINTOSH,               "MACINTOSH"},
    { CODE_PAGES::CP_X_MAC_JAPANESE,          "X_MAC_JAPANESE"},
    { CODE_PAGES::CP_X_MAC_CHINESETRAD,       "X_MAC_CHINESETRAD"},
    { CODE_PAGES::CP_X_MAC_KOREAN,            "X_MAC_KOREAN"},
    { CODE_PAGES::CP_X_MAC_ARABIC,            "X_MAC_ARABIC"},
    { CODE_PAGES::CP_X_MAC_HEBREW,            "X_MAC_HEBREW"},
    { CODE_PAGES::CP_X_MAC_GREEK,             "X_MAC_GREEK"},
    { CODE_PAGES::CP_X_MAC_CYRILLIC,          "X_MAC_CYRILLIC"},
    { CODE_PAGES::CP_X_MAC_CHINESESIMP,       "X_MAC_CHINESESIMP"},
    { CODE_PAGES::CP_X_MAC_ROMANIAN,          "X_MAC_ROMANIAN"},
    { CODE_PAGES::CP_X_MAC_UKRAINIAN,         "X_MAC_UKRAINIAN"},
    { CODE_PAGES::CP_X_MAC_THAI,              "X_MAC_THAI"},
    { CODE_PAGES::CP_X_MAC_CE,                "X_MAC_CE"},
    { CODE_PAGES::CP_X_MAC_ICELANDIC,         "X_MAC_ICELANDIC"},
    { CODE_PAGES::CP_X_MAC_TURKISH,           "X_MAC_TURKISH"},
    { CODE_PAGES::CP_X_MAC_CROATIAN,          "X_MAC_CROATIAN"},
    { CODE_PAGES::CP_UTF_32,                  "UTF_32"},
    { CODE_PAGES::CP_UTF_32BE,                "UTF_32BE"},
    { CODE_PAGES::CP_X_CHINESE_CNS,           "X_CHINESE_CNS"},
    { CODE_PAGES::CP_X_CP20001,               "X_CP20001"},
    { CODE_PAGES::CP_X_CHINESE_ETEN,          "X_CHINESE_ETEN"},
    { CODE_PAGES::CP_X_CP20003,               "X_CP20003"},
    { CODE_PAGES::CP_X_CP20004,               "X_CP20004"},
    { CODE_PAGES::CP_X_CP20005,               "X_CP20005"},
    { CODE_PAGES::CP_X_IA5,                   "X_IA5"},
    { CODE_PAGES::CP_X_IA5_GERMAN,            "X_IA5_GERMAN"},
    { CODE_PAGES::CP_X_IA5_SWEDISH,           "X_IA5_SWEDISH"},
    { CODE_PAGES::CP_X_IA5_NORWEGIAN,         "X_IA5_NORWEGIAN"},
    { CODE_PAGES::CP_US_ASCII,                "US_ASCII"},
    { CODE_PAGES::CP_X_CP20261,               "X_CP20261"},
    { CODE_PAGES::CP_X_CP20269,               "X_CP20269"},
    { CODE_PAGES::CP_IBM273,                  "IBM273"},
    { CODE_PAGES::CP_IBM277,                  "IBM277"},
    { CODE_PAGES::CP_IBM278,                  "IBM278"},
    { CODE_PAGES::CP_IBM280,                  "IBM280"},
    { CODE_PAGES::CP_IBM284,                  "IBM284"},
    { CODE_PAGES::CP_IBM285,                  "IBM285"},
    { CODE_PAGES::CP_IBM290,                  "IBM290"},
    { CODE_PAGES::CP_IBM297,                  "IBM297"},
    { CODE_PAGES::CP_IBM420,                  "IBM420"},
    { CODE_PAGES::CP_IBM423,                  "IBM423"},
    { CODE_PAGES::CP_IBM424,                  "IBM424"},
    { CODE_PAGES::CP_X_EBCDIC_KOREANEXTENDED, "X_EBCDIC_KOREANEXTENDED"},
    { CODE_PAGES::CP_IBM_THAI,                "IBM_THAI"},
    { CODE_PAGES::CP_KOI8_R,                  "KOI8_R"},
    { CODE_PAGES::CP_IBM871,                  "IBM871"},
    { CODE_PAGES::CP_IBM880,                  "IBM880"},
    { CODE_PAGES::CP_IBM905,                  "IBM905"},
    { CODE_PAGES::CP_IBM00924,                "IBM00924"},
    { CODE_PAGES::CP_EUC_JP_JIS,              "EUC_JP_JIS"},
    { CODE_PAGES::CP_X_CP20936,               "X_CP20936"},
    { CODE_PAGES::CP_X_CP20949,               "X_CP20949"},
    { CODE_PAGES::CP_CP1025,                  "CP1025"},
    { CODE_PAGES::CP_KOI8_U,                  "KOI8_U"},
    { CODE_PAGES::CP_ISO_8859_1,              "ISO_8859_1"},
    { CODE_PAGES::CP_ISO_8859_2,              "ISO_8859_2"},
    { CODE_PAGES::CP_ISO_8859_3,              "ISO_8859_3"},
    { CODE_PAGES::CP_ISO_8859_4,              "ISO_8859_4"},
    { CODE_PAGES::CP_ISO_8859_5,              "ISO_8859_5"},
    { CODE_PAGES::CP_ISO_8859_6,              "ISO_8859_6"},
    { CODE_PAGES::CP_ISO_8859_7,              "ISO_8859_7"},
    { CODE_PAGES::CP_ISO_8859_8,              "ISO_8859_8"},
    { CODE_PAGES::CP_ISO_8859_9,              "ISO_8859_9"},
    { CODE_PAGES::CP_ISO_8859_13,             "ISO_8859_13"},
    { CODE_PAGES::CP_ISO_8859_15,             "ISO_8859_15"},
    { CODE_PAGES::CP_X_EUROPA,                "X_EUROPA"},
    { CODE_PAGES::CP_ISO_8859_8_I,            "ISO_8859_8_I"},
    { CODE_PAGES::CP_ISO_2022_JP,             "ISO_2022_JP"},
    { CODE_PAGES::CP_CSISO2022JP,             "CSISO2022JP"},
    { CODE_PAGES::CP_ISO_2022_JP_JIS,         "ISO_2022_JP_JIS"},
    { CODE_PAGES::CP_ISO_2022_KR,             "ISO_2022_KR"},
    { CODE_PAGES::CP_X_CP50227,               "X_CP50227"},
    { CODE_PAGES::CP_EUC_JP,                  "EUC_JP"},
    { CODE_PAGES::CP_EUC_CN,                  "EUC_CN"},
    { CODE_PAGES::CP_EUC_KR,                  "EUC_KR"},
    { CODE_PAGES::CP_HZ_GB_2312,              "HZ_GB_2312"},
    { CODE_PAGES::CP_GB18030,                 "GB18030"},
    { CODE_PAGES::CP_X_ISCII_DE,              "X_ISCII_DE"},
    { CODE_PAGES::CP_X_ISCII_BE,              "X_ISCII_BE"},
    { CODE_PAGES::CP_X_ISCII_TA,              "X_ISCII_TA"},
    { CODE_PAGES::CP_X_ISCII_TE,              "X_ISCII_TE"},
    { CODE_PAGES::CP_X_ISCII_AS,              "X_ISCII_AS"},
    { CODE_PAGES::CP_X_ISCII_OR,              "X_ISCII_OR"},
    { CODE_PAGES::CP_X_ISCII_KA,              "X_ISCII_KA"},
    { CODE_PAGES::CP_X_ISCII_MA,              "X_ISCII_MA"},
    { CODE_PAGES::CP_X_ISCII_GU,              "X_ISCII_GU"},
    { CODE_PAGES::CP_X_ISCII_PA,              "X_ISCII_PA"},
    { CODE_PAGES::CP_UTF_7,                   "UTF_7"},
    { CODE_PAGES::CP_UTF_8,                   "UTF_8"},
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}



const char* to_string(WIN_VERSION e) {
  CONST_MAP(WIN_VERSION, const char*, 9) enumStrings {
    { WIN_VERSION::WIN_UNKNOWN,   "UNKNOWN"       },
    { WIN_VERSION::WIN_SEH,       "SEH"           },
    { WIN_VERSION::WIN8_1,        "WIN_8_1"       },
    { WIN_VERSION::WIN10_0_9879,  "WIN10_0_9879"  },
    { WIN_VERSION::WIN10_0_14286, "WIN10_0_14286" },
    { WIN_VERSION::WIN10_0_14383, "WIN10_0_14383" },
    { WIN_VERSION::WIN10_0_14901, "WIN10_0_14901" },
    { WIN_VERSION::WIN10_0_15002, "WIN10_0_15002" },
    { WIN_VERSION::WIN10_0_16237, "WIN10_0_16237" },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(GUARD_CF_FLAGS e) {
  CONST_MAP(GUARD_CF_FLAGS, const char*, 7) enumStrings {
    { GUARD_CF_FLAGS::GCF_NONE,                             "NONE"                            },
    { GUARD_CF_FLAGS::GCF_INSTRUMENTED,                     "INSTRUMENTED"                    },
    { GUARD_CF_FLAGS::GCF_W_INSTRUMENTED,                   "W_INSTRUMENTED"                  },
    { GUARD_CF_FLAGS::GCF_FUNCTION_TABLE_PRESENT,           "FUNCTION_TABLE_PRESENT"          },
    { GUARD_CF_FLAGS::GCF_EXPORT_SUPPRESSION_INFO_PRESENT,  "EXPORT_SUPPRESSION_INFO_PRESENT" },
    { GUARD_CF_FLAGS::GCF_ENABLE_EXPORT_SUPPRESSION,        "ENABLE_EXPORT_SUPPRESSION"       },
    { GUARD_CF_FLAGS::GCF_LONGJUMP_TABLE_PRESENT,           "LONGJUMP_TABLE_PRESENT"          },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(GUARD_RF_FLAGS e) {
  CONST_MAP(GUARD_RF_FLAGS, const char*, 3) enumStrings {
    { GUARD_RF_FLAGS::GRF_INSTRUMENTED, "INSTRUMENTED" },
    { GUARD_RF_FLAGS::GRF_ENABLE,       "ENABLE"       },
    { GUARD_RF_FLAGS::GRF_STRICT,       "STRICT"       },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? "Out of range" : it->second;
}


const char* to_string(CODE_VIEW_SIGNATURES e) {
  CONST_MAP(CODE_VIEW_SIGNATURES, const char*, 5) enumStrings {
    { CODE_VIEW_SIGNATURES::CVS_UNKNOWN, "UNKNOWN" },
    { CODE_VIEW_SIGNATURES::CVS_PDB_70,  "PDB_70"  },
    { CODE_VIEW_SIGNATURES::CVS_PDB_20,  "PDB_20"  },
    { CODE_VIEW_SIGNATURES::CVS_CV_50,   "CV_50"   },
    { CODE_VIEW_SIGNATURES::CVS_CV_41,   "CV_41"   },
  };
  auto   it  = enumStrings.find(e);
  return it == enumStrings.end() ? to_string(CODE_VIEW_SIGNATURES::CVS_UNKNOWN) : it->second;
}



} // namespace PE
} // namespace LIEF
