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

Obsah / Utility / TEXT / TextFindCharFirst, TextFindChar

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


TextFindCharFirst, TextFindChar - Vyhledání prvního/dalšího znaku v textu

Funkce TextFindCharFirst vyhledá v textu první výskyt daného znaku v kódu UNICODE (1 dvojslovo). Funkce TextFindChar vyhledá první výskyt znaku od dané pozice v textu (včetně).


; -----------------------------------------------------------------------------
;                   Find character in forward direction
; -----------------------------------------------------------------------------
; INPUT:	EAX = UNICODE character
;		EBX = pointer to TEXT where to search
;		EDX = start offset (it can be out of range)
; OUTPUT:	EDX = offset of found text (or EDX = -1 if text not found)
;		CY = text not found (EDX = -1)
; NOTES:	Set EDX to 0 to find first occurrence of the text.
; -----------------------------------------------------------------------------

; ------------- Find first occurrence of the character

TextFindCharFirst:
		xor	edx,edx		; EDX <- 0, find first occurrence

Na vstupu funkce obsahuje registr EAX hodnotu hledaného znaku v kódu UNICODE. Registr EBX obsahuje ukazatel na textovou proměnnou s textem k prohledání. Registr EDX obsahuje počáteční offset v textu, od kterého bude znak vyhledáván. V případě funkce TextFindCharFirst je obsah registru EDX nejdříve vynulován, čímž se zajistí nastavení ukazatele na začátek textu.

Je-li znak v textu nalezen, je navrácena v registru EDX pozice (offset) znaku v textu a příznak CF je vynulován. Není-li znak nalezen, je v registru EDX navrácena hodnota -1 a je navrácen příznak chyby CY.


; ------------- Find 1-byte character

TextFindChar:	cmp	eax,7fh		; is it 1-byte character?
		jbe	TextFindByte	; find 1-byte character

Znak bude v textu vyhledáván jako řetězec v kódu UTF-8. Pro UTF-8 platí, že znaky s kódem 0 až 7Fh (tj. 7 bitů) jsou v textu uloženy jako 1 bajt. Další bajty v kódu mají vždy hodnotu 80h a více, takže znak může být v textu vyhledán přímo pomocí funkce TextFindByte.


; ------------- Find 2-byte character

		push	eax		; push EAX
		cmp	eax,7ffh	; is it 2-byte character?
		ja	TextFindChar2	; it is more than 2-byte character
		shl	eax,2		; save high 2 bits
		shr	al,2		; AL <- low 6 bits
		or	ax,0c080h	; AX <- add flags
		xchg	al,ah		; AL <- first byte, AH <- second byte
		call	TextFindWord	; find 2-byte character
		pop	eax		; pop EAX
		ret

Znaky v rozsahu 80h až 7FFh (tj. 15 bitů) jsou v kódu UTF-8 kódovány pomocí 2 bajtů. První bajt obsahuje vyšších 6 bitů s nastavenými bity 6 a 7, druhý bajt obsahuje nižších 7 bitů s nastaveným bitem 7. Znak je vyhledán jako slovo (2 bajty) pomocí funkce TextFindWord.


; ------------- Push registers

TextFindChar2:	push	edi		; push EDI
		push	ebp		; push EBP		
		sub	esp,TEXT_size+8+4 ; ESP <- create local buffer

; ------------- Store character into local buffer (we may ignore TEXT_Ref)

		lea	edi,[esp+TEXT_Text] ; EDI <- local buffer
		mov	ebp,8		; EBP <- size of buffer
		call	CharUTF8Write	; write character into UTF-8 buffer
		sub	ebp,8		; EBP <- -text length
		neg	ebp		; EBP <- text length
		mov	[esp+TEXT_Length],ebp ; set text length

Znaky v rozsahu 800h a výše budou vyhledávány jako vícebajtové textové řetězce. V zásobníku se vytvoří místo pro pomocnou textovou proměnnou, pro buffer znaku uloženého jako text v kódu UTF-8 a pro záhlaví textového řetězce. Znak je dekódován do bufferu do kódu UTF-8 pomocí funkce CharUTF8Write a do pomocné textové proměnné je uložena délka hledaného řetězce v kódu UTF-8.


; ------------- Find character

		mov	ebp,esp		; EBP <- pointer to TEXTDATA to find
		lea	eax,[esp+TEXT_size+8] ; EAX <- pointer to TEXT variable
		mov	[eax],ebp	; store pointer to TEXTDATA
		call	TextFind	; find character

; ------------- Pop registers

		lea	esp,[esp+TEXT_size+8+4] ; pop ESP
		pop	ebp		; pop EBP
		pop	edi		; pop EDI
		pop	eax		; pop EAX
		ret

Do pomocné proměnné v zásobníku je uložen ukazatel na textová data a textový řetězec je vyhledán v textu pomocí funkce TextFind. U hledaného řetězce se ignoruje položka referenčního čítače, která proto není inicializovaná. Po ukončení hledání se obnoví ukazatel zásobníku a registry ze zásobníku.


Obsah / Utility / TEXT / TextFindCharFirst, TextFindChar