源码 头文件 sdf_exception.h
#pragma once
#include <exception>
#include <string>
namespace sdf {
namespace common{
using sdf_error_code_t = uint32_t;
class SdfException : std::exception{
public:
explicit SdfException(sdf_error_code_t errorCode) : error_code(error_code){};
SdfException(sdf_error_code_t errorCode,std::string error_message){}
SdfException(sdf_error_code_t x,sdf_error_code_t y,sdf_error_code_t z):error_code(pack211(x,y,z)){}
SdfException(sdf_error_code_t x,sdf_error_code_t y,sdf_error_code_t z,std::string error_message){}
const char *what() const noexcept override;
sdf_error_code_t get_error_code() const{
return error_code;
}
public:
static sdf_error_code_t pack211(sdf_error_code_t x,sdf_error_code_t y,sdf_error_code_t z){
return x << 16U | y << 8U | z; //Appending u to any integral constant makes the compiler interpret it as unsigned.
}
private:
sdf_error_code_t error_code;
std::string error_message;
bool error_message_packed = false;//< flag for lazy packing error message
};
}
}
学习
源文件 sdf_exception.cpp
#include "sdf_exception.h"
#include "logging.h"
namespace sdf {
namespace common {
std::string pack_error_message(sdf_error_code_t error_code,
const std::string &error_message) {
char buffer[1024];
auto length =
std::snprintf(buffer, sizeof(buffer), "sdf exception: [0x%08x] %s\n",
error_code, error_message.c_str());
if (length < 0 || length >= static_cast<int>(sizeof(buffer))) {
log_fatal("Unexpected error message length: %s", length);
}
return buffer;
}
SdfException::SdfException(sdf_error_code_t error_code,
std::string error_message)
: error_code(error_code), error_message(std::move(error_message)) {}
SdfException::SdfException(sdf_error_code_t x, sdf_error_code_t y,
sdf_error_code_t z, std::string error_message)
: error_code(pack211(x, y, z)), error_message(std::move(error_message)) {}
const char *SdfException::what() const noexcept {
if (!error_message_packed) {
const_cast<bool &>(error_message_packed) = true;
const_cast<std::string &>(error_message) =
pack_error_message(error_code, error_message);
}
return error_message.c_str();
}
} // namespace common
} // namespace sdf
学习
- snprintf() 参考链接
- 浅析c++中的类型转换--static_cast 参考链接
- std::move 参考链接
代码调用
代码层次结构
所需要的配套文件
logging.h
#pragma once
namespace sdf {
namespace common {
enum LogLevel {
SDF_LOG_DEBUG,
SDF_LOG_INFO,
SDF_LOG_WARN,
SDF_LOG_ERROR,
SDF_LOG_FATAL,
SDF_LOG_IMPORTANT_INFO
};
void set_logging_level(LogLevel level);
#define LOGGER_DECLARATION(level) void log_##level(const char *format, ...);
LOGGER_DECLARATION(debug)
LOGGER_DECLARATION(info)
LOGGER_DECLARATION(warn)
LOGGER_DECLARATION(error)
LOGGER_DECLARATION(fatal)
LOGGER_DECLARATION(important)
#undef LOGGER_DECLARATION
} // namespace common
} // namespace sdf
logging.cpp
#include "logging.h"
//#include "sdf_config.h"
#include <cstdarg>
#include <cstdio>
#include <ctime>
#include <mutex>
#ifdef ENABLE_SYSLOG
#include <syslog.h>
#endif
namespace sdf {
namespace common {
const char *get_current_time() {
static char buffer[80];
time_t raw_time;
std::time(&raw_time);
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S",
localtime(&raw_time));
return buffer;
}
class Logger {
public:
static inline void set_logging_level(LogLevel level) {
default_logging_level = level;
}
#ifndef ENABLE_SYSLOG
static void vlog(LogLevel level, const char *format, va_list ap) {
if (level < Logger::default_logging_level) {
return;
}
auto endpoint = stdout;
if (level == SDF_LOG_ERROR || level == SDF_LOG_FATAL) {
endpoint = stderr;
}
const char *level_info = nullptr;
switch (level) {
case SDF_LOG_DEBUG:
level_info = "DEBUG";
break;
case SDF_LOG_INFO:
case SDF_LOG_IMPORTANT_INFO:
level_info = "INFO";
break;
case SDF_LOG_WARN:
level_info = "WARN";
break;
case SDF_LOG_ERROR:
level_info = "ERROR";
break;
case SDF_LOG_FATAL:
level_info = "FATAL";
break;
default:
break;
}
std::lock_guard<std::mutex> lock(log_mutex);
::fprintf(endpoint, "[%s][%s] ", get_current_time(), level_info);
::vfprintf(endpoint, format, ap);
::fprintf(endpoint, "\n");
if (level == SDF_LOG_FATAL) {
::abort();
}
}
#else
static void vlog(LogLevel level, const char *format, va_list ap) {
if (level < Logger::default_logging_level) {
return;
}
int syslog_level = 0;
switch (level) {
case SDF_LOG_DEBUG:
syslog_level = LOG_DEBUG;
break;
case SDF_LOG_INFO:
syslog_level = LOG_INFO;
break;
case SDF_LOG_IMPORTANT_INFO:
syslog_level = LOG_NOTICE;
break;
case SDF_LOG_WARN:
syslog_level = LOG_WARNING;
break;
case SDF_LOG_ERROR:
syslog_level = LOG_ERR;
break;
case SDF_LOG_FATAL:
syslog_level = LOG_CRIT;
break;
default:
break;
}
// std::lock_guard<std::mutex> lock(log_mutex);
vsyslog(syslog_level, format, ap);
if (level == SDF_LOG_FATAL) {
::abort();
}
}
#endif
static inline void log(LogLevel level, const char *format, ...) {
va_list ap;
va_start(ap, format);
vlog(level, format, ap);
va_end(ap);
}
private:
static LogLevel default_logging_level;
static std::mutex log_mutex;
};
LogLevel Logger::default_logging_level = LogLevel::SDF_LOG_INFO;
std::mutex Logger::log_mutex;
void set_logging_level(LogLevel level) { Logger::set_logging_level(level); }
#define LOGGER_DEFINITION(level, level_tag) \
void log_##level(const char *format, ...) { \
va_list ap; \
va_start(ap, format); \
Logger::vlog(level_tag, format, ap); \
va_end(ap); \
}
LOGGER_DEFINITION(debug, SDF_LOG_DEBUG)
LOGGER_DEFINITION(info, SDF_LOG_INFO)
LOGGER_DEFINITION(warn, SDF_LOG_WARN)
LOGGER_DEFINITION(error, SDF_LOG_ERROR)
LOGGER_DEFINITION(fatal, SDF_LOG_FATAL)
LOGGER_DEFINITION(important, SDF_LOG_IMPORTANT_INFO)
#undef LOGGER_DEFINITION
} // namespace common
} // namespace sdf
random_generator.cpp
#include "random_generator.h"
#include "../common/sdf_exception.h"
#include <string>
#include <iostream>
std::string::size_type sdf::sys::GenerateRandom::NDSKeyStore_Common_GenerateRandom( size_t uiLength){
std::cout << uiLength << std::endl;
try {
if(uiLength != 1024)
// throw common::SdfException(-1);
throw common::SdfException(45,"There is an error in the program, please solve it immediately!!");
// throw common::SdfException(1,2,3);
// throw common::SdfException(1,2,3,"There is an error in the program, please solve it immediately!");
} catch (common::SdfException& e) {
// std::cerr<<"ERROR CODE:"<< e.get_error_code() << std::endl;
std::cerr << e.what() << std::endl;
}
}
random_generator.h
#pragma once
#include <cstddef>
#include <string>
namespace sdf {
namespace sys{
class GenerateRandom {
public:
explicit GenerateRandom() = default;
virtual ~GenerateRandom() = default;
static std::string::size_type NDSKeyStore_Common_GenerateRandom(size_t uiLength);
};
}// namespace sys
}// namespace sdf
main函数调用
#include <iostream>
#include <sstream>
#include "../src/algorithm/random/random_generator.h"
#include "../src/algorithm/common/StringBuffer.h"
#define BUF_SIZE 1024
int main(){
sdf::sys::GenerateRandom::NDSKeyStore_Common_GenerateRandom(1026);
return 0;
}
注意事项: