Скачиваний:
29
Добавлен:
01.05.2014
Размер:
12.64 Кб
Скачать

// //
// Содержит разнообразные функции для работы со строками //
// типа AnsiString и класс TStringBuilder, используемый //
// для быстрого создания строк из отдельных фрагментов. //

unit uStrings;

interface

{ ВАЖНОЕ ЗАМЕЧАНИЕ:

Если необходимо применить G_StrToUpper(P: PChar), G_StrToAnsi(P: PChar) или
другую подобную функцию, в которую передается указатель и данные по указателю
изменяются, к строке S типа String, то сначала надо вызвать стандартную
процедуру UniqueString(S) для фактического выделения памяти и исключения
множественных ссылок и ссылок на константную строку. Только после этого
можно изменять строку по указателю, как, например: G_StrToUpper(Pointer(S)). }

uses SysUtils, uConsts;

{ Функции для сравнения строк }


{ G_CompareText сравнивает две строки без учета регистра. Возвращаемый
результат меньше нуля, если S1 < S2; больше нуля, если S1 > S2, и равен нулю,
если S1 = S2. Эта функция прекращает сравнение, когда обнаружено различие
строк или когда обнаружен символ с кодом 0, т.е. символ конца строки. }

function G_CompareText(const S1, S2: string): Integer; overload;
function G_CompareText(P1, P2: PChar): Integer; overload;

{ G_SameStr сравнивает две строки с учетом регистра и возвращает True, если
строки равны, иначе возвращает False. }

function G_SameStr(const S1, S2: string): Boolean; overload;
function G_SameStr(P1, P2: Pointer): Boolean; overload;

{ G_SameText сравнивает две строки без учета регистра и возвращает True, если
строки равны, иначе возвращает False. }

function G_SameText(const S1, S2: string): Boolean; overload;
function G_SameText(P1, P2: Pointer): Boolean; overload;


{ Поиск, замена и удаление подстрок и отдельных символов }


{ G_CharPos находит первое вхождение символа C в строке S, начиная с символа
номер StartPos. Возвращает номер найденного символа или ноль, если символ C
в строке S не найден. }

function G_CharPos(C: Char; const S: string; StartPos: Integer = 1): Integer; overload;
function G_CharPos(C: Char; P: Pointer; StartPos: Integer = 1): Integer; overload;



{ Класс TStringBuilder для динамического создания или изменения строк
произвольной длины }

{ Ускоренная работа со строками через менеджер памяти AcedMemory }

{DEFINE USE_ACED_MEMORY} // Определить при использовании AcedMemory

{DEFINE USE_DYNAMIC_TABLES}

{$IFNDEF USE_DYNAMIC_TABLES}

