#ifndef GERMANAIRLINESVA_GACONNECTOR_UTIL_H #define GERMANAIRLINESVA_GACONNECTOR_UTIL_H #ifdef IBM #define WIN32_LEAN_AND_MEAN #endif #define BUFSIZE 1024 #define MD5LEN 16 #define EARTH_M 6371000 #ifdef IBM // clang-format off #include #include // clang-format on #endif #ifdef APL #include #include #endif #ifdef LIN #include #include #endif #if defined APL || defined LIN #include #include #include #endif #include #include #include #include #include #include #include namespace germanairlinesva_util { template static inline std::vector select_T(const std::vector &inVec, std::function predicate) { std::vector result; copy_if(inVec.begin(), inVec.end(), back_inserter(result), predicate); return result; } #if defined APL || defined LIN static inline unsigned long get_size_by_fd(int fd) { struct stat buf { }; if (fstat(fd, &buf) < 0) return 0; return buf.st_size; } #endif static inline void to_hex(const char *hash, char *buffer) { for (int i = 0; i < MD5LEN; i++) { if (buffer != nullptr) { sprintf(&buffer[2 * i], "%02x", hash[i] & 0xff); } } } static inline bool fileExists(const char *path) { return static_cast(std::ifstream(path)); } #ifdef IBM static inline int generateMD5(const char *filepath, char *lastHash, const std::function toLog) { BOOL bResult = FALSE; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HANDLE hFile; BYTE rgbFile[BUFSIZE] = {0}; DWORD cbRead = 0; BYTE rgbHash[MD5LEN] = {0}; DWORD cbHash = 0; // Logic to check usage goes here. hFile = CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr); // Get handle to the crypto provider if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { toLog("CryptAcquireContext returned with error " + std::to_string(GetLastError())); CloseHandle(hFile); return 1; } if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { toLog("CryptCreateHash returned with error " + std::to_string(GetLastError())); CloseHandle(hFile); CryptReleaseContext(hProv, 0); return 1; } while ((bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, nullptr))) { if (0 == cbRead) { break; } if (!CryptHashData(hHash, rgbFile, cbRead, 0)) { toLog("CryptHashData returned with error " + std::to_string(GetLastError())); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return 1; } } if (!bResult) { toLog("ReadFile returned with error " + std::to_string(GetLastError())); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return 1; } cbHash = MD5LEN; if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { to_hex((char *)rgbHash, lastHash); } else { toLog("CryptGetHashParam returned with error " + std::to_string(GetLastError())); } CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); CloseHandle(hFile); return 0; } #endif #ifdef APL #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" static inline int generateMD5(const char *filepath, char *lastHash, const std::function &toLog) { int file_descript; unsigned long file_size; char *file_buffer; unsigned char result[MD5LEN]; file_descript = open(filepath, O_RDONLY); if (file_descript < 0) return 1; file_size = get_size_by_fd(file_descript); file_buffer = (char *)mmap(0, file_size, PROT_READ, MAP_SHARED, file_descript, 0); CC_MD5_CTX context; CC_MD5_Init(&context); CC_MD5_Update(&context, file_buffer, (CC_LONG)file_size); CC_MD5_Final(result, &context); munmap(file_buffer, file_size); close(file_descript); to_hex((char *)result, lastHash); return 0; } #pragma clang diagnostic pop #endif #ifdef LIN #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" static inline int generateMD5(const char *filepath, char *buffer, const std::function &toLog) { int file_descriptor; unsigned long file_size; char *file_buffer; unsigned char result[MD5LEN]; file_descriptor = open(filepath, O_RDONLY); if (file_descriptor < 0) return 1; file_size = get_size_by_fd(file_descriptor); if (file_size == 0) return 1; file_buffer = (char *) mmap(nullptr, file_size, PROT_READ, MAP_SHARED, file_descriptor, 0); MD5((unsigned char *)file_buffer, file_size, result); munmap(file_buffer, file_size); close(file_descriptor); to_hex((char *)result, buffer); return 0; } #pragma clang diagnostic pop #endif #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" static inline void setThreadName(const std::string &name) { #ifdef APL // // Apple reserves 16 bytes for its thread names // Notice that the Apple version of pthread_setname_np // does not take a pthread_t argument // pthread_setname_np(name.substr(0, 63).c_str()); #endif #ifdef LIN // // Linux only reserves 16 bytes for its thread names // See prctl and PR_SET_NAME property in // http://man7.org/linux/man-pages/man2/prctl.2.html // pthread_setname_np(pthread_self(), name.substr(0, 15).c_str()); #endif } #pragma clang diagnostic pop // trim from start (in place) static inline void ltrim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); })); } // trim from end (in place) static inline void rtrim(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }) .base(), s.end()); } static inline std::string rtrim_copy(std::string s) { rtrim(s); return s; } // trim from both ends (in place) static inline void trim(std::string &s) { ltrim(s); rtrim(s); } static inline std::vector split(const std::string &s, char delim) { std::vector result; std::stringstream ss(s); std::string item; while (getline(ss, item, delim)) { result.push_back(item); } return result; } } // namespace germanairlinesva_util #endif