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

Obsah / Utility / TEXT / TextTrimMid

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


TextTrimMid - Ořezání mezer a řídicích znaků z textu

Funkce TextTrimMid odstraní nevýznamné mezery a řídicí znaky (tj. znaky s kódem 32 a menším) z textu.


; -----------------------------------------------------------------------------
;               Trim spaces and control characters from the text
; -----------------------------------------------------------------------------
; INPUT:	EBX = pointer to TEXT
; OUTPUT:	CY = memory error (text not changed)
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr EBX ukazatel na textovou proměnnou. V případě chyby paměti funkce navrátí příznak chyby CY.


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

TextTrimMid:	push	eax		; push EAX
		push	ecx		; push ECX
		push	esi		; push ESI
		push	edi		; push EDI

; ------------- Copy text on write

		call	TextCopyWrite	; copy text on write
		jc	TextTrimMid8	; memory error

Po úschově registrů je nejdříve připraven text k zápisu, tj. je provedena jeho kopie pomocí funkce TextCopyWrite, aby data nebyla sdílena s více proměnnými. V případě chyby paměti je funkce ihned ukončena.


; ------------- Prepare registers

		mov	esi,[ebx]	; ESI <- pointer to TEXT
		mov	ecx,[esi+TEXT_Length] ; ECX <- text length
		add	esi,TEXT_Text	; ESI <- source pointer
		jecxz	TextTrimMid8	; nothing to delete (here is NC)
		mov	edi,esi		; EDI <- destination pointer

Do registrů ESI a EDI jsou připraveny ukazatele na začátek textu, do registru ECX je připravena délka textu. V případě nulové délky textu je funkce ihned ukončena s navrácením vynulovaného příznaku chyby NC.


; ------------- Trim spaces and control characters

TextTrimMid2:	lodsb			; AL <- load one character
		cmp	al,33		; check one character
		stosb			; store character
		sbb	edi,byte 0	; return pointer if invalid character
		loop	TextTrimMid2	; next byte

Text je procházen bajt po bajtu a každý načtený znak je opět uložen zpět do bufferu textu. Ukládací ukazatel v registru EDI je navrácen zpět o 1 v případě, že byl přenesen nevýznamný znak mezery, tj. bajt s kódem 0 až 32. Tímto způsobem dojde k vypuštění nevýznamných mezer z textu. Využívá se přitom skutečnosti, že při kódování textu UTF-8 jsou znaky s hodnotou 0 až 7Fh uloženy přímo jako jednobajtové kódy. Všechny ostatní bajty kódu UTF-8 jsou vždy 80h a více, proto postačí vyhledávat přímo bajty s hodnotou 0 až 32 bez dalšího rozlišování kódu UTF-8.


; ------------- Resize data buffer

		cmp	esi,edi		; text changed?
		mov	eax,[ebx]	; EAX <- data buffer
		je	TextTrimMid8	; text not changed
		add	eax,TEXT_Text	; EAX <- start of text
		sub	edi,eax		; EDI <- new length
		xchg	eax,edi		; EAX <- new length
		call	TextResize	; resize data buffer

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

TextTrimMid8:	pop	edi		; pop EDI
		pop	esi		; pop ESI
		pop	ecx		; pop ECX
		pop	eax		; pop EAX
		ret

Po provedení redukce se porovná zdrojový a cílový ukazatel. Pokud nejsou shodné, došlo k redukci alespoň jednoho bajtu a je potřeba zmenšit velikost bufferu textu. Nová délka textu je zjištěna rozdílem ukládací adresy v registru EDI a adresy začátku textu v registru EAX. Velikost bufferu je opravena funkcí TextResize.


Obsah / Utility / TEXT / TextTrimMid