const
ToUpperChars: array[0..255] of Char =
(#$00,#$01,#$02,#$03,#$04,#$05,#$06,#$07,#$08,#$09,#$0A,#$0B,#$0C,#$0D,#$0E,#$0F,
#$10,#$11,#$12,#$13,#$14,#$15,#$16,#$17,#$18,#$19,#$1A,#$1B,#$1C,#$1D,#$1E,#$1F,
#$20,#$21,#$22,#$23,#$24,#$25,#$26,#$27,#$28,#$29,#$2A,#$2B,#$2C,#$2D,#$2E,#$2F,
#$30,#$31,#$32,#$33,#$34,#$35,#$36,#$37,#$38,#$39,#$3A,#$3B,#$3C,#$3D,#$3E,#$3F,
#$40,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4A,#$4B,#$4C,#$4D,#$4E,#$4F,
#$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5A,#$5B,#$5C,#$5D,#$5E,#$5F,
#$60,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4A,#$4B,#$4C,#$4D,#$4E,#$4F,
#$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5A,#$7B,#$7C,#$7D,#$7E,#$7F,
#$80,#$81,#$82,#$81,#$84,#$85,#$86,#$87,#$88,#$89,#$8A,#$8B,#$8C,#$8D,#$8E,#$8F,
#$80,#$91,#$92,#$93,#$94,#$95,#$96,#$97,#$98,#$99,#$8A,#$9B,#$8C,#$8D,#$8E,#$8F,
#$A0,#$A1,#$A1,#$A3,#$A4,#$A5,#$A6,#$A7,#$A8,#$A9,#$AA,#$AB,#$AC,#$AD,#$AE,#$AF,
#$B0,#$B1,#$B2,#$B2,#$A5,#$B5,#$B6,#$B7,#$A8,#$B9,#$AA,#$BB,#$A3,#$BD,#$BD,#$AF,
#$C0,#$C1,#$C2,#$C3,#$C4,#$C5,#$C6,#$C7,#$C8,#$C9,#$CA,#$CB,#$CC,#$CD,#$CE,#$CF,
#$D0,#$D1,#$D2,#$D3,#$D4,#$D5,#$D6,#$D7,#$D8,#$D9,#$DA,#$DB,#$DC,#$DD,#$DE,#$DF,
#$C0,#$C1,#$C2,#$C3,#$C4,#$C5,#$C6,#$C7,#$C8,#$C9,#$CA,#$CB,#$CC,#$CD,#$CE,#$CF,
#$D0,#$D1,#$D2,#$D3,#$D4,#$D5,#$D6,#$D7,#$D8,#$D9,#$DA,#$DB,#$DC,#$DD,#$DE,#$DF);

{$ELSE}

var
ToUpperChars: array[0..255] of Char;

{$ENDIF}

implementation

uses Windows, uBinary, uCommon;

{ Функции для сравнения строк }

function G_CompareText(const S1, S2: string): Integer;
asm
CMP EAX,EDX
JE @@ex
TEST EAX,EAX
JE @@2
TEST EDX,EDX
JE @@3
PUSH ESI
PUSH EDI
MOV ESI,EAX
MOV EDI,EDX
JMP @@1
@@ex: XOR EAX,EAX
RET
@@0: TEST AL,AL
JE @@4
INC ESI
INC EDI
@@1: MOVZX EAX,BYTE PTR [ESI]
MOVZX EDX,BYTE PTR [EDI]
CMP AL,DL
JE @@0
MOV AL,BYTE PTR [EAX+ToUpperChars]
MOV DL,BYTE PTR [EDX+ToUpperChars]
CMP AL,DL
JE @@0
MOVZX EAX,AL
MOVZX EDX,DL
SUB EAX,EDX
POP EDI
POP ESI
RET
@@2: TEST EDX,EDX
JE @@7
MOV CH,BYTE PTR [EDX]
TEST CH,CH
JE @@7
NOT EAX
RET
@@3: MOV CL,BYTE PTR [EAX]
TEST CL,CL
JE @@5
MOV EAX,1
RET
@@4: POP EDI
POP ESI
@@5: XOR EAX,EAX
@@7:
end;

function G_CompareText(P1, P2: PChar): Integer;
asm
CMP EAX,EDX
JE @@ex
TEST EAX,EAX
JE @@2
TEST EDX,EDX
JE @@3
PUSH ESI
PUSH EDI
MOV ESI,EAX
MOV EDI,EDX
JMP @@1
@@ex: XOR EAX,EAX
RET
@@0: TEST AL,AL
JE @@4
INC ESI
INC EDI
@@1: MOVZX EAX,BYTE PTR [ESI]
MOVZX EDX,BYTE PTR [EDI]
CMP AL,DL
JE @@0
MOV AL,BYTE PTR [EAX+ToUpperChars]
MOV DL,BYTE PTR [EDX+ToUpperChars]
CMP AL,DL
JE @@0
MOVZX EAX,AL
MOVZX EDX,DL
SUB EAX,EDX
POP EDI
POP ESI
RET
@@2: TEST EDX,EDX
JE @@7
MOV CH,BYTE PTR [EDX]
TEST CH,CH
JE @@7
NOT EAX
RET
@@3: MOV CL,BYTE PTR [EAX]
TEST CL,CL
JE @@5
MOV EAX,1
RET
@@4: POP EDI
POP ESI
@@5: XOR EAX,EAX
@@7:
end;

function G_SameStr(const S1, S2: string): Boolean;
asm
CMP EAX,EDX
JE @@08
TEST EAX,EAX
JE @@qt2
TEST EDX,EDX
JE @@qt1
MOV ECX,[EAX-4]
CMP ECX,[EDX-4]
JE @@01
@@qt1: XOR EAX,EAX
@@qt2: RET
@@01: PUSH EBX
SUB ECX,8
JS @@nx
@@lp: MOV EBX,DWORD PTR [EAX+ECX]
CMP EBX,DWORD PTR [EDX+ECX]
JNE @@zq
MOV EBX,DWORD PTR [EAX+ECX+4]
CMP EBX,DWORD PTR [EDX+ECX+4]
JNE @@zq
SUB ECX,8
JNS @@lp
@@nx: JMP DWORD PTR @@tV[ECX*4+32]
@@tV: DD @@eq,@@t1,@@t2,@@t3
DD @@t4,@@t5,@@t6,@@t7
@@t7: MOV BL,BYTE PTR [EAX+6]
XOR BL,BYTE PTR [EDX+6]
JNE @@zq
@@t6: MOV BL,BYTE PTR [EAX+5]
XOR BL,BYTE PTR [EDX+5]
JNE @@zq
@@t5: MOV BL,BYTE PTR [EAX+4]
XOR BL,BYTE PTR [EDX+4]
JNE @@zq
@@t4: MOV EBX,DWORD PTR [EAX]
CMP EBX,DWORD PTR [EDX]
JNE @@zq
@@eq: POP EBX
@@08: MOV EAX,1
RET
@@t3: MOV BL,BYTE PTR [EAX+2]
XOR BL,BYTE PTR [EDX+2]
JNE @@zq
@@t2: MOV BL,BYTE PTR [EAX+1]
XOR BL,BYTE PTR [EDX+1]
JNE @@zq
@@t1: MOV BL,BYTE PTR [EAX]
XOR BL,BYTE PTR [EDX]
JNE @@zq
POP EBX
MOV EAX,1
RET
@@zq: POP EBX
@@07: XOR EAX,EAX
end;

function G_SameStr(P1, P2: Pointer): Boolean;
asm
CMP EAX,EDX
JE @@08
TEST EAX,EAX
JE @@qt2
TEST EDX,EDX
JE @@qt1
MOV ECX,[EAX-4]
CMP ECX,[EDX-4]
JE @@01
@@qt1: XOR EAX,EAX
@@qt2: RET
@@01: PUSH EBX
SUB ECX,8
JS @@nx
@@lp: MOV EBX,DWORD PTR [EAX+ECX]
CMP EBX,DWORD PTR [EDX+ECX]
JNE @@zq
MOV EBX,DWORD PTR [EAX+ECX+4]
CMP EBX,DWORD PTR [EDX+ECX+4]
JNE @@zq
SUB ECX,8
JNS @@lp
@@nx: JMP DWORD PTR @@tV[ECX*4+32]
@@tV: DD @@eq,@@t1,@@t2,@@t3
DD @@t4,@@t5,@@t6,@@t7
@@t7: MOV BL,BYTE PTR [EAX+6]
XOR BL,BYTE PTR [EDX+6]
JNE @@zq
@@t6: MOV BL,BYTE PTR [EAX+5]
XOR BL,BYTE PTR [EDX+5]
JNE @@zq
@@t5: MOV BL,BYTE PTR [EAX+4]
XOR BL,BYTE PTR [EDX+4]
JNE @@zq
@@t4: MOV EBX,DWORD PTR [EAX]
CMP EBX,DWORD PTR [EDX]
JNE @@zq
@@eq: POP EBX
@@08: MOV EAX,1
RET
@@t3: MOV BL,BYTE PTR [EAX+2]
XOR BL,BYTE PTR [EDX+2]
JNE @@zq
@@t2: MOV BL,BYTE PTR [EAX+1]
XOR BL,BYTE PTR [EDX+1]
JNE @@zq
@@t1: MOV BL,BYTE PTR [EAX]
XOR BL,BYTE PTR [EDX]
JNE @@zq
POP EBX
MOV EAX,1
RET
@@zq: POP EBX
@@07: XOR EAX,EAX
end;

function G_SameText(const S1, S2: string): Boolean;
asm
CMP EAX,EDX
JE @@08
TEST EAX,EAX
JE @@09
TEST EDX,EDX
JE @@07
MOV ECX,[EAX-4]
CMP ECX,[EDX-4]
JE @@im
XOR EAX,EAX
RET
@@im: TEST ECX,ECX
JE @@07
PUSH ESI
PUSH EDI
MOV ESI,EAX
MOV EDI,EDX
@@00: DEC ECX
JS @@qt
@@01: MOVZX EAX,BYTE PTR [ESI+ECX]
MOVZX EDX,BYTE PTR [EDI+ECX]
CMP AL,DL
JE @@00
MOV AL,BYTE PTR [EAX+ToUpperChars]
XOR AL,BYTE PTR [EDX+ToUpperChars]
JE @@00
POP EDI
POP ESI
@@07: XOR EAX,EAX
@@09: RET
@@qt: POP EDI
POP ESI
@@08: MOV EAX,1
end;

function G_SameText(P1, P2: Pointer): Boolean;
asm
CMP EAX,EDX
JE @@08
TEST EAX,EAX
JE @@09
TEST EDX,EDX
JE @@07
MOV ECX,[EAX-4]
CMP ECX,[EDX-4]
JE @@im
XOR EAX,EAX
RET
@@im: TEST ECX,ECX
JE @@07
PUSH ESI
PUSH EDI
MOV ESI,EAX
MOV EDI,EDX
@@00: DEC ECX
JS @@qt
@@01: MOVZX EAX,BYTE PTR [ESI+ECX]
MOVZX EDX,BYTE PTR [EDI+ECX]
CMP AL,DL
JE @@00
MOV AL,BYTE PTR [EAX+ToUpperChars]
XOR AL,BYTE PTR [EDX+ToUpperChars]
JE @@00
POP EDI
POP ESI
@@07: XOR EAX,EAX
@@09: RET
@@qt: POP EDI
POP ESI
@@08: MOV EAX,1
end;

{ Поиск, замена и удаление подстрок и отдельных символов }

function G_CharPos(C: Char; const S: string; StartPos: Integer): Integer;
asm
TEST EDX,EDX
JE @@qt
PUSH EDI
MOV EDI,EDX
LEA EDX,[ECX-1]
MOV ECX,[EDI-4]
SUB ECX,EDX
JLE @@m1
PUSH EDI
ADD EDI,EDX
POP EDX
REPNE SCASB
JNE @@m1
MOV EAX,EDI
SUB EAX,EDX
POP EDI
RET
@@m1: POP EDI
@@qt: XOR EAX,EAX
end;

function G_CharPos(C: Char; P: Pointer; StartPos: Integer): Integer;
asm
TEST EDX,EDX
JE @@qt
PUSH EDI
MOV EDI,EDX
LEA EDX,[ECX-1]
MOV ECX,[EDI-4]
SUB ECX,EDX
JLE @@m1
PUSH EDI
ADD EDI,EDX
POP EDX
REPNE SCASB
JNE @@m1
MOV EAX,EDI
SUB EAX,EDX
POP EDI
RET
@@m1: POP EDI
@@qt: XOR EAX,EAX
end;

{$IFDEF USE_DYNAMIC_TABLES}

initialization
CharUpperBuff(@ToUpperChars,256);

{$ENDIF}

end.

Соседние файлы в папке utils