zoukankan      html  css  js  c++  java
  • 模板化字节交换

    //模板化的字节交换函数 
    #include <sys/types.h>
    #include <cstdint>
    #include <cstdlib>
    
    //用法:当我需要对某个值交换字节序并序列化该值的时候,我只需要调用一个函数Write即可。
    //不需要关心是什么类型,不需要关心要调用哪个函数,一切都由模板帮我们实现
    template <typename T>
    void Write(T inData)
    {
        T swappedData = ByteSwap(inData);
        Write(&swappedData, sizeof(swappedData));
    }
    
    
    //一:
    //先实现交换字节的函数的特化版本
    inline uint16_t ByteSwap2(uint16_t inData)
    {
        return (inData << 8) | (inData >> 8);
    }
    
    inline uint32_t ByteSwap4(uint32_t inData)
    {
        return ((inData << 24) & 0xff000000) | ((inData << 8) & 0x00ff0000) | ((inData >> 8) & 0x0000ff00) | ((inData >> 24) & 0x000000ff);
    }
    
    inline uint64_t ByteSwap8(uint64_t inData)
    {
        return ((inData >> 56) & 0x00000000000000ff) | 
                ((inData >> 40) & 0x000000000000ff00) |
                ((inData >> 24) & 0x0000000000ff0000) |
                ((inData >> 8) & 0x00000000ff000000) |
                ((inData << 8) & 0x000000ff00000000) |
                ((inData << 24) & 0x0000ff0000000000) |
                ((inData << 40) & 0x00ff000000000000) | ((inData << 56) & 0xff00000000000000);
    }
    
    
    //二:实现特化类和相应的函数
    template<typename T>
    class ByteSwapper<T, 2>
    {
    public:
        T Swap(T inData) const
        {
            uint16_t result = ByteSwap2(inData);
            return result;
        }
    };
    
    template<typename T>
    class ByteSwapper<T, 4>
    {
    public:
        T Swap(T inData) const
        {
            uint32_t result = ByteSwap4(inData);
            return result;
        }
    };
    
    template<typename T>
    class ByteSwapper<T, 8>
    {
    public:
        T Swap(T inData) const
        {
            uint64_t result = ByteSwap8(inData);
            return result;
        }
    };
    
    
    //三:依据推导出来的inData数据类型调用某个特化类的函数
    template <typename T>
    T ByteSwap(T inData)
    {
        return ByteSwapper<T, sizeof(T)>().Swap(inData);
    }
    
    
    //四:不足的地方是,以上的实现只能针对无符号整数的字节序转换
    //如果想要支持float、double、有符号整数等其他数据类型的字节转换,需要增加多一个类并对步骤二进行修改 
    template<typename tFrom, typename tTo>
    class TypeAliaser
    {
    public:
        TypeAliaser(tFrom inFromValue) : mAsFromType(inFromValue) {}
    
        tTo &Get()
        {
            return mAsFromType;
        }
        union
        {
            tFrom mAsFromType;        //union其实就是对让模板对数据类型的推导做了一次转换
            tTo mAsToType;            //例如:float是32位,那么tFrom为float,tTo为uint32_t
        };
    };
    
    
    //对步骤二的修改:
    template<typename T>
    class ByteSwapper<T, 2>
    {
    public:
        T Swap(T inData) const
        {
            //最后.Get()拿出来的值被推导后数据类型为uint16_t
            uint16_t result = ByteSwap2(TypeAliaser<T, uint16_t>(inData).Get());
            //将原数据类型返回
            return TypeAliaser<uint16_t, T>(result).Get();
        }
    };
    
    template<typename T>
    class ByteSwapper<T, 4>
    {
    public:
        T Swap(T inData) const
        {
            uint16_t result = ByteSwap4(TypeAliaser<T, uint32_t>(inData).Get());
            return TypeAliaser<uint32_t, T>(result).Get();
        }
    };
    
    template<typename T>
    class ByteSwapper<T, 8>
    {
    public:
        T Swap(T inData) const
        {
            uint16_t result = ByteSwap8(TypeAliaser<T, uint64_t>(inData).Get());
            return TypeAliaser<uint64_t, T>(result).Get();
        }
    };
  • 相关阅读:
    机器学习八
    机器学习七
    机器学习六
    机器学习五
    JMeter获取复杂的JSON串中的参数的值
    Jmeter返回参数值写入文件
    python 连接数据库
    jmeter返回的Unicode转换成utf8
    Appium与python自动测试环境及demo详解
    python解析复杂json字符串
  • 原文地址:https://www.cnblogs.com/jialin0x7c9/p/13763793.html
Copyright © 2011-2022 走看看