yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
4c76b2759
master
1#ifndef SLANG_CORE_CHAR_ENCODE_H 2#define SLANG_CORE_CHAR_ENCODE_H 3 4#include "slang-basic.h" 5#include "slang-secure-crt.h" 6 7namespace Slang 8{ 9 10// NOTE! Order must be kept the same to match up with 11enum class CharEncodeType 12{ 13UTF8 , 14UTF16 , 15UTF16Reversed , 16UTF32 , 17CountOf , 18}; 19 20template < typename ReadByteFunc > 21Char32 getUnicodePointFromUTF8 (const ReadByteFunc & readByte ) 22{ 23Char32 codePoint = 0 ; 24uint32_t leading = uint32_t (readByte ()); 25uint32_t mask = 0x80 ; 26Index count = 0 ; 27while (leading & mask ) 28 { 29count ++ ; 30mask >>=1 ; 31 } 32codePoint = (leading & (mask - 1 )); 33for (Index i = 1 ;i <=count - 1 ;i ++ ) 34 { 35codePoint <<=6 ; 36codePoint += (readByte ()& 0x3F ); 37 } 38return codePoint ; 39} 40 41template < typename ReadByteFunc > 42Char32 getUnicodePointFromUTF16 (const ReadByteFunc & readByte ) 43{ 44uint32_t byte0 = Byte (readByte ()); 45uint32_t byte1 = Byte (readByte ()); 46uint32_t word0 = byte0 + (byte1 <<8 ); 47if (word0 >=0xD800 && word0 <=0xDFFF ) 48 { 49uint32_t byte2 = Byte (readByte ()); 50uint32_t byte3 = Byte (readByte ()); 51uint32_t word1 = byte2 + (byte3 <<8 ); 52return Char32 (((word0 & 0x3FF ) <<10 )+ (word1 & 0x3FF )+ 0x10000 ); 53 } 54else 55return Char32 (word0 ); 56} 57 58template < typename ReadByteFunc > 59Char32 getUnicodePointFromUTF16Reversed (const ReadByteFunc & readByte ) 60{ 61uint32_t byte0 = Byte (readByte ()); 62uint32_t byte1 = Byte (readByte ()); 63uint32_t word0 = (byte0 <<8 )+ byte1 ; 64if (word0 >=0xD800 && word0 <=0xDFFF ) 65 { 66uint32_t byte2 = Byte (readByte ()); 67uint32_t byte3 = Byte (readByte ()); 68uint32_t word1 = (byte2 <<8 )+ byte3 ; 69return Char32 (((word0 & 0x3FF ) <<10 )+ (word1 & 0x3FF )); 70 } 71else 72return Char32 (word0 ); 73} 74 75template < typename ReadByteFunc > 76Char32 getUnicodePointFromUTF32 (const ReadByteFunc & readByte ) 77{ 78uint32_t byte0 = Byte (readByte ()); 79uint32_t byte1 = Byte (readByte ()); 80uint32_t byte2 = Byte (readByte ()); 81uint32_t byte3 = Byte (readByte ()); 82return Char32 (byte0 + (byte1 <<8 )+ (byte2 <<16 )+ (byte3 <<24 )); 83} 84 85// Encode functions return the amount of elements output to the buffer 86inline int encodeUnicodePointToUTF8 (Char32 codePoint ,char * outBuffer ) 87{ 88char * const dst = outBuffer ; 89// TODO(JS): This supports 4 + 6 * 3 = 22 bits. 90// The standard allows up to 0x10FFFF. 91if (codePoint <=0x7F ) 92 { 93dst [0 ]= char (codePoint ); 94return 1 ; 95 } 96else if (codePoint <=0x7FF ) 97 { 98dst [0 ]= char (0xC0 + (codePoint >>6 )); 99dst [1 ]= char (0x80 + (codePoint & 0x3F )); 100return 2 ; 101 } 102else if (codePoint <=0xFFFF ) 103 { 104dst [0 ]= char (0xE0 + (codePoint >>12 )); 105dst [1 ]= char (0x80 + ((codePoint >>6 )& (0x3F ))); 106dst [2 ]= char (0x80 + (codePoint & 0x3F )); 107return 3 ; 108 } 109else 110 { 111dst [0 ]= char (0xF0 + (codePoint >>18 )); 112dst [1 ]= char (0x80 + ((codePoint >>12 )& 0x3F )); 113dst [2 ]= char (0x80 + ((codePoint >>6 )& 0x3F )); 114dst [3 ]= char (0x80 + (codePoint & 0x3F )); 115return 4 ; 116 } 117} 118 119inline int encodeUnicodePointToUTF16 (Char32 codePoint ,Char16 * outBuffer ) 120{ 121Char16 * const dst = outBuffer ; 122if (codePoint <=0xD7FF || (codePoint >=0xE000 && codePoint <=0xFFFF )) 123 { 124dst [0 ]= Char16 (codePoint ); 125return 1 ; 126 } 127else 128 { 129const uint32_t sub = codePoint - 0x10000 ; 130dst [0 ]= Char16 ((sub >>10 )+ 0xD800 ); 131dst [1 ]= Char16 ((sub & 0x3FF )+ 0xDC00 ); 132return 2 ; 133 } 134} 135 136SLANG_FORCE_INLINE Char16 reverseByteOrder (Char16 val ) 137{ 138return (val >>8 ) | (val <<8 ); 139} 140 141inline int encodeUnicodePointToUTF16Reversed (Char32 codePoint ,Char16 * outBuffer ) 142{ 143Char16 * const dst = outBuffer ; 144if (codePoint <=0xD7FF || (codePoint >=0xE000 && codePoint <=0xFFFF )) 145 { 146dst [0 ]= reverseByteOrder (Char16 (codePoint )); 147return 1 ; 148 } 149else 150 { 151const uint32_t sub = codePoint - 0x10000 ; 152const uint32_t high = (sub >>10 )+ 0xD800 ; 153const uint32_t low = (sub & 0x3FF )+ 0xDC00 ; 154dst [0 ]= reverseByteOrder (Char16 (high )); 155dst [1 ]= reverseByteOrder (Char16 (low )); 156return 2 ; 157 } 158} 159 160static const Char16 kUTF16Header = 0xFEFF ; 161static const Char16 kUTF16ReversedHeader = 0xFFFE ; 162 163class CharEncoding 164{ 165public : 166static CharEncoding * UTF8 ,* UTF16 ,* UTF16Reversed ,* UTF32 ; 167 168/// Encode Utf8 held in slice append into ioBuffer 169virtual void encode (const UnownedStringSlice & str ,List < Byte >& ioBuffer )= 0 ; 170/// Decode buffer into Utf8 held in ioBuffer 171virtual void decode (const Byte * buffer ,int length ,List < char >& ioBuffer )= 0 ; 172 173virtual ~CharEncoding () {} 174 175/// Get the encoding type 176CharEncodeType getEncodingType ()const {return m_encodingType ; } 177 178/// Given some bytes determines a character encoding type, based on the initial bytes. 179/// If can't be determined will assume UTF8. 180/// Outputs the offset to the first non mark in outOffset 181static CharEncodeType determineEncoding ( 182const Byte * bytes , 183size_t bytesCount , 184size_t & outOffset ); 185 186/// Get the 187static CharEncoding * getEncoding (CharEncodeType type ) {return g_encoding [Index (type )]; } 188 189CharEncoding (CharEncodeType encodingType ) 190 :m_encodingType (encodingType ) 191 { 192 } 193 194protected : 195CharEncodeType m_encodingType ; 196 197static CharEncoding * const g_encoding [Index (CharEncodeType ::CountOf )]; 198}; 199 200struct UTF8Util 201{ 202/// Given a slice calculate the number of code points (unicode chars) 203/// 204/// NOTE! This doesn't check the *validity* of code points/encoding. 205/// Non valid utf8 input or ending starting in partial characters, will produce 206/// undefined results without error. 207static Index calcCodePointCount (const UnownedStringSlice & in ); 208 209 210/// Given a slice in UTF8, calculate the number of UTF16 characters needed to represent the 211/// string. 212static Index calcUTF16CharCount (const UnownedStringSlice & in ); 213}; 214 215}// namespace Slang 216 217#endif