网络编程入门07
LogStream.h
const int kSmallBuffer = 4000;
const int kLargeBuffer = 4000*1000;
temlpate <int SIZE>
class FixedBuffer{
private:
void (*cookie_)();
char data_[SIZE];
char* cur_;
public:
FixedBuffer() : cur_(data_){//构造函数
setCookie(cookieStart);
}
~dtr() {
setCookie(cookieEnd);
}
void append(const char* /*restrict*/ buf, size_t len) //追加数据
{
// FIXME: append partially
if (implicit_cast<size_t>(avail()) > len)
{
memcpy(cur_, buf, len);
cur_ += len;
}
}
const char* data() const { return data_; } //返回数据头
int length() const { return static_cast<int>(cur_ - data_); } //返回数据长度
char* current() { return cur_; } //返回当前数据尾巴
int avail() const { return static_cast<int>(end() - cur_); } //返回缓冲区剩余长度
void add(size_t len) { cur_ += len; } //数据区 边长
const char* debugString();
void setCookie(void (*cookie)()) { cookie_ = cookie; } //设置cookie_ 函数指针
// for used by unit test
string toString() const { return string(data_, length()); }
StringPiece toStringPiece() const { return StringPiece(data_, length()); }
private:
const char* end() const { return data_ + sizeof data_; } //返回缓冲区长度
// Must be outline function for cookies.
static void cookieStart(); //静态函数
static void cookieEnd();
}
class LogStream : noncopyable //内部用缓冲区,实现了对移位运算符重载,实现了自己的Log流类
{
public:
typedef LogStream self;
typedef detail::FixedBuffer<detail::kSmallBuffer> Buffer; //FixedBuffer座位内部成员
private:
void staticCheck();
template<typename T>
void formatInteger(T); //模板函数
Buffer buffer_; //FixedBuffer
static const int kMaxNumericSize = 32;
public:
self& operator<<(bool v) //写入bool值
{
buffer_.append(v ? "1" : "0", 1);
return *this;
}
self& operator<<(short);
self& operator<<(unsigned short);
self& operator<<(int);
self& operator<<(unsigned int);
self& operator<<(int);
self& operator<<(unsigned int);
self& operator<<(long);
self& operator<<(unsigned long);
self& operator<<(long long);
self& operator<<(unsigned long long);
self& operator<<(const void*);
self& operator<<(float v)
{
*this << static_cast<double>(v);
return *this;
}
self& operator<<(double);
// self& operator<<(long double);
self& operator<<(char v)
{
buffer_.append(&v, 1);
return *this;
}
self& operator<<(const char* str)
{
if (str)
{
buffer_.append(str, strlen(str));
}
else
{
buffer_.append("(null)", 6);
}
return *this;
}
self& operator<<(const unsigned char* str)
{
return operator<<(reinterpret_cast<const char*>(str));
}
self& operator<<(const string& v)
{
buffer_.append(v.c_str(), v.size());
return *this;
}
self& operator<<(const StringPiece& v)
{
buffer_.append(v.data(), v.size());
return *this;
}
self& operator<<(const Buffer& v)
{
*this << v.toStringPiece();
return *this;
}
void append(const char* data, int len) { buffer_.append(data, len); }
const Buffer& buffer() const { return buffer_; }
void resetBuffer() { buffer_.reset(); }
}
class Fmt{ //类似于redis SDS,
private:
char buf_[32];
int length_;
public:
template<typename T>
Fmt(const char* fmt, T val);
const char* data() { return buf_;}
int length() const { return length_;}
}
inline LogStream& operator<<(LogStream& s, const Fmt& fmt) //实现了logStream对 fmt的输入重载
{
s.append(fmt.data(), fmt.length());
return s;
}
string formatSI(int64_t n); //int转成国际单位制
string formatIEC(int64_t n); //int转为IEC制
template<typename T>
size_t convert(char buf[], T value); //把int转换为字符串,算法是去余,除10,最后翻转 123455 先得到554321 在翻转一下
*#if __WORDSIZE == 64*
*# ifndef __intptr_t_defined*
*typedef long int intptr_t;*
*# define __intptr_t_defined*
*# endif*
*typedef unsigned long int uintptr_t;*
*#else*
*# ifndef __intptr_t_defined*
*typedef int intptr_t;*
*# define __intptr_t_defined*
*# endif*
*typedef unsigned int uintptr_t;*
*#endif*
size_t convertHex(char buf[], uintptr_t value) //uint 转换为 16进制 mod 取余, 除16 ,翻转
Logging.h
class Logger{e
private:
class Impl
{
public:
typedef Logger::LogLevel LogLevel;
Impl(LogLevel level, int old_errno, const SourceFile& file, int line);
void formatTime();
void finish();
Timestamp time_;
LogStream stream_;
LogLevel level_;
int line_;
SourceFile basename_;
};
Impl impl_; //内部有一个Impl对象
};
public:
enum LogLevel{}
class SourceFile { //有感觉是一个类似sds的东西
const char* data_;
int size_;
public:
template<int N>
SourceFile(const char (&arr) [N]) : data_(arr), size_(N - 1) {
const char* slash = strrchr(data_, '/') ; //找到第一个找到'/'字符的那个点
if (slash)
{
data_ = slash + 1;
size_ -= static_cast<int>(data_ - arr);
}
}
explicit SourceFile(const char* filename)
: data_(filename)
{
const char* slash = strrchr(filename, '/');
if (slash)
{
data_ = slash + 1;
}
size_ = static_cast<int>(strlen(data_));
}
}
Logger(SourceFile file, int line); //一些log的构造方法
Logger(SourceFile file, int line, LogLevel level);
Logger(SourceFile file, int line, LogLevel level, const char* func);
Logger(SourceFile file, int line, bool toAbort);
~Logger();
LogStream& stream() { return impl_.stream_; }
static LogLevel logLevel();
static void setLogLevel(LogLevel level);
typedef void (*OutputFunc)(const char* msg, int len);
typedef void (*FlushFunc)();
static void setOutput(OutputFunc);
static void setFlush(FlushFunc);
static void setTimeZone(const TimeZone& tz);
}
extern Logger::LogLevel g_logLevel;
inline Logger::LogLevel Logger::logLevel()
{
return g_logLevel;
}
const char* strerror_tl(int savedErrno);
template <typename T>
T* CheckNotNull(Logger::SourceFile file, int line, const char *names, T* ptr)
{
if (ptr == NULL)
{
Logger(file, line, Logger::FATAL).stream() << names;
}
return ptr;
}
BlockingQueue.h
template<typename T>
class BlockingQueue : noncopyable //实现了一个线程安全的双端队列,push和take都需要加锁,使用条件变量和锁实现
{
public:
BlockingQueue()
: mutex_(),
notEmpty_(mutex_),
queue_()
{
}
}
BoundBlockingQueue.h
template<typename T>
class BoundedBlockingQueue : noncopyable //一个容量有限制的线程安全对了, 队列可能会满由,由两个条件变量实现 非空和非满
{
public:
explicit BoundedBlockingQueue(int maxSize)
: mutex_(),
notEmpty_(mutex_),
notFull_(mutex_),
queue_(maxSize)
{
}
Exception.h
class Exception : public std::exception
//对与异常的包装与处理