wstrings.inc 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2005 by Florian Klaempfl,
  4. member of the Free Pascal development team.
  5. This file implements support routines for WideStrings/Unicode with FPC
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {
  13. This file contains the implementation of the WideString type,
  14. and all things that are needed for it.
  15. WideString is defined as a 'silent' pwidechar :
  16. a pwidechar that points to :
  17. @-8 : SizeInt for reference count;
  18. @-4 : SizeInt for size;
  19. @ : String + Terminating #0;
  20. Pwidechar(Widestring) is a valid typecast.
  21. So WS[i] is converted to the address @WS+i-1.
  22. Constants should be assigned a reference count of -1
  23. Meaning that they can't be disposed of.
  24. }
  25. Type
  26. PWideRec = ^TWideRec;
  27. TWideRec = Packed Record
  28. Ref,
  29. Len : SizeInt;
  30. First : WideChar;
  31. end;
  32. Const
  33. WideRecLen = SizeOf(TWideRec);
  34. WideFirstOff = SizeOf(TWideRec)-sizeof(WideChar);
  35. {
  36. Default WideChar <-> Char conversion is to only convert the
  37. lower 127 chars, all others are translated to spaces.
  38. These routines can be overwritten for the Current Locale
  39. }
  40. procedure DefaultWide2AnsiMove(source:pwidechar;var dest:ansistring;len:SizeInt);
  41. var
  42. i : SizeInt;
  43. begin
  44. //writeln('in widetoansimove');
  45. setlength(dest,len);
  46. for i:=1 to len do
  47. begin
  48. if word(source^)<256 then
  49. dest[i]:=char(word(source^))
  50. else
  51. dest[i]:='?';
  52. //inc(dest);
  53. inc(source);
  54. end;
  55. end;
  56. procedure DefaultAnsi2WideMove(source:pchar;var dest:widestring;len:SizeInt);
  57. var
  58. i : SizeInt;
  59. begin
  60. //writeln('in ansitowidemove');
  61. setlength(dest,len);
  62. for i:=1 to len do
  63. begin
  64. // if byte(source^)<128 then
  65. dest[i]:=widechar(byte(source^));
  66. // else
  67. // dest^:=' ';
  68. //inc(dest);
  69. inc(source);
  70. end;
  71. end;
  72. Procedure GetWideStringManager (Var Manager : TWideStringManager);
  73. begin
  74. manager:=widestringmanager;
  75. end;
  76. Procedure SetWideStringManager (Const New : TWideStringManager; Var Old: TWideStringManager);
  77. begin
  78. Old:=widestringmanager;
  79. widestringmanager:=New;
  80. end;
  81. Procedure SetWideStringManager (Const New : TWideStringManager);
  82. begin
  83. widestringmanager:=New;
  84. end;
  85. (*
  86. Procedure UniqueWideString(Var S : WideString); [Public,Alias : 'FPC_WIDESTR_UNIQUE'];
  87. {
  88. Make sure reference count of S is 1,
  89. using copy-on-write semantics.
  90. }
  91. begin
  92. end;
  93. *)
  94. {****************************************************************************
  95. Internal functions, not in interface.
  96. ****************************************************************************}
  97. procedure WideStringError;
  98. begin
  99. HandleErrorFrame(204,get_frame);
  100. end;
  101. {$ifdef WideStrDebug}
  102. Procedure DumpWideRec(S : Pointer);
  103. begin
  104. If S=Nil then
  105. Writeln ('String is nil')
  106. Else
  107. Begin
  108. With PWideRec(S-WideFirstOff)^ do
  109. begin
  110. Write ('(Maxlen: ',maxlen);
  111. Write (' Len:',len);
  112. Writeln (' Ref: ',ref,')');
  113. end;
  114. end;
  115. end;
  116. {$endif}
  117. Function NewWideString(Len : SizeInt) : Pointer;
  118. {
  119. Allocate a new WideString on the heap.
  120. initialize it to zero length and reference count 1.
  121. }
  122. Var
  123. P : Pointer;
  124. begin
  125. {$ifdef MSWINDOWS}
  126. if winwidestringalloc then
  127. P:=SysAllocStringLen(nil,Len*sizeof(WideChar)+WideRecLen)
  128. else
  129. {$endif MSWINDOWS}
  130. GetMem(P,Len*sizeof(WideChar)+WideRecLen);
  131. If P<>Nil then
  132. begin
  133. PWideRec(P)^.Len:=0; { Initial length }
  134. PWideRec(P)^.Ref:=1; { Set reference count }
  135. PWideRec(P)^.First:=#0; { Terminating #0 }
  136. inc(p,WideFirstOff); { Points to string now }
  137. end
  138. else
  139. WideStringError;
  140. NewWideString:=P;
  141. end;
  142. Procedure DisposeWideString(Var S : Pointer);
  143. {
  144. Deallocates a WideString From the heap.
  145. }
  146. begin
  147. If S=Nil then
  148. exit;
  149. Dec (S,WideFirstOff);
  150. {$ifdef MSWINDOWS}
  151. if winwidestringalloc then
  152. SysFreeString(S)
  153. else
  154. {$endif MSWINDOWS}
  155. FreeMem (S);
  156. S:=Nil;
  157. end;
  158. Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);[Public,Alias:'FPC_WIDESTR_DECR_REF']; compilerproc;
  159. {
  160. Decreases the ReferenceCount of a non constant widestring;
  161. If the reference count is zero, deallocate the string;
  162. }
  163. Type
  164. pSizeInt = ^SizeInt;
  165. Var
  166. l : pSizeInt;
  167. Begin
  168. { Zero string }
  169. If S=Nil then exit;
  170. { check for constant strings ...}
  171. l:=@PWIDEREC(S-WideFirstOff)^.Ref;
  172. If l^<0 then exit;
  173. { declocked does a MT safe dec and returns true, if the counter is 0 }
  174. If declocked(l^) then
  175. { Ref count dropped to zero }
  176. DisposeWideString (S); { Remove...}
  177. end;
  178. { alias for internal use }
  179. Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);[external name 'FPC_WIDESTR_DECR_REF'];
  180. Procedure fpc_WideStr_Incr_Ref (S : Pointer);[Public,Alias:'FPC_WIDESTR_INCR_REF']; compilerproc;
  181. Begin
  182. If S=Nil then
  183. exit;
  184. { Let's be paranoid : Constant string ??}
  185. If PWideRec(S-WideFirstOff)^.Ref<0 then exit;
  186. inclocked(PWideRec(S-WideFirstOff)^.Ref);
  187. end;
  188. { alias for internal use }
  189. Procedure fpc_WideStr_Incr_Ref (S : Pointer);[external name 'FPC_WIDESTR_INCR_REF'];
  190. function fpc_WideStr_To_ShortStr (high_of_res: SizeInt;const S2 : WideString): shortstring;[Public, alias: 'FPC_WIDESTR_TO_SHORTSTR']; compilerproc;
  191. {
  192. Converts a WideString to a ShortString;
  193. }
  194. Var
  195. Size : SizeInt;
  196. temp : ansistring;
  197. begin
  198. if S2='' then
  199. fpc_WideStr_To_ShortStr:=''
  200. else
  201. begin
  202. Size:=Length(S2);
  203. If Size>high_of_res then
  204. Size:=high_of_res;
  205. widestringmanager.Wide2AnsiMoveProc(PWideChar(S2),temp,Size);
  206. fpc_WideStr_To_ShortStr:=temp;
  207. end;
  208. end;
  209. Function fpc_ShortStr_To_WideStr (Const S2 : ShortString): WideString;compilerproc;
  210. {
  211. Converts a ShortString to a WideString;
  212. }
  213. Var
  214. Size : SizeInt;
  215. begin
  216. Size:=Length(S2);
  217. //Setlength (fpc_ShortStr_To_WideStr,Size);
  218. if Size>0 then
  219. begin
  220. widestringmanager.Ansi2WideMoveProc(PChar(@S2[1]),fpc_ShortStr_To_WideStr,Size);
  221. { Terminating Zero }
  222. PWideChar(Pointer(fpc_ShortStr_To_WideStr)+Size*sizeof(WideChar))^:=#0;
  223. end;
  224. end;
  225. Function fpc_WideStr_To_AnsiStr (const S2 : WideString): AnsiString; compilerproc;
  226. {
  227. Converts a WideString to an AnsiString
  228. }
  229. Var
  230. Size : SizeInt;
  231. begin
  232. if s2='' then
  233. exit;
  234. Size:=Length(WideString(S2));
  235. // Setlength (fpc_WideStr_To_AnsiStr,Size);
  236. if Size>0 then
  237. begin
  238. widestringmanager.Wide2AnsiMoveProc(PWideChar(Pointer(S2)),fpc_WideStr_To_AnsiStr,Size);
  239. { Terminating Zero }
  240. // PChar(Pointer(fpc_WideStr_To_AnsiStr)+Size)^:=#0;
  241. end;
  242. end;
  243. Function fpc_AnsiStr_To_WideStr (Const S2 : AnsiString): WideString; compilerproc;
  244. {
  245. Converts an AnsiString to a WideString;
  246. }
  247. Var
  248. Size : SizeInt;
  249. begin
  250. if s2='' then
  251. exit;
  252. Size:=Length(S2);
  253. // Setlength (result,Size);
  254. if Size>0 then
  255. begin
  256. widestringmanager.Ansi2WideMoveProc(PChar(S2),result,Size);
  257. { Terminating Zero }
  258. // PWideChar(Pointer(result)+Size*sizeof(WideChar))^:=#0;
  259. end;
  260. end;
  261. { compilers with widestrings should have compiler procs }
  262. Function fpc_PWideChar_To_AnsiStr(const p : pwidechar): ansistring; compilerproc;
  263. var
  264. Size : SizeInt;
  265. begin
  266. if p=nil then
  267. exit;
  268. Size := IndexWord(p^, -1, 0);
  269. // Setlength (result,Size);
  270. if Size>0 then
  271. begin
  272. widestringmanager.Wide2AnsiMoveProc(P,result,Size);
  273. { Terminating Zero }
  274. // PChar(Pointer(result)+Size)^:=#0;
  275. end;
  276. end;
  277. Function fpc_PWideChar_To_WideStr(const p : pwidechar): widestring; compilerproc;
  278. var
  279. Size : SizeInt;
  280. begin
  281. if p=nil then
  282. exit;
  283. Size := IndexWord(p^, -1, 0);
  284. Setlength (result,Size);
  285. if Size>0 then
  286. begin
  287. Move(p^,PWideChar(Pointer(result))^,Size*sizeof(WideChar));
  288. { Terminating Zero }
  289. PWideChar(Pointer(result)+Size*sizeof(WideChar))^:=#0;
  290. end;
  291. end;
  292. Function fpc_PWideChar_To_ShortStr(const p : pwidechar): shortstring; compilerproc;
  293. var
  294. Size : SizeInt;
  295. temp: ansistring;
  296. begin
  297. if p=nil then
  298. begin
  299. fpc_PWideChar_To_ShortStr:='';
  300. exit;
  301. end;
  302. Size := IndexWord(p^, $7fffffff, 0);
  303. // Setlength (result,Size+1);
  304. if Size>0 then
  305. begin
  306. // If Size>255 then
  307. // Size:=255;
  308. widestringmanager.Wide2AnsiMoveProc(p,temp,Size);
  309. // byte(result[0]):=byte(Size);
  310. end;
  311. result := temp
  312. end;
  313. { checked against the ansistring routine, 2001-05-27 (FK) }
  314. Procedure fpc_WideStr_Assign (Var S1 : Pointer;S2 : Pointer);[Public,Alias:'FPC_WIDESTR_ASSIGN']; compilerproc;
  315. {
  316. Assigns S2 to S1 (S1:=S2), taking in account reference counts.
  317. }
  318. begin
  319. If S2<>nil then
  320. If PWideRec(S2-WideFirstOff)^.Ref>0 then
  321. Inc(PWideRec(S2-WideFirstOff)^.ref);
  322. { Decrease the reference count on the old S1 }
  323. fpc_widestr_decr_ref (S1);
  324. { And finally, have S1 pointing to S2 (or its copy) }
  325. S1:=S2;
  326. end;
  327. { alias for internal use }
  328. Procedure fpc_WideStr_Assign (Var S1 : Pointer;S2 : Pointer);[external name 'FPC_WIDESTR_ASSIGN'];
  329. { checked against the ansistring routine, 2001-05-27 (FK) }
  330. function fpc_WideStr_Concat (const S1,S2 : WideString): WideString; compilerproc;
  331. var
  332. S3: WideString absolute result;
  333. {
  334. Concatenates 2 WideStrings : S1+S2.
  335. Result Goes to S3;
  336. }
  337. Var
  338. Size,Location : SizeInt;
  339. begin
  340. { only assign if s1 or s2 is empty }
  341. if (S1='') then
  342. S3 := S2
  343. else
  344. if (S2='') then
  345. S3 := S1
  346. else
  347. begin
  348. { create new result }
  349. Size:=Length(S2);
  350. Location:=Length(S1);
  351. SetLength (S3,Size+Location);
  352. Move (S1[1],S3[1],Location*sizeof(WideChar));
  353. Move (S2[1],S3[location+1],(Size+1)*sizeof(WideChar));
  354. end;
  355. end;
  356. Function fpc_Char_To_WideStr(const c : WideChar): WideString; compilerproc;
  357. {
  358. Converts a Char to a WideString;
  359. }
  360. begin
  361. if c = #0 then
  362. { result is automatically set to '' }
  363. exit;
  364. Setlength (fpc_Char_To_WideStr,1);
  365. fpc_Char_To_WideStr[1]:=c;
  366. { Terminating Zero }
  367. PWideChar(Pointer(fpc_Char_To_WideStr)+sizeof(WideChar))^:=#0;
  368. end;
  369. Function fpc_PChar_To_WideStr(const p : pchar): WideString; compilerproc;
  370. Var
  371. L : SizeInt;
  372. begin
  373. if (not assigned(p)) or (p[0]=#0) Then
  374. { result is automatically set to '' }
  375. exit;
  376. l:=IndexChar(p^,-1,#0);
  377. //SetLength(fpc_PChar_To_WideStr,L);
  378. widestringmanager.Ansi2WideMoveProc(P,fpc_PChar_To_WideStr,l);
  379. end;
  380. Function fpc_CharArray_To_WideStr(const arr: array of char): WideString; compilerproc;
  381. var
  382. i : SizeInt;
  383. begin
  384. if arr[0]=#0 Then
  385. { result is automatically set to '' }
  386. exit;
  387. i:=IndexChar(arr,high(arr)+1,#0);
  388. if i = -1 then
  389. i := high(arr)+1;
  390. SetLength(fpc_CharArray_To_WideStr,i);
  391. widestringmanager.Ansi2WideMoveProc (pchar(@arr),fpc_CharArray_To_WideStr,i);
  392. end;
  393. function fpc_WideCharArray_To_ShortStr(const arr: array of widechar): shortstring;[public,alias:'FPC_WIDECHARARRAY_TO_SHORTSTR']; compilerproc;
  394. var
  395. l: longint;
  396. index: longint;
  397. len: byte;
  398. temp: ansistring;
  399. begin
  400. l := high(arr)+1;
  401. if l>=256 then
  402. l:=255
  403. else if l<0 then
  404. l:=0;
  405. index:=IndexWord(arr[0],l,0);
  406. if (index < 0) then
  407. len := l
  408. else
  409. len := index;
  410. widestringmanager.Wide2AnsiMoveProc (pwidechar(@arr),temp,len);
  411. fpc_WideCharArray_To_ShortStr := temp;
  412. //fpc_WideCharArray_To_ShortStr[0]:=chr(len);
  413. end;
  414. Function fpc_WideCharArray_To_AnsiStr(const arr: array of widechar): AnsiString; compilerproc;
  415. var
  416. i : SizeInt;
  417. begin
  418. if arr[0]=#0 Then
  419. { result is automatically set to '' }
  420. exit;
  421. i:=IndexWord(arr,high(arr)+1,0);
  422. if i = -1 then
  423. i := high(arr)+1;
  424. SetLength(fpc_WideCharArray_To_AnsiStr,i);
  425. widestringmanager.Wide2AnsiMoveProc (pwidechar(@arr),fpc_WideCharArray_To_AnsiStr,i);
  426. end;
  427. Function fpc_WideCharArray_To_WideStr(const arr: array of widechar): WideString; compilerproc;
  428. var
  429. i : SizeInt;
  430. begin
  431. if arr[0]=#0 Then
  432. { result is automatically set to '' }
  433. exit;
  434. i:=IndexWord(arr,high(arr)+1,0);
  435. if i = -1 then
  436. i := high(arr)+1;
  437. SetLength(fpc_WideCharArray_To_WideStr,i);
  438. Move(pwidechar(@arr)^, PWideChar(Pointer(@fpc_WideCharArray_To_WideStr[1]))^,i*sizeof(WideChar));
  439. { Terminating Zero }
  440. PWideChar(Pointer(@fpc_WideCharArray_To_WideStr[1])+i*sizeof(WideChar))^:=#0;
  441. end;
  442. { inside the compiler, the resulttype is modified to that of the actual }
  443. { chararray we're converting to (JM) }
  444. function fpc_widestr_to_chararray(arraysize: SizeInt; const src: WideString): fpc_big_chararray;[public,alias: 'FPC_WIDESTR_TO_CHARARRAY']; compilerproc;
  445. var
  446. len: SizeInt;
  447. temp: ansistring;
  448. begin
  449. len := length(src);
  450. { make sure we don't dereference src if it can be nil (JM) }
  451. if len > 0 then
  452. widestringmanager.wide2ansimoveproc(pwidechar(@src[1]),temp,len);
  453. len := length(temp);
  454. if len > arraysize then
  455. len := arraysize;
  456. move(temp[1],fpc_widestr_to_chararray[0],len);
  457. fillchar(fpc_widestr_to_chararray[len],arraysize-len,0);
  458. end;
  459. { inside the compiler, the resulttype is modified to that of the actual }
  460. { widechararray we're converting to (JM) }
  461. function fpc_widestr_to_widechararray(arraysize: SizeInt; const src: WideString): fpc_big_widechararray;[public,alias: 'FPC_WIDESTR_TO_WIDECHARARRAY']; compilerproc;
  462. var
  463. len: SizeInt;
  464. begin
  465. len := length(src);
  466. if len > arraysize then
  467. len := arraysize;
  468. { make sure we don't try to access element 1 of the ansistring if it's nil }
  469. if len > 0 then
  470. move(src[1],fpc_widestr_to_widechararray[0],len*SizeOf(WideChar));
  471. fillchar(fpc_widestr_to_widechararray[len],(arraysize-len)*SizeOf(WideChar),0);
  472. end;
  473. { inside the compiler, the resulttype is modified to that of the actual }
  474. { chararray we're converting to (JM) }
  475. function fpc_ansistr_to_widechararray(arraysize: SizeInt; const src: AnsiString): fpc_big_widechararray;[public,alias: 'FPC_ANSISTR_TO_WIDECHARARRAY']; compilerproc;
  476. var
  477. len: SizeInt;
  478. temp: widestring;
  479. begin
  480. len := length(src);
  481. { make sure we don't dereference src if it can be nil (JM) }
  482. if len > 0 then
  483. widestringmanager.ansi2widemoveproc(pchar(@src[1]),temp,len);
  484. len := length(temp);
  485. if len > arraysize then
  486. len := arraysize;
  487. move(temp[1],fpc_ansistr_to_widechararray[0],len*sizeof(widechar));
  488. fillchar(fpc_ansistr_to_widechararray[len],(arraysize-len)*SizeOf(WideChar),0);
  489. end;
  490. function fpc_shortstr_to_widechararray(arraysize: SizeInt; const src: ShortString): fpc_big_widechararray;[public,alias: 'FPC_SHORTSTR_TO_WIDECHARARRAY']; compilerproc;
  491. var
  492. len: longint;
  493. temp : widestring;
  494. begin
  495. len := length(src);
  496. { make sure we don't access char 1 if length is 0 (JM) }
  497. if len > 0 then
  498. widestringmanager.ansi2widemoveproc(pchar(@src[1]),temp,len);
  499. len := length(temp);
  500. if len > arraysize then
  501. len := arraysize;
  502. move(temp[1],fpc_shortstr_to_widechararray[0],len*sizeof(widechar));
  503. fillchar(fpc_shortstr_to_widechararray[len],(arraysize-len)*SizeOf(WideChar),0);
  504. end;
  505. Function fpc_WideStr_Compare(const S1,S2 : WideString): SizeInt;[Public,Alias : 'FPC_WIDESTR_COMPARE']; compilerproc;
  506. {
  507. Compares 2 WideStrings;
  508. The result is
  509. <0 if S1<S2
  510. 0 if S1=S2
  511. >0 if S1>S2
  512. }
  513. Var
  514. MaxI,Temp : SizeInt;
  515. begin
  516. if pointer(S1)=pointer(S2) then
  517. begin
  518. fpc_WideStr_Compare:=0;
  519. exit;
  520. end;
  521. Maxi:=Length(S1);
  522. temp:=Length(S2);
  523. If MaxI>Temp then
  524. MaxI:=Temp;
  525. Temp:=CompareWord(S1[1],S2[1],MaxI);
  526. if temp=0 then
  527. temp:=Length(S1)-Length(S2);
  528. fpc_WideStr_Compare:=Temp;
  529. end;
  530. Procedure fpc_WideStr_CheckZero(p : pointer);[Public,Alias : 'FPC_WIDESTR_CHECKZERO']; compilerproc;
  531. begin
  532. if p=nil then
  533. HandleErrorFrame(201,get_frame);
  534. end;
  535. Procedure fpc_WideStr_CheckRange(len,index : SizeInt);[Public,Alias : 'FPC_WIDESTR_RANGECHECK']; compilerproc;
  536. begin
  537. if (index>len) or (Index<1) then
  538. HandleErrorFrame(201,get_frame);
  539. end;
  540. Procedure fpc_WideStr_SetLength (Var S : WideString; l : SizeInt);[Public,Alias : 'FPC_WIDESTR_SETLENGTH']; compilerproc;
  541. {
  542. Sets The length of string S to L.
  543. Makes sure S is unique, and contains enough room.
  544. }
  545. Var
  546. Temp : Pointer;
  547. movelen: SizeInt;
  548. begin
  549. if (l>0) then
  550. begin
  551. if Pointer(S)=nil then
  552. begin
  553. { Need a complete new string...}
  554. Pointer(s):=NewWideString(l);
  555. end
  556. { windows doesn't support reallocing widestrings, this code
  557. is anyways subject to be removed because widestrings shouldn't be
  558. ref. counted anymore (FK) }
  559. else if
  560. {$ifdef MSWINDOWS}
  561. not winwidestringalloc and
  562. {$endif MSWINDOWS}
  563. (PWideRec(Pointer(S)-WideFirstOff)^.Ref = 1) then
  564. begin
  565. Dec(Pointer(S),WideFirstOff);
  566. if L*sizeof(WideChar)+WideRecLen>MemSize(Pointer(S)) then
  567. reallocmem(pointer(S), L*sizeof(WideChar)+WideRecLen);
  568. Inc(Pointer(S), WideFirstOff);
  569. end
  570. else
  571. begin
  572. { Reallocation is needed... }
  573. Temp:=Pointer(NewWideString(L));
  574. if Length(S)>0 then
  575. begin
  576. if l < succ(length(s)) then
  577. movelen := l
  578. { also move terminating null }
  579. else movelen := succ(length(s));
  580. Move(Pointer(S)^,Temp^,movelen * Sizeof(WideChar));
  581. end;
  582. fpc_widestr_decr_ref(Pointer(S));
  583. Pointer(S):=Temp;
  584. end;
  585. { Force nil termination in case it gets shorter }
  586. PWord(Pointer(S)+l*sizeof(WideChar))^:=0;
  587. PWideRec(Pointer(S)-FirstOff)^.Len:=l;
  588. end
  589. else
  590. begin
  591. { Length=0 }
  592. if Pointer(S)<>nil then
  593. fpc_widestr_decr_ref (Pointer(S));
  594. Pointer(S):=Nil;
  595. end;
  596. end;
  597. {*****************************************************************************
  598. Public functions, In interface.
  599. *****************************************************************************}
  600. function WideCharToString(S : PWideChar) : AnsiString;
  601. begin
  602. result:=WideCharLenToString(s,Length(WideString(s)));
  603. end;
  604. function StringToWideChar(const Src : AnsiString;Dest : PWideChar;DestSize : SizeInt) : PWideChar;
  605. var
  606. temp:widestring;
  607. begin
  608. widestringmanager.Ansi2WideMoveProc(PChar(Src),temp,Length(Src));
  609. if Length(temp)<DestSize then
  610. move(temp[1],Dest^,Length(temp)*SizeOf(WideChar))
  611. else
  612. move(temp[1],Dest^,(DestSize-1)*SizeOf(WideChar));
  613. Dest[DestSize-1]:=#0;
  614. result:=Dest;
  615. end;
  616. function WideCharLenToString(S : PWideChar;Len : SizeInt) : AnsiString;
  617. begin
  618. //SetLength(result,Len);
  619. widestringmanager.Wide2AnsiMoveproc(S,result,Len);
  620. end;
  621. procedure WideCharLenToStrVar(Src : PWideChar;Len : SizeInt;var Dest : AnsiString);
  622. begin
  623. Dest:=WideCharLenToString(Src,Len);
  624. end;
  625. procedure WideCharToStrVar(S : PWideChar;var Dest : AnsiString);
  626. begin
  627. Dest:=WideCharToString(S);
  628. end;
  629. Function fpc_widestr_Unique(Var S : Pointer): Pointer; [Public,Alias : 'FPC_WIDESTR_UNIQUE']; compilerproc;
  630. {
  631. Make sure reference count of S is 1,
  632. using copy-on-write semantics.
  633. }
  634. Var
  635. SNew : Pointer;
  636. L : SizeInt;
  637. begin
  638. pointer(result) := pointer(s);
  639. If Pointer(S)=Nil then
  640. exit;
  641. if PWideRec(Pointer(S)-WideFirstOff)^.Ref<>1 then
  642. begin
  643. L:=PWideRec(Pointer(S)-WideFirstOff)^.len;
  644. SNew:=NewWideString (L);
  645. Move (PWideChar(S)^,SNew^,(L+1)*sizeof(WideChar));
  646. PWideRec(SNew-WideFirstOff)^.len:=L;
  647. fpc_widestr_decr_ref (Pointer(S)); { Thread safe }
  648. pointer(S):=SNew;
  649. pointer(result):=SNew;
  650. end;
  651. end;
  652. Function Fpc_WideStr_Copy (Const S : WideString; Index,Size : SizeInt) : WideString;compilerproc;
  653. var
  654. ResultAddress : Pointer;
  655. begin
  656. ResultAddress:=Nil;
  657. dec(index);
  658. if Index < 0 then
  659. Index := 0;
  660. { Check Size. Accounts for Zero-length S, the double check is needed because
  661. Size can be maxint and will get <0 when adding index }
  662. if (Size>Length(S)) or
  663. (Index+Size>Length(S)) then
  664. Size:=Length(S)-Index;
  665. If Size>0 then
  666. begin
  667. If Index<0 Then
  668. Index:=0;
  669. ResultAddress:=Pointer(NewWideString (Size));
  670. if ResultAddress<>Nil then
  671. begin
  672. Move (PWideChar(S)[Index],ResultAddress^,Size*sizeof(WideChar));
  673. PWideRec(ResultAddress-WideFirstOff)^.Len:=Size;
  674. PWideChar(ResultAddress+Size*sizeof(WideChar))^:=#0;
  675. end;
  676. end;
  677. Pointer(fpc_widestr_Copy):=ResultAddress;
  678. end;
  679. Function Pos (Const Substr : WideString; Const Source : WideString) : SizeInt;
  680. var
  681. i,MaxLen : SizeInt;
  682. pc : pwidechar;
  683. begin
  684. Pos:=0;
  685. if Length(SubStr)>0 then
  686. begin
  687. MaxLen:=Length(source)-Length(SubStr);
  688. i:=0;
  689. pc:=@source[1];
  690. while (i<=MaxLen) do
  691. begin
  692. inc(i);
  693. if (SubStr[1]=pc^) and
  694. (CompareWord(Substr[1],pc^,Length(SubStr))=0) then
  695. begin
  696. Pos:=i;
  697. exit;
  698. end;
  699. inc(pc);
  700. end;
  701. end;
  702. end;
  703. { Faster version for a widechar alone }
  704. Function Pos (c : WideChar; Const s : WideString) : SizeInt;
  705. var
  706. i: SizeInt;
  707. pc : pwidechar;
  708. begin
  709. pc:=@s[1];
  710. for i:=1 to length(s) do
  711. begin
  712. if pc^=c then
  713. begin
  714. pos:=i;
  715. exit;
  716. end;
  717. inc(pc);
  718. end;
  719. pos:=0;
  720. end;
  721. Function Pos (c : WideChar; Const s : AnsiString) : SizeInt;
  722. var
  723. i: SizeInt;
  724. pc : pchar;
  725. begin
  726. pc:=@s[1];
  727. for i:=1 to length(s) do
  728. begin
  729. if widechar(pc^)=c then
  730. begin
  731. pos:=i;
  732. exit;
  733. end;
  734. inc(pc);
  735. end;
  736. pos:=0;
  737. end;
  738. Function Pos (c : AnsiString; Const s : WideString) : SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  739. begin
  740. result:=Pos(WideString(c),s);
  741. end;
  742. Function Pos (c : ShortString; Const s : WideString) : SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  743. begin
  744. result:=Pos(WideString(c),s);
  745. end;
  746. Function Pos (c : WideString; Const s : AnsiString) : SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  747. begin
  748. result:=Pos(c,WideString(s));
  749. end;
  750. { Faster version for a char alone. Must be implemented because }
  751. { pos(c: char; const s: shortstring) also exists, so otherwise }
  752. { using pos(char,pchar) will always call the shortstring version }
  753. { (exact match for first argument), also with $h+ (JM) }
  754. Function Pos (c : Char; Const s : WideString) : SizeInt;
  755. var
  756. i: SizeInt;
  757. wc : widechar;
  758. pc : pwidechar;
  759. begin
  760. wc:=c;
  761. pc:=@s[1];
  762. for i:=1 to length(s) do
  763. begin
  764. if pc^=wc then
  765. begin
  766. pos:=i;
  767. exit;
  768. end;
  769. inc(pc);
  770. end;
  771. pos:=0;
  772. end;
  773. Procedure Delete (Var S : WideString; Index,Size: SizeInt);
  774. Var
  775. LS : SizeInt;
  776. begin
  777. If Length(S)=0 then
  778. exit;
  779. if index<=0 then
  780. exit;
  781. LS:=PWideRec(Pointer(S)-WideFirstOff)^.Len;
  782. if (Index<=LS) and (Size>0) then
  783. begin
  784. UniqueString (S);
  785. if Size+Index>LS then
  786. Size:=LS-Index+1;
  787. if Index+Size<=LS then
  788. begin
  789. Dec(Index);
  790. Move(PWideChar(S)[Index+Size],PWideChar(S)[Index],(LS-Index+1)*sizeof(WideChar));
  791. end;
  792. Setlength(s,LS-Size);
  793. end;
  794. end;
  795. Procedure Insert (Const Source : WideString; Var S : WideString; Index : SizeInt);
  796. var
  797. Temp : WideString;
  798. LS : SizeInt;
  799. begin
  800. If Length(Source)=0 then
  801. exit;
  802. if index <= 0 then
  803. index := 1;
  804. Ls:=Length(S);
  805. if index > LS then
  806. index := LS+1;
  807. Dec(Index);
  808. Pointer(Temp) := NewWideString(Length(Source)+LS);
  809. SetLength(Temp,Length(Source)+LS);
  810. If Index>0 then
  811. move (PWideChar(S)^,PWideChar(Temp)^,Index*sizeof(WideChar));
  812. Move (PWideChar(Source)^,PWideChar(Temp)[Index],Length(Source)*sizeof(WideChar));
  813. If (LS-Index)>0 then
  814. Move(PWideChar(S)[Index],PWideChar(temp)[Length(Source)+index],(LS-Index)*sizeof(WideChar));
  815. S:=Temp;
  816. end;
  817. function UpCase(const s : WideString) : WideString;
  818. begin
  819. result:=widestringmanager.UpperWideStringProc(s);
  820. end;
  821. Procedure SetString (Var S : WideString; Buf : PWideChar; Len : SizeInt);
  822. var
  823. BufLen: SizeInt;
  824. begin
  825. SetLength(S,Len);
  826. If (Buf<>Nil) and (Len>0) then
  827. begin
  828. BufLen := IndexWord(Buf^, Len+1, 0);
  829. If (BufLen>0) and (BufLen < Len) then
  830. Len := BufLen;
  831. Move (Buf[0],S[1],Len*sizeof(WideChar));
  832. PWideChar(Pointer(S)+Len*sizeof(WideChar))^:=#0;
  833. end;
  834. end;
  835. Procedure SetString (Var S : WideString; Buf : PChar; Len : SizeInt);
  836. var
  837. BufLen: SizeInt;
  838. begin
  839. SetLength(S,Len);
  840. If (Buf<>Nil) and (Len>0) then
  841. begin
  842. BufLen := IndexByte(Buf^, Len+1, 0);
  843. If (BufLen>0) and (BufLen < Len) then
  844. Len := BufLen;
  845. widestringmanager.Ansi2WideMoveProc(Buf,S,Len);
  846. //PWideChar(Pointer(S)+Len*sizeof(WideChar))^:=#0;
  847. end;
  848. end;
  849. Function fpc_Val_Real_WideStr(Const S : WideString; Var Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_WIDESTR']; compilerproc;
  850. Var
  851. SS : String;
  852. begin
  853. fpc_Val_Real_WideStr := 0;
  854. if length(S) > 255 then
  855. code := 256
  856. else
  857. begin
  858. SS := S;
  859. Val(SS,fpc_Val_Real_WideStr,code);
  860. end;
  861. end;
  862. Function fpc_Val_UInt_WideStr (Const S : WideString; Var Code : ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_WIDESTR']; compilerproc;
  863. Var
  864. SS : ShortString;
  865. begin
  866. fpc_Val_UInt_WideStr := 0;
  867. if length(S) > 255 then
  868. code := 256
  869. else
  870. begin
  871. SS := S;
  872. Val(SS,fpc_Val_UInt_WideStr,code);
  873. end;
  874. end;
  875. Function fpc_Val_SInt_WideStr (DestSize: SizeInt; Const S : WideString; Var Code : ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_WIDESTR']; compilerproc;
  876. Var
  877. SS : ShortString;
  878. begin
  879. fpc_Val_SInt_WideStr:=0;
  880. if length(S)>255 then
  881. code:=256
  882. else
  883. begin
  884. SS := S;
  885. fpc_Val_SInt_WideStr := int_Val_SInt_ShortStr(DestSize,SS,Code);
  886. end;
  887. end;
  888. {$ifndef CPU64}
  889. Function fpc_Val_qword_WideStr (Const S : WideString; Var Code : ValSInt): qword; [public, alias:'FPC_VAL_QWORD_WIDESTR']; compilerproc;
  890. Var
  891. SS : ShortString;
  892. begin
  893. fpc_Val_qword_WideStr:=0;
  894. if length(S)>255 then
  895. code:=256
  896. else
  897. begin
  898. SS := S;
  899. Val(SS,fpc_Val_qword_WideStr,Code);
  900. end;
  901. end;
  902. Function fpc_Val_int64_WideStr (Const S : WideString; Var Code : ValSInt): Int64; [public, alias:'FPC_VAL_INT64_WIDESTR']; compilerproc;
  903. Var
  904. SS : ShortString;
  905. begin
  906. fpc_Val_int64_WideStr:=0;
  907. if length(S)>255 then
  908. code:=256
  909. else
  910. begin
  911. SS := S;
  912. Val(SS,fpc_Val_int64_WideStr,Code);
  913. end;
  914. end;
  915. {$endif CPU64}
  916. procedure fpc_WideStr_Float(d : ValReal;len,fr,rt : SizeInt;var s : WideString);compilerproc;
  917. var
  918. ss : shortstring;
  919. begin
  920. str_real(len,fr,d,treal_type(rt),ss);
  921. s:=ss;
  922. end;
  923. Procedure fpc_WideStr_SInt(v : ValSint; Len : SizeInt; Var S : WideString);compilerproc;
  924. Var
  925. SS : ShortString;
  926. begin
  927. Str (v:Len,SS);
  928. S:=SS;
  929. end;
  930. Procedure fpc_WideStr_UInt(v : ValUInt;Len : SizeInt; Var S : WideString);compilerproc;
  931. Var
  932. SS : ShortString;
  933. begin
  934. str(v:Len,SS);
  935. S:=SS;
  936. end;
  937. {$ifndef CPU64}
  938. Procedure fpc_WideStr_Int64(v : Int64; Len : SizeInt; Var S : WideString);compilerproc;
  939. Var
  940. SS : ShortString;
  941. begin
  942. Str (v:Len,SS);
  943. S:=SS;
  944. end;
  945. Procedure fpc_WideStr_Qword(v : Qword;Len : SizeInt; Var S : WideString);compilerproc;
  946. Var
  947. SS : ShortString;
  948. begin
  949. str(v:Len,SS);
  950. S:=SS;
  951. end;
  952. {$endif CPU64}
  953. function UnicodeToUtf8(Dest: PChar; Source: PWideChar; MaxBytes: SizeInt): SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  954. begin
  955. if assigned(Source) then
  956. Result:=UnicodeToUtf8(Dest,MaxBytes,Source,IndexWord(Source^,-1,0))
  957. else
  958. Result:=0;
  959. end;
  960. function UnicodeToUtf8(Dest: PChar; MaxDestBytes: SizeUInt; Source: PWideChar; SourceChars: SizeUInt): SizeUInt;
  961. var
  962. i,j : SizeUInt;
  963. w : word;
  964. begin
  965. result:=0;
  966. if source=nil then
  967. exit;
  968. i:=0;
  969. j:=0;
  970. if assigned(Dest) then
  971. begin
  972. while (i<SourceChars) and (j<MaxDestBytes) do
  973. begin
  974. w:=word(Source[i]);
  975. case w of
  976. 0..$7f:
  977. begin
  978. Dest[j]:=char(w);
  979. inc(j);
  980. end;
  981. $80..$7ff:
  982. begin
  983. if j+1>=MaxDestBytes then
  984. break;
  985. Dest[j]:=char($c0 or (w shr 6));
  986. Dest[j+1]:=char($80 or (w and $3f));
  987. inc(j,2);
  988. end;
  989. else
  990. begin
  991. if j+2>=MaxDestBytes then
  992. break;
  993. Dest[j]:=char($e0 or (w shr 12));
  994. Dest[j+1]:=char($80 or ((w shr 6)and $3f));
  995. Dest[j+2]:=char($80 or (w and $3f));
  996. inc(j,3);
  997. end;
  998. end;
  999. inc(i);
  1000. end;
  1001. if j>MaxDestBytes-1 then
  1002. j:=MaxDestBytes-1;
  1003. Dest[j]:=#0;
  1004. end
  1005. else
  1006. begin
  1007. while i<SourceChars do
  1008. begin
  1009. case word(Source[i]) of
  1010. $0..$7f:
  1011. inc(j);
  1012. $80..$7ff:
  1013. inc(j,2);
  1014. else
  1015. inc(j,3);
  1016. end;
  1017. end;
  1018. end;
  1019. result:=j+1;
  1020. end;
  1021. function Utf8ToUnicode(Dest: PWideChar; Source: PChar; MaxChars: SizeInt): SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  1022. begin
  1023. if assigned(Source) then
  1024. Result:=Utf8ToUnicode(Dest,MaxChars,Source,strlen(Source))
  1025. else
  1026. Result:=0;
  1027. end;
  1028. function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: SizeUInt; Source: PChar; SourceBytes: SizeUInt): SizeUInt;
  1029. var
  1030. i,j : SizeUInt;
  1031. w: SizeUInt;
  1032. b : byte;
  1033. begin
  1034. if not assigned(Source) then
  1035. begin
  1036. result:=0;
  1037. exit;
  1038. end;
  1039. result:=SizeUInt(-1);
  1040. i:=0;
  1041. j:=0;
  1042. if assigned(Dest) then
  1043. begin
  1044. while (j<MaxDestChars) and (i<SourceBytes) do
  1045. begin
  1046. b:=byte(Source[i]);
  1047. w:=b;
  1048. inc(i);
  1049. // 2 or 3 bytes?
  1050. if b>=$80 then
  1051. begin
  1052. w:=b and $3f;
  1053. if i>=SourceBytes then
  1054. exit;
  1055. // 3 bytes?
  1056. if (b and $20)<>0 then
  1057. begin
  1058. b:=byte(Source[i]);
  1059. inc(i);
  1060. if i>=SourceBytes then
  1061. exit;
  1062. if (b and $c0)<>$80 then
  1063. exit;
  1064. w:=(w shl 6) or (b and $3f);
  1065. end;
  1066. b:=byte(Source[i]);
  1067. w:=(w shl 6) or (b and $3f);
  1068. if (b and $c0)<>$80 then
  1069. exit;
  1070. inc(i);
  1071. end;
  1072. Dest[j]:=WideChar(w);
  1073. inc(j);
  1074. end;
  1075. if j>=MaxDestChars then j:=MaxDestChars-1;
  1076. Dest[j]:=#0;
  1077. end
  1078. else
  1079. begin
  1080. while i<SourceBytes do
  1081. begin
  1082. b:=byte(Source[i]);
  1083. inc(i);
  1084. // 2 or 3 bytes?
  1085. if b>=$80 then
  1086. begin
  1087. if i>=SourceBytes then
  1088. exit;
  1089. // 3 bytes?
  1090. b := b and $3f;
  1091. if (b and $20)<>0 then
  1092. begin
  1093. b:=byte(Source[i]);
  1094. inc(i);
  1095. if i>=SourceBytes then
  1096. exit;
  1097. if (b and $c0)<>$80 then
  1098. exit;
  1099. end;
  1100. if (byte(Source[i]) and $c0)<>$80 then
  1101. exit;
  1102. inc(i);
  1103. end;
  1104. inc(j);
  1105. end;
  1106. end;
  1107. result:=j+1;
  1108. end;
  1109. function UTF8Encode(const s : WideString) : UTF8String;
  1110. var
  1111. i : SizeInt;
  1112. hs : UTF8String;
  1113. begin
  1114. result:='';
  1115. if s='' then
  1116. exit;
  1117. SetLength(hs,length(s)*3);
  1118. i:=UnicodeToUtf8(pchar(hs),length(hs)+1,PWideChar(s),length(s));
  1119. if i>0 then
  1120. begin
  1121. SetLength(hs,i-1);
  1122. result:=hs;
  1123. end;
  1124. end;
  1125. function UTF8Decode(const s : UTF8String): WideString;
  1126. var
  1127. i : SizeInt;
  1128. hs : WideString;
  1129. begin
  1130. result:='';
  1131. if s='' then
  1132. exit;
  1133. SetLength(hs,length(s));
  1134. i:=Utf8ToUnicode(PWideChar(hs),length(hs)+1,pchar(s),length(s));
  1135. if i>0 then
  1136. begin
  1137. SetLength(hs,i-1);
  1138. result:=hs;
  1139. end;
  1140. end;
  1141. function AnsiToUtf8(const s : ansistring): UTF8String;{$ifdef SYSTEMINLINE}inline;{$endif}
  1142. begin
  1143. Result:=Utf8Encode(s);
  1144. end;
  1145. function Utf8ToAnsi(const s : UTF8String) : ansistring;{$ifdef SYSTEMINLINE}inline;{$endif}
  1146. begin
  1147. Result:=Utf8Decode(s);
  1148. end;
  1149. function WideStringToUCS4String(const s : WideString) : UCS4String;
  1150. var
  1151. i : SizeInt;
  1152. begin
  1153. setlength(result,length(s)+1);
  1154. for i:=1 to length(s) do
  1155. result[i-1]:=UCS4Char(s[i]);
  1156. result[length(s)]:=UCS4Char(0);
  1157. end;
  1158. function UCS4StringToWideString(const s : UCS4String) : WideString;
  1159. var
  1160. i : SizeInt;
  1161. begin
  1162. setlength(result,length(s)-1);
  1163. for i:=1 to length(s)-1 do
  1164. result[i]:=WideChar(s[i-1]);
  1165. end;
  1166. procedure unimplementedwidestring;
  1167. begin
  1168. HandleErrorFrame(215,get_frame);
  1169. end;
  1170. function GenericWideCase(const s : WideString) : WideString;
  1171. begin
  1172. unimplementedwidestring;
  1173. end;
  1174. function CompareWideString(const s1, s2 : WideString) : PtrInt;
  1175. begin
  1176. unimplementedwidestring;
  1177. end;
  1178. function CompareTextWideString(const s1, s2 : WideString): PtrInt;
  1179. begin
  1180. unimplementedwidestring;
  1181. end;
  1182. function CharLengthPChar(const Str: PChar): PtrInt;
  1183. begin
  1184. unimplementedwidestring;
  1185. end;
  1186. procedure initwidestringmanager;
  1187. begin
  1188. fillchar(widestringmanager,sizeof(widestringmanager),0);
  1189. widestringmanager.Wide2AnsiMoveProc:=@defaultWide2AnsiMove;
  1190. widestringmanager.Ansi2WideMoveProc:=@defaultAnsi2WideMove;
  1191. widestringmanager.UpperWideStringProc:=@GenericWideCase;
  1192. widestringmanager.LowerWideStringProc:=@GenericWideCase;
  1193. widestringmanager.CompareWideStringProc:=@CompareWideString;
  1194. widestringmanager.CompareTextWideStringProc:=@CompareTextWideString;
  1195. widestringmanager.CharLengthPCharProc:=@CharLengthPChar;
  1196. end;