Obsah / Utility / TEXT / TextDelete
Zdrojový kód:
INCLUDE\UTIL\TEXT.INC, UTIL\TEXT.ASM
TextDelete - Zrušení
části textu
Funkce TextDelete zruší
část textu.
; -----------------------------------------------------------------------------
; Delete part of text
; -----------------------------------------------------------------------------
; INPUT: EBX = pointer to TEXT variable
; ECX = length of text to delete (in bytes, may be out of range)
; EDX = offset of text to delete (it may be out of range)
; OUTPUT: CY = memory error (text not changed)
; NOTES: It limits offset and length to a valid range.
; -----------------------------------------------------------------------------
|
Na vstupu funkce obsahuje registr EBX
ukazatel na textovou proměnnou. V registru EDX je pozice
(offset) začátku rušené části textu a v registru ECX délka
rušené části textu (v bajtech). V případě chyby paměti
funkce navrátí příznak chyby CY a text zůstane nezměněn.
Funkce omezuje pozici a délku textu do platných rozsahů.
TextDelete: push eax ; push EAX
push ecx ; push ECX
push edx ; push EDX
push esi ; push ESI
push edi ; push EDI
; ------------- Copy text on write
call TextCopyWrite ; copy text on write
jc TextDelete6 ; memory error
|
Na začátku funkce se obsah textové
proměnné zkopíruje pro zápis, pokud jsou data textové
proměnné vlastněna více proměnnými. V případě chyby
paměti se funkce ihned ukončí s chybovým příznakem.
; ------------- Limit minimal start position
or edx,edx ; check minimal start position
js TextDelete7 ; limit minimal start position
.................
; ------------- Limit minimal start position
TextDelete7: add ecx,edx ; ECX <- correct text length
xor edx,edx ; EDX <- limit start position
jmp short TextDelete1
|
Pokud leží ukazatel pozice před
začátkem textu, opraví se délka textu a počíteční pozice
se omezí na offset 0.
; ------------- Check minimal text length
TextDelete1: or ecx,ecx ; check text length
jle TextDelete6 ; no text to delete (here is NC)
|
Není-li délka textu v registru ECX
platné kladné číslo, nejsou žádná data k rušení a funkce
se ukončí s vynulovaným příznakem chyby.
; ------------- Check maximal start position
mov edi,[ebx] ; EDI <- data buffer
mov eax,[edi+TEXT_Length] ; EAX <- text length
sub eax,edx ; EAX <- remaining characters
jle TextDelete5 ; no data left
|
Do registru EDI je připraven ukazatel na
textový buffer a do registru EAX je připravena délka
zbývající části textu za ukazatelem pozice.
; ------------- Limit maximal text length
sub eax,ecx ; EAX <- rest of text
js TextDelete8 ; length is too big
.................
; ------------- Limit maximal text length
TextDelete8: add ecx,eax ; ECX <- limit maximal text length
xor eax,eax ; EAX <- no text left
jmp short TextDelete3
|
Do registru EAX je připravena délka textu
za rušeným úsekem. Při překročení konce textu bude délka
zbylých dat omezena na 0 a délka rušené části bude omezena
na platný rozsah.
; ------------- Prepare buffer address
TextDelete3: lea edi,[edi+TEXT_Text+edx] ; EDI <- start of deleted text
lea esi,[edi+ecx] ; ESI <- end of deleted text
; ------------- New length of text (->EDX)
add edx,eax ; EDX <- new length of text
; ------------- Delete text
mov ecx,eax ; ECX <- length of text
shr ecx,2 ; ECX <- length of text in DWORDs
rep movsd ; shift text in DWORDs
and eax,byte 3 ; EAX <- rest in last DWORD
xchg eax,ecx ; ECX <- rest in last DWORD
rep movsb ; copy rest of text
|
Do registru EDI je připraven ukazatel na
začátek rušené části textu, do registr ESI ukazatel na
začátek zbytku textu za rušenou částí a zbytek textu je
přesunut na místo rušené části textu. Přesun se provádí
nejdříve po celých dvojslovech a potom zbytek dat v posledním
dvojslovu.
; ------------- Resize buffer
xchg eax,edx ; EAX <- new length of text
call TextResize ; resze buffer
; ------------- Pop registers
TextDelete5: clc ; clear error flag
TextDelete6: pop edi ; pop EDI
pop esi ; pop ESI
pop edx ; pop EDX
pop ecx ; pop ECX
pop eax ; pop EAX
ret
|
Na závěr je nastavena nová délka textu
pomocí funkce TextResize.
Obsah / Utility / TEXT / TextDelete