protobuf io 代码阅读

protobuf io 代码阅读_第1张图片

上图只写了部分,主要是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;
}

 先写到这里,洗洗,睡觉了。。

你可能感兴趣的:(protobuf io 代码阅读)