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

Obsah / Utility / CHARSET / CharTransWords

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


CharTransWords - Konverze textu na slova (první písmeno velké)

Funkce CharTransWords zkonvertuje text na slova, tj. první písmeno skupiny písmen je velké a ostatní malá, případně též současně zkonvertuje text z jedné kódové stránky na jinou.


; -----------------------------------------------------------------------------
;              Convert text to words (first character is capital)
; -----------------------------------------------------------------------------
; INPUT:	AX = source code page
;		BX = destination code page
;		ECX = size of source buffer (bytes)
;		EDX = invalid character (0 = use similar ASCII or default char)
;		ESI = source buffer
;		EDI = destination buffer (NULL = get required size of buffer)
;		EBP = size of destination buffer (bytes, ignored if EDI=NULL)
; OUTPUT:	EAX = size of destination data (bytes, 0=invalid code page)
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr AX číslo kódové stránky zdrojového textu, registr BX číslo cílové kódové stránky, ECX velikost zdrojového textu (v bajtech), EDX Unicode kód náhradního znaku (který se použije, pokud znak není v cílové kódové stránce podporován), ESI ukazatel na zdrojový text, EDI ukazatel na cílový buffer a EBP velikost cílového bufferu. Funkce vrací v registru EAX velikost dat uložených do cílového bufferu (může být 0 v případě zadání neplatné kódové stránky). Je-li náhradní znak v registru EDX nulový, nahradí se neexistující znak nejbližším podobným znakem z ASCII tabulky. Je-li adresa cílového bufferu v registru EDI nulová, funkce pouze zjistí potřebnou velikost dat v cílovém bufferu.


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

CharTransWords:	push	ebx		; push EBX
		push	ecx		; push ECX
		push	esi		; push ESI
		push	edi		; push EDI
		push	ebp		; push EBP

; ------------- Get source character set structure (-> EBX, later -> EAX)

		push	ebx		; push EBX (destination code page)
		call	GetCharSet	; get character set structure
		pop	eax		; EAX <- destination code page
		jc	CharTransWords9	; codepage not found

; ------------- Get destination character set structure (-> EBX)

		push	ebx		; push EBX (source character set)
		call	GetCharSet	; get character set structure
		pop	eax		; EAX <- source character set
		jc	CharTransWords9	; page not found

; ------------- Check destination buffer

		or	edi,edi		; is destination buffer valid?
		jz	CharTransWords6	; destination buffer is not valid

Na začátku funkce se nejdříve vyhledá popisovač zdrojové kódové stránky (ukazatel se později uloží do registru EAX), popisovač cílové kódové stránky (ukazatel se uloží do registru EBX) a zkontroluje se, zda je požadována konverze textu nebo pouze zjištění velikosti cílového bufferu. Při zadání neplatné zdrojové nebo cílové kódové stránky se funkce předčasně ukončí.


; ------------- Convert text - first letter

