Skip to content

Commit d823c6c

Browse files
committedMay 13, 2024
[代码重构与功能更新]
- 在`breakpad.cc`中,增加了对宽字符串到UTF-8字符串转换的函数,以支持在Windows平台上更准确地处理错误信息和日志记录。 - 更新了`Breakpad`类的析构函数,使用`= default`以使用编译器提供的默认析构函数。 - 更新了根`CMakeLists.txt`文件中的`cmake_minimum_required`版本,从3.5更新到3.18,以支持更多现代化的CMake特性。 - 在`CountDownLatch`的测试用例中,增加了对`CountDownLatch`实际使用场景的模拟,通过模拟多个工作线程和清理线程,展示了`CountDownLatch`如何在实际应用中同步线程。 - 在`main.cc`中,对Glog日志系统的配置进行了改进,增加了日志目录的创建,并调整了日志清理的策略。 - 在`openssl_x509.cc`中,使用更现代的OpenSSL API生成和验证X509证书,移除了已弃用的函数,改用`BIO_new_file`和`PEM_read_bio_*`函数进行文件操作,提高了代码的健壮性。 - 在根`CMakeLists.txt`文件中,将项目名称从`Cpp-Example`修正为`Cpp-Examples`,以反映项目的实际内容。 - 新增了`vcpkg.json`文件,集中声明了项目的vcpkg依赖,简化了依赖管理过程。
1 parent 8fadf5c commit d823c6c

File tree

6 files changed

+153
-62
lines changed

6 files changed

+153
-62
lines changed
 

‎Breakpad/breakpad.cc

+32-11
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,42 @@
1313
#include <locale>
1414

1515
#ifdef _WIN32
16-
bool callback(const wchar_t *dump_path,
16+
17+
auto convertWideStringToUTF8(const wchar_t *wstr) -> std::string
18+
{
19+
if (wstr == nullptr) {
20+
return {};
21+
}
22+
23+
// 首先,获取转换后的字符串长度(不包括空终止符)
24+
int len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr);
25+
26+
// 如果转换失败,返回空字符串
27+
if (len == 0) {
28+
return {};
29+
}
30+
31+
// 分配足够的空间来存储转换后的字符串
32+
std::string utf8String(len, 0);
33+
34+
// 执行转换
35+
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &utf8String[0], len, nullptr, nullptr);
36+
37+
// 去除末尾的空字符
38+
utf8String.resize(len - 1);
39+
return utf8String;
40+
}
41+
42+
auto callback(const wchar_t *dump_path,
1743
const wchar_t *id,
1844
void *context,
1945
EXCEPTION_POINTERS *exinfo,
2046
MDRawAssertionInfo *assertion,
21-
bool succeeded)
47+
bool succeeded) -> bool
2248
{
23-
auto succeeded_str = succeeded ? "succeeded" : "fialed";
24-
auto convert_str = [](const wchar_t *wstr) {
25-
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
26-
return converter.to_bytes(wstr);
27-
};
28-
auto dump_path_str = convert_str(dump_path) + convert_str(id);
29-
std::cout << "Create dump file " << succeeded_str << " Dump path: " << dump_path_str
30-
<< std::endl;
49+
const auto *succeeded_str = succeeded ? "succeeded" : "fialed";
50+
auto dump_path_str = convertWideStringToUTF8(dump_path) + convertWideStringToUTF8(id);
51+
std::cout << "Create dump file " << succeeded_str << " Dump path: " << dump_path_str << '\n';
3152
return succeeded;
3253
}
3354
#elif __APPLE__
@@ -66,4 +87,4 @@ Breakpad::Breakpad(const std::string &dump_path)
6687
#endif
6788
}
6889

69-
Breakpad::~Breakpad() {}
90+
Breakpad::~Breakpad() = default;

‎CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# 设定版本号
2-
cmake_minimum_required(VERSION 3.5)
2+
cmake_minimum_required(VERSION 3.18)
33

