Obsah / Utility / UNICHAR / Funkce typů znaků
Zdrojový kód:
INCLUDE\UTIL\UNICHAR.INC, UTIL\UNICHAR.ASM.
Funkce typů
znaků
; -----------------------------------------------------------------------------
; Get Unicode character type descriptor
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: EBX = pointer to Unicode character type descriptor UNITYPE
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
GetUniType: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja GetUniType4 ; invalid character
; ------------- Push registers
push eax ; push EAX
; ------------- Get pointer to descriptor (-> EBX)
GETUNITYPE eax,al,ah,eax,ebx ; get pointer to descriptor
; ------------- Pop registers
pop eax ; pop EAX
ret
; ------------- Invalid Unicode character (character is out of range)
GetUniType4: mov ebx,CHTypeInv ; EBX <- invalid character
ret
|
Funkce GetUniType slouží k vyhledání
ukazatele na popisovač typu Unicode znaku. Vstupem funkce je
Unicode kód znaku v registru EAX. Výstupem je ukazatel na
popisovač typu znaku v registru EBX.
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah,
navrátí se ukazatel na popisovač neplatného znaku. Jinak se
pokračuje vyhledáním ukazatele na popisovač typu znaku
pomocí makra GETUNITYPE.
; -----------------------------------------------------------------------------
; Get flags of Unicode character type
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: DL = flags of Unicode character type (see CHNONE, CHCTR, ...)
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
GetUniTypeFlags:cmp eax,CHTYPEMAX ; check maximal Unicode character
ja GetUniTypeFlgs4 ; invalid character
; ------------- Push registers
push eax ; push EAX
push ebx ; push EBX
; ------------- Get flags (-> DL)
movzx ebx,ah ; EBX <- character HIGH
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
movzx eax,al ; EAX <- character LOW
mov dl,[ebx+eax*UNITYPE_size+UNI_Flags] ; DL <- flags
; ------------- Pop registers
pop ebx ; pop EBX
pop eax ; pop EAX
ret
; ------------- Invalid Unicode character (character is out of range)
GetUniTypeFlgs4:mov dl,CHNONE ; DL <- invalid character
ret
|
Funkce GetUniTypeFlags slouží ke
zjištění příznaků typu Unicode znaku. Vstupem funkce je
Unicode kód znaku v registru EAX. Výstupem jsou příznaky typu
znaku v registru EBX (CHNONE, CHCTR atd. - viz UNITYPE).
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah,
navrátí se příznaky pro neplatný znak. Jinak se pokračuje
načtením příznaků z popisovače znaku. Do registru EBX je
připraven vyšší bajt kódu znaku a s jeho pomocí načten do
registru EBX ukazatel na podtabulku typů znaků (z pole
ukazatelů CHTypeTab). Do registru EAX je připraven nižší
bajt kódu znaku a po sloučení s ukazatelem na podtabulku jsou
z příslušného popisovače načteny do registru DL příznaky
typu znaku.
; -----------------------------------------------------------------------------
; Check if Unicode character is valid
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: CY = character is not valid
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
CheckUniChar: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja CheckUniChar4 ; invalid character
; ------------- Push registers
push eax ; push EAX
push ebx ; push EBX
; ------------- Check if character is valid (-> CY = character is not valid)
movzx ebx,ah ; EBX <- character HIGH
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
movzx eax,al ; EAX <- character LOW
cmp byte [ebx+eax*UNITYPE_size+UNI_Flags],1 ; check flags
; ------------- Pop registers
pop ebx ; pop EBX
pop eax ; pop EAX
ret
; ------------- Invalid Unicode character (character is out of range)
CheckUniChar4: stc ; set error flag
ret
|
Funkce CheckUniChar testuje, zda je Unicode
znak platný, tj. podporovaný tabulkami systému Litos. Vstupem
funkce je Unicode kód znaku v registru EAX. Výstupem je
příznak CF, který je nastaven v případě neplatnosti znaku
(tj. stav NC pro platný znak, stav CY pro neplatný znak).
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah,
navrátí se nastavený příznak CY jako příznak neplatnosti
znaku. Jinak se pokračuje testem příznaků v popisovači
znaku. Do registru EBX je připraven vyšší bajt kódu znaku a
s jeho pomocí načten do registru EBX ukazatel na podtabulku
typů znaků (z pole ukazatelů CHTypeTab). Do registru EAX je
připraven nižší bajt kódu znaku a po sloučení s ukazatelem
na podtabulku je v příslušném popisovači proveden test
platnosti znaku - pokud je bajt příznaků nastaven na hodnotu
0, jedná se o neplatný znak.
; -----------------------------------------------------------------------------
; Check if Unicode character is a letter (small or capital)
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: NZ = character is a letter
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
CheckUniLetter: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja CheckUniLetter4 ; invalid character
; ------------- Push registers
push eax ; push EAX
push ebx ; push EBX
; ------------- Check if character is a letter
movzx ebx,ah ; EBX <- character HIGH
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
movzx eax,al ; EAX <- character LOW
test byte [ebx+eax*UNITYPE_size+UNI_Flags],CHCAP+CHSMA
; ------------- Pop registers
pop ebx ; pop EBX
pop eax ; pop EAX
ret
; ------------- Invalid Unicode character (character is out of range)
CheckUniLetter4:cmp eax,eax ; set ZF (character is not a letter)
ret
|
Funkce CheckUniLetter testuje, zda je
Unicode znak písmenem. Vstupem funkce je Unicode kód znaku v
registru EAX. Výstupem je příznak ZF, který je nastaven v
případě, že znak není písmeno (tj. stav NZ znamená
písmeno, stav ZY jiný znak než písmeno).
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah,
navrátí se nastavený příznak ZY jako příznak, že znak
není písmenem. Jinak se pokračuje testem příznaků v
popisovači znaku. Do registru EBX je připraven vyšší bajt
kódu znaku a s jeho pomocí načten do registru EBX ukazatel na
podtabulku typů znaků (z pole ukazatelů CHTypeTab). Do
registru EAX je připraven nižší bajt kódu znaku a po
sloučení s ukazatelem na podtabulku je v příslušném
popisovači proveden test, zda je znak písmenem - je-li nastaven
příznak CHCAP nebo CHSMA bude navrácen příznak NZ.
; -----------------------------------------------------------------------------
; Convert Unicode character to ASCII alternative
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: EAX = ASCII alternative
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
UniCharToASCII: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja UniCharToASCII4 ; invalid character
; ------------- Push registers
push ebx ; push EBX
; ------------- Get ASCII alternative (-> EAX)
movzx ebx,ah ; EBX <- character HIGH
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
movzx eax,al ; EAX <- character LOW
mov al,[ebx+eax*UNITYPE_size+UNI_ASCII] ; EAX <- ASCII
; ------------- Pop registers
pop ebx ; pop EBX
ret
; ------------- Invalid Unicode character (character is out of range)
UniCharToASCII4:mov eax,UNINOASC ; EAX <- invalid character
ret
|
Funkce UniCharToASCII zkonvertuje Unicode
znak na ASCII alternativu. Vstupem funkce je Unicode kód znaku v
registru EAX. Výstupem je ASCII alternativa znaku v registru
EAX.
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah,
navrátí se implicitní kód neplatného znaku UNINOASC. Jinak
se pokračuje načtením ASCII alternativy z popisovače znaku.
Do registru EBX je připraven vyšší bajt kódu znaku a s jeho
pomocí načten do registru EBX ukazatel na podtabulku typů
znaků (z pole ukazatelů CHTypeTab). Do registru EAX je
připraven nižší bajt kódu znaku a po sloučení s ukazatelem
na podtabulku je z příslušného popisovače načtena do
registru AL ASCII alternativa znaku.
; -----------------------------------------------------------------------------
; Get alphabetic sorting value of Unicode character - case sensitive
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; EDI = pointer to nationality descriptor NATION
; OUTPUT: EAX = alphabetic sorting value
; B0..B15 = unicode character
; B16..B23 = ASCII alternative
; B24..B31 = character flags (character group)
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
UniCharSort: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja UniCharSort8 ; invalid character
; ------------- Push registers
push ebx ; push EBX
push ecx ; push ECX
; ------------- Prepare table address (-> EBX,ECX)
UniCharSort2: movzx ebx,ah ; EBX <- character HIGH
movzx ecx,al ; EAX <- character LOW
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
; ------------- Get sorting value (-> EAX)
UniCharSort4: shl eax,16 ; EAX <- shift Unicode character left
mov ax,[ebx+ecx*UNITYPE_size] ; AX <- Flags + ASCII
xchg al,ah ; AL <- ASCII, AH <- Flags
ror eax,16 ; do correction of bit position
; ------------- Prepare sorting table
movzx ebx,ah ; EBX <- character HIGH
shl ebx,2 ; EBX <- character HIGH * 4
add ebx,[edi+NAT_AlphaHash] ; EBX <- pointer to hash table
mov ebx,[ebx] ; EBX <- hash table
; ------------- Get sorting value
cmp byte [ebx+ecx],0 ; is sorting value valid?
je UniCharSort6 ; sorting value is not valid
ror eax,16 ; shift bits
mov al,[ebx+ecx] ; AL <- get sorting value
ror eax,16 ; shift bits
; ------------- Pop registers
UniCharSort6: pop ecx ; pop ECX
pop ebx ; pop EBX
ret
; ------------- Invalid Unicode character (character is out of range)
UniCharSort8: mov eax,UNINOASC ; EAX <- invalid character
ret
|
Funkce UniCharSort navrátí abecední
třídicí klíč pro Unicode znak (s rozlišením velkých a
malých písmen). Vstupem funkce je Unicode kód znaku v registru
EAX a ukazazatel na popisovač národnostních informací NATIONAL v registru EDI. Výstupem je abecední třídicí
klíč v registru EAX.
Třídicí klíč se skládá z 16
nižších bitů Unicode kódu znaku, 8 bitů ASCII alternativy
znaku a 8 bitů kategorie znaku. Při třídění textů se
porovnáním třídicího klíče znaky rozdělí do skupin
nejdříve podle kategorií (tj. řídicí znaky, potom mezera,
za ní značky atd.), potom podle ASCII alternativy a nakonec
podle nižších 16 bitů Unicode ködu (které se uplatní pokud
znaky nemají dostatečné rozlišení ASCII alternativou).
Namísto ASCII alternativy se použíje köd z třídicí tabulky
znaků, je-li k dispozici.
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah,
navrátí se implicitní kód neplatného znaku UNINOASC. Jinak
se pokračuje vygenerováním třídicího klíče. Do registru
EBX je připraven vyšší bajt kódu znaku a s jeho pomocí
načten do registru EBX ukazatel na podtabulku typů znaků (z
pole ukazatelů CHTypeTab).
Rotací registru EAX doleva o 16 bitů se
uchová nižší slovo registru. Do registru ECX je připraven
nižší bajt kódu znaku a po sloučení s ukazatelem na
podtabulku je z příslušného popisovače načtena do registru
AX ASCII alternativa znaku spolu s příznaky, Je opraveno
pořadí bajtů, aby se příznaky nacházely ve vyšším bajtu
a poté se rotací data přesunou do vyššího slova registru
EAX a do nižšího slova se navrátí původních 16 bitů kódu
znaku.
Do registru EBX se připraví vyšší bajt
kódu znaku a použije se k načtení adresy hashovací
podtabulky třídění znaků z popisovače národnostních
informací. Má-li znak platnou třídicí hodnotu (tj. obsahuje
bajt 80h a více), použije se tato hodnota namísto ASCII
alternativy znaku.
; -----------------------------------------------------------------------------
; Get alphabetic sorting value of Unicode character - capital case
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; EDI = pointer to nationality descriptor NATIONAL
; OUTPUT: EAX = alphabetic sorting value
; B0..B15 = unicode character
; B16..B23 = ASCII alternative
; B24..B31 = character flags (character group)
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
UniCharSortCap: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja UniCharSort8 ; invalid character
; ------------- Push registers
push ebx ; push EBX
push ecx ; push ECX
; ------------- Prepare table address (-> EBX,ECX)
movzx ebx,ah ; EBX <- character HIGH
movzx ecx,al ; EAX <- character LOW
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
; ------------- Check if it has valid capital letter
test byte [ebx+ecx*UNITYPE_size+UNI_Flags],CHSMA ; small?
jz UniCharSort4 ; not small letter
cmp word [ebx+ecx*UNITYPE_size+UNI_Change],0 ; change?
je UniCharSort4 ; no change
; ------------- Change to capital letter
mov ax,[ebx+ecx*UNITYPE_size+UNI_Change] ; capital letter
jmp short UniCharSort2
|
Funkce UniCharSortCap je podobná funkci
UniCharSort s tím rozdílem, ž třídicí klíč nerozlišuje
mezi velkými a malými písmeny, protože funkce znak nejdříve
zkonvertuje na velké písmeno.
; -----------------------------------------------------------------------------
; Convert Unicode character to small letter
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: EAX = small letter
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
UniCharToSmall: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja UniCharToSmall4 ; invalid character
; ------------- Push registers
push ebx ; push EBX
push ecx ; push ECX
; ------------- Get type descriptor (-> ECX)
movzx ebx,ah ; EBX <- character HIGH
movzx ecx,al ; ECX <- character LOW
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
mov ecx,[ebx+ecx*UNITYPE_size] ; ECX <- descriptor
; ------------- Check if character is a capital letter
test cl,CHCAP ; is it a capital letter?
jz UniCharToSmall2 ; it is not capital letter
; ------------- Convert to small letter
shr ecx,16 ; ECX <- small letter
jz UniCharToSmall2 ; there is no small letter
xchg eax,ecx ; EAX <- small letter
; ------------- Pop registers
UniCharToSmall2:pop ecx ; pop ECX
pop ebx ; pop EBX
UniCharToSmall4:ret
|
Funkce UniCharToSmall zkonvertuje znak na
malé písmeno. Vstupem fukce je Unicode köd znaku v registru
EAX, výstupem je znak převedený na malé písmeno, opět v
registru EAX.
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah, funkce
se navrátí bez změny znaku.
Je-li znak platný, je do registru EBX
připraven vyšší bajt ködu znaku a z tabulky CHTypeTab
načten ukazatel na podtabulku popisovače typu znaku. Do
registru ECX je připraven nižší bajt ködu znaku a z
podtabulky popisovače je do registru ECX načten popisovač typu
znaku.
Není-li znakem velké písmeno, funkce se
ukončí bez dalších operací. Jinak se z popisovače typu
vyjme köd párového malého písmene (rotací ECX o 16 bitů
vpravo) a pokud je köd malého písmene platný, je navrácen
funkcí jako nový köd znaku.
; -----------------------------------------------------------------------------
; Convert Unicode character to capital letter
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: EAX = capital letter
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
UniCharToCap: cmp eax,CHTYPEMAX ; check maximal Unicode character
ja UniCharToCap4 ; invalid character
; ------------- Push registers
push ebx ; push EBX
push ecx ; push ECX
; ------------- Get type descriptor (-> ECX)
movzx ebx,ah ; EBX <- character HIGH
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
movzx ecx,al ; ECX <- character LOW
mov ecx,[ebx+ecx*UNITYPE_size] ; ECX <- descriptor
; ------------- Check if character is a small letter
test cl,CHSMA ; is it a small letter?
jz UniCharToCap2 ; it is not small letter
; ------------- Convert to capital letter
shr ecx,16 ; ECX <- capital letter
jz UniCharToCap2 ; there is no capital letter
xchg eax,ecx ; EAX <- capital letter
; ------------- Pop registers
UniCharToCap2: pop ecx ; pop ECX
pop ebx ; pop EBX
UniCharToCap4: ret
|
Funkce UniCharToCap zkonvertuje znak na
velké písmeno. Vstupem fukce je Unicode köd znaku v registru
EAX, výstupem je znak převedený na velké písmeno, opět v
registru EAX.
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah, funkce
se navrátí bez změny znaku.
Je-li znak platný, je do registru EBX
připraven vyšší bajt ködu znaku a z tabulky CHTypeTab
načten ukazatel na podtabulku popisovače typu znaku. Do
registru ECX je připraven nižší bajt ködu znaku a z
podtabulky popisovače je do registru ECX načten popisovač typu
znaku.
Není-li znakem malé písmeno, funkce se
ukončí bez dalších operací. Jinak se z popisovače typu
vyjme köd párového velkého písmene (rotací ECX o 16 bitů
vpravo) a pokud je köd velkého písmene platný, je navrácen
funkcí jako nový köd znaku.
; -----------------------------------------------------------------------------
; Convert Unicode character to small/capital letter (invert)
; -----------------------------------------------------------------------------
; INPUT: EAX = Unicode character
; OUTPUT: EAX = small/capital letter
; -----------------------------------------------------------------------------
; ------------- Check range of Unicode character
UniCharToSmaCap:cmp eax,CHTYPEMAX ; check maximal Unicode character
ja UniCharToSmaCa4 ; invalid character
; ------------- Push registers
push ebx ; push EBX
push ecx ; push ECX
; ------------- Get small/capital letter (-> ECX)
movzx ebx,ah ; EBX <- character HIGH
mov ebx,[CHTypeTab+ebx*4] ; EBX <- subtable
movzx ecx,al ; ECX <- character LOW
movzx ecx,word [ebx+ecx*UNITYPE_size+UNI_Change] ;ECX<-letter
; ------------- Convert to small/capital letter
jecxz UniCharToSmaCa2 ; there is no small/capital letter
xchg eax,ecx ; EAX <- small/capital letter
; ------------- Pop registers
UniCharToSmaCa2:pop ecx ; pop ECX
pop ebx ; pop EBX
UniCharToSmaCa4:ret
|
Funkce UniCharToSmaCap zkonvertuje znak na
opačné velké/malé písmeno. Vstupem fukce je Unicode köd
znaku v registru EAX, výstupem je znak převedený na
velké/malé písmeno, opět v registru EAX.
Na začátku funkce je nejdříve ověřena
platnost Unicode znaku. Pokud je mimo podporovaný rozsah, funkce
se navrátí bez změny znaku.
Je-li znak platný, je do registru EBX
připraven vyšší bajt ködu znaku a z tabulky CHTypeTab
načten ukazatel na podtabulku popisovače typu znaku. Do
registru ECX je připraven nižší bajt ködu znaku a z
podtabulky popisovače je do registru ECX načten köd párového
velkého/malého písmene. Pokud je köd párového
velkého/malého písmene platný, je navrácen funkcí jako
nový köd znaku.
Obsah / Utility / UNICHAR / Funkce typů znaků