character.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. unit character;
  2. interface
  3. {$ifndef VER2_4}
  4. {$mode objfpc}
  5. {$H+}
  6. {$PACKENUM 1}
  7. {$SCOPEDENUMS ON}
  8. type
  9. // Unicode General Category
  10. TUnicodeCategory = (
  11. ucUppercaseLetter, // Lu = Letter, uppercase
  12. ucLowercaseLetter, // Ll = Letter, lowercase
  13. ucTitlecaseLetter, // Lt = Letter, titlecase
  14. ucModifierLetter, // Lm = Letter, modifier
  15. ucOtherLetter, // Lo = Letter, other
  16. ucNonSpacingMark, // Mn = Mark, nonspacing
  17. ucCombiningMark, // Mc = Mark, spacing combining
  18. ucEnclosingMark, // Me = Mark, enclosing
  19. ucDecimalNumber, // Nd = Number, decimal digit
  20. ucLetterNumber, // Nl = Number, letter
  21. ucOtherNumber, // No = Number, other
  22. ucConnectPunctuation, // Pc = Punctuation, connector
  23. ucDashPunctuation, // Pd = Punctuation, dash
  24. ucOpenPunctuation, // Ps = Punctuation, open
  25. ucClosePunctuation, // Pe = Punctuation, close
  26. ucInitialPunctuation, // Pi = Punctuation, initial quote (may behave like Ps or Pe depending on usage)
  27. ucFinalPunctuation, // Pf = Punctuation, final quote (may behave like Ps or Pe depending on usage)
  28. ucOtherPunctuation, // Po = Punctuation, other
  29. ucMathSymbol, // Sm = Symbol, math
  30. ucCurrencySymbol, // Sc = Symbol, currency
  31. ucModifierSymbol, // Sk = Symbol, modifier
  32. ucOtherSymbol, // So = Symbol, other
  33. ucSpaceSeparator, // Zs = Separator, space
  34. ucLineSeparator, // Zl = Separator, line
  35. ucParagraphSeparator, // Zp = Separator, paragraph
  36. ucControl, // Cc = Other, control
  37. ucFormat, // Cf = Other, format
  38. ucSurrogate, // Cs = Other, surrogate
  39. ucPrivateUse, // Co = Other, private use
  40. ucUnassigned // Cn = Other, not assigned (including noncharacters)
  41. );
  42. { TCharacter }
  43. TCharacter = class sealed
  44. public
  45. class function ConvertFromUtf32(AChar : UCS4Char) : UnicodeString; static;
  46. class function ConvertToUtf32(const AString : UnicodeString; AIndex : Integer) : UCS4Char; overload; static;
  47. class function ConvertToUtf32(const AString : UnicodeString; AIndex : Integer; out ACharLength : Integer) : UCS4Char; overload; static;
  48. class function ConvertToUtf32(const AHighSurrogate, ALowSurrogate : UnicodeChar) : UCS4Char; overload; static;
  49. class function GetNumericValue(AChar : UnicodeChar) : Double; static; overload;
  50. class function GetNumericValue(const AString : UnicodeString; AIndex : Integer) : Double; overload; static;
  51. class function GetUnicodeCategory(AChar : UnicodeChar) : TUnicodeCategory; overload; static;
  52. class function GetUnicodeCategory(const AString : UnicodeString; AIndex : Integer) : TUnicodeCategory; overload; static;
  53. class function IsControl(AChar : UnicodeChar) : Boolean; overload; static;
  54. class function IsControl(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  55. class function IsDigit(AChar : UnicodeChar) : Boolean; overload; static;
  56. class function IsDigit(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  57. class function IsSurrogate(AChar : UnicodeChar) : Boolean; overload; static;
  58. class function IsSurrogate(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  59. class function IsHighSurrogate(AChar : UnicodeChar) : Boolean; overload; static;
  60. class function IsHighSurrogate(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  61. class function IsLowSurrogate(AChar : UnicodeChar) : Boolean; overload; static;
  62. class function IsLowSurrogate(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  63. class function IsSurrogatePair(const AHighSurrogate, ALowSurrogate : UnicodeChar) : Boolean; overload; static; inline;
  64. class function IsSurrogatePair(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  65. class function IsLetter(AChar : UnicodeChar) : Boolean; overload; static;
  66. class function IsLetter(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  67. class function IsLetterOrDigit(AChar : UnicodeChar) : Boolean; overload; static;
  68. class function IsLetterOrDigit(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  69. class function IsLower(AChar : UnicodeChar) : Boolean; overload; static;
  70. class function IsLower(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  71. class function IsNumber(AChar : UnicodeChar) : Boolean; overload; static;
  72. class function IsNumber(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  73. class function IsPunctuation(AChar : UnicodeChar) : Boolean; overload; static;
  74. class function IsPunctuation(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  75. class function IsSeparator(AChar : UnicodeChar) : Boolean; overload; static;
  76. class function IsSeparator(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  77. class function IsSymbol(AChar : UnicodeChar) : Boolean; overload; static;
  78. class function IsSymbol(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  79. class function IsUpper(AChar : UnicodeChar) : Boolean; overload; static;
  80. class function IsUpper(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  81. class function IsWhiteSpace(AChar : UnicodeChar) : Boolean; overload; static;
  82. class function IsWhiteSpace(const AString : UnicodeString; AIndex : Integer) : Boolean; overload; static;
  83. class function ToLower(AChar : UnicodeChar) : UnicodeChar; overload; static;
  84. class function ToLower(const AString : UnicodeString) : UnicodeString; overload; static;
  85. class function ToUpper(AChar : UnicodeChar) : UnicodeChar; overload; static;
  86. class function ToUpper(const AString : UnicodeString) : UnicodeString; overload; static;
  87. end;
  88. {$endif VER2_4}
  89. implementation
  90. {$ifndef VER2_4}
  91. uses
  92. SysUtils,
  93. RtlConsts;
  94. type
  95. PUC_Prop = ^TUC_Prop;
  96. TUC_Prop = packed record
  97. Category : TUnicodeCategory;
  98. NumericValue : Double;
  99. SimpleUpperCase : DWord;
  100. SimpleLowerCase : DWord;
  101. WhiteSpace : Boolean;
  102. end;
  103. {$INCLUDE unicodedata.inc}
  104. const
  105. LOW_SURROGATE_BEGIN = Word($DC00);
  106. LOW_SURROGATE_END = Word($DFFF);
  107. HIGH_SURROGATE_BEGIN = Word($D800);
  108. HIGH_SURROGATE_END = Word($DBFF);
  109. UCS4_HALF_BASE = LongWord($10000);
  110. UCS4_HALF_MASK = Word($3FF);
  111. MAX_LEGAL_UTF32 = $10FFFF;
  112. const
  113. LETTER_CATEGORIES = [
  114. TUnicodeCategory.ucUppercaseLetter, TUnicodeCategory.ucLowercaseLetter,
  115. TUnicodeCategory.ucTitlecaseLetter, TUnicodeCategory.ucModifierLetter,
  116. TUnicodeCategory.ucOtherLetter
  117. ];
  118. LETTER_OR_DIGIT_CATEGORIES =
  119. LETTER_CATEGORIES +
  120. [TUnicodeCategory.ucDecimalNumber,TUnicodeCategory.ucLetterNumber];
  121. NUMBER_CATEGORIES =
  122. [ TUnicodeCategory.ucDecimalNumber, TUnicodeCategory.ucLetterNumber,
  123. TUnicodeCategory.ucOtherNumber
  124. ];
  125. PUNCTUATION_CATEGORIES = [
  126. TUnicodeCategory.ucConnectPunctuation, TUnicodeCategory.ucDashPunctuation,
  127. TUnicodeCategory.ucOpenPunctuation, TUnicodeCategory.ucClosePunctuation,
  128. TUnicodeCategory.ucInitialPunctuation, TUnicodeCategory.ucFinalPunctuation,
  129. TUnicodeCategory.ucOtherPunctuation
  130. ];
  131. SEPARATOR_CATEGORIES =
  132. [ TUnicodeCategory.ucSpaceSeparator, TUnicodeCategory.ucLineSeparator,
  133. TUnicodeCategory.ucParagraphSeparator
  134. ];
  135. SYMBOL_CATEGORIES =
  136. [ TUnicodeCategory.ucMathSymbol, TUnicodeCategory.ucCurrencySymbol,
  137. TUnicodeCategory.ucModifierSymbol, TUnicodeCategory.ucOtherSymbol
  138. ];
  139. class function GetProps(const ACodePoint : Word) : PUC_Prop; inline;
  140. begin
  141. Result:=
  142. @UC_PROP_ARRAY[
  143. UC_TABLE_2[
  144. (UC_TABLE_1[WordRec(ACodePoint).Hi] * 256) +
  145. WordRec(ACodePoint).Lo
  146. ]
  147. ];
  148. end;
  149. { TCharacter }
  150. class function TCharacter.ConvertFromUtf32(AChar : UCS4Char) : UnicodeString; static;
  151. begin
  152. if AChar < UCS4_HALF_BASE then
  153. begin
  154. if IsSurrogate(UnicodeChar(AChar)) then
  155. raise EArgumentOutOfRangeException.CreateFmt(SInvalidUTF32Char, [AChar]);
  156. Result := UnicodeChar(AChar);
  157. end
  158. else
  159. begin
  160. if AChar > MAX_LEGAL_UTF32 then
  161. raise EArgumentOutOfRangeException.CreateFmt(SInvalidUTF32Char, [AChar]);
  162. SetLength(Result, 2);
  163. AChar := AChar - UCS4_HALF_BASE;
  164. Result[1] := UnicodeChar((AChar shr 10) + HIGH_SURROGATE_BEGIN);
  165. Result[2] := UnicodeChar((AChar and UCS4_HALF_MASK) + LOW_SURROGATE_BEGIN);
  166. end;
  167. end;
  168. class function TCharacter.ConvertToUtf32(const AString : UnicodeString; AIndex : Integer) : UCS4Char; overload; static;
  169. begin
  170. if (AIndex < 1) or (AIndex > Length(AString)) then
  171. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  172. Result := Word(AString[AIndex]);
  173. if IsHighSurrogate(UnicodeChar(Result)) then
  174. begin
  175. if Length(AString) < Succ(AIndex) then
  176. raise EArgumentException.CreateFmt(SInvalidHighSurrogate, [AIndex]);
  177. Result := ConvertToUtf32(UnicodeChar(Result), AString[Succ(AIndex)]);
  178. end;
  179. end;
  180. class function TCharacter.ConvertToUtf32(const AString : UnicodeString; AIndex : Integer; out ACharLength : Integer) : UCS4Char; overload; static;
  181. begin
  182. if (AIndex < 1) or (AIndex > Length(AString)) then
  183. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  184. Result := Word(AString[AIndex]);
  185. if IsHighSurrogate(UnicodeChar(Result)) then
  186. begin
  187. if Length(AString) < Succ(AIndex) then
  188. raise EArgumentException.CreateFmt(SInvalidHighSurrogate, [AIndex]);
  189. Result := ConvertToUtf32(UnicodeChar(Result), AString[Succ(AIndex)]);
  190. ACharLength := 2;
  191. end
  192. else
  193. ACharLength := 1;
  194. end;
  195. class function TCharacter.ConvertToUtf32(const AHighSurrogate, ALowSurrogate : UnicodeChar) : UCS4Char; overload; static;
  196. begin
  197. if not IsHighSurrogate(AHighSurrogate) then
  198. raise EArgumentOutOfRangeException.CreateFmt(SHighSurrogateOutOfRange, [Word(AHighSurrogate)]);
  199. if not IsLowSurrogate(ALowSurrogate) then
  200. raise EArgumentOutOfRangeException.CreateFmt(SLowSurrogateOutOfRange, [Word(ALowSurrogate)]);
  201. Result := (UCS4Char(AHighSurrogate) - HIGH_SURROGATE_BEGIN) shl 10 + (UCS4Char(ALowSurrogate) - LOW_SURROGATE_BEGIN) + UCS4_HALF_BASE;
  202. end;
  203. class function TCharacter.GetNumericValue(AChar : UnicodeChar) : Double; static;
  204. begin
  205. Result := GetProps(Word(AChar))^.NumericValue;
  206. end;
  207. class function TCharacter.GetNumericValue(
  208. const AString : UnicodeString;
  209. AIndex : Integer
  210. ) : Double; static;
  211. begin
  212. if (AIndex < 1) or (AIndex > Length(AString)) then
  213. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  214. Result := GetNumericValue(AString[AIndex]);
  215. end;
  216. class function TCharacter.GetUnicodeCategory(AChar : UnicodeChar) : TUnicodeCategory; static;
  217. begin
  218. Result := GetProps(Word(AChar))^.Category;
  219. end;
  220. class function TCharacter.GetUnicodeCategory(
  221. const AString : UnicodeString;
  222. AIndex : Integer
  223. ) : TUnicodeCategory; static;
  224. begin
  225. if (AIndex < 1) or (AIndex > Length(AString)) then
  226. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  227. Result := GetUnicodeCategory(AString[AIndex]);
  228. end;
  229. class function TCharacter.IsControl(AChar : UnicodeChar) : Boolean; static;
  230. begin
  231. Result := (GetProps(Word(AChar))^.Category = TUnicodeCategory.ucControl);
  232. end;
  233. class function TCharacter.IsControl(
  234. const AString : UnicodeString;
  235. AIndex : Integer
  236. ) : Boolean; static;
  237. begin
  238. if (AIndex < 1) or (AIndex > Length(AString)) then
  239. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  240. Result := IsControl(AString[AIndex]);
  241. end;
  242. class function TCharacter.IsDigit(AChar : UnicodeChar) : Boolean; static;
  243. begin
  244. Result := (GetProps(Word(AChar))^.Category = TUnicodeCategory.ucDecimalNumber);
  245. end;
  246. class function TCharacter.IsDigit(
  247. const AString : UnicodeString;
  248. AIndex : Integer
  249. ) : Boolean; static;
  250. begin
  251. if (AIndex < 1) or (AIndex > Length(AString)) then
  252. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  253. Result := IsDigit(AString[AIndex]);
  254. end;
  255. class function TCharacter.IsSurrogate(AChar : UnicodeChar) : Boolean; static;
  256. begin
  257. Result := (GetProps(Word(AChar))^.Category = TUnicodeCategory.ucSurrogate);
  258. end;
  259. class function TCharacter.IsSurrogate(
  260. const AString : UnicodeString;
  261. AIndex : Integer
  262. ) : Boolean; static;
  263. begin
  264. if (AIndex < 1) or (AIndex > Length(AString)) then
  265. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  266. Result := IsSurrogate(AString[AIndex]);
  267. end;
  268. class function TCharacter.IsHighSurrogate(AChar : UnicodeChar) : Boolean; static;
  269. begin
  270. Result := (GetProps(Word(AChar))^.Category = TUnicodeCategory.ucSurrogate) and
  271. (Word(AChar) >= HIGH_SURROGATE_BEGIN) and
  272. (Word(AChar) <= HIGH_SURROGATE_END);
  273. end;
  274. class function TCharacter.IsHighSurrogate(
  275. const AString : UnicodeString;
  276. AIndex : Integer
  277. ) : Boolean; static;
  278. begin
  279. if (AIndex < 1) or (AIndex > Length(AString)) then
  280. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  281. Result := IsHighSurrogate(AString[AIndex]);
  282. end;
  283. class function TCharacter.IsLowSurrogate(AChar : UnicodeChar) : Boolean; static;
  284. begin
  285. Result := (GetProps(Word(AChar))^.Category = TUnicodeCategory.ucSurrogate) and
  286. (Word(AChar) >= LOW_SURROGATE_BEGIN) and
  287. (Word(AChar) <= LOW_SURROGATE_END);
  288. end;
  289. class function TCharacter.IsLowSurrogate(
  290. const AString : UnicodeString;
  291. AIndex : Integer
  292. ) : Boolean; static;
  293. begin
  294. if (AIndex < 1) or (AIndex > Length(AString)) then
  295. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  296. Result := IsLowSurrogate(AString[AIndex]);
  297. end;
  298. class function TCharacter.IsSurrogatePair(
  299. const AHighSurrogate,
  300. ALowSurrogate : UnicodeChar
  301. ) : Boolean;static;
  302. begin
  303. Result :=
  304. ( (Word(AHighSurrogate) >= HIGH_SURROGATE_BEGIN) and
  305. (Word(AHighSurrogate) <= HIGH_SURROGATE_END)
  306. ) and
  307. ( (Word(ALowSurrogate) >= LOW_SURROGATE_BEGIN) and
  308. (Word(ALowSurrogate) <= LOW_SURROGATE_END)
  309. )
  310. end;
  311. class function TCharacter.IsSurrogatePair(
  312. const AString : UnicodeString;
  313. AIndex : Integer
  314. ) : Boolean;static;
  315. begin
  316. if (AIndex < 1) or (AIndex > Length(AString)) then
  317. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  318. Result := IsSurrogatePair(AString[AIndex],AString[AIndex+1]);
  319. end;
  320. class function TCharacter.IsLetter(AChar : UnicodeChar) : Boolean; static;
  321. begin
  322. Result := (GetProps(Word(AChar))^.Category in LETTER_CATEGORIES);
  323. end;
  324. class function TCharacter.IsLetter(
  325. const AString : UnicodeString;
  326. AIndex : Integer
  327. ) : Boolean; static;
  328. begin
  329. if (AIndex < 1) or (AIndex > Length(AString)) then
  330. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  331. Result := IsLetter(AString[AIndex]);
  332. end;
  333. class function TCharacter.IsLetterOrDigit(AChar : UnicodeChar) : Boolean; static;
  334. begin
  335. Result := (GetProps(Word(AChar))^.Category in LETTER_OR_DIGIT_CATEGORIES);
  336. end;
  337. class function TCharacter.IsLetterOrDigit(
  338. const AString : UnicodeString;
  339. AIndex : Integer
  340. ) : Boolean; static;
  341. begin
  342. if (AIndex < 1) or (AIndex > Length(AString)) then
  343. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  344. Result := IsLetterOrDigit(AString[AIndex]);
  345. end;
  346. class function TCharacter.IsLower(AChar : UnicodeChar) : Boolean; static;
  347. begin
  348. Result := (GetProps(Word(AChar))^.Category = TUnicodeCategory.ucLowercaseLetter);
  349. end;
  350. class function TCharacter.IsLower(
  351. const AString : UnicodeString;
  352. AIndex : Integer
  353. ) : Boolean; static;
  354. begin
  355. if (AIndex < 1) or (AIndex > Length(AString)) then
  356. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  357. Result := IsLower(AString[AIndex]);
  358. end;
  359. class function TCharacter.IsNumber(AChar : UnicodeChar) : Boolean; static;
  360. begin
  361. Result := (GetProps(Word(AChar))^.Category in NUMBER_CATEGORIES);
  362. end;
  363. class function TCharacter.IsNumber(
  364. const AString : UnicodeString;
  365. AIndex : Integer
  366. ) : Boolean;static;
  367. begin
  368. if (AIndex < 1) or (AIndex > Length(AString)) then
  369. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  370. Result := IsNumber(AString[AIndex]);
  371. end;
  372. class function TCharacter.IsPunctuation(AChar : UnicodeChar) : Boolean;static;
  373. begin
  374. Result := (GetProps(Word(AChar))^.Category in PUNCTUATION_CATEGORIES);
  375. end;
  376. class function TCharacter.IsPunctuation(
  377. const AString : UnicodeString;
  378. AIndex : Integer
  379. ) : Boolean;static;
  380. begin
  381. if (AIndex < 1) or (AIndex > Length(AString)) then
  382. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  383. Result := IsPunctuation(AString[AIndex]);
  384. end;
  385. class function TCharacter.IsSeparator(AChar: UnicodeChar): Boolean;static;
  386. begin
  387. Result := (GetProps(Word(AChar))^.Category in SEPARATOR_CATEGORIES);
  388. end;
  389. class function TCharacter.IsSeparator(
  390. const AString : UnicodeString;
  391. AIndex : Integer
  392. ) : Boolean;static;
  393. begin
  394. if (AIndex < 1) or (AIndex > Length(AString)) then
  395. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  396. Result := IsSeparator(AString[AIndex]);
  397. end;
  398. class function TCharacter.IsSymbol(AChar: UnicodeChar): Boolean;static;
  399. begin
  400. Result := (GetProps(Word(AChar))^.Category in SYMBOL_CATEGORIES);
  401. end;
  402. class function TCharacter.IsSymbol(
  403. const AString : UnicodeString;
  404. AIndex : Integer
  405. ) : Boolean;static;
  406. begin
  407. if (AIndex < 1) or (AIndex > Length(AString)) then
  408. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  409. Result := IsSymbol(AString[AIndex]);
  410. end;
  411. class function TCharacter.IsUpper(AChar : UnicodeChar) : Boolean;static;
  412. begin
  413. Result := (GetProps(Word(AChar))^.Category = TUnicodeCategory.ucUppercaseLetter);
  414. end;
  415. class function TCharacter.IsUpper(
  416. const AString : UnicodeString;
  417. AIndex : Integer
  418. ) : Boolean;static;
  419. begin
  420. if (AIndex < 1) or (AIndex > Length(AString)) then
  421. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  422. Result := IsUpper(AString[AIndex]);
  423. end;
  424. class function TCharacter.IsWhiteSpace(AChar : UnicodeChar) : Boolean;static;
  425. begin
  426. Result := GetProps(Word(AChar))^.WhiteSpace;
  427. end;
  428. class function TCharacter.IsWhiteSpace(
  429. const AString : UnicodeString;
  430. AIndex : Integer
  431. ) : Boolean;static;
  432. begin
  433. if (AIndex < 1) or (AIndex > Length(AString)) then
  434. raise EArgumentOutOfRangeException.CreateFmt(SStringIndexOutOfRange, [AIndex, Length(AString)]);
  435. Result := IsWhiteSpace(AString[AIndex]);
  436. end;
  437. class function TCharacter.ToLower(AChar : UnicodeChar) : UnicodeChar;static;
  438. begin
  439. Result := UnicodeChar(GetProps(Word(AChar))^.SimpleLowerCase);
  440. if (Result = UnicodeChar(0)) then
  441. Result := AChar;
  442. end;
  443. class function TCharacter.ToLower(const AString : UnicodeString) : UnicodeString;static;
  444. var
  445. i, c : SizeInt;
  446. pp, pr : PUnicodeChar;
  447. begin
  448. c := Length(AString);
  449. SetLength(Result,c);
  450. if (c > 0) then begin
  451. pp := @AString[1];
  452. pr := @Result[1];
  453. for i := 1 to c do begin
  454. pr^ := ToLower(pp^);
  455. Inc(pp);
  456. Inc(pr);
  457. end;
  458. end;
  459. end;
  460. class function TCharacter.ToUpper(AChar : UnicodeChar) : UnicodeChar;static;
  461. begin
  462. Result := UnicodeChar(GetProps(Word(AChar))^.SimpleUpperCase);
  463. if (Result = UnicodeChar(0)) then
  464. Result := AChar;
  465. end;
  466. class function TCharacter.ToUpper(const AString : UnicodeString) : UnicodeString;static;
  467. var
  468. i, c : SizeInt;
  469. pp, pr : PUnicodeChar;
  470. begin
  471. c := Length(AString);
  472. SetLength(Result,c);
  473. if (c > 0) then begin
  474. pp := @AString[1];
  475. pr := @Result[1];
  476. for i := 1 to c do begin
  477. pr^ := ToUpper(pp^);
  478. Inc(pp);
  479. Inc(pr);
  480. end;
  481. end;
  482. end;
  483. {$endif VER2_4}
  484. end.