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

Obsah / Utility / CHARSET / CharUTF16LEW

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


CharUTF16LEW - Uložení znaku do bufferu ve formátu UTF-16LE

Funkce CharUTF16LEW uloží Unicode znak do bufferu v kódu UTF-16LE, little endian (tj. formát PC Intel, v paměti je uložen nejdříve nižší bajt dat a poté vyší bajt).


; -----------------------------------------------------------------------------
;            Write character into UTF-16LE (PC, little endian) buffer
; -----------------------------------------------------------------------------
; INPUT:	EAX = Unicode character
;		EDI = destination buffer
;		EBP = remaining space in buffer
; OUTPUT:	EDI = next destination buffer
;		EBP = next remaining space in buffer
; DESTROYS:	EAX
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr EAX Unicode kód ukládaného znaku, registr EDI ukazatel do výstupního bufferu a registr EBP čítač zbylých dat ve výstupním bufferu. Na výstupu funkce je ukazatel v EDI posunut na novou zápisovou pozici a registr EBP obsahuje nový čítač zbylých dat v bufferu. Funkce zničí obsah registru EAX.


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

CharUTF16LEW:	or	ebp,ebp		; check free space
		jz	CharUTF16LEW7	; buffer full
                                    
		cmp	eax,0ffffh	; 1 word?
		ja	CharUTF16LEW6	; more than 1 word

		dec	ebp		; decrease remaining space
		jz	CharUTF16LEW3	; buffer full
		dec	ebp		; decrease remaining space
		stosw			; store character
		ret

CharUTF16LEW3:	stosb			; store LOW byte
		ret

Na začátku funkce se otestuje registr EBP, zda je k dispozici místo pro uložení dalšího bajtu. Pokud má ukládaný znak hodnotu 0 až 0FFFFh, uloží se jeho hodnota ihned jako kód s 1 slovem. Je-li k dispozici pouze 1 bajt volného místa, uloží se pouze první bajt slova. Kód znaku nesmí mít hodnotu 0D800h až 0DFFFh, protože ty patří mezi zakázané znaky Unicode.


; ------------- 2 Words (20 bits, 110110xxxxxxxxxx 110111xxxxxxxxxx 
;				= D800..DBFF DC00..DFFF)
CharUTF16LEW6:	push	eax		; push EAX
		shr	eax,10		; EAX <- high 10 bits
		add	eax,0d800h-40h	; add high surrogate start - base
		dec	ebp		; decrease remaining space
		jz	CharUTF16LEW8	; buffer full
		stosw			; store high word
		pop	eax		; pop EAX

		dec	ebp		; decrease remaining space
		jz	CharUTF16LEW7	; buffer full

		and	eax,3ffh	; mask low 10 bits
		add	eax,0dc00h	; add low surrogate start
                dec	ebp		; decrease remaining space
		jz	CharUTF16LEW3	; buffer full
		dec	ebp		; decrease remaining space
		stosw			; store low word
CharUTF16LEW7:	ret

CharUTF16LEW8:	stosb			; store LOW byte
		pop	eax		; pop EAX
		ret

Znaky s kódem vyšším než 16 bitů se uloží jako 2 slova (nejsou podporovány znaky větší než 20 bitů). Do registru EAX se připraví horních 10 bitů znaku a přičte se korekce 0D800h (jako příznak prvního slova kódu o 2 slovech) snížená o bázi 10000h (rotovaná o 10 bitů doprava). Je-li v bufferu místo pouze pro 1 bajt, uloží se pouze 1. bajt prvního slova.

Po uložení prvního slova se připraví 10 nižších bitů znaku a přičte se korekce 0DC00h (jako příznak druhého slova kódu o 2 slovech). Slovo se uloží buď celé nebo pouze 1: bajt není-li dostatek místa v cílovém bufferu.


Obsah / Utility / CHARSET / CharUTF16LEW