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

Obsah / Utility / CHARSET / CharUTF8Write

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


CharUTF8Write - Uložení znaku do bufferu ve formátu UTF-8

Funkce CharUTF8Write uloží Unicode znak do bufferu v kódu UTF-8.


; -----------------------------------------------------------------------------
;                      Write character into UTF-8 buffer
; -----------------------------------------------------------------------------
; INPUT:	EAX = Unicode character (max. 31 bits)
;		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 Byte (7 bits, 0xxxxxxx = 0..7F)

CharUTF8Write:	or	ebp,ebp		; check free space
		jz	CharUTF8Write24	; buffer full

		cmp	eax,byte 7fh	; check character (7 bits)
		ja	CharUTF8Write2	; character has more bytes
		stosb			; store byte
		dec	ebp		; decrease remaining space
		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ž 7Fh, uloží se jeho hodnota ihned, protože znaky v tomto rozsahu (7 bitů) jsou v kódu UTF-8 ukládány jako jeden bajt.


; ------------- 2 Bytes (11 bits, 110xxxxx 10xxxxxx = C0..DF 80..BF)

CharUTF8Write2:	cmp	eax,7ffh	; check character (11 bits)
		ja	CharUTF8Write3	; character has more bytes

		push	eax		; push EAX
		shr	eax,6		; AL <- get highest 5 bits
		or	al,0c0h		; add flags
CharUTF8Write22:stosb			; store byte
		dec	ebp		; decrease remaining space
		pop	eax		; pop EAX
		jz	CharUTF8Write24	; buffer full

		and	al,3fh		; mask 6 bits
		or	al,80h		; add flags
		stosb			; store byte
		dec	ebp		; decrease remaining space
CharUTF8Write24:ret

Znaky s hodnotou 80h až 7FFh (tj. 11 bitů) se v kódu UTF-8 uloží jako 2 bajty. Nejdříve jsou uloženy bity 6 až 10 (tj. 5 bitů) jako první bajt, je k nim přidána hodnota 0C0h jako příznak kódu se 2 bajty. Nižších 6 bitů je uloženo jako druhý bajt kódu spolu s hodnotou 80h jako příznak druhého bajtu.


; ------------- 3 Bytes (16 bits, 1110xxxx 10xxxxxx 10xxxxxx =
;					E0..EF 80..BF 80..BF
CharUTF8Write3:	cmp	eax,0ffffh	; check character (16 bits)
		ja	CharUTF8Write4	; character has more bytes

		push	eax		; push EAX
		shr	eax,12		; AL <- get highest 4 bits
		or	al,0e0h		; add flags
CharUTF8Write32:stosb			; store byte
		dec	ebp		; decrease remaining space
		pop	eax		; pop EAX
		jz	CharUTF8Write24	; buffer full

		push	eax		; push EAX
		shr	eax,6		; AL <- get 6 bits
		and	al,3fh		; mask 6 bits
		or	al,80h		; add flags
		jmp	short CharUTF8Write22

Znaky s hodnotou 800h až 0FFFFh (tj. 16 bitů) se v kódu UTF-8 uloží jako 3 bajty. Nejdříve jsou uloženy bity 12 až 15 (tj. 4 bity) jako první bajt, je k nim přidána hodnota 0E0h jako příznak kódu se 3 bajty. Nižších 12 bitů je uloženo postupně po 6 bitech jako druhý a třetí bajt spolu s hodnotou 80h jako příznak datového bajtu.


; ------------- 4 Bytes (21 bits, 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx =
;					F0..F7 80..BF 80..BF 80..BF
CharUTF8Write4:	cmp	eax,1fffffh	; check character (21 bits)
		ja	CharUTF8Write5	; character has more bytes

		push	eax		; push EAX
		shr	eax,18		; AL <- get highest 3 bits
		or	al,0f0h		; add flags
CharUTF8Write42:stosb			; store byte
		dec	ebp		; decrease remaining space
		pop	eax		; pop EAX
		jz	CharUTF8Write24	; buffer full

		push	eax		; push EAX
		shr	eax,12		; AL <- get 6 bits
		and	al,3fh		; mask 6 bits
		or	al,80h		; add flags
		jmp	short CharUTF8Write32

Znaky s hodnotou 10000h až 1FFFFFh (tj. 21 bitů) se v kódu UTF-8 uloží jako 4 bajty. Nejdříve jsou uloženy bity 18 až 20 (tj. 3 bity) jako první bajt, je k nim přidána hodnota 0F0h jako příznak kódu se 4 bajty. Nižších 18 bitů je uloženo postupně po 6 bitech jako druhý, třetí a čtvrtý bajt spolu s hodnotou 80h jako příznak datového bajtu.


; ------------- 5 Bytes (26 bits, 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
;					= F8..FB 80..BF 80..BF 80..BF 80..BF
CharUTF8Write5:	cmp	eax,3ffffffh	; check character (26 bits)
		ja	CharUTF8Write6	; character has more bytes

		push	eax		; push EAX
		shr	eax,24		; AL <- get highest 2 bits
		or	al,0f8h		; add flags
CharUTF8Write52:stosb			; store byte
		dec	ebp		; decrease remaining space
		pop	eax		; pop EAX
		jz	CharUTF8Write24	; buffer full

		push	eax		; push EAX
		shr	eax,18		; AL <- get 6 bits
		and	al,3fh		; mask 6 bits
		or	al,80h		; add flags
		jmp	short CharUTF8Write42

Znaky s hodnotou 200000h až 3FFFFFFh (tj. 26 bitů) se v kódu UTF-8 uloží jako 5 bajtů. Nejdříve jsou uloženy bity 24 až 25 (tj. 2 bity) jako první bajt, je k nim přidána hodnota 0F8h jako příznak kódu s 5 bajty. Nižších 24 bitů je uloženo postupně po 6 bitech jako druhý, třetí, čtvrtý a pátý bajt spolu s hodnotou 80h jako příznak datového bajtu.


; ------------- 6 Bytes (31 bits, 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
;			 10xxxxxx = FC..FD 80..BF 80..BF 80..BF 80..BF 80..BF
CharUTF8Write6:	push	eax		; push EAX
		shr	eax,30		; AL <- get highest 1 bit
		and	al,1		; mask 1 bit
		or	al,0fch		; add flags
		stosb			; store byte
		dec	ebp		; decrease remaining space
		pop	eax		; pop EAX
		jz	CharUTF8Write24	; buffer full

		push	eax		; push EAX
		shr	eax,24		; AL <- get 6 bits
		and	al,3fh		; mask 6 bits
		or	al,80h		; add flags
		jmp	short CharUTF8Write52

Znaky s hodnotou 4000000h až 7FFFFFFFh (tj. 31 bitů) se v kódu UTF-8 uloží jako 6 bajtů. Nejdříve je uložen bit 30 jako první bajt, je k němu přidána hodnota 0FCh jako příznak kódu s 6 bajty. Nižších 30 bitů je uloženo postupně po 6 bitech jako druhý, třetí, čtvrtý, pátý a šestý bajt spolu s hodnotou 80h jako příznak datového bajtu.


Obsah / Utility / CHARSET / CharUTF8Write