CharTransWords2:jecxz	CharTransWords9	; no source data
		push	eax		; push EAX (source character set)
		push	ebx		; push EBX (destination character set)
		xchg	eax,ebx		; EBX <- source character set
		call	dword [ebx+CHSET_ReadChar] ; read character
		pop	ebx		; pop EBX (destination character set)
		call	UniCharToCap	; convert to capital letter
		push	eax		; push EAX (character)
		call	dword [ebx+CHSET_WriteChar] ; write character
		pop	eax		; pop EAX (character)
		call	CheckUniLetter	; check character if it is a letter
		pop	eax		; pop EAX (source character set
		jz	CharTransWords2	; character is not a letter

; ------------- Convert text - next letter

CharTransWords4:jecxz	CharTransWords9	; no source data
		push	eax		; push EAX (source character set)
		push	ebx		; push EBX (destination character set)
		xchg	eax,ebx		; EBX <- source character set
		call	dword [ebx+CHSET_ReadChar] ; read character
		pop	ebx		; pop EBX (destination character set)
		call	UniCharToSmall	; convert to small letter
		push	eax		; push EAX (character)
		call	dword [ebx+CHSET_WriteChar] ; write character
		pop	eax		; pop EAX (character)
		call	CheckUniLetter	; check character if it is a letter
		pop	eax		; pop EAX (source character set
		jnz	CharTransWords4	; character is a letter
		jmp	short CharTransWords2 ; character is not a letter

Je-li ukazatel na cílový buffer platný, bude se provádět konverze textu. Obsluhuje se samostatně první písmeno slova a další písmena slova.

V cyklu je postupně načítán znak po znaku dané zdrojové znakové sady pomocí funkce CHSET_ReadChar. Navrácený znak je v kódu Unicode (v registru EAX). Jedná se o obsluhu prvního písmene slova, proto je navrácený znak zkonvertován na velké písmeno funkcí UniCharToCap. Následná funkce CHSET_WriteChar znak uloží do výstupního bufferu v dané cílové znakové sadě a provede se pomocí funkce CheckUniLetter test, zda znak bylo písmeno. Pokud to nebylo písmeno, opakuje se obsluha prvního znaku slova.

Pokud znakem bylo písmeno, přechází se na obsluhu dalšího znaku slova. Obsluha je podobná jako obsluha prvního písmene s tím rozdílem, že znak se konvertuje na malé písmeno funkcí UniCharToSmall. Je-li znakem písmeno, pokračuje se obsluhou dalšího znaku. Není-li to písmeno, navrátí se zpět k obsluze prvního písmene slova.

Cyklus se opakuje dokud jsou k dispozici nějaká další zdrojová data (čítač zdrojových dat v registru ECX je postupně snižován funkcí pro čtení znaku).


; ------------- Get size of buffer - first letter

CharTransWords6:jecxz	CharTransWords9	; no source data
		push	eax		; push EAX (source character set)
		push	ebx		; push EBX (destination character set)
		xchg	eax,ebx		; EBX <- source character set
		call	dword [ebx+CHSET_ReadChar] ; read character
		pop	ebx		; pop EBX (destination character set)
		call	UniCharToCap	; convert to capital letter
		push	eax		; push EAX (character)
		call	dword [ebx+CHSET_SizeChar] ; get size of character
		pop	eax		; pop EAX (character)
		call	CheckUniLetter	; check character if it is a letter
		pop	eax		; pop EAX (source character set
		jz	CharTransWords6	; character is not a letter

; ------------- Get size of buffer - next letter

CharTransWords8:jecxz	CharTransWords9	; no source data
		push	eax		; push EAX (source character set)
		push	ebx		; push EBX (destination character set)
		xchg	eax,ebx		; EBX <- source character set
		call	dword [ebx+CHSET_ReadChar] ; read character
		pop	ebx		; pop EBX (destination character set)
		call	UniCharToSmall	; convert to small letter
		push	eax		; push EAX (character)
		call	dword [ebx+CHSET_SizeChar] ; get size of character
		pop	eax		; pop EAX (character)
		call	CheckUniLetter	; check character if it is a letter
		pop	eax		; pop EAX (source character set
		jnz	CharTransWords8	; character is a letter
		jmp	short CharTransWords6 ; character is not a letter

Je-li ukazatel na cílový buffer nulový, bude se zjišťovat velikost cílového textu. Obsluhuje se samostatně první písmeno slova a další písmena slova.

V cyklu je postupně načítán znak po znaku dané zdrojové znakové sady pomocí funkce CHSET_ReadChar. Navrácený znak je v kódu Unicode (v registru EAX). Jedná se o obsluhu prvního písmene slova, proto je navrácený znak zkonvertován na velké písmeno funkcí UniCharToCap. Následná funkce CHSET_SizeChar posouvá čítač cílových dat v registru EDI v dané cílové znakové sadě. Poté se provede pomocí funkce CheckUniLetter test, zda znak bylo písmeno. Pokud to nebylo písmeno, opakuje se obsluha prvního znaku slova.

Pokud znakem bylo písmeno, přechází se na obsluhu dalšího znaku slova. Obsluha je podobná jako obsluha prvního písmene s tím rozdílem, že znak se konvertuje na malé písmeno funkcí UniCharToSmall. Je-li znakem písmeno, pokračuje se obsluhou dalšího znaku. Není-li to písmeno, navrátí se zpět k obsluze prvního písmene slova.

Cyklus se opakuje dokud jsou k dispozici nějaká další zdrojová data (čítač zdrojových dat v registru ECX je postupně snižován funkcí pro čtení znaku).


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

CharTransWords9:xchg	eax,edi		; EAX <- new destination bufferu
		pop	ebp		; pop EBP
		pop	edi		; pop EDI
		pop	esi		; pop ESI
		pop	ecx		; pop ECX
		pop	ebx		; pop EBX
		sub	eax,edi		; EAX <- size of data in buffer
		ret

Při návratu z funkce je do registru EAX načtena z registru EDI nová cílová adresa nebo nový čítač cílových dat. Po návratu ostatních registrů a odečtení původní cílové adresy v registru EDI se obdrží velikost uložených dat do výstupního bufferu resp. velikost cílových dat při zjišťování velikosti.


Obsah / Utility / CHARSET / CharTransWords