44
if(CMAKE_HOST_WIN32)
55
set(CMAKE_TOOLCHAIN_FILE

‎CountDownLatch/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
add_executable(CountDownLatch_test main.cc countdownlatch.hpp)
1+
add_executable(countdownlatch_test main.cc countdownlatch.hpp)
22

33
if(CMAKE_HOST_UNIX)
4-
target_link_libraries(CountDownLatch_test pthread)
4+
target_link_libraries(countdownlatch_test pthread)
55
endif()

‎CountDownLatch/main.cc

+47-10
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,53 @@
33
#include <iostream>
44
#include <thread>
55

6+
struct Job
7+
{
8+
const std::string name;
9+
std::string product{"not worked"};
10+
std::thread action{};
11+
};
12+
13+
void countDownLatchTest()
14+
{
15+
Job jobs[]{{"Annika"}, {"Buru"}, {"Chuck"}};
16+
17+
CountDownLatch work_done{std::size(jobs)};
18+
CountDownLatch start_clean_up{1};
19+
20+
auto work = [&](Job &my_job) {
21+
my_job.product = my_job.name + " worked";
22+
work_done.countDown();
23+
start_clean_up.wait();
24+
my_job.product = my_job.name + " cleaned";
25+
};
26+
27+
std::cout << "Work is starting... ";
28+
for (auto &job : jobs) {
29+
job.action = std::thread{work, std::ref(job)};
30+
}
31+
32+
work_done.wait();
33+
std::cout << "done:\n";
34+
for (auto const &job : jobs) {
35+
std::cout << " " << job.product << '\n';
36+
}
37+
38+
std::cout << "Workers are cleaning up... ";
39+
start_clean_up.countDown();
40+
for (auto &job : jobs) {
41+
job.action.join();
42+
}
43+
44+
std::cout << "done:\n";
45+
for (auto const &job : jobs) {
46+
std::cout << " " << job.product << '\n';
47+
}
48+
}
49+
650
auto main() -> int
751
{
8-
CountDownLatch latch(1);
9-
std::thread thread([&]() {
10-
std::cout << "thread start" << std::endl;
11-
latch.wait();
12-
std::cout << "thread end" << std::endl;
13-
});
14-
std::cout << "main start" << std::endl;
15-
latch.countDown();
16-
thread.join();
17-
std::cout << "main end" << std::endl;
52+
countDownLatchTest();
53+
54+
return 0;
1855
}

‎Glog/main.cc

+18-14
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,33 @@
55
auto main(int argc, char **argv) -> int
66
{
77
(void) argc;
8-
(void) argv;
8+
9+
const auto *log_dir = "./glog_demo";
910

1011
// Initialize Google’s logging library.
1112
google::InitGoogleLogging(argv[0]);
1213
google::InstallFailureSignalHandler();
1314
google::SetLogFilenameExtension(".log");
14-
google::EnableLogCleaner(3);
15+
google::EnableLogCleaner(7);
1516
//google::DisableLogCleaner();
16-
FLAGS_alsologtostderr = true; //是否将日志输出到文件和stderr
17-
FLAGS_colorlogtostderr = true; //是否启用不同颜色显示
18-
fLS::FLAGS_log_dir = "./Log";
17+
FLAGS_alsologtostderr = true; // 是否将日志输出到文件和stderr
18+
FLAGS_colorlogtostderr = true; // 是否启用不同颜色显示
19+
FLAGS_max_log_size = 1000; // 最大日志文件大小
20+
fLS::FLAGS_log_dir = log_dir;
21+
22+
std::filesystem::create_directories(log_dir);
1923

20-
std::filesystem::create_directories("./Log");
24+
std::string message("Hello World");
2125

22-
LOG(INFO) << "INFO_LOG Hello, world!";
23-
LOG(WARNING) << "WARNING_LOG Hello, world!";
24-
LOG(ERROR) << "ERROR_LOG Hello, world!";
25-
//LOG(FATAL) << "FATAL_LOG Hello, world!";
26+
LOG(INFO) << message;
27+
LOG(WARNING) << message;
28+
LOG(ERROR) << message;
29+
// LOG(FATAL) << message;
2630

27-
DLOG(INFO) << "DINFO_LOG Hello, world!";
28-
DLOG(WARNING) << "DWARNING_LOG Hello, world!";
29-
DLOG(ERROR) << "DERROR_LOG Hello, world!";
30-
//DLOG(FATAL) << "DFATAL_LOG Hello, world!";
31+
DLOG(INFO) << message;
32+
DLOG(WARNING) << message;
33+
DLOG(ERROR) << message;
34+
// DLOG(FATAL) << message;
3135

3236
google::ShutdownGoogleLogging();
3337
return 0;

‎OpenSSL/openssl_x509.cc

+53-24
Original file line numberDiff line numberDiff line change
@@ -12,65 +12,94 @@
1212
void x509_generate_certificate(const std::string &x509Path, const std::string &pkeyPath)
1313
{
1414
// 生成私钥
15-
EVP_PKEY *pkey = EVP_PKEY_new();
16-
EVP_PKEY_assign_RSA(pkey, RSA_generate_key(2048, RSA_F4, NULL, NULL));
15+
auto *pKey = EVP_RSA_gen(2048);
1716

1817
// 生成证书
1918
X509 *x509 = X509_new();
2019
X509_set_version(x509, 2);
2120
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
2221
X509_gmtime_adj(X509_get_notBefore(x509), 0);
2322
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);
24-
X509_set_pubkey(x509, pkey);
23+
X509_set_pubkey(x509, pKey);
2524

2625
// 设置证书信息
2726
X509_NAME *name = X509_get_subject_name(x509);
28-
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (const unsigned char *) "CN", -1, -1, 0);
29-
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (const unsigned char *) "CN", -1, -1, 0);
30-
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const unsigned char *) "CN", -1, -1, 0);
27+
X509_NAME_add_entry_by_txt(name,
28+
"C",
29+
MBSTRING_ASC,
30+
reinterpret_cast<const unsigned char *>("CN"),
31+
-1,
32+
-1,
33+
0);
34+
X509_NAME_add_entry_by_txt(name,
35+
"O",
36+
MBSTRING_ASC,
37+
reinterpret_cast<const unsigned char *>("CN"),
38+
-1,
39+
-1,
40+
0);
41+
X509_NAME_add_entry_by_txt(name,
42+
"CN",
43+
MBSTRING_ASC,
44+
reinterpret_cast<const unsigned char *>("CN"),
45+
-1,
46+
-1,
47+
0);
3148
X509_set_issuer_name(x509, name);
3249

