| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 "UtilAll.h" |
| |
| #include <chrono> |
| |
| namespace rocketmq { |
| //<!************************************************************************ |
| std::string UtilAll::s_localHostName; |
| std::string UtilAll::s_localIpAddress; |
| |
| bool UtilAll::startsWith_retry(const string& topic) { |
| return topic.find(RETRY_GROUP_TOPIC_PREFIX) == 0; |
| } |
| |
| string UtilAll::getRetryTopic(const string& consumerGroup) { |
| return RETRY_GROUP_TOPIC_PREFIX + consumerGroup; |
| } |
| |
| void UtilAll::Trim(string& str) { |
| str.erase(0, str.find_first_not_of(' ')); // prefixing spaces |
| str.erase(str.find_last_not_of(' ') + 1); // surfixing spaces |
| } |
| |
| bool UtilAll::isBlank(const string& str) { |
| if (str.empty()) { |
| return true; |
| } |
| |
| string::size_type left = str.find_first_not_of(WHITESPACE); |
| |
| if (left == string::npos) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| const int hex2int[256] = { |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
| -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; |
| |
| uint64 UtilAll::hexstr2ull(const char* str) { |
| uint64 num = 0; |
| unsigned char* ch = (unsigned char*)str; |
| while (*ch != '\0') { |
| num = (num << 4) + hex2int[*ch]; |
| ch++; |
| } |
| return num; |
| } |
| |
| int64 UtilAll::str2ll(const char* str) { |
| return boost::lexical_cast<int64>(str); |
| } |
| |
| string UtilAll::bytes2string(const char* bytes, int len) { |
| if (bytes == NULL || len <= 0) { |
| return string(); |
| } |
| |
| #ifdef WIN32 |
| string buffer; |
| for (int i = 0; i < len; i++) { |
| char tmp[3]; |
| sprintf(tmp, "%02X", (unsigned char)bytes[i]); |
| buffer.append(tmp); |
| } |
| |
| return buffer; |
| #else |
| static const char hex_str[] = "0123456789ABCDEF"; |
| |
| char result[len * 2 + 1]; |
| |
| result[len * 2] = 0; |
| for (int i = 0; i < len; i++) { |
| result[i * 2 + 0] = hex_str[(bytes[i] >> 4) & 0x0F]; |
| result[i * 2 + 1] = hex_str[(bytes[i]) & 0x0F]; |
| } |
| |
| string buffer(result); |
| return buffer; |
| #endif |
| } |
| |
| bool UtilAll::SplitURL(const string& serverURL, string& addr, short& nPort) { |
| size_t pos = serverURL.find(':'); |
| if (pos == string::npos) { |
| return false; |
| } |
| |
| addr = serverURL.substr(0, pos); |
| if (0 == addr.compare("localhost")) { |
| addr = "127.0.0.1"; |
| } |
| |
| pos++; |
| string port = serverURL.substr(pos, serverURL.length() - pos); |
| nPort = atoi(port.c_str()); |
| if (nPort == 0) { |
| return false; |
| } |
| return true; |
| } |
| |
| int UtilAll::Split(vector<string>& ret_, const string& strIn, const char sep) { |
| if (strIn.empty()) |
| return 0; |
| |
| string tmp; |
| string::size_type pos_begin = strIn.find_first_not_of(sep); |
| string::size_type comma_pos = 0; |
| |
| while (pos_begin != string::npos) { |
| comma_pos = strIn.find(sep, pos_begin); |
| if (comma_pos != string::npos) { |
| tmp = strIn.substr(pos_begin, comma_pos - pos_begin); |
| pos_begin = comma_pos + 1; |
| } else { |
| tmp = strIn.substr(pos_begin); |
| pos_begin = comma_pos; |
| } |
| |
| if (!tmp.empty()) { |
| ret_.push_back(tmp); |
| tmp.clear(); |
| } |
| } |
| return ret_.size(); |
| } |
| int UtilAll::Split(vector<string>& ret_, const string& strIn, const string& sep) { |
| if (strIn.empty()) |
| return 0; |
| |
| string tmp; |
| string::size_type pos_begin = strIn.find_first_not_of(sep); |
| string::size_type comma_pos = 0; |
| |
| while (pos_begin != string::npos) { |
| comma_pos = strIn.find(sep, pos_begin); |
| if (comma_pos != string::npos) { |
| tmp = strIn.substr(pos_begin, comma_pos - pos_begin); |
| pos_begin = comma_pos + sep.length(); |
| } else { |
| tmp = strIn.substr(pos_begin); |
| pos_begin = comma_pos; |
| } |
| |
| if (!tmp.empty()) { |
| ret_.push_back(tmp); |
| tmp.clear(); |
| } |
| } |
| return ret_.size(); |
| } |
| |
| bool UtilAll::StringToInt32(const std::string& str, int32_t& out) { |
| out = 0; |
| if (str.empty()) { |
| return false; |
| } |
| |
| char* end = NULL; |
| errno = 0; |
| long l = strtol(str.c_str(), &end, 10); |
| /* Both checks are needed because INT_MAX == LONG_MAX is possible. */ |
| if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX)) |
| return false; |
| if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN)) |
| return false; |
| if (*end != '\0') |
| return false; |
| out = l; |
| return true; |
| } |
| |
| bool UtilAll::StringToInt64(const std::string& str, int64_t& val) { |
| char* endptr = NULL; |
| errno = 0; /* To distinguish success/failure after call */ |
| val = strtoll(str.c_str(), &endptr, 10); |
| |
| /* Check for various possible errors */ |
| if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0)) { |
| return false; |
| } |
| /*no digit was found Or Further characters after number*/ |
| if (endptr == str.c_str()) { |
| return false; |
| } |
| /*no digit was found Or Further characters after number*/ |
| if (*endptr != '\0') { |
| return false; |
| } |
| /* If we got here, strtol() successfully parsed a number */ |
| return true; |
| } |
| |
| string UtilAll::getLocalHostName() { |
| if (s_localHostName.empty()) { |
| // boost::system::error_code error; |
| // s_localHostName = boost::asio::ip::host_name(error); |
| |
| char name[1024]; |
| boost::system::error_code ec; |
| if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) { |
| return std::string(); |
| } |
| s_localHostName.append(name, strlen(name)); |
| } |
| return s_localHostName; |
| } |
| |
| string UtilAll::getLocalAddress() { |
| if (s_localIpAddress.empty()) { |
| boost::asio::io_service io_service; |
| boost::asio::ip::tcp::resolver resolver(io_service); |
| boost::asio::ip::tcp::resolver::query query(getLocalHostName(), ""); |
| boost::system::error_code error; |
| boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query, error); |
| if (error) { |
| return ""; |
| } |
| boost::asio::ip::tcp::resolver::iterator end; // End marker. |
| boost::asio::ip::tcp::endpoint ep; |
| while (iter != end) { |
| ep = *iter++; |
| } |
| s_localIpAddress = ep.address().to_string(); |
| } |
| return s_localIpAddress; |
| } |
| |
| string UtilAll::getHomeDirectory() { |
| #ifndef WIN32 |
| char* homeEnv = getenv("HOME"); |
| string homeDir; |
| if (homeEnv == NULL) { |
| homeDir.append(getpwuid(getuid())->pw_dir); |
| } else { |
| homeDir.append(homeEnv); |
| } |
| #else |
| string homeDir(getenv("USERPROFILE")); |
| #endif |
| return homeDir; |
| } |
| |
| string UtilAll::getProcessName() { |
| #ifndef WIN32 |
| char buf[PATH_MAX + 1] = {0}; |
| int count = PATH_MAX + 1; |
| char procpath[PATH_MAX + 1] = {0}; |
| sprintf(procpath, "/proc/%d/exe", getpid()); |
| |
| if (access(procpath, F_OK) == -1) { |
| return ""; |
| } |
| |
| int retval = readlink(procpath, buf, count - 1); |
| if ((retval < 0 || retval >= count - 1)) { |
| return ""; |
| } |
| if (!strcmp(buf + retval - 10, " (deleted)")) |
| buf[retval - 10] = '\0'; // remove last " (deleted)" |
| else |
| buf[retval] = '\0'; |
| |
| char* process_name = strrchr(buf, '/'); |
| if (process_name) { |
| return std::string(process_name + 1); |
| } else { |
| return ""; |
| } |
| #else |
| TCHAR szFileName[MAX_PATH + 1]; |
| GetModuleFileName(NULL, szFileName, MAX_PATH + 1); |
| return std::string(szFileName); |
| #endif |
| } |
| |
| uint64_t UtilAll::currentTimeMillis() { |
| auto since_epoch = |
| std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()); |
| return static_cast<uint64_t>(since_epoch.count()); |
| } |
| |
| uint64_t UtilAll::currentTimeSeconds() { |
| auto since_epoch = |
| std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()); |
| return static_cast<uint64_t>(since_epoch.count()); |
| } |
| |
| bool UtilAll::deflate(std::string& input, std::string& out, int level) { |
| boost::iostreams::zlib_params zlibParams(level, boost::iostreams::zlib::deflated); |
| boost::iostreams::filtering_ostream compressingStream; |
| compressingStream.push(boost::iostreams::zlib_compressor(zlibParams)); |
| compressingStream.push(boost::iostreams::back_inserter(out)); |
| compressingStream << input; |
| boost::iostreams::close(compressingStream); |
| |
| return true; |
| } |
| |
| bool UtilAll::inflate(std::string& input, std::string& out) { |
| boost::iostreams::filtering_ostream decompressingStream; |
| decompressingStream.push(boost::iostreams::zlib_decompressor()); |
| decompressingStream.push(boost::iostreams::back_inserter(out)); |
| decompressingStream << input; |
| boost::iostreams::close(decompressingStream); |
| |
| return true; |
| } |
| |
| bool UtilAll::ReplaceFile(const std::string& from_path, const std::string& to_path) { |
| #ifdef WIN32 |
| // Try a simple move first. It will only succeed when |to_path| doesn't |
| // already exist. |
| if (::MoveFile(from_path.c_str(), to_path.c_str())) |
| return true; |
| // Try the full-blown replace if the move fails, as ReplaceFile will only |
| // succeed when |to_path| does exist. When writing to a network share, we may |
| // not be able to change the ACLs. Ignore ACL errors then |
| // (REPLACEFILE_IGNORE_MERGE_ERRORS). |
| if (::ReplaceFile(to_path.c_str(), from_path.c_str(), NULL, REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL)) { |
| return true; |
| } |
| return false; |
| #else |
| if (rename(from_path.c_str(), to_path.c_str()) == 0) |
| return true; |
| return false; |
| #endif |
| } |
| |
| std::map<std::string, std::string> UtilAll::ReadProperties(const std::string& path) { |
| std::map<std::string, std::string> property_map; |
| std::ifstream property_file; |
| property_file.open(path); |
| std::string line_buffer; |
| |
| if (property_file.is_open()) { |
| while (!property_file.eof()) { |
| std::getline(property_file, line_buffer); |
| std::size_t pos{0}; |
| pos = line_buffer.find('#'); |
| if (pos != string::npos) { |
| line_buffer = line_buffer.substr(0, pos); |
| } |
| if (line_buffer.empty()) { |
| continue; |
| } |
| pos = line_buffer.find('='); |
| if (pos != string::npos) { |
| std::string key = boost::trim_copy(line_buffer.substr(0, pos)); |
| std::string value = boost::trim_copy(line_buffer.substr(pos + 1)); |
| property_map[key] = value; |
| } |
| } |
| } |
| |
| return property_map; |
| } |
| |
| } // namespace rocketmq |