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

Obsah / Utility / TEXT / TextOffToPos

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


TextOffToPos - Přepočet bajtového offsetu znaku na pozici

Funkce TextOffToPos přepočte bajtový offset znaku v textu na pozici znaku (vyjádřenou ve znacích).


; -----------------------------------------------------------------------------
;                    Recalc byte offset to character position
; -----------------------------------------------------------------------------
; INPUT:	EAX = byte offset (it may be out of range)
;		EBX = pointer to TEXT
; OUTPUT:	EAX = character position
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr EAX bajtový offset znaku v textu, registr EBX ukazatel na textovou proměnnou. Na výstupu obsahuje registr EAX pozici znaku v textu. Pokud ležel offset mimo platný rozsah, je pozice opravena do platných mezí. Znak mající offset za koncem textu bude mít pozici rovnou délce textu ve znacích (tedy ukazující za poslední znak textu).


; ------------- Check minimal byte offset

TextOffToPos:	or	eax,eax		; check minimal character position
		jle	short TextPosToOff9 ; offset is <= 0

Je-li offset znaku záporný (nebo nula), navrátí funkce ihned pozici nula. Část kódu je společná s funkcí TextPosToOff.


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

		push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI

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

		mov	esi,[ebx]	; ESI <- data buffer
		xor	edx,edx		; EDX <- 0, position accumulator
		mov	ecx,[esi+TEXT_Length] ; ECX <- length of text
		cmp	eax,ecx		; check byte offset
		jae	TextOffToPos2	; byte offset is OK
		xchg	eax,ecx		; ECX <- limit byte offset
TextOffToPos2:	add	esi,TEXT_Text	; ESI <- start of text
		jecxz	TextOffToPos8	; no text

Text bude procházen od začátku řetězce, aby se mohly odpočítat platné znaky. Registr EDX bude čítat nalezené znaky a je proto vynulován. Do registru ECX je připraven offset znaku - pokud přesáhl konec textu, je jeho hodnota omezena (je nahrazen délkou textu). Do registru ESI se připraví ukazatel na začátek textu. V případě nulové délky textu bude funkce předčasně ukončena.


; ------------- Convert offset to position

		xor	eax,eax		; EAX <- 0
TextOffToPos4:	lodsb			; AL <- load character
		cmp	al,0feh		; detection bytes?
		jae	TextOffToPos6	; skip detection bytes
		and	al,0c0h		; mask bits
		cmp	al,80h		; is it first byte of character?
		setne	al		; AL <- 1 if it is first byte
		add	edx,eax		; increase character position
TextOffToPos6:	loop	TextOffToPos4	; next character

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

TextOffToPos8:	xchg	eax,edx		; EAX <- text length
		pop	esi		; pop ESI
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		ret

Při konverzi offsetu na pozici se text prochází od začátku bajt po bajtu a je-li nalezen bajt indikující začátek kódu znaku, zvýší se čítač pozice znaků. Po dosažení požadovaného offsetu znaku je funkce ukončena. Za bajt začátku kódu jsou považovány bajty s hodnotou 0 až 7Fh a 0C0h až 0FDh. Bajty 0FEh a 0FFh jsou synchronizační, v kódu UTF-8 by se neměly vyskytovat a jsou proto přeskakovány. Výsledná pozice znaku se přenese z čítače v registru EDX do výstupního registru EAX..


Obsah / Utility / TEXT / TextOffToPos