编程技术记录

世界你好!

使用C++的模板、自动类型推导技术

#ifndef  HtoN_h
#define HtoN_h

#include <arpa/inet.h>

#if __ANDROID__
    #ifndef htonll
        #define htonll(x) htonq(x)
    #endif

    #ifndef ntohll
        #define ntohll(x) ntohq(x)
    #endif
#endif

namespace zxszl
{
    template <typename T> T zl_hton (T t) { return t;}
    template <> inline uint16_t zl_hton<uint16_t> (uint16_t t) { return htons(t); }
    template <> inline int16_t zl_hton<int16_t> (int16_t t) { return htons(t); }
    template <> inline uint32_t zl_hton<uint32_t> (uint32_t t) { return htonl(t); }
    template <> inline int32_t zl_hton<int32_t> (int32_t t) { return htonl(t); }
    template <> inline uint64_t zl_hton<uint64_t> (uint64_t t) { return htonll(t); }
    template <> inline int64_t zl_hton<int64_t> (int64_t t) { return htonll(t); }

    template <typename T> T zl_ntoh (T t) { return t;}
    template <> inline uint16_t zl_ntoh<uint16_t> (uint16_t t) { return ntohs(t); }
    template <> inline int16_t zl_ntoh<int16_t> (int16_t t) { return ntohs(t); }
    template <> inline uint32_t zl_ntoh<uint32_t> (uint32_t t) { return ntohl(t); }
    template <> inline int32_t zl_ntoh<int32_t> (int32_t t) { return ntohl(t); }
    template <> inline uint64_t zl_ntoh<uint64_t> (uint64_t t) { return ntohll(t); }
    template <> inline int64_t zl_ntoh<int64_t> (int64_t t) { return ntohll(t); }

    class __judge_little_endian
    {
    public:
        static inline bool isle() { static const int _a = 0xAABBCCDD; return *(unsigned char *)(&_a) == 0xDD;}
    };

#define zl_rorder_s(x) \
            ((__uint16_t)((((__uint16_t)(x) & 0xff00) >> 8) | \
            (((__uint16_t)(x) & 0x00ff) << 8)))

#define zl_rorder_l(x) \
            ((__uint32_t)((((__uint32_t)(x) & 0xff000000) >> 24) | \
            (((__uint32_t)(x) & 0x00ff0000) >>  8) | \
            (((__uint32_t)(x) & 0x0000ff00) <<  8) | \
            (((__uint32_t)(x) & 0x000000ff) << 24)))

#define zl_rorder_ll(x) \
            ((__uint64_t)((((__uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
            (((__uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
            (((__uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
            (((__uint64_t)(x) & 0x000000ff00000000ULL) >>  8) | \
            (((__uint64_t)(x) & 0x00000000ff000000ULL) <<  8) | \
            (((__uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
            (((__uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
            (((__uint64_t)(x) & 0x00000000000000ffULL) << 56)))

    template <typename T> T zl_htole (T t) { return t;}
    template <> inline uint16_t zl_htole<uint16_t> (uint16_t t) {return __judge_little_endian::isle() ? t : zl_rorder_s(t);}
    template <> inline int16_t zl_htole<int16_t> (int16_t t) {return __judge_little_endian::isle() ? t :  zl_rorder_s(t);}
    template <> inline uint32_t zl_htole<uint32_t> (uint32_t t) {return __judge_little_endian::isle() ? t :  zl_rorder_l(t);}
    template <> inline int32_t zl_htole<int32_t> (int32_t t) {return __judge_little_endian::isle() ? t :  zl_rorder_l(t);}
    template <> inline uint64_t zl_htole<uint64_t> (uint64_t t) { return __judge_little_endian::isle() ? t :  zl_rorder_ll(t); }
    template <> inline int64_t zl_htole<int64_t> (int64_t t) { return __judge_little_endian::isle() ? t :  zl_rorder_ll(t); }

    template <typename T> T zl_letoh (T t) { return t;}
    template <> inline uint16_t zl_letoh<uint16_t> (uint16_t t) {return __judge_little_endian::isle() ? t : zl_rorder_s(t);}
    template <> inline int16_t zl_letoh<int16_t> (int16_t t) {return __judge_little_endian::isle() ? t :  zl_rorder_s(t);}
    template <> inline uint32_t zl_letoh<uint32_t> (uint32_t t) {return __judge_little_endian::isle() ? t :  zl_rorder_l(t);}
    template <> inline int32_t zl_letoh<int32_t> (int32_t t) {return __judge_little_endian::isle() ? t :  zl_rorder_l(t);}
    template <> inline uint64_t zl_letoh<uint64_t> (uint64_t t) { return __judge_little_endian::isle() ? t :  zl_rorder_ll(t); }
    template <> inline int64_t zl_letoh<int64_t> (int64_t t) { return __judge_little_endian::isle() ? t :  zl_rorder_ll(t); }

#undef zl_rorder_s
#undef zl_rorder_l
#undef zl_rorder_ll
}

#endif /* HtoN_h */

使用示例

using namespace zxszl;

short m = 10;
short n = zl_hton(m);
m = zl_ntoh(n);

int x = 100;
int y = zl_hton(x);
x = zl_ntoh(y);

发表回复

© Beli. All Rights Reserved.