#ifndef HGL_ENDIAN_INCLUDE #define HGL_ENDIAN_INCLUDE #include // 平台定义 #include namespace hgl { namespace endian { /** * Windows代码页枚举 * 全部Windows所支持代码页请参见 http://msdn.microsoft.com/en-us/library/dd317756 * https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers */ enum class CharCodePage:uint16 ///代码页枚举 { NONE=0, ///<起始定义,无意义 IBM437 =437, /// const CharSetName &GetCurCharSet(); ///<取得当前程序编码字符集 constexpr CharSetName utf8_charset="utf8"; constexpr CharSetName utf16le_charset="utf-16le"; constexpr CharSetName utf16be_charset="utf-16be"; constexpr CharSetName utf32le_charset="utf-32le"; constexpr CharSetName utf32be_charset="utf-32be"; template<> inline const CharSetName &GetCurCharSet<2,HGL_LITTLE_ENDIAN >(){return utf16le_charset;} template<> inline const CharSetName &GetCurCharSet<2,HGL_BIG_ENDIAN >(){return utf16be_charset;} template<> inline const CharSetName &GetCurCharSet<4,HGL_LITTLE_ENDIAN >(){return utf32le_charset;} template<> inline const CharSetName &GetCurCharSet<4,HGL_BIG_ENDIAN >(){return utf32be_charset;} template inline const CharSetName &GetCharSet() { return GetCurCharSet(); } /** * 字节序文件头数据结构 */ struct BOMFileHeader { int size; ///<字节序文件头长度 uint8 data[4]; ///<字节序数据 ByteOrderMask bom; ///<字节序枚举 const CharSetName *char_set;///<字符集名称 uint16 code_page; ///<代码页 }; /** * 字节序文件头定义 */ constexpr BOMFileHeader BOMData[size_t(ByteOrderMask::RANGE_SIZE)]= { {3,{0xEF,0xBB,0xBF} ,ByteOrderMask::UTF8, &utf8_charset ,(uint16)CharCodePage::UTF8 }, {2,{0xFF,0xFE} ,ByteOrderMask::UTF16LE,&utf16le_charset ,(uint16)CharCodePage::UTF16LE }, {2,{0xFE,0xFF} ,ByteOrderMask::UTF16BE,&utf16be_charset ,(uint16)CharCodePage::UTF16BE }, {4,{0xFF,0xFE,0x00,0x00},ByteOrderMask::UTF32LE,&utf32le_charset ,(uint16)CharCodePage::UTF32LE }, {4,{0x00,0x00,0xFE,0xFF},ByteOrderMask::UTF32BE,&utf32be_charset ,(uint16)CharCodePage::UTF32BE } }; inline const BOMFileHeader *GetBOM(const ByteOrderMask &bom) { return RangeCheck(bom)?BOMData+uint(bom)-uint(ByteOrderMask::BEGIN_RANGE):nullptr; } inline ByteOrderMask CheckBOM(const void *data) { const BOMFileHeader *bom=BOMData; for(int i=int(ByteOrderMask::BEGIN_RANGE);idata,bom->size)==0) return (ByteOrderMask)i; } return ByteOrderMask::NONE; } template inline T EndianSwap(const T value) { union { T v; uint8 bytes[sizeof(T)]; }a,b; a.v=value; for(uint i=0;i inline int8 EndianSwap< int8>(const int8 value){return value;} template<> inline uint8 EndianSwap(const uint8 value){return value;} template<> inline uint16 EndianSwap(const uint16 value) { return ((value&0xFF)<<8) |((value&0xFF00)>>8); } template<> inline uint32 EndianSwap(const uint32 value) { return ((value&0xFF)<<24) |((value&0xFF00)<<8) |((value&0xFF0000)>>8) |((value&0xFF000000)>>24); } template<> inline uint64 EndianSwap(const uint64 value) { return ((value&0xFF)<<56) |((value&0xFF00)<<40) |((value&0xFF0000)<<24) |((value&0xFF000000)<<8) |((value&0xFF00000000)>>8) |((value&0xFF0000000000)>>24) |((value&0xFF000000000000)>>40) |((value&0xFF00000000000000)>>56); } template<> inline u16char EndianSwap(const u16char value){return EndianSwap(uint16(value));} template inline void EndianSwap(T *value,const int64 count) { for(int64 i=0;i inline void EndianSwap(T *dst,const T *src,const int64 count) { for(uint i=0;i inline void EndianSwap(D *dst,const S *src,const int64 count) { for(uint i=0;i T ToBigEndian(T value){return value;} template inline void ToBigEndian(T *value,const int64 count){} template inline void ToBigEndian(D *dst,const S *src,const int64 count){hgl_cpy(dst,src,count);} template T ToLittleEndian(T value){return EndianSwap(value);} template inline void ToLittleEndian(T *value,const int64 count){EndianSwap(value,count);} template inline void ToLittleEndian(D *dst,const S *src,const int64 count){EndianSwap(dst,src,count);} #else constexpr uint HGL_BOM_UTF16LE =0xfeff; constexpr uint HGL_BOM_UTF16BE =0xfffe; constexpr uint HGL_BOM_UTF32LE =0x0000feff; constexpr uint HGL_BOM_UTF32BE =0xfffe0000; #define LittleToCurrentEndian ToLittleEndian #define BigToCurrentEndian EndianSwap template T ToBigEndian(T value){return EndianSwap(value);} template inline void ToBigEndian(T *value,const int64 count){EndianSwap(value,count);} template inline void ToBigEndian(D *dst,const S *src,const int64 count){EndianSwap(dst,src,count);} template T ToLittleEndian(T value){return value;} template inline void ToLittleEndian(T *,const int64){} template inline void ToLittleEndian(D *dst,const S *src,const int64 count){typeconv(dst,src,count);} #endif//HGL_BIG_ENDIAN template struct UTF16CharConvert; template<> struct UTF16CharConvert { #if HGL_ENDIAN == HGL_BIG_ENDIAN static void convert(u16char *str,const int length) { EndianSwap(str,length); } #else static void convert(const u16char *,const int){} #endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN static void convert(u16char *out_str,const u16char *in_str,const int length) { #if HGL_ENDIAN == HGL_LITTLE_ENDIAN memcpy(out_str,in_str,length*sizeof(u16char)); #else EndianSwap(in_str,length); #endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN } };//template<> struct UTF16CharConvert template<> struct UTF16CharConvert { static void convert(u16char *str,const int length) { #if HGL_ENDIAN == HGL_LITTLE_ENDIAN EndianSwap(str,length); #endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN } static void convert(u16char *out_str,const u16char *in_str,const int length) { #if HGL_ENDIAN == HGL_LITTLE_ENDIAN memcpy(out_str,in_str,length*sizeof(u16char)); #else EndianSwap(in_str,length); #endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN } };//template<> struct UTF16ToWideChar }//namespace endian using namespace endian; }//namespace hgl #endif//HGL_ENDIAN_INCLUDE