上图只写了部分,主要是input, output两大类, 类之间的关系相差不多,所以只画了input
注:虽然名字叫ZeroCopyInputStream, 但是拜读代码时才发现并不是真正意义上的零拷贝技术,只不过是减少memcpy的次数,
虽然如此,但也值得学习,可以看为服务端编程的基本规范把
通过CopyingInputStreamAdaptor,CopyingInputStream来减小 FileInputStream/IstreamInputStream, 与CopyingFileInputStream/CopyingIstreamInputStream之间的耦合
代码中也看到了:effect c++所提倡的 类拷贝构造和赋值构造函数处理方法
//eg private
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
//macro definiton #undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS #define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) TypeName(const TypeName&); void operator=(const TypeName&)
强制成员函数inline方法:
#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE #if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) // For functions we want to force inline. // Introduced in gcc 3.1. #define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) #else // Other compilers will have to figure it out for themselves. #define GOOGLE_ATTRIBUTE_ALWAYS_INLINE #endif #endif
读到了关于字符串转整形数的代码,按照里面的代码注释说明(不得不说protobuf的代码注释很到位!)
// ---------------------------------------------------------------------- // strto32() // strtou32() // strto64() // strtou64() // Architecture-neutral plug compatible replacements for strtol() and // strtoul(). Long's have different lengths on ILP-32 and LP-64 // platforms, so using these is safer, from the point of view of // overflow behavior, than using the standard libc functions. // ---------------------------------------------------------------------- LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr, int base); LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr, int base);
网上搜了一下:(http://blog.csdn.net/foreverfresh/article/details/6731785)
32位环境涉及"ILP32"数据模型,是因为C数据类型为32位的int、long、指针。而64位环境使用不同的数据模型,此时的long和指针已为64位,故称作"LP64"数据模型。 从平台独立和兼容性考虑,写了上面的封装函数,具体如下:
inline int32 strto32(const char *nptr, char **endptr, int base) { if (sizeof(int32) == sizeof(long)) return strtol(nptr, endptr, base); else return strto32_adaptor(nptr, endptr, base); } inline uint32 strtou32(const char *nptr, char **endptr, int base) { if (sizeof(uint32) == sizeof(unsigned long)) return strtoul(nptr, endptr, base); else return strtou32_adaptor(nptr, endptr, base); }
//显然用下面的代码,转32位整型数,保持溢出逻辑判断在32位和64位机器一致
// ---------------------------------------------------------------------- // strto32_adaptor() // strtou32_adaptor() // Implementation of strto[u]l replacements that have identical // overflow and underflow characteristics for both ILP-32 and LP-64 // platforms, including errno preservation in error-free calls. // ---------------------------------------------------------------------- int32 strto32_adaptor(const char *nptr, char **endptr, int base) { const int saved_errno = errno; errno = 0; const long result = strtol(nptr, endptr, base); if (errno == ERANGE && result == LONG_MIN) { return kint32min; } else if (errno == ERANGE && result == LONG_MAX) { return kint32max; } else if (errno == 0 && result < kint32min) { errno = ERANGE; return kint32min; } else if (errno == 0 && result > kint32max) { errno = ERANGE; return kint32max; } if (errno == 0) errno = saved_errno; return static_cast<int32>(result); }
再来一段对union的使用
inline uint32 WireFormatLite::EncodeFloat(float value) { union {float f; uint32 i;}; f = value; return i; } inline float WireFormatLite::DecodeFloat(uint32 value) { union {float f; uint32 i;}; i = value; return f; }
先写到这里,洗洗,睡觉了。。