3350
// 签名证书
34-
X509_sign(x509, pkey, EVP_sha1());
51+
X509_sign(x509, pKey, EVP_sha1());
3552

3653
// 保存证书
37-
FILE *fp = fopen(x509Path.c_str(), "wb");
38-
PEM_write_X509(fp, x509);
39-
fclose(fp);
54+
auto *out = BIO_new_file(x509Path.c_str(), "w");
55+
if (out != nullptr) {
56+
PEM_write_bio_X509(out, x509);
57+
BIO_free(out);
58+
}
4059

4160
// 保存私钥
42-
fp = fopen(pkeyPath.c_str(), "wb");
43-
PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
44-
fclose(fp);
61+
out = BIO_new_file(pkeyPath.c_str(), "w");
62+
if (out != nullptr) {
63+
PEM_write_bio_PrivateKey(out, pKey, nullptr, nullptr, 0, nullptr, nullptr);
64+
BIO_free(out);
65+
}
4566

4667
// 释放资源
4768
X509_free(x509);
48-
EVP_PKEY_free(pkey);
69+
EVP_PKEY_free(pKey);
4970
}
5071

5172
// x509 读取证书 并验证
5273
void x509_read_certificate(const std::string &x509Path, const std::string &pkeyPath)
5374
{
5475
// 读取证书
55-
FILE *fp = fopen(x509Path.c_str(), "rb");
56-
X509 *x509 = PEM_read_X509(fp, NULL, NULL, NULL);
57-
fclose(fp);
76+
auto *in = BIO_new_file(x509Path.c_str(), "r");
77+
if (in == nullptr) {
78+
std::cerr << "read certificate failed" << '\n';
79+
return;
80+
}
81+
X509 *x509 = PEM_read_bio_X509(in, nullptr, nullptr, nullptr);
82+
BIO_free(in);
5883

5984
// 读取私钥
60-
fp = fopen(pkeyPath.c_str(), "rb");
61-
EVP_PKEY *pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
62-
fclose(fp);
85+
in = BIO_new_file(pkeyPath.c_str(), "r");
86+
if (in == nullptr) {
87+
std::cerr << "read pkey failed" << '\n';
88+
return;
89+
}
90+
EVP_PKEY *pKey = PEM_read_bio_PrivateKey(in, nullptr, nullptr, nullptr);
91+
BIO_free(in);
6392

6493
// 验证证书
65-
if (X509_verify(x509, pkey) == 1) {
66-
std::cout << "verify success" << std::endl;
94+
if (X509_verify(x509, pKey) == 1) {
95+
std::cout << "verify success" << '\n';
6796
} else {
68-
std::cout << "verify failed" << std::endl;
97+
std::cout << "verify failed" << '\n';
6998
}
7099

71100
// 释放资源
72101
X509_free(x509);
73-
EVP_PKEY_free(pkey);
102+
EVP_PKEY_free(pKey);
74103
}
75104

76105
auto main() -> int

0 commit comments

Comments
 (0)
Please sign in to comment.