FileVersion.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "FileVersion.hpp"
  2. #include <cassert>
  3. #include <cstring>
  4. #include <fstream>
  5. #include <sstream>
  6. #include <regex>
  7. namespace {
  8. bool ParseVersionFromELF(const std::string& filename, FileVersion::VersionInfo& info) {
  9. std::ifstream file(filename, std::ios::binary);
  10. if (!file) return false;
  11. // ELF魔数检查 (7F 45 4C 46)
  12. char magic[4];
  13. file.read(magic, 4);
  14. if (strncmp(magic, "\x7F""ELF", 4) != 0)
  15. return false;
  16. // 简化的ELF解析逻辑 - 实际项目应使用libelf
  17. file.seekg(0, std::ios::end);
  18. size_t size = file.tellg();
  19. file.seekg(0);
  20. std::string content(size, '\0');
  21. file.read(&content[0], size);
  22. // 使用正则表达式查找版本模式 (例如: "1.2.3.4")
  23. std::regex version_re(R"((\d+)\.(\d+)\.(\d+)\.(\d+))");
  24. std::smatch match;
  25. if (std::regex_search(content, match, version_re)) {
  26. info.major = static_cast<uint16_t>(std::stoi(match[1]));
  27. info.minor = static_cast<uint16_t>(std::stoi(match[2]));
  28. info.build = static_cast<uint16_t>(std::stoi(match[3]));
  29. info.revision = static_cast<uint16_t>(std::stoi(match[4]));
  30. return true;
  31. }
  32. return false;
  33. }
  34. }
  35. //-----------------------------------------------------------------------------
  36. // FileVersion
  37. //-----------------------------------------------------------------------------
  38. FileVersion::FileVersion() : m_bValid(false) {
  39. memset(&m_version, 0, sizeof(m_version));
  40. }
  41. FileVersion::FileVersion(const char* lpszFileName) : m_bValid(false) {
  42. memset(&m_version, 0, sizeof(m_version));
  43. Open(lpszFileName);
  44. }
  45. FileVersion::~FileVersion (void){
  46. Close ();
  47. }
  48. void FileVersion::Close() {
  49. m_bValid = false;
  50. memset(&m_version, 0, sizeof(m_version));
  51. }
  52. bool FileVersion::Open(const char* lpszFileName) {
  53. if (!lpszFileName) {
  54. assert(false);
  55. return false;
  56. }
  57. Close();
  58. m_bValid = GetVersionInfo(lpszFileName);
  59. return m_bValid;
  60. }
  61. bool FileVersion::GetVersionInfo (const char* lpszFileName)
  62. {
  63. return ParseVersionFromELF(lpszFileName, m_version);
  64. }
  65. bool FileVersion::IsValid() const { return m_bValid; }
  66. uint16_t FileVersion::GetVersionMajor() const {
  67. assert(m_bValid);
  68. return m_version.major;
  69. }
  70. uint16_t FileVersion::GetVersionMinor() const {
  71. assert(m_bValid);
  72. return m_version.minor;
  73. }
  74. uint16_t FileVersion::GetVersionBuild() const {
  75. assert(m_bValid);
  76. return m_version.build;
  77. }
  78. uint16_t FileVersion::GetVersionRevision() const {
  79. assert(m_bValid);
  80. return m_version.revision;
  81. }
  82. std::string FileVersion::GetVersionString() const {
  83. if (!m_bValid) return "";
  84. return std::to_string(m_version.major) + "." +
  85. std::to_string(m_version.minor) + "." +
  86. std::to_string(m_version.build) + "." +
  87. std::to_string(m_version.revision);
  88. }