Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Obsah / Utility / CHARSET / CharUTF16LER

Zdrojový kód: INCLUDE\UTIL\CHARSET.INC, UTIL\CHARSET.ASM


CharUTF16LER - Načtení znaku z bufferu ve formátu UTF-16LE

Funkce CharUTF16LER načte znak z bufferu ve formátu UTF-16LE, little endian (tj. formát PC Intel, v paměti je uložen nejdříve nižší bajt dat a poté vyší bajt).


; -----------------------------------------------------------------------------
;             Read character from UTF-16LE (PC, little endian) buffer
; -----------------------------------------------------------------------------
; INPUT:	ECX = remaining bytes
;		EDX = invalid character (in Unicode, 0 = default character)
;		ESI = source buffer
; OUTPUT:	EAX = Unicode character (or invalid character if no data)
;		ECX = next remaining bytes
;		ESI = next source buffer
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr ESI ukazatel na data ve vstupním bufferu, registr ECX počet bajtů ve vstupním bufferu a registr EDX Unicode kód znaku, který se použije v případě neplatných dat v bufferu. Na výstupu z funkce je v registru EAX navrácen Unicode kód načteného znaku (nebo neplatný kód z registru EDX, pokud nejsou k dispozici další data), v registru ESI nový ukazatel na vstupní data a v registru ECX nová velikost vstupních dat.


; ------------- Read first word

CharUTF16LER:	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

Na začátku funkce je nejdříve provedena kontrola, zda jsou k dispozici další 2 bajty vstupních dat. Pokud ne, bude navrácen obsah registru EDX jako příznak chyby. Jsou-li k dospozici další 2 bajty, je načteno do registru AX další připravené slovo dat.


; ------------- 1 Word (almost 16 bits, 0000..D7FF or E000..FFFF)

		cmp	ah,0d8h		; check low limit
		jb	CharUTF16LER4	; valid character
		cmp	ah,0e0h		; check high limit
		jae	CharUTF16LER4	; valid character
		cmp	ah,0dch		; check invalid range
		jae	CharUTF16LER8	; invalid character

Leží-li hodnota prvního slova dat v rozsahu 0000h až 0D7FFh nebo 0E000h až 0FFFFh, jedná se o platný kód znaku o velikosti 16 bitů a funkce se ihned ukončí. Slovo s hodnotou 0DC00h až 0DFFFh je pro první slovo kódu neplatné a funkce se v tom případě ukončí s chybou. Jinak se pokračuje obsluhou kódu o velikosti 2 slov.


; ------------- 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

		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
CharUTF16LER4:	ret

Kód o velikosti 2 slov ukládá znaky o velikosti 20 bitů. Z prvního slova je uchováno 10 bitů a ze vstupního bufferu je načteno další slovo. Druhé slovo má povolený rozsah hodnot 0DC00h až 0DFFFh. Je-li rozsah hodnot v pořádku, uchová se z druhého slova 10 bitů a sloučí se do jednoho kódu s 10 bity z prvního slova. K výslednému kódu se přičte korekce 10000h, protože 2-slovní kódy ukládají znaky s kódem 10000h a výše.


; ------------- Error

CharUTF16LER6:	dec	esi		; return data
		dec	esi		; return data
		dec	esi		; preset - 1

CharUTF16LER7:	inc	esi		; skip last (invalid) byte
CharUTF16LER8:	mov	eax,edx		; EAX <- invalid character
		or	eax,eax		; default character?
		jnz	CharUTF16LER9	; not default character
CharUTF16LER84:	mov	al,UNINOASC	; use default character
CharUTF16LER9:	ret

V případě neplatného znaku se navrátí ukazatel zdrojových dat (pokud byl posunut) a navrátí se v registru EAX buď neplatný znak z registru EDX nebo implicitní neplatný znak UNINOASC, pokud byl obsah registru EDX nulový.


Obsah / Utility / CHARSET / CharUTF16LER