{
Lang – основной модуль для разработки программ и библиотек.
Copyright © 2016, 2019, 2022–2023 Малик Разработчик
Это свободная программа: вы можете перераспространять её и/или
изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она может быть полезна,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.
}
unit Lang;
{$MODE DELPHI}
{$ASMMODE INTEL}
interface
uses
Windows,
Classes;
{%region public }
type
boolean = System.Boolean;
wchar = System.WideChar;
float = System.Single;
double = System.Double;
real = System.Extended;
byte = System.Shortint;
short = System.Smallint;
int = System.Longint;
long = System.Int64;
boolean_Array1d = packed array of boolean;
wchar_Array1d = packed array of wchar;
float_Array1d = packed array of float;
double_Array1d = packed array of double;
real_Array1d = packed array of real;
byte_Array1d = packed array of byte;
short_Array1d = packed array of short;
int_Array1d = packed array of int;
long_Array1d = packed array of long;
AnsiString_Array1d = packed array of AnsiString;
UnicodeString_Array1d = packed array of UnicodeString;
boolean_Array2d = packed array of boolean_Array1d;
wchar_Array2d = packed array of wchar_Array1d;
float_Array2d = packed array of float_Array1d;
double_Array2d = packed array of double_Array1d;
real_Array2d = packed array of real_Array1d;
byte_Array2d = packed array of byte_Array1d;
short_Array2d = packed array of short_Array1d;
int_Array2d = packed array of int_Array1d;
long_Array2d = packed array of long_Array1d;
AnsiString_Array2d = packed array of AnsiString_Array1d;
UnicodeString_Array2d = packed array of UnicodeString_Array1d;
const
MAX_STRUCTURE_SIZE = int($01000000);
ROUND_TO_NEAREST = int(0);
ROUND_DOWN = int(1);
ROUND_UP = int(2);
ROUND_TOWARD_ZERO = int(3);
MAX_INT = int($7fffffff);
MIN_INT = int($80000000);
MAX_LONG = long($7fffffffffffffff);
MIN_LONG = long($8000000000000000);
PI = real(3.141592653589793238462);
E = real(2.718281828459045235360);
POS_INF = real(1.0 / 0.0);
NEG_INF = real(-1.0 / 0.0);
NAN = real(0.0 / 0.0);
INF = POS_INF;
DIRECTORY_SEPARATOR = '\';
LINE_ENDING = #13#10;
HEX_DIGITS = '0123456789abcdef';
type
ByteArray = packed array [0..(MAX_STRUCTURE_SIZE div sizeof(byte)) - 1] of byte;
ShortArray = packed array [0..(MAX_STRUCTURE_SIZE div sizeof(short)) - 1] of short;
IntArray = packed array [0..(MAX_STRUCTURE_SIZE div sizeof(int)) - 1] of int;
PByteArray = ^ByteArray;
PShortArray = ^ShortArray;
PIntArray = ^IntArray;
Pointer = System.Pointer;
GUID = System.TGUID;
const
INTERFACE_GUID = '{74C86B60-AC5B-4E8D-8ACD-29A50B5C1500}';
CLASS_GUID = '{74C86B60-AC5B-4E8D-8ACD-29A50B5C1501}';
RUNNABLE_GUID = '{74C86B60-AC5B-4E8D-8ACD-29A50B5C1502}';
type
_Interface = interface;
_Class = interface;
Runnable = interface;
_Object = class;
RefCountInterfacedObject = class;
ClassData = class;
Thread = class;
Exception = class;
RuntimeException = class;
NullPointerException = class;
IndexOutOfBoundsException = class;
ArrayIndexOutOfBoundsException = class;
IllegalArgumentException = class;
LongRecord = packed record
case int of
0: (value: long);
1: (lo: int;
hi: int);
end;
FloatRecord = packed record
case int of
0: (value: float);
1: (bits: int);
end;
DoubleRecord = packed record
case int of
0: (value: double);
1: (bits: long);
end;
RealRecord = packed record
case int of
0: (value: real);
1: (significand: long;
exponentAngSign: short);
end;
{$M+}
_Interface = interface(IUnknown) [INTERFACE_GUID]
function getInterface(const iid: GUID; out obj): boolean;
function getInterfaceWeak(const iid: GUID; out obj): boolean;
function getClass(): _Class;
function asObject(): TObject;
end;
{$M-}
_Class = interface(_Interface) [CLASS_GUID]
function isInheritedFrom(cls: _Class): boolean;
function isInstance(obj: TObject): boolean;
function getInstanceSize(): int;
function getSuperclass(): _Class;
function getName(): AnsiString;
function getSimpleName(): AnsiString;
function getClassType(): TClass;
end;
Runnable = interface(_Interface) [RUNNABLE_GUID]
procedure run();
end;
{$M+}
_Object = class(TObject, IUnknown, _Interface)
public
constructor create();
destructor destroy; override;
procedure afterConstruction(); override;
procedure beforeDestruction(); override;
procedure free();
{ IUnknown }
function queryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: GUID; out obj): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual;
function _addref(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual;
function _release(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual;
{ _Interface }
function getInterface(const iid: GUID; out obj): boolean;
function getInterfaceWeak(const iid: GUID; out obj): boolean;
function getClass(): _Class;
function asObject(): TObject;
public
class function asClass(): _Class;
end;
{$M-}
RefCountInterfacedObject = class(_Object)
strict private
refcount: int;
public
constructor create();
procedure afterConstruction(); override;
procedure beforeDestruction(); override;
function _addref(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; override; final;
function _release(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; override; final;
public
class function newInstance(): TObject; override;
end;
ClassData = class(RefCountInterfacedObject, _Class)
strict private
clsptr: TClass;
public
constructor create(clsptr: TClass);
function isInheritedFrom(cls: _Class): boolean;
function isInstance(obj: TObject): boolean;
function getInstanceSize(): int;
function getSuperclass(): _Class;
function getName(): AnsiString;
function getSimpleName(): AnsiString;
function getClassType(): TClass;
end;
Thread = class(_Object, Runnable)
private
freeOnTerminate: boolean;
target: Runnable;
inst: Classes.TThread;
name: AnsiString;
public
constructor create(target: Runnable; const name: AnsiString; freeOnTerminate: boolean);
procedure run(); virtual;
procedure start(); virtual;
function getName(): AnsiString; virtual;
end;
ThreadLock = class(_Object)
strict private
lock: Windows.CRITICAL_SECTION;
public
constructor create(); virtual;
destructor destroy; override;
procedure enter(); virtual;
procedure leave(); virtual;
end;
Exception = class(_Object)
strict private
fmessage: AnsiString;
public
constructor create(); overload;
constructor create(const message: AnsiString); overload;
function getMessage(): AnsiString; virtual;
end;
RuntimeException = class(Exception)
public
constructor create(); overload;
constructor create(const message: AnsiString); overload;
end;
NullPointerException = class(RuntimeException)
public
constructor create(); overload;
constructor create(const message: AnsiString); overload;
end;
IndexOutOfBoundsException = class(RuntimeException)
public
constructor create(); overload;
constructor create(const message: AnsiString); overload;
constructor create(index: int); overload;
end;
ArrayIndexOutOfBoundsException = class(IndexOutOfBoundsException)
public
constructor create(); overload;
constructor create(const message: AnsiString); overload;
constructor create(index: int); overload;
end;
IllegalArgumentException = class(RuntimeException)
public
constructor create(); overload;
constructor create(const message: AnsiString); overload;
end;
{%endregion}
{%region routine }
procedure startThread(target: Runnable); overload;
procedure startThread(target: Runnable; const name: AnsiString); overload;
procedure configureFPU();
procedure setRoundMode(mode: int);
function sar(value, bits: int): int;
function isNaN(value: real): boolean; inline;
function isInfinity(value: real): boolean; stdcall;
function byteSwap(value: int): int; overload;
function byteSwap(value: long): long; stdcall; overload;
function floatToIntBits(a: float): int; inline;
function intBitsToFloat(a: int): float; inline;
function doubleToLongBits(a: double): long; inline;
function longBitsToDouble(a: long): double; inline;
function extractSignificand(a: real): long; inline;
function extractExponentAndSign(a: real): int; inline;
function buildReal(exponentAndSign: int; significand: long): real; inline;
function buildLong(lo, hi: int): long; inline;
function cmpgReal(v1, v2: real): int; stdcall;
function cmplReal(v1, v2: real): int; stdcall;
function zeroExtend(value: int): long; inline;
function abs(x: int): int; inline; overload;
function abs(x: long): int; inline; overload;
function abs(x: real): real; inline; overload;
function min(a, b: int): int; inline; overload;
function min(a, b: long): long; inline; overload;
function max(a, b: int): int; inline; overload;
function max(a, b: long): long; inline; overload;
function mulLong(multiplier1, multiplier2: long): long; stdcall;
function divLong(divident, divisor: long; out remainder: long): long; stdcall;
function toInt(value: real): int; stdcall;
function toLong(value: real): long; stdcall;
function round(value: real): long; stdcall;
function arctan(y, x: real): real; stdcall;
function roundToInteger(value: real): real; stdcall;
function intPart(value: real): real; stdcall;
function fracPart(value: real): real; stdcall;
function sqrt(value: real): real; stdcall;
function sin(value: real): real; stdcall;
function cos(value: real): real; stdcall;
function pow2(value: real): real; stdcall;
function log2(value: real): real; stdcall;
function floor(value: real): real; stdcall;
function ceil(value: real): real; stdcall;
function pointerToInt(p: pointer): ptrint; inline;
function intToPointer(p: ptrint): pointer; inline;
function toFloat(value: real): float; stdcall;
function toDouble(value: real): double; stdcall;
function toReal(value: int): real; stdcall; overload;
function toReal(value: long): real; stdcall; overload;
function toReal(value: float): real; stdcall; overload;
function toReal(value: double): real; stdcall; overload;
function toDecString(value: real): AnsiString; overload;
function toDecString(value: long): AnsiString; overload;
function toHexString(value: long; digits: int): AnsiString;
function toUTF8String(const s: UnicodeString): AnsiString;
function toUTF16String(const s: AnsiString): UnicodeString;
function toUpperCase(const s: AnsiString): AnsiString; overload;
function toUpperCase(const s: UnicodeString): UnicodeString; overload;
function toLowerCase(const s: AnsiString): AnsiString; overload;
function toLowerCase(const s: UnicodeString): UnicodeString; overload;
function getCharCodes(const s: AnsiString): int_Array1d; overload;
function getCharCodes(const s: UnicodeString): int_Array1d; overload;
function extractString(const buf: byte_Array1d; offset, length: int): AnsiString;
function stringToByteArray(const s: AnsiString): byte_Array1d;
function startsWith(const prefix, s: AnsiString; position: int): boolean; overload;
function startsWith(const prefix, s: UnicodeString; position: int): boolean; overload;
function startsWith(const prefix, s: AnsiString): boolean; overload;
function startsWith(const prefix, s: UnicodeString): boolean; overload;
function endsWith(const suffix, s: AnsiString): boolean; overload;
function endsWith(const suffix, s: UnicodeString): boolean; overload;
function trim(const s: AnsiString): AnsiString; overload;
function trim(const s: UnicodeString): UnicodeString; overload;
function parseDecInt(const s: AnsiString; default: int): int;
function parseHexInt(const s: AnsiString; default: int): int;
function parseDecLong(const s: AnsiString; default: long): long;
function parseHexLong(const s: AnsiString; default: long): long;
function parseReal(const s: AnsiString; default: real): real;
function parseParams(): AnsiString_Array1d;
function boolean_Array1d_create(length: int): boolean_Array1d;
function wchar_Array1d_create(length: int): wchar_Array1d;
function float_Array1d_create(length: int): float_Array1d;
function double_Array1d_create(length: int): double_Array1d;
function real_Array1d_create(length: int): real_Array1d;
function byte_Array1d_create(length: int): byte_Array1d;
function short_Array1d_create(length: int): short_Array1d;
function int_Array1d_create(length: int): int_Array1d;
function long_Array1d_create(length: int): long_Array1d;
function String_Array1d_create(length: int): AnsiString_Array1d;
function UnicodeString_Array1d_create(length: int): UnicodeString_Array1d;
function boolean_Array2d_create(length: int): boolean_Array2d; overload;
function wchar_Array2d_create(length: int): wchar_Array2d; overload;
function float_Array2d_create(length: int): float_Array2d; overload;
function double_Array2d_create(length: int): double_Array2d; overload;
function real_Array2d_create(length: int): real_Array2d; overload;
function byte_Array2d_create(length: int): byte_Array2d; overload;
function short_Array2d_create(length: int): short_Array2d; overload;
function int_Array2d_create(length: int): int_Array2d; overload;
function long_Array2d_create(length: int): long_Array2d; overload;
function String_Array2d_create(length: int): AnsiString_Array2d; overload;
function UnicodeString_Array2d_create(length: int): UnicodeString_Array2d; overload;
function boolean_Array2d_create(length, sublength: int): boolean_Array2d; overload;
function wchar_Array2d_create(length, sublength: int): wchar_Array2d; overload;
function float_Array2d_create(length, sublength: int): float_Array2d; overload;
function double_Array2d_create(length, sublength: int): double_Array2d; overload;
function real_Array2d_create(length, sublength: int): real_Array2d; overload;
function byte_Array2d_create(length, sublength: int): byte_Array2d; overload;
function short_Array2d_create(length, sublength: int): short_Array2d; overload;
function int_Array2d_create(length, sublength: int): int_Array2d; overload;
function long_Array2d_create(length, sublength: int): long_Array2d; overload;
function String_Array2d_create(length, sublength: int): AnsiString_Array2d; overload;
function UnicodeString_Array2d_create(length, sublength: int): UnicodeString_Array2d; overload;
function String_create(length: int): AnsiString;
function UnicodeString_create(length: int): UnicodeString; overload;
function UnicodeString_create(const chars: wchar_Array1d): UnicodeString; overload;
function UnicodeString_create(const chars: wchar_Array1d; offset, length: int): UnicodeString; overload;
function toBooleanArray1d(const arr: array of boolean): boolean_Array1d;
function toWcharArray1d(const arr: array of wchar): wchar_Array1d;
function toFloatArray1d(const arr: array of float): float_Array1d;
function toDoubleArray1d(const arr: array of double): double_Array1d;
function toRealArray1d(const arr: array of real): real_Array1d;
function toByteArray1d(const arr: array of byte): byte_Array1d;
function toShortArray1d(const arr: array of short): short_Array1d;
function toIntArray1d(const arr: array of int): int_Array1d;
function toLongArray1d(const arr: array of long): long_Array1d;
function toStringArray1d(const arr: array of AnsiString): AnsiString_Array1d;
function toUnicodeStringArray1d(const arr: array of UnicodeString): UnicodeString_Array1d;
function toBooleanArray2d(const arr: array of boolean_Array1d): boolean_Array2d;
function toWcharArray2d(const arr: array of wchar_Array1d): wchar_Array2d;
function toFloatArray2d(const arr: array of float_Array1d): float_Array2d;
function toDoubleArray2d(const arr: array of double_Array1d): double_Array2d;
function toRealArray2d(const arr: array of real_Array1d): real_Array2d;
function toByteArray2d(const arr: array of byte_Array1d): byte_Array2d;
function toShortArray2d(const arr: array of short_Array1d): short_Array2d;
function toIntArray2d(const arr: array of int_Array1d): int_Array2d;
function toLongArray2d(const arr: array of long_Array1d): long_Array2d;
function toStringArray2d(const arr: array of AnsiString_Array1d): AnsiString_Array2d;
function toUnicodeStringArray2d(const arr: array of UnicodeString_Array1d): UnicodeString_Array2d;
procedure arraycopy(const src: boolean_Array1d; srcOffset: int; const dst: boolean_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: wchar_Array1d; srcOffset: int; const dst: wchar_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: float_Array1d; srcOffset: int; const dst: float_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: double_Array1d; srcOffset: int; const dst: double_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: real_Array1d; srcOffset: int; const dst: real_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: byte_Array1d; srcOffset: int; const dst: byte_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: short_Array1d; srcOffset: int; const dst: short_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: int_Array1d; srcOffset: int; const dst: int_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: long_Array1d; srcOffset: int; const dst: long_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: AnsiString_Array1d; srcOffset: int; const dst: AnsiString_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: UnicodeString_Array1d; srcOffset: int; const dst: UnicodeString_Array1d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: boolean_Array2d; srcOffset: int; const dst: boolean_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: wchar_Array2d; srcOffset: int; const dst: wchar_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: float_Array2d; srcOffset: int; const dst: float_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: double_Array2d; srcOffset: int; const dst: double_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: real_Array2d; srcOffset: int; const dst: real_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: byte_Array2d; srcOffset: int; const dst: byte_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: short_Array2d; srcOffset: int; const dst: short_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: int_Array2d; srcOffset: int; const dst: int_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: long_Array2d; srcOffset: int; const dst: long_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: AnsiString_Array2d; srcOffset: int; const dst: AnsiString_Array2d; dstOffset: int; length: int); overload;
procedure arraycopy(const src: UnicodeString_Array2d; srcOffset: int; const dst: UnicodeString_Array2d; dstOffset: int; length: int); overload;
{%endregion}
implementation
{%region private }
type
RunnableThread = class(TThread)
strict private
owner: Thread;
protected
procedure execute(); override;
public
constructor create(owner: Thread);
end;
{%endregion}
{%region routine }
function interlockedIncrement(target: Pointer): int; assembler; nostackframe;
asm
lea edx, [eax+$00]
mov eax, $01
lock xadd dword[edx+$00], eax
lea eax, [eax+$01]
end;
function interlockedDecrement(target: Pointer): int; assembler; nostackframe;
asm
lea edx, [eax+$00]
mov eax, -$01
lock xadd dword[edx+$00], eax
lea eax, [eax-$01]
end;
function pow10(value: real; power: int): real; stdcall;
type
RealArray = packed array [0..4] of Word;
const
tab0: array [0..31] of RealArray =
(
( $0000, $0000, $0000, $8000, $3fff ), ( $0000, $0000, $0000, $a000, $4002 ),
( $0000, $0000, $0000, $c800, $4005 ), ( $0000, $0000, $0000, $fa00, $4008 ),
( $0000, $0000, $0000, $9c40, $400c ), ( $0000, $0000, $0000, $c350, $400f ),
( $0000, $0000, $0000, $f424, $4012 ), ( $0000, $0000, $8000, $9896, $4016 ),
( $0000, $0000, $2000, $bebc, $4019 ), ( $0000, $0000, $2800, $ee6b, $401c ),
( $0000, $0000, $f900, $9502, $4020 ), ( $0000, $0000, $b740, $ba43, $4023 ),
( $0000, $0000, $a510, $e8d4, $4026 ), ( $0000, $0000, $e72a, $9184, $402a ),
( $0000, $8000, $20f4, $b5e6, $402d ), ( $0000, $a000, $a931, $e35f, $4030 ),
( $0000, $0400, $c9bf, $8e1b, $4034 ), ( $0000, $c500, $bc2e, $b1a2, $4037 ),
( $0000, $7640, $6b3a, $de0b, $403a ), ( $0000, $89e8, $2304, $8ac7, $403e ),
( $0000, $ac62, $ebc5, $ad78, $4041 ), ( $8000, $177a, $26b7, $d8d7, $4044 ),
( $9000, $6eac, $7832, $8786, $4048 ), ( $b400, $0a57, $163f, $a968, $404b ),
( $a100, $cced, $1bce, $d3c2, $404e ), ( $84a0, $4014, $5161, $8459, $4052 ),
( $a5c8, $9019, $a5b9, $a56f, $4055 ), ( $0f3a, $f420, $8f27, $cecb, $4058 ),
( $0984, $f894, $3978, $813f, $405c ), ( $0be5, $36b9, $07d7, $a18f, $405f ),
( $4edf, $0467, $c9cd, $c9f2, $4062 ), ( $2296, $4581, $7c40, $fc6f, $4065 )
);
tab1: array [0..15] of RealArray =
(
( $0000, $0000, $0000, $8000, $3fff ), ( $b59e, $2b70, $ada8, $9dc5, $4069 ),
( $a6d5, $ffcf, $1f49, $c278, $40d3 ), ( $14a3, $c59b, $ab16, $efb3, $413d ),
( $8ce0, $80e9, $47c9, $93ba, $41a8 ), ( $17aa, $7fe6, $a12b, $b616, $4212 ),
( $556b, $3927, $f78d, $e070, $427c ), ( $c930, $e33c, $96ff, $8a52, $42e7 ),
( $de8e, $9df9, $ebfb, $aa7e, $4351 ), ( $2f8c, $5c6a, $fc19, $d226, $43bb ),
( $e376, $f2cc, $2f29, $8184, $4426 ), ( $0ad2, $db90, $2700, $9fa4, $4490 ),
( $aa17, $aef8, $e310, $c4c5, $44fa ), ( $9c59, $e9b0, $9c07, $f28a, $4564 ),
( $f3d4, $ebf7, $4ae1, $957a, $45cf ), ( $a262, $0795, $d8dc, $b83e, $4639 )
);
tab2: array [0..9] of RealArray =
(
( $0000, $0000, $0000, $8000, $3fff ), ( $91c7, $a60e, $a0ae, $e319, $46a3 ),
( $0c17, $8175, $7586, $c976, $4d48 ), ( $a7e4, $3993, $353b, $b2b8, $53ed ),
( $5de5, $c53d, $3b5d, $9e8b, $5a92 ), ( $f0a6, $20a1, $54c0, $8ca5, $6137 ),
( $5a8b, $d88b, $5d25, $f989, $67db ), ( $f3f8, $bf27, $c8a2, $dd5d, $6e80 ),
( $979b, $8a20, $5202, $c460, $7525 ), ( $59f0, $6ed5, $1162, $ae35, $7bca )
);
{
расшифровка:
const
tab0: array [0..31] of real =
(
1e+0000, 1e+0001, 1e+0002, 1e+0003, 1e+0004, 1e+0005, 1e+0006, 1e+0007,
1e+0008, 1e+0009, 1e+0010, 1e+0011, 1e+0012, 1e+0013, 1e+0014, 1e+0015,
1e+0016, 1e+0017, 1e+0018, 1e+0019, 1e+0020, 1e+0021, 1e+0022, 1e+0023,
1e+0024, 1e+0025, 1e+0026, 1e+0027, 1e+0028, 1e+0029, 1e+0030, 1e+0031
);
tab1: array [0..15] of real =
(
1e+0000, 1e+0032, 1e+0064, 1e+0096, 1e+0128, 1e+0160, 1e+0192, 1e+0224,
1e+0256, 1e+0288, 1e+0320, 1e+0352, 1e+0384, 1e+0416, 1e+0448, 1e+0480
);
tab2: array [0..9] of real =
(
1e+0000, 1e+0512, 1e+1024, 1e+1536, 1e+2048,
1e+2560, 1e+3072, 1e+3584, 1e+4096, 1e+4608
);
}
var
pow0: int;
pow1: int;
pow2: int;
begin
result := value;
setRoundMode(ROUND_TO_NEAREST);
if power > 0 then begin
if power >= 5120 then begin
result := INF;
exit;
end;
pow0 := power and $1f;
pow1 := (power shr 5) and $0f;
pow2 := (power shr 9) and $0f;
result := result * real(tab0[pow0]) * real(tab1[pow1]) * real(tab2[pow2]);
end else
if power < 0 then begin
power := -power;
if power >= 5120 then begin
result := 0;
exit;
end;
pow0 := power and $1f;
pow1 := (power shr 5) and $0f;
pow2 := (power shr 9) and $0f;
result := result / real(tab0[pow0]) / real(tab1[pow1]) / real(tab2[pow2]);
end;
end;
procedure startThread(target: Runnable);
begin
(Thread.create(target, 'Безымянный поток', true)).start();
end;
procedure startThread(target: Runnable; const name: AnsiString);
begin
(Thread.create(target, name, true)).start();
end;
procedure configureFPU(); assembler; nostackframe;
asm
lea esp, [esp-$04]
fnstcw word [esp+$00]
or dword[esp+$00], $0000003f
and dword[esp+$00], $0000f3ff
fnclex
fldcw word [esp+$00]
lea esp, [esp+$04]
end;
procedure setRoundMode(mode: int); assembler; nostackframe;
asm
lea esp, [esp-$04]
fnstcw word [esp+$00]
and dword[esp+$00], $0000f3ff
and eax, $03
shl eax, $0a
or dword[esp+$00], eax
fclex
fldcw word [esp+$00]
lea esp, [esp+$04]
end;
function sar(value, bits: int): int; assembler; nostackframe;
asm
mov cl, dl
sar eax, cl
end;
function isNaN(value: real): boolean; inline;
begin
result := cmplReal(value, value) <> 0;
end;
function isInfinity(value: real): boolean; stdcall; assembler; nostackframe;
asm
fld tbyte[value]
fxam
fnstsw ax
ffree st
fincstp
sahf
jz @0
jnp @0
jnc @0
mov eax, true
ret $0c
@0: mov eax, false
end;
function byteSwap(value: int): int; assembler; nostackframe;
asm
bswap eax
end;
function byteSwap(value: long): long; stdcall; assembler; nostackframe;
asm
mov eax, dword[value+$04]
mov edx, dword[value+$00]
bswap eax
bswap edx
end;
function floatToIntBits(a: float): int; inline;
begin
result := FloatRecord(a).bits;
end;
function intBitsToFloat(a: int): float; inline;
begin
result := FloatRecord(a).value;
end;
function doubleToLongBits(a: double): long; inline;
begin
result := DoubleRecord(a).bits;
end;
function longBitsToDouble(a: long): double; inline;
begin
result := DoubleRecord(a).value;
end;
function extractSignificand(a: real): long; inline;
begin
result := RealRecord(a).significand;
end;
function extractExponentAndSign(a: real): int; inline;
begin
result := RealRecord(a).exponentAngSign and $ffff;
end;
function buildReal(exponentAndSign: int; significand: long): real; inline;
var
r: RealRecord absolute result;
begin
result := 0;
r.exponentAngSign := short(exponentAndSign);
r.significand := significand;
end;
function buildLong(lo, hi: int): long; inline;
var
r: LongRecord;
begin
r.lo := lo;
r.hi := hi;
result := r.value;
end;
function cmpgReal(v1, v2: real): int; stdcall; assembler; nostackframe;
asm
fld tbyte[v2]
fld tbyte[v1]
fcompp
fnstsw ax
sahf
jp @gt
ja @gt
je @eq
mov eax, -$01
ret $18
@eq: xor eax, eax
ret $18
@gt: mov eax, $01
end;
function cmplReal(v1, v2: real): int; stdcall; assembler; nostackframe;
asm
fld tbyte[v2]
fld tbyte[v1]
fcompp
fnstsw ax
sahf
jp @lt
ja @gt
je @eq
@lt: mov eax, -$01
ret $18
@eq: xor eax, eax
ret $18
@gt: mov eax, $01
end;
function zeroExtend(value: int): long; inline;
begin
result := long(value) and long($00000000ffffffff);
end;
function abs(x: int): int; inline;
begin
if x >= 0 then begin
result := x;
end else begin
result := -x;
end;
end;
function abs(x: long): int; inline;
begin
if x >= 0 then begin
result := x;
end else begin
result := -x;
end;
end;
function abs(x: real): real; inline;
begin
if cmpgReal(x, 0.0) >= 0 then begin
result := x;
end else begin
result := -x;
end;
end;
function min(a, b: int): int; inline;
begin
if a <= b then begin
result := a;
end else begin
result := b;
end;
end;
function min(a, b: long): long; inline;
begin
if a <= b then begin
result := a;
end else begin
result := b;
end;
end;
function max(a, b: int): int; inline;
begin
if a >= b then begin
result := a;
end else begin
result := b;
end;
end;
function max(a, b: long): long; inline;
begin
if a >= b then begin
result := a;
end else begin
result := b;
end;
end;
function mulLong(multiplier1, multiplier2: long): long; stdcall; assembler; nostackframe;
asm
mov eax, [multiplier2+$04]
mul dword[multiplier1+$00]
lea ecx, [eax+$00]
mov eax, [multiplier1+$04]
mul dword[multiplier2+$00]
lea ecx, [eax+ecx]
mov eax, [multiplier1+$00]
mul dword[multiplier2+$00]
lea edx, [ecx+edx]
end;
function divLong(divident, divisor: long; out remainder: long): long; stdcall; assembler; nostackframe;
asm
push ebx
mov ebx, [divisor+$04]
mov ecx, [divisor+$08]
mov eax, [divident+$04]
mov edx, [divident+$08]
{ знак делителя }
test ecx, $80000000
jnz @3
push dword $00
jmp @4
@3: push dword $01
neg ebx
adc ecx, $00
neg ecx
{ знак делимого }
@4: test edx, $80000000
jnz @5
push dword $00
jmp @6
@5: push dword $01
neg eax
adc edx, $00
neg edx
{ подготовка к делению }
@6: push esi
push edi
push ebp
lea ebp, [ecx+$00]
xor esi, esi
xor edi, edi
mov ecx, $40
{ деление }
{ edx:eax = делимое -> частное }
{ ebp:ebx = делитель }
{ edi:esi = 0 -> остаток }
@0: shl eax, $01
rcl edx, $01
rcl esi, $01
rcl edi, $01
cmp edi, ebp
jb @2
ja @1
cmp esi, ebx
jb @2
@1: sub esi, ebx
sbb edi, ebp
lea eax, [eax+$01]
@2: loop @0
{ знак остатка }
pop ebp
test byte [esp+$08], $01
jz @7
neg esi
adc edi, $00
neg edi
test byte [esp+$0c], $01
jnz @7
neg eax
adc edx, $00
neg edx
jmp @8
{ знак частного }
@7: test byte [esp+$08], $01
jnz @8
test byte [esp+$0c], $01
jz @8
neg eax
adc edx, $00
neg edx
{ запись остатка }
@8: mov ebx, [remainder+$14]
mov dword[ebx+$00], esi
mov dword[ebx+$04], edi
{ выход из функции }
pop edi
pop esi
lea esp, [esp+$08]
pop ebx
end;
function toInt(value: real): int; stdcall; assembler; nostackframe;
asm
fld tbyte[value]
fxam
fnstsw ax
ffree st
fincstp
sahf
jz @0
jp @0
jnc @0
xor eax, eax
ret $0c
@0: lea esp, [esp-$04]
mov dword[esp+$00], MAX_INT
fild dword[esp+$00]
lea esp, [esp+$04]
fld tbyte[value]
fcompp
fnstsw ax
sahf
jbe @1
mov eax, MAX_INT
ret $0c
@1: mov eax, ROUND_TOWARD_ZERO
call setRoundMode
fld tbyte[value]
lea esp, [esp-$04]
fistp dword[esp+$00]
pop eax
end;
function toLong(value: real): long; stdcall; assembler; nostackframe;
asm
fld tbyte[value]
fxam
fnstsw ax
ffree st
fincstp
sahf
jz @0
jp @0
jnc @0
xor eax, eax
xor edx, edx
ret $0c
@0: lea esp, [esp-$08]
mov dword[esp+$00], $ffffffff
mov dword[esp+$04], $7fffffff
fild qword[esp+$00]
lea esp, [esp+$08]
fld tbyte[value]
fcompp
fnstsw ax
sahf
jbe @1
mov eax, $ffffffff
mov edx, $7fffffff
ret $0c
@1: mov eax, ROUND_TOWARD_ZERO
call setRoundMode
fld tbyte[value]
lea esp, [esp-$08]
fistp qword[esp+$00]
pop eax
pop edx
end;
function round(value: real): long; stdcall; assembler; nostackframe;
asm
fld tbyte[value]
fxam
fnstsw ax
ffree st
fincstp
sahf
jz @0
jp @0
jnc @0
xor eax, eax
xor edx, edx
ret $0c
@0: lea esp, [esp-$08]
mov dword[esp+$00], $ffffffff
mov dword[esp+$04], $7fffffff
fild qword[esp+$00]
lea esp, [esp+$08]
fld tbyte[value]
fcompp
fnstsw ax
sahf
jbe @1
mov eax, $ffffffff
mov edx, $7fffffff
ret $0c
@1: mov eax, ROUND_TO_NEAREST
call setRoundMode
fld tbyte[value]
lea esp, [esp-$08]
fistp qword[esp+$00]
pop eax
pop edx
end;
function arctan(y, x: real): real; stdcall; assembler; nostackframe;
asm
fld tbyte[y]
fld tbyte[x]
fpatan
end;
function roundToInteger(value: real): real; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_TO_NEAREST
call setRoundMode
fld tbyte[value]
frndint
end;
function intPart(value: real): real; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_TOWARD_ZERO
call setRoundMode
fld tbyte[value]
frndint
end;
function fracPart(value: real): real; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_TOWARD_ZERO
call setRoundMode
fld tbyte[value]
fld st
frndint
fsubp st(1), st
end;
function sqrt(value: real): real; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_TO_NEAREST
call setRoundMode
fld tbyte[value]
fsqrt
end;
function sin(value: real): real; stdcall; assembler; nostackframe;
asm
fld tbyte[value]
fxam
fnstsw ax
ffree st
fincstp
sahf
jz @0
jc @3
@0: mov eax, ROUND_TO_NEAREST
call setRoundMode
fld tbyte[value]
fsin
fnstsw ax
sahf
jp @1
ret $0c
@1: ffree st
fincstp
lea esp, [esp-$0c]
mov dword[esp+$00], $2168c235
mov dword[esp+$04], $c90fdaa2
mov dword[esp+$08], $00004001
fld tbyte[esp+$00]
lea esp, [esp+$0c]
fld tbyte[value]
@2: fprem
fstsw ax
test ax, $0400
jnz @2
fstp st(1)
fsin
ret $0c
@3: lea esp, [esp-$0c]
mov dword[esp+$00], $00000000
mov dword[esp+$04], $c0000000
mov dword[esp+$08], $00007fff
fld tbyte[esp+$00]
lea esp, [esp+$0c]
end;
function cos(value: real): real; stdcall; assembler; nostackframe;
asm
fld tbyte[value]
fxam
fnstsw ax
ffree st
fincstp
sahf
jz @0
jc @3
@0: mov eax, ROUND_TO_NEAREST
call setRoundMode
fld tbyte[value]
fcos
fnstsw ax
sahf
jp @1
ret $0c
@1: ffree st
fincstp
lea esp, [esp-$0c]
mov dword[esp+$00], $2168c235
mov dword[esp+$04], $c90fdaa2
mov dword[esp+$08], $00004001
fld tbyte[esp+$00]
lea esp, [esp+$0c]
fld tbyte[value]
@2: fprem
fstsw ax
test ax, $0400
jnz @2
fstp st(1)
fcos
ret $0c
@3: lea esp, [esp-$0c]
mov dword[esp+$00], $00000000
mov dword[esp+$04], $c0000000
mov dword[esp+$08], $00007fff
fld tbyte[esp+$00]
lea esp, [esp+$0c]
end;
function pow2(value: real): real; stdcall; assembler; nostackframe;
asm
fld tbyte[value]
fxam
fnstsw ax
sahf
jz @1
jnp @1
jnc @1
ffree st
fincstp
test ah, $02
jz @0
push dword $00000000
fild dword[esp+$00]
lea esp, [esp+$04]
ret $0c
@0: lea esp, [esp-$0c]
mov dword[esp+$00], $00000000
mov dword[esp+$04], $80000000
mov dword[esp+$08], $00007fff
fld tbyte[esp+$00]
lea esp, [esp+$0c]
ret $0c
@1: mov eax, ROUND_TOWARD_ZERO
call setRoundMode
fld st
frndint
mov eax, ROUND_TO_NEAREST
call setRoundMode
fsubp st(1), st
f2xm1
fld1
faddp st(1), st
fld tbyte[value]
fld1
fscale
fmulp st(2), st
ffree st
fincstp
end;
function log2(value: real): real; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_TO_NEAREST
call setRoundMode
fld1
fld tbyte[value]
fyl2x
end;
function floor(value: real): real; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_DOWN
call setRoundMode
fld tbyte[value]
frndint
end;
function ceil(value: real): real; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_UP
call setRoundMode
fld tbyte[value]
frndint
end;
{$WARNINGS OFF}
{$HINTS OFF}
function pointerToInt(p: Pointer): PtrInt; inline;
begin
result := PtrInt(p);
end;
function intToPointer(p: PtrInt): Pointer; inline;
begin
result := Pointer(p);
end;
{$WARNINGS ON}
{$HINTS ON}
function toFloat(value: real): float; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_TO_NEAREST
call setRoundMode
fld tbyte[value]
lea esp, [esp-$04]
fstp dword[esp+$00]
fld dword[esp+$00]
lea esp, [esp+$04]
end;
function toDouble(value: real): double; stdcall; assembler; nostackframe;
asm
mov eax, ROUND_TO_NEAREST
call setRoundMode
fld tbyte[value]
lea esp, [esp-$08]
fstp qword[esp+$00]
fld qword[esp+$00]
lea esp, [esp+$08]
end;
function toReal(value: int): real; stdcall; assembler; nostackframe;
asm
fild dword[value]
end;
function toReal(value: long): real; stdcall; assembler; nostackframe;
asm
fild qword[value]
end;
function toReal(value: float): real; stdcall; assembler; nostackframe;
asm
fld dword[value]
end;
function toReal(value: double): real; stdcall; assembler; nostackframe;
asm
fld qword[value]
end;
function toDecString(value: real): AnsiString;
const
digits = '0123456789';
var
buf: packed array [0..31] of char;
i: int;
len: int;
order: int;
dotpos: int;
rem: long;
intval: long;
expform: boolean;
begin
if isNaN(value) then begin
result := 'NaN';
exit;
end;
if cmplReal(value, POS_INF) = 0 then begin
result := '+Inf';
exit;
end;
if cmplReal(value, NEG_INF) = 0 then begin
result := '-Inf';
exit;
end;
initialize(buf);
fillChar(buf, sizeof(buf), '0');
len := 0;
if int(RealRecord(value).exponentAngSign) < 0 then begin
buf[len] := '-';
inc(len);
value := -value;
end;
if cmplReal(value, 0.0) <> 0 then begin
order := toInt(3.010299956639811952e-0001 * log2(value)); { order = lg(value) }
expform := (value < 1.e-0006) or (value >= 1.e+0018);
if expform then begin
{ (value < 1.e-0006) or (value >= 1.e+0018) }
if order < 0 then begin
dec(order);
end;
intval := round(pow10(value, 17 - order));
if intval < 100000000000000000 then begin
intval := mulLong(intval, 10);
dec(order);
end;
if intval > 999999999999999999 then begin
intval := divLong(intval, 10, rem);
inc(order);
end;
dotpos := len + 1;
end else
if value < 1.e+0000 then begin
{ (value >= 1.e-0006) and (value < 1.e+0000) }
intval := round(pow10(value, 17));
dotpos := len + 1;
end else
if value < 1.e+0017 then begin
{ (value >= 1.e+0000) and (value < 1.e+0017) }
intval := round(pow10(value, 17 - order));
if intval <= 99999999999999999 then begin
intval := mulLong(intval, 10);
dec(order);
end;
if intval > 999999999999999999 then begin
intval := divLong(intval, 10, rem);
inc(order);
end;
dotpos := len + order + 1;
end else begin
{ (value >= 1.e+0017) and (value < 1.e+0018) }
intval := round(value);
if intval > 999999999999999999 then begin
intval := 999999999999999999;
end;
dotpos := len + 18;
end;
buf[dotpos] := '.';
for i := len + 17 downto len do begin
intval := divLong(intval, 10, rem);
buf[i + byte(i >= dotpos)] := digits[int(rem) + 1];
end;
inc(len, 20);
while buf[len - 1] in ['0', '.'] do begin
dec(len);
if buf[len] = '.' then begin
break;
end;
end;
if expform then begin
buf[len] := 'E';
if order < 0 then begin
buf[len + 1] := '-';
order := -order;
end else begin
buf[len + 1] := '+';
end;
buf[len + 2] := digits[((order div 1000) mod 10) + 1];
buf[len + 3] := digits[((order div 100) mod 10) + 1];
buf[len + 4] := digits[((order div 10) mod 10) + 1];
buf[len + 5] := digits[(order mod 10) + 1];
inc(len, 6);
end;
end else begin
inc(len);
end;
result := String_create(len);
move(buf[0], result[1], len);
end;
function toDecString(value: long): AnsiString;
const
BASE = 10;
MIN_VALUE_STRING = '-9223372036854775808';
DEC_DIGITS = '0123456789';
MINUS = '-';
var
sign: boolean;
begin
if value = MIN_LONG then begin
result := MIN_VALUE_STRING;
exit;
end;
result := '';
if value < 0 then begin
value := -value;
sign := true;
end else begin
sign := false;
end;
repeat
result := DEC_DIGITS[byte(value mod BASE) + 1] + result;
value := value div BASE;
until value = 0;
if sign then begin
result := MINUS + result;
end;
end;
function toHexString(value: long; digits: int): AnsiString;
const
MASK = long($0fffffffffffffff);
begin
if digits <= 0 then begin
digits := 1;
end;
result := '';
repeat
result := HEX_DIGITS[byte(value and $f) + 1] + result;
value := (value shr 4) and MASK;
dec(digits);
until (value = 0) and (digits <= 0);
end;
function toUTF8String(const s: UnicodeString): AnsiString;
var
buf: PChar;
cap: int;
idx: int;
procedure appendStr(const s: AnsiString);
var
l: int;
begin
l := length(s);
if idx > cap - l then begin
inc(cap, (l + $7fff) and (-$8000));
buf := reallocMemory(buf, cap);
end;
move(s[1], buf[idx], l);
inc(idx, l);
end;
var
i: int;
c: int;
c1: int;
uchr: AnsiString;
begin
buf := nil;
cap := 0;
idx := 0;
i := 1;
while i <= length(s) do begin
c := int(s[i]) and $ffff;
inc(i);
if (i <= length(s)) and (c >= $d800) and (c < $dc00) then begin
c1 := int(s[i]) and $ffff;
if (c1 >= $dc00) and (c1 < $e000) then begin
c := ((c and $03ff) shl $0a) + (c1 and $03ff) + $00010000;
inc(i);
end;
end;
case c of
$00000000..$0000007f:
uchr := char(c);
$00000080..$000007ff:
uchr := char($c0 + ((c shr $06) and $1f)) + char($80 + (c and $3f));
$00000800..$0000ffff:
uchr := char($e0 + ((c shr $0c) and $0f)) + char($80 + ((c shr $06) and $3f)) + char($80 + (c and $3f));
else
uchr := char($f0 + ((c shr $12) and $07)) + char($80 + ((c shr $0c) and $3f)) + char($80 + ((c shr $06) and $3f)) + char($80 + (c and $3f));
end;
appendStr(uchr);
end;
result := String_create(idx);
move(buf[0], result[1], idx);
freeMemory(buf);
end;
function toUTF16String(const s: AnsiString): UnicodeString;
var
buf: PWideChar;
cap: int;
idx: int;
procedure appendChar(c: int);
begin
if idx >= cap - 1 then begin
inc(cap, $8000);
buf := reallocMemory(buf, sizeof(wchar) * cap);
end;
if c < $00010000 then begin
buf[idx] := wchar(c);
inc(idx);
end else begin
dec(c, $00010000);
buf[idx] := wchar($d800 + ((c shr $0a) and $ffff));
buf[idx + 1] := wchar($dc00 + (c and $03ff));
inc(idx, 2);
end;
end;
var
i: int;
c: int;
uchr: int;
shift: int;
begin
buf := nil;
cap := 0;
idx := 0;
uchr := 0;
shift := -1;
for i := 1 to length(s) do begin
c := int(s[i]) and $ff;
case c of
$00..$7f: begin
if shift >= 0 then begin
appendChar(uchr);
end;
appendChar(c);
end;
$80..$bf: begin
uchr := uchr + ((c and $3f) shl shift);
dec(shift, $06);
if shift < 0 then begin
appendChar(uchr);
end;
end;
$c0..$df: begin
if shift >= 0 then begin
appendChar(uchr);
end;
uchr := (c and $1f) shl $06;
shift := $00;
end;
$e0..$ef: begin
if shift >= 0 then begin
appendChar(uchr);
end;
uchr := (c and $0f) shl $0c;
shift := $06;
end;
else
if shift >= 0 then begin
appendChar(uchr);
end;
uchr := (c and $07) shl $12;
shift := $0c;
end;
end;
result := UnicodeString_create(idx);
move(buf[0], result[1], sizeof(wchar) * idx);
freeMemory(buf);
end;
function toUpperCase(const s: AnsiString): AnsiString;
var
l: int;
i: int;
c: char;
begin
l := length(s);
result := copy(s, 1, l);
for i := 1 to l do begin
c := result[i];
if (c >= 'a') and (c <= 'z') then begin
result[i] := char(int(c) - 32);
end;
end;
end;
function toUpperCase(const s: UnicodeString): UnicodeString;
var
l: int;
i: int;
c: wchar;
begin
l := length(s);
result := copy(s, 1, l);
for i := 1 to l do begin
c := result[i];
if (c >= 'a') and (c <= 'z') then begin
result[i] := wchar(int(c) - 32);
end;
end;
end;
function toLowerCase(const s: AnsiString): AnsiString;
var
l: int;
i: int;
c: Char;
begin
l := length(s);
result := copy(s, 1, l);
for i := 1 to l do begin
c := result[i];
if (c >= 'A') and (c <= 'Z') then begin
result[i] := char(int(c) + 32);
end;
end;
end;
function toLowerCase(const s: UnicodeString): UnicodeString;
var
l: int;
i: int;
c: wchar;
begin
l := length(s);
result := copy(s, 1, l);
for i := 1 to l do begin
c := result[i];
if (c >= 'A') and (c <= 'Z') then begin
result[i] := wchar(int(c) + 32);
end;
end;
end;
function getCharCodes(const s: AnsiString): int_Array1d;
begin
result := getCharCodes(toUTF16String(s));
end;
function getCharCodes(const s: UnicodeString): int_Array1d;
var
i: int;
j: int;
c: int;
w: int;
w1: int;
begin
c := 0;
i := 1;
while i <= length(s) do begin
w := int(s[i]) and $ffff;
inc(i);
inc(c);
if (i <= length(s)) and (w >= $d800) and (w < $dc00) then begin
w1 := int(s[i]) and $ffff;
if (w1 >= $dc00) and (w1 < $e000) then begin
inc(i);
end;
end;
end;
result := int_Array1d_create(c);
i := 1;
j := 0;
while i <= length(s) do begin
w := int(s[i]) and $ffff;
inc(i);
if (i <= length(s)) and (w >= $d800) and (w < $dc00) then begin
w1 := int(s[i]) and $ffff;
if (w1 >= $dc00) and (w1 < $e000) then begin
result[j] := ((w and $03ff) shl $0a) + (w1 and $03ff) + $00010000;
inc(i);
end else begin
result[j] := w;
end;
end else begin
result[j] := w;
end;
inc(j);
end;
end;
function extractString(const buf: byte_Array1d; offset, length: int): AnsiString;
var
lim: int;
len: int;
begin
lim := offset + length;
len := System.length(buf);
if (lim > len) or (lim < offset) or (offset < 0) or (offset > len) then begin
raise ArrayIndexOutOfBoundsException.create('extractString: индекс элемента массива выходит из диапазона.');
end;
result := String_create(length);
move(buf[offset], result[1], length);
end;
function stringToByteArray(const s: AnsiString): byte_Array1d;
var
l: int;
begin
l := length(s);
result := byte_Array1d_create(l);
move(s[1], result[0], l);
end;
function startsWith(const prefix, s: AnsiString; position: int): boolean;
begin
result := (position >= 1) and (position <= length(s) - length(prefix) + 1) and (copy(s, position, length(prefix)) = prefix);
end;
function startsWith(const prefix, s: UnicodeString; position: int): boolean;
begin
result := (position >= 1) and (position <= length(s) - length(prefix) + 1) and (copy(s, position, length(prefix)) = prefix);
end;
function startsWith(const prefix, s: AnsiString): boolean;
begin
result := startsWith(prefix, s, 1);
end;
function startsWith(const prefix, s: UnicodeString): boolean;
begin
result := startsWith(prefix, s, 1);
end;
function endsWith(const suffix, s: AnsiString): boolean;
begin
result := startsWith(suffix, s, length(s) - length(suffix) + 1);
end;
function endsWith(const suffix, s: UnicodeString): boolean;
begin
result := startsWith(suffix, s, length(s) - length(suffix) + 1);
end;
function trim(const s: AnsiString): AnsiString;
var
b: int;
e: int;
l: int;
begin
l := length(s);
b := 1;
while (b <= l) and (s[b] <= #32) do begin
inc(b);
end;
e := l;
while (e >= b) and (s[e] <= #32) do begin
dec(e);
end;
result := copy(s, b, e - b + 1);
end;
function trim(const s: UnicodeString): UnicodeString;
var
b: int;
e: int;
l: int;
begin
l := length(s);
b := 1;
while (b <= l) and (s[b] <= #32) do begin
inc(b);
end;
e := l;
while (e >= b) and (s[e] <= #32) do begin
dec(e);
end;
result := copy(s, b, e - b + 1);
end;
function parseDecInt(const s: AnsiString; default: int): int;
var
n: boolean;
i: int;
c: int;
begin
if length(s) <= 0 then begin
result := default;
exit;
end;
result := 0;
n := s[1] = '-';
for i := 1 to length(s) do begin
c := int(s[i]);
case char(c) of
'0'..'9': begin
result := (result * 10) + (c - int('0'));
end;
'-': begin
if i > 1 then begin
result := default;
exit;
end;
end;
else
result := default;
exit;
end;
end;
if n then begin
result := -result;
end;
end;
function parseHexInt(const s: AnsiString; default: int): int;
var
i: int;
c: int;
l: int;
begin
l := length(s);
if l = 0 then begin
result := default;
exit;
end;
result := 0;
for i := 1 to l do begin
c := int(s[i]);
case char(c) of
'0'..'9': begin
result := (result shl 4) + (c - int('0'));
end;
'A'..'F': begin
result := (result shl 4) + (c - int('A') + 10);
end;
'a'..'f': begin
result := (result shl 4) + (c - int('a') + 10);
end;
else
result := default;
exit;
end;
end;
end;
function parseDecLong(const s: AnsiString; default: long): long;
var
n: boolean;
i: int;
c: int;
begin
result := 0;
n := (length(s) > 0) and (s[1] = '-');
for i := 1 to length(s) do begin
c := int(s[i]);
case char(c) of
'0'..'9': begin
result := mulLong(result, 10) + (long(c) - long('0'));
end;
'-': begin
if i > 1 then begin
result := default;
exit;
end;
end;
else
result := default;
exit;
end;
end;
if n then begin
result := -result;
end;
end;
function parseHexLong(const s: AnsiString; default: long): long;
var
i: int;
c: int;
l: int;
begin
l := length(s);
if l = 0 then begin
result := default;
exit;
end;
result := 0;
for i := 1 to l do begin
c := int(s[i]);
case char(c) of
'0'..'9': begin
result := (result shl 4) + (long(c) - long('0'));
end;
'A'..'F': begin
result := (result shl 4) + (long(c) - long('A') + 10);
end;
'a'..'f': begin
result := (result shl 4) + (long(c) - long('a') + 10);
end;
else
result := default;
exit;
end;
end;
end;
function parseReal(const s: AnsiString; default: real): real;
var
error: boolean;
negative: boolean;
c: System.Char;
pos: int;
order: int;
fracLength: int;
text: PChar;
lc: AnsiString;
begin
if length(s) = 0 then begin
result := default;
exit;
end;
lc := toLowerCase(s);
if (lc = '+inf') or (lc = 'inf') then begin
result := POS_INF;
exit;
end;
if lc = '-inf' then begin
result := NEG_INF;
exit;
end;
if lc = 'nan' then begin
result := NAN;
exit;
end;
result := 0;
error := false;
negative := false;
pos := 0;
fracLength := 0;
order := 0;
text := PChar(s);
case text[0] of
'+', ' ': begin
inc(pos);
end;
'-': begin
negative := true;
inc(pos);
end;
end;
c := text[pos];
while (c >= '0') and (c <= '9') do begin
result := (10.0 * result) + toReal(int(c) - int('0'));
inc(pos);
c := text[pos];
end;
if c = '.' then begin
inc(pos);
c := text[pos];
while (c >= '0') and (c <= '9') do begin
result := (10.0 * result) + toReal(int(c) - int('0'));
inc(fracLength);
inc(pos);
c := text[pos];
end;
end;
if negative then begin
result := -result;
negative := false;
end;
c := text[pos];
if c in ['E', 'e'] then begin
inc(pos);
case text[pos] of
'+': begin
inc(pos);
end;
'-': begin
negative := true;
inc(pos);
end;
end;
c := text[pos];
if (c >= '0') and (c <= '9') then begin
repeat
order := (10 * order) + (int(c) - int('0'));
if order > 9999 then begin
error := true;
break;
end;
inc(pos);
c := text[pos];
until (c < '0') or (c > '9');
end else begin
error := true;
end;
end;
if text[pos] <> #0 then begin
error := true;
end;
if not error then begin
if negative then begin
order := -order;
end;
result := pow10(result, order - fracLength);
if isInfinity(result) then begin
error := true;
end;
end;
if error then begin
result := default;
end;
end;
function parseParams(): AnsiString_Array1d;
const
SPACE = #32;
QUOTE = '"';
var
s: UnicodeString;
r: AnsiString;
i: int;
c: int;
l: int;
b: int;
f: boolean;
begin
s := UnicodeString(Windows.getCommandLineW());
c := 0;
l := length(s);
f := false;
for i := 1 to l do begin
if s[i] = QUOTE then begin
f := not f;
end;
if (not f) and (i > 1) and (s[i - 1] > SPACE) and (s[i] = SPACE) then begin
inc(c);
end;
end;
if (l > 0) and (s[l] > SPACE) then begin
inc(c);
end;
result := String_Array1d_create(c);
c := 0;
b := 1;
f := false;
for i := 1 to l do begin
if (not f) and (s[i] > SPACE) and (((i > 1) and (s[i - 1] = SPACE)) or (i = 1)) then begin
b := i;
end;
if s[i] = QUOTE then begin
f := not f;
end;
if (not f) and (s[i] > SPACE) and (((i < l) and (s[i + 1] = SPACE)) or (i = l)) then begin
if s[i] = QUOTE then begin
result[c] := toUTF8String(copy(s, b + 1, i - b - 1));
end else begin
result[c] := toUTF8String(copy(s, b, i - b + 1));
end;
inc(c);
end;
end;
if length(result) > 0 then begin
r := result[0];
for i := length(r) downto 1 do begin
if r[i] = '/' then begin
r[i] := DIRECTORY_SEPARATOR;
end;
end;
result[0] := r;
end;
end;
function boolean_Array1d_create(length: int): boolean_Array1d;
begin
setLength(result, length);
end;
function wchar_Array1d_create(length: int): wchar_Array1d;
begin
setLength(result, length);
end;
function float_Array1d_create(length: int): float_Array1d;
begin
setLength(result, length);
end;
function double_Array1d_create(length: int): double_Array1d;
begin
setLength(result, length);
end;
function real_Array1d_create(length: int): real_Array1d;
begin
setLength(result, length);
end;
function byte_Array1d_create(length: int): byte_Array1d;
begin
setLength(result, length);
end;
function short_Array1d_create(length: int): short_Array1d;
begin
setLength(result, length);
end;
function int_Array1d_create(length: int): int_Array1d;
begin
setLength(result, length);
end;
function long_Array1d_create(length: int): long_Array1d;
begin
setLength(result, length);
end;
function String_Array1d_create(length: int): AnsiString_Array1d;
begin
setLength(result, length);
end;
function UnicodeString_Array1d_create(length: int): UnicodeString_Array1d;
begin
setLength(result, length);
end;
function boolean_Array2d_create(length: int): boolean_Array2d;
begin
setLength(result, length);
end;
function wchar_Array2d_create(length: int): wchar_Array2d;
begin
setLength(result, length);
end;
function float_Array2d_create(length: int): float_Array2d;
begin
setLength(result, length);
end;
function double_Array2d_create(length: int): double_Array2d;
begin
setLength(result, length);
end;
function real_Array2d_create(length: int): real_Array2d;
begin
setLength(result, length);
end;
function byte_Array2d_create(length: int): byte_Array2d;
begin
setLength(result, length);
end;
function short_Array2d_create(length: int): short_Array2d;
begin
setLength(result, length);
end;
function int_Array2d_create(length: int): int_Array2d;
begin
setLength(result, length);
end;
function long_Array2d_create(length: int): long_Array2d;
begin
setLength(result, length);
end;
function String_Array2d_create(length: int): AnsiString_Array2d;
begin
setLength(result, length);
end;
function UnicodeString_Array2d_create(length: int): UnicodeString_Array2d;
begin
setLength(result, length);
end;
function boolean_Array2d_create(length, sublength: int): boolean_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function wchar_Array2d_create(length, sublength: int): wchar_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function float_Array2d_create(length, sublength: int): float_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function double_Array2d_create(length, sublength: int): double_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function real_Array2d_create(length, sublength: int): real_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function byte_Array2d_create(length, sublength: int): byte_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function short_Array2d_create(length, sublength: int): short_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function int_Array2d_create(length, sublength: int): int_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function long_Array2d_create(length, sublength: int): long_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function String_Array2d_create(length, sublength: int): AnsiString_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function UnicodeString_Array2d_create(length, sublength: int): UnicodeString_Array2d;
var
i: int;
begin
setLength(result, length);
for i := length - 1 downto 0 do begin
setLength(result[i], sublength);
end;
end;
function String_create(length: int): AnsiString;
begin
setLength(result, length);
end;
function UnicodeString_create(length: int): UnicodeString;
begin
setLength(result, length);
end;
function UnicodeString_create(const chars: wchar_Array1d): UnicodeString;
begin
result := UnicodeString_create(chars, 0, length(chars));
end;
function UnicodeString_create(const chars: wchar_Array1d; offset, length: int): UnicodeString;
var
lim: int;
len: int;
begin
lim := offset + length;
len := System.length(chars);
if (lim > len) or (lim < offset) or (offset < 0) or (offset > len) then begin
raise ArrayIndexOutOfBoundsException.create('UnicodeString_create: индекс элемента массива выходит из диапазона.');
end;
result := UnicodeString_create(length);
move(chars[offset], result[1], length * sizeof(wchar));
end;
function toBooleanArray1d(const arr: array of boolean): boolean_Array1d;
begin
result := boolean_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(boolean));
end;
function toWcharArray1d(const arr: array of wchar): wchar_Array1d;
begin
result := wchar_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(wchar));
end;
function toFloatArray1d(const arr: array of float): float_Array1d;
begin
result := float_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(float));
end;
function toDoubleArray1d(const arr: array of double): double_Array1d;
begin
result := double_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(double));
end;
function toRealArray1d(const arr: array of real): real_Array1d;
begin
result := real_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(real));
end;
function toByteArray1d(const arr: array of byte): byte_Array1d;
begin
result := byte_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(byte));
end;
function toShortArray1d(const arr: array of short): short_Array1d;
begin
result := short_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(short));
end;
function toIntArray1d(const arr: array of int): int_Array1d;
begin
result := int_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(int));
end;
function toLongArray1d(const arr: array of long): long_Array1d;
begin
result := long_Array1d_create(length(arr));
move(arr[0], result[0], length(result) * sizeof(long));
end;
function toStringArray1d(const arr: array of AnsiString): AnsiString_Array1d;
var
i: int;
begin
result := String_Array1d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toUnicodeStringArray1d(const arr: array of UnicodeString): UnicodeString_Array1d;
var
i: int;
begin
result := UnicodeString_Array1d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toBooleanArray2d(const arr: array of boolean_Array1d): boolean_Array2d;
var
i: int;
begin
result := boolean_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toWcharArray2d(const arr: array of wchar_Array1d): wchar_Array2d;
var
i: int;
begin
result := wchar_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toFloatArray2d(const arr: array of float_Array1d): float_Array2d;
var
i: int;
begin
result := float_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toDoubleArray2d(const arr: array of double_Array1d): double_Array2d;
var
i: int;
begin
result := double_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toRealArray2d(const arr: array of real_Array1d): real_Array2d;
var
i: int;
begin
result := real_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toByteArray2d(const arr: array of byte_Array1d): byte_Array2d;
var
i: int;
begin
result := byte_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toShortArray2d(const arr: array of short_Array1d): short_Array2d;
var
i: int;
begin
result := short_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toIntArray2d(const arr: array of int_Array1d): int_Array2d;
var
i: int;
begin
result := int_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toLongArray2d(const arr: array of long_Array1d): long_Array2d;
var
i: int;
begin
result := long_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toStringArray2d(const arr: array of AnsiString_Array1d): AnsiString_Array2d;
var
i: int;
begin
result := String_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
function toUnicodeStringArray2d(const arr: array of UnicodeString_Array1d): UnicodeString_Array2d;
var
i: int;
begin
result := UnicodeString_Array2d_create(length(arr));
for i := length(result) - 1 downto 0 do begin
result[i] := arr[i];
end;
end;
procedure arraycopy(const src: boolean_Array1d; srcOffset: int; const dst: boolean_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(boolean));
end;
procedure arraycopy(const src: wchar_Array1d; srcOffset: int; const dst: wchar_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(wchar));
end;
procedure arraycopy(const src: float_Array1d; srcOffset: int; const dst: float_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(float));
end;
procedure arraycopy(const src: double_Array1d; srcOffset: int; const dst: double_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(double));
end;
procedure arraycopy(const src: real_Array1d; srcOffset: int; const dst: real_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(real));
end;
procedure arraycopy(const src: byte_Array1d; srcOffset: int; const dst: byte_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(byte));
end;
procedure arraycopy(const src: short_Array1d; srcOffset: int; const dst: short_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(short));
end;
procedure arraycopy(const src: int_Array1d; srcOffset: int; const dst: int_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(int));
end;
procedure arraycopy(const src: long_Array1d; srcOffset: int; const dst: long_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
move(src[srcOffset], dst[dstOffset], length * sizeof(long));
end;
procedure arraycopy(const src: AnsiString_Array1d; srcOffset: int; const dst: AnsiString_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: UnicodeString_Array1d; srcOffset: int; const dst: UnicodeString_Array1d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: boolean_Array2d; srcOffset: int; const dst: boolean_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: wchar_Array2d; srcOffset: int; const dst: wchar_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: float_Array2d; srcOffset: int; const dst: float_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: double_Array2d; srcOffset: int; const dst: double_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: real_Array2d; srcOffset: int; const dst: real_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: byte_Array2d; srcOffset: int; const dst: byte_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: short_Array2d; srcOffset: int; const dst: short_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: int_Array2d; srcOffset: int; const dst: int_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: long_Array2d; srcOffset: int; const dst: long_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: AnsiString_Array2d; srcOffset: int; const dst: AnsiString_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
procedure arraycopy(const src: UnicodeString_Array2d; srcOffset: int; const dst: UnicodeString_Array2d; dstOffset: int; length: int);
var
lim: int;
len: int;
i: int;
begin
lim := srcOffset + length;
len := System.length(src);
if (lim > len) or (lim < srcOffset) or (srcOffset < 0) or (srcOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
lim := dstOffset + length;
len := System.length(dst);
if (lim > len) or (lim < dstOffset) or (dstOffset < 0) or (dstOffset > len) then begin
raise ArrayIndexOutOfBoundsException.create('arraycopy: индекс элемента массива выходит из диапазона.');
end;
if (src = dst) and (srcOffset < dstOffset) then begin
for i := length - 1 downto 0 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end else begin
for i := 0 to length - 1 do begin
dst[dstOffset + i] := src[srcOffset + i];
end;
end;
end;
{%endregion}
{%region _Object }
class function _Object.asClass(): _Class;
begin
result := ClassData.create(classType());
end;
constructor _Object.create();
begin
inherited create();
end;
destructor _Object.destroy;
begin
inherited destroy;
end;
procedure _Object.afterConstruction();
begin
end;
procedure _Object.beforeDestruction();
begin
end;
procedure _Object.free();
begin
if self <> nil then begin
destroy;
end;
end;
function _Object.queryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: GUID; out obj): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
begin
if getInterface(iid, obj) then begin
result := S_OK;
end else begin
result := E_NOINTERFACE;
end;
end;
function _Object._addref(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
begin
result := -1;
end;
function _Object._release(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
begin
result := -1;
end;
function _Object.getInterface(const iid: GUID; out obj): boolean;
begin
result := inherited getInterface(iid, obj);
end;
function _Object.getInterfaceWeak(const iid: GUID; out obj): boolean;
begin
result := inherited getInterfaceWeak(iid, obj);
end;
function _Object.getClass(): _Class;
begin
result := ClassData.create(classType());
end;
function _Object.asObject(): TObject;
begin
result := self;
end;
{%endregion}
{%region RefCountInterfacedObject }
class function RefCountInterfacedObject.newInstance(): TObject;
begin
result := inherited newInstance();
if result <> nil then begin
RefCountInterfacedObject(result).refcount := 1;
end;
end;
constructor RefCountInterfacedObject.create();
begin
inherited create();
end;
procedure RefCountInterfacedObject.afterConstruction(); assembler;
asm
lock dec dword[eax+offset refcount]
end;
procedure RefCountInterfacedObject.beforeDestruction();
begin
if refcount <> 0 then begin
raise RuntimeException.create('Error 204 (refcount != 0)');
end;
end;
function RefCountInterfacedObject._addref(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
begin
result := interlockedIncrement(@refcount);
end;
function RefCountInterfacedObject._release(): int; {$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
begin
result := interlockedDecrement(@refcount);
if result = 0 then begin
destroy;
end;
end;
{%endregion}
{%region ClassData }
constructor ClassData.create(clsptr: TClass);
begin
inherited create();
self.clsptr := clsptr;
end;
function ClassData.isInheritedFrom(cls: _Class): boolean;
begin
if cls <> nil then begin
result := clsptr.inheritsFrom(cls.getClassType());
end else begin
result := false;
end;
end;
function ClassData.isInstance(obj: TObject): boolean;
begin
result := (obj <> nil) and (obj.classType().inheritsFrom(clsptr));
end;
function ClassData.getInstanceSize(): int;
begin
result := int(clsptr.instanceSize());
end;
function ClassData.getSuperclass(): _Class;
begin
result := ClassData.create(clsptr.classParent());
end;
function ClassData.getName(): AnsiString;
begin
result := clsptr.unitName() + '.' + clsptr.className();
end;
function ClassData.getSimpleName(): AnsiString;
begin
result := clsptr.className();
end;
function ClassData.getClassType(): TClass;
begin
result := clsptr;
end;
{%endregion}
{%region Thread }
constructor Thread.create(target: Runnable; const name: AnsiString; freeOnTerminate: boolean);
begin
inherited create();
self.freeOnTerminate := freeOnTerminate;
if target = nil then begin
self.target := self;
end else begin
self.target := target;
end;
self.name := name;
self.inst := RunnableThread.create(self);
end;
procedure Thread.run();
begin
end;
procedure Thread.start();
var
t: TThread;
begin
t := inst;
if t <> nil then begin
t.start();
end;
end;
function Thread.getName(): AnsiString;
begin
result := name;
end;
{%endregion}
{%region ThreadLock }
constructor ThreadLock.create();
begin
inherited create();
Windows.initializeCriticalSection(@lock);
end;
destructor ThreadLock.destroy;
begin
Windows.deleteCriticalSection(@lock);
inherited destroy;
end;
procedure ThreadLock.enter();
begin
Windows.enterCriticalSection(@lock);
end;
procedure ThreadLock.leave();
begin
Windows.leaveCriticalSection(@lock);
end;
{%endregion}
{%region Exception }
constructor Exception.create();
begin
inherited create();
end;
constructor Exception.create(const message: AnsiString);
begin
inherited create();
self.fmessage := message;
end;
function Exception.getMessage(): AnsiString;
begin
result := fmessage;
end;
{%endregion}
{%region RuntimeException }
constructor RuntimeException.create();
begin
inherited create();
end;
constructor RuntimeException.create(const message: AnsiString);
begin
inherited create(message);
end;
{%endregion}
{%region NullPointerException }
constructor NullPointerException.create();
begin
inherited create();
end;
constructor NullPointerException.create(const message: AnsiString);
begin
inherited create(message);
end;
{%endregion}
{%region IndexOutOfBoundsException }
constructor IndexOutOfBoundsException.create();
begin
inherited create();
end;
constructor IndexOutOfBoundsException.create(const message: AnsiString);
begin
inherited create(message);
end;
constructor IndexOutOfBoundsException.create(index: int);
begin
inherited create('Индекс выходит из диапазона: ' + toDecString(index) + '.');
end;
{%endregion}
{%region ArrayIndexOutOfBoundsException }
constructor ArrayIndexOutOfBoundsException.create();
begin
inherited create();
end;
constructor ArrayIndexOutOfBoundsException.create(const message: AnsiString);
begin
inherited create(message);
end;
constructor ArrayIndexOutOfBoundsException.create(index: int);
begin
inherited create('индекс элемента массива выходит из диапазона: ' + toDecString(index) + '.');
end;
{%endregion}
{%region IllegalArgumentException }
constructor IllegalArgumentException.create();
begin
inherited create();
end;
constructor IllegalArgumentException.create(const message: AnsiString);
begin
inherited create(message);
end;
{%endregion}
{%region RunnableThread }
constructor RunnableThread.create(owner: Thread);
begin
inherited create(true, defaultStackSize);
self.freeOnTerminate := true;
self.owner := owner;
end;
procedure RunnableThread.execute();
var
owner: Thread;
begin
owner := self.owner;
try
owner.target.run();
except
end;
Pointer(owner.target) := nil;
owner.inst := nil;
if owner.freeOnTerminate then begin
owner.free();
end;
end;
{%endregion}
initialization {%region}
configureFPU();
{%endregion}
end.