; ------------- Read first word
CharUTF16BER: jecxz CharUTF16LER8 ; no data
dec ecx ; decrease number of bytes
jz CharUTF16LER7 ; no data
xor eax,eax ; EAX <- 0
dec ecx ; decrease number of bytes
lodsw ; AX <- load first word
xchg al,ah ; exchange byte order
; ------------- 1 Word (almost 16 bits, 0000..D7FF or E000..FFFF)
cmp ah,0d8h ; check low limit
jb CharUTF16BER4 ; valid character
cmp ah,0e0h ; check high limit
jae CharUTF16BER4 ; valid character
cmp ah,0dch ; check invalid range
jae CharUTF16LER8 ; invalid character
; ------------- 2 Words (20 bits, 110110xxxxxxxxxx 110111xxxxxxxxxx
; = D800..DBFF DC00..DFFF)
cmp ecx,byte 2 ; check number of bytes
jb CharUTF16LER8 ; no data
and ah,3 ; mask 10 bits
shl eax,16 ; free AX
lodsw ; AX <- load second word
xchg al,ah ; exchange byte order
cmp ah,0dch ; check low limit
jb CharUTF16LER6 ; invalid character
cmp ah,0e0h ; check high limit
jae CharUTF16LER6 ; invalid character
dec ecx ; decrease number of bytes
dec ecx ; decrease number of bytes
shl ax,6 ; destroy 6 bits
shr eax,6 ; shift character to position
add eax,10000h ; add character base
CharUTF16BER4: ret
|