1 {*********************************************************}
3 { Zeos Database Objects }
4 { Compatibility Classes and Functions }
6 { Originally written by Sergey Seroukhov }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
65 {$IFDEF WITH_WIDESTRUTILS}
68 {$If defined(MSWINDOWS) and not defined(FPC)}
72 {$IFDEF MSEgui}mclasses,{$ENDIF}
73 {$IFDEF WITH_LCONVENCODING} LConvEncoding,{$ENDIF}
79 ULong = {$IFDEF WIN64}LongWord{$ELSE}PTRUINT{$ENDIF};
80 // EgonHugeist: Use always a 4Byte Integer as long the PlainDriver dll's are 32Bit for Windows64
81 //on the other hand MySQL64 and FB64 have problems on Win64!
85 PNativeUInt = ^NativeUInt;
89 NativeUInt = LongWord;
90 PNativeUInt = ^NativeUInt;
91 PWord = ^Word; // M.A.
94 ULongLong = {$IFDEF WITH_UINT64}Uint64{$ELSE}Int64{$ENDIF}; //delphi don“t have Unsigned Int64 type
97 PULongLong = ^ULongLong;
101 ZPPWideChar = ^PWideChar;//BCB issue: PPWideChar is not part of system
103 TObjectDynArray = array of TObject;
106 TDBScreenCursor = (dcrDefault, dcrHourGlass, dcrSQLWait, dcrOther);
108 IDBScreen = interface
109 ['{29A1C508-6ADC-44CD-88DE-4F51B25D5995}']
110 function GetCursor: TDBScreenCursor;
111 procedure SetCursor(Cursor: TDBScreenCursor);
113 property Cursor: TDBScreenCursor read GetCursor write SetCursor;
117 LoginDialogProc: function (const ADatabaseName: string; var AUserName,
118 APassword: string): Boolean;
122 {$IFNDEF FPC} //delphi and windows
125 Brackets = ['(',')','[',']','{','}'];
126 StdWordDelims = [#0..' ',',','.',';','/','\',':','''','"','`'] + Brackets;
128 function Hash(S : AnsiString) : LongWord;
129 function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
134 const SharedSuffix='.dll';
137 const SharedSuffix='.dylib';
140 const SharedSuffix='.so';
142 const SharedSuffix='.dll'; //Delphi
151 INVALID_HANDLE_VALUE = 0;
156 function LoadLibrary(ModuleName: PChar): HMODULE;
157 function FreeLibrary(Module: HMODULE): LongBool;
158 function GetProcAddress(Module: HMODULE; Proc: PChar): Pointer;
164 {$IFNDEF WITH_RAWBYTESTRING}
165 RawByteString = AnsiString;
168 ZWideString = {$IFDEF PWIDECHAR_IS_PUNICODECHAR}UnicodeString{$ELSE}WideString{$ENDIF};
171 {declare move or converter functions for the String Types}
172 TZAnsiToRaw = function (const Src: AnsiString; const RawCP: Word): RawByteString;
173 TZRawToAnsi = function (const Src: RawByteString; const RawCP: Word): AnsiString;
174 TZAnsiToUTF8 = function (const Src: AnsiString): UTF8String;
175 TZUTF8ToAnsi = function (const Src: UTF8String): AnsiString;
176 TZRawToUTF8 = function (const Src: RawByteString; const CP: Word): UTF8String;
177 TZUTF8ToRaw = function (const Src: UTF8String; const CP: Word): RawByteString;
178 TZRawToString = function (const Src: RawByteString; const RawCP, StringCP: Word): String;
179 TZStringToRaw = function (const Src: String; const StringCP, RawCP: Word): RawByteString;
180 TZUTF8ToString = function (const Src: UTF8String; const StringCP: Word): String;
181 TZStringToUTF8 = function (const Src: String; const StringCP: Word): UTF8String;
182 TZAnsiToString = function (const Src: AnsiString; const StringCP: Word): String;
183 TZStringToAnsi = function (const Src: String; const StringCP: Word): AnsiString;
184 TZRawToUnicode = function (const S: RawByteString; const CP: Word): ZWideString;
185 TZUnicodeToRaw = function (const US: ZWideString; CP: Word): RawByteString;
186 TZUnicodeToString = function (const Src: ZWideString; const StringCP: Word): String;
187 TZStringToUnicode = function (const Src: String; const StringCP: Word): ZWideString;
189 {** Defines the Target Ansi codepages for the Controls }
190 TZControlsCodePage = ({$IFDEF UNICODE}cCP_UTF16, cCP_UTF8, cGET_ACP{$ELSE}{$IFDEF FPC}cCP_UTF8, cCP_UTF16, cGET_ACP{$ELSE}cGET_ACP, cCP_UTF8, cCP_UTF16{$ENDIF}{$ENDIF});
193 ceDefault, //Internal switch for the two Functions below do not use it as a CodePage-declaration!
194 ceAnsi, //Base Ansi-String: prefered CodePage
195 ceUTF8, //UTF8_Unicode: 1-4Byte/Char
196 ceUTF16, //Wide or Unicode string encoding for Field-mapping
199 {Here it's possible to add some more, to handle the Ansi->Unicode-Translations}
201 PZCodePage = ^TZCodePage;
203 Name: String; //Name of Client-CharacterSet
204 ID: Integer; //may be an ordinal value of predefined Types or the database used id}
205 CharWidth: Integer; //count of Bytes per char
206 Encoding: TZCharEncoding; //The Type of String-Translation handling
207 CP: Word; //The CodePage the AnsiString must have to
208 ZAlias: String; //A possible (saver?) CharacterSet which is more Zeos compatible... If it's empty it will be ignored!!!
209 IsStringFieldCPConsistent: Boolean; //Is the current client characterset codepage consistent for all codepages?
212 TConvertEncodingFunctions = record
213 ZAnsiToUTF8: TZAnsiToUTF8;
214 ZUTF8ToAnsi: TZUTF8ToAnsi;
215 ZUTF8ToString: TZUTF8ToString;
216 ZStringToUTF8: TZStringToUTF8;
217 ZAnsiToRaw: TZAnsiToRaw;
218 ZRawToAnsi: TZRawToAnsi;
219 ZRawToUTF8: TZRawToUTF8;
220 ZUTF8ToRaw: TZUTF8ToRaw;
221 ZStringToRaw: TZStringToRaw;
222 ZRawToString: TZRawToString;
223 ZAnsiToString: TZAnsiToString;
224 ZStringToAnsi: TZStringToAnsi;
225 ZUnicodeToRaw: TZUnicodeToRaw;
226 ZRawToUnicode: TZRawToUnicode;
227 ZUnicodeToString: TZUnicodeToString;
228 ZStringToUnicode: TZStringToUnicode;
231 PZConSettings = ^TZConSettings;
232 TZConSettings = record
233 AutoEncode: Boolean; //Check Encoding and or convert string with FromCP ToCP
234 CPType: TZControlsCodePage; //the CP-Settings type the controls do expect
235 CTRL_CP: Word; //Target CP of string conversion (CP_ACP/CP_UPF8)
236 ConvFuncs: TConvertEncodingFunctions; //a rec for the Convert functions used by the objects
237 ClientCodePage: PZCodePage; //The codepage informations of the current characterset
239 {$IFDEF WITH_LCONVENCODING}
240 PlainConvertFunc: TConvertEncodingFunction;
241 DbcConvertFunc: TConvertEncodingFunction;
245 TZCodePagedObject = Class(TInterfacedObject)
247 FConSettings: PZConSettings;
249 function ZDbcString(const Ansi: RawByteString; ConSettings: PZConSettings): String; overload;
250 function ZDbcString(const Ansi: RawByteString; FromCP: Word): String; overload;
251 function ZDbcString(const Ansi: RawByteString; const Encoding: TZCharEncoding = ceDefault): String; overload;
252 function ZDbcString(const AStr: ZWideString; const Encoding: TZCharEncoding = ceDefault): String; overload;
253 function ZDbcUnicodeString(const AStr: RawByteString): ZWideString; overload;
254 function ZDbcUnicodeString(const AStr: RawByteString; const FromCP: Word): ZWideString; overload;
255 {$IFDEF WITH_RAWBYTESTRING}
256 function ZDbcUnicodeString(const AStr: String; const FromCP: Word): ZWideString; overload;
258 function ZPlainString(const AStr: String; ConSettings: PZConSettings): RawByteString; overload;
259 function ZPlainString(const AStr: String; ConSettings: PZConSettings; const ToCP: Word): RawByteString; overload;
260 function ZPlainString(const AStr: String; const Encoding: TZCharEncoding = ceDefault): RawByteString; overload;
261 function ZPlainString(const AStr: WideString; const Encoding: TZCharEncoding = ceDefault): RawByteString; overload;
262 function ZPlainString(const AStr: WideString; ConSettings: PZConSettings): RawByteString; overload;
263 function ZPlainString(const AStr: WideString; ConSettings: PZConSettings; const ToCP: Word): RawByteString; overload;
264 function ZPlainUnicodeString(const AStr: String): WideString;
265 procedure SetConSettingsFromInfo(Info: TStrings);
266 property ConSettings: PZConSettings read FConSettings write FConSettings;
268 destructor Destroy; override;
271 {$IFDEF WITH_LCONVENCODING}
272 function NoConvert(const s: string): string;
276 {$IF not Declared(DetectUTF8Encoding)}
277 {$DEFINE ZDetectUTF8Encoding}
279 TEncodeType = (etUSASCII, etUTF8, etANSI);
281 function DetectUTF8Encoding(Ansi: RawByteString): TEncodeType;
284 {$IFNDEF WITH_CHARINSET}
285 function CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean; overload;
286 function CharInSet(C: WideChar; const CharSet: TSysCharSet): Boolean; overload;
289 {$IF not Declared(UTF8ToString)}
290 {$DEFINE ZUTF8ToString}
291 function UTF8ToString(const s: RawByteString): ZWideString;
295 ClientCodePageDummy: TZCodepage =
296 (Name: ''; ID: 0; CharWidth: 1; Encoding: ceAnsi;
297 CP: $ffff; ZAlias: '');
299 ConSettingsDummy: TZConSettings =
301 CPType: {$IFDEF DELPHI}{$IFDEF UNICODE}cCP_UTF16{$ELSE}cGET_ACP{$ENDIF}{$ELSE}cCP_UTF8{$ENDIF};
302 ClientCodePage: @ClientCodePageDummy;
303 {$IFDEF WITH_LCONVENCODING}
304 PlainConvertFunc: @NoConvert;
305 DbcConvertFunc: @NoConvert;
313 {$IFDEF ZDetectUTF8Encoding}
314 function DetectUTF8Encoding(Ansi: RawByteString): TEncodeType; //EgonHugeist: Detect a valid UTF8Sequence
319 function P(Pos: Integer = 0): Byte;
321 Result := Byte(Source[Pos]);
324 procedure IncPos(X: Integer = 1);
331 if Ansi = '' then Exit;
334 Source := PAnsiChar(Ansi);
336 // skip US-ASCII Chars they are allways valid.
338 while ( I <= Len ) do
340 if P >= $80 then break;
344 if i > Len then exit; //US ACII
346 //No US-Ascii at all.
353 $C2..$DF: // non-overlong 2-byte
355 and (P(1) in [$80..$BF]) then
360 $E0: // excluding overlongs
362 and (P(1) in [$A0..$BF])
363 and (P(2) in [$80..$BF]) then
368 $E1..$EF: // straight 3-byte & excluding surrogates
370 and (P(1) in [$80..$BF])
371 and (P(2) in [$80..$BF]) then
378 and (P(1) in [$90..$BF])
379 and (P(2) in [$80..$BF])
380 and (P(3) in [$80..$BF]) then
385 $F1..$F3: // planes 4-15
387 and (P(1) in [$80..$BF])
388 and (P(2) in [$80..$BF])
389 and (P(3) in [$80..$BF]) then
396 and (P(1) in [$80..$8F])
397 and (P(2) in [$80..$BF])
398 and (P(3) in [$80..$BF]) then
408 Result := etUTF8 //UTF8
410 Result := etANSI; //Ansi
416 Now use the new Functions to get encoded Strings instead of
417 hard-coded Compiler-Directives or UTF8Encode/Decode:
419 function ZDbcString(const Ansi: AnsiString; const Encoding: TZCharEncoding = ceDefault): String;
420 function ZPlainString(const Str: String; const Encoding: TZCharEncoding = ceDefault): AnsiString;
422 These functions do auto arrange the in/out-coming AnsiStrings in
423 dependency of the used CharacterSet and the used Compiler whithout
425 So my thouths where use only these two function for all
426 String/Ansi/Unicode-handlings of DBC-layer. Which means in full effect
427 no more directives in Zeos Source-Code then here to do this handling.
428 @param Ansi: the String which has to be handled.
429 @param Encoding is set to Default-Character-Set we've choosen bevor (on conecting)
430 Change this if you need some Transtations to a specified Encoding.
431 Example: CharacterSet was set to Latin1 and some "special"-String MUST BE
432 UTF8 instead of Latin1. (SSL-Keys eventualy)
433 @param Convert ignored for Delphi means if the Chararacters should be propper
434 to the specified codepage
437 IS there a need for it? AnsiEncoded adaps automaticaly to WideString
438 So what about coming UTF16/32????
440 function TZCodePagedObject.ZDbcString(const Ansi: RawByteString;
441 ConSettings: PZConSettings): String;
442 {$IFDEF WITH_FPC_STRING_CONVERSATION}
443 var TempAnsi: RawByteString;
447 if not ConSettings^.AutoEncode then
451 case ConSettings^.ClientCodePage^.Encoding of
454 Result := UTF8ToString(Ansi);
456 if ( ConSettings^.CPType in [cCP_UTF8, cCP_UTF16] ) then
459 {$IFDEF WITH_LCONVENCODING}
460 Result := ConSettings.DbcConvertFunc(Ansi);
462 {$IFDEF WITH_FPC_STRING_CONVERSATION}
464 //avoid string conversion -> move memory
465 TempAnsi := AnsiToStringEx(Ansi, ConSettings^.ClientCodePage^.CP, ConSettings^.CTRL_CP);
466 SetLength(Result, Length(TempAnsi));
467 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
470 Result := AnsiToStringEx(Ansi, ConSettings^.ClientCodePage^.CP, ConSettings^.CTRL_CP);
476 Result := AnsiToStringEx(Ansi, ConSettings^.ClientCodePage^.CP);
478 if ConSettings.AutoEncode then
479 if ConSettings^.ClientCodePage^.CP = zCP_NONE then //that's not nice it slows down the incoming strings! Find a way to determine allways the current server CP
480 case DetectUTF8Encoding(Ansi) of
481 etUSASCII: Result := Ansi;
483 if ConSettings^.CTRL_CP = zCP_UTF8 then
484 {$IFDEF WITH_FPC_STRING_CONVERSATION}
486 //avoid string conversion -> move memory
487 TempAnsi := AnsiToUTF8(Ansi); //hope we've compatible results ))):
488 SetLength(Result, Length(TempAnsi));
489 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
492 Result := AnsiToUTF8(Ansi) //hope we've compatible results ))):
497 if ConSettings^.CTRL_CP = zCP_UTF8 then
500 {$IFDEF WITH_FPC_STRING_CONVERSATION}
502 //avoid string conversion -> move memory
503 TempAnsi := AnsiToStringEx(Ansi, zCP_UTF8, ConSettings.CTRL_CP);
504 SetLength(Result, Length(TempAnsi));
505 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
508 {$IFDEF WITH_LCONVENCODING}
511 Result := AnsiToStringEx(Ansi, zCP_UTF8, ConSettings.CTRL_CP);
516 {$IFDEF WITH_LCONVENCODING}
517 Result := ConSettings.DbcConvertFunc(Ansi)
519 {$IFDEF WITH_FPC_STRING_CONVERSATION}
521 //avoid string conversion -> move memory
522 TempAnsi := AnsiToStringEx(Ansi, ConSettings.ClientCodePage.CP, ConSettings.CTRL_CP);
523 SetLength(Result, Length(TempAnsi));
524 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
527 Result := AnsiToStringEx(Ansi, ConSettings.ClientCodePage.CP, ConSettings.CTRL_CP)
536 function TZCodePagedObject.ZDbcString(const Ansi: RawByteString; FromCP: Word): String;
539 CurrentEncoding: TZCharEncoding;
541 if FromCP = FConsettings.ClientCodePage.CP then
542 Result := ZDbcString(Ansi, ConSettings)
545 CurrentCP := FConsettings.ClientCodePage.CP;
546 CurrentEncoding := FConSettings.ClientCodePage.Encoding;
547 if ( FromCP = zCP_UTF8 ) then
548 FConSettings.ClientCodePage.Encoding := ceUTF8
550 FConSettings.ClientCodePage.Encoding := ceAnsi;
551 FConsettings.ClientCodePage.CP := FromCP;
552 Result := ZDbcString(Ansi, FConSettings);
553 FConsettings.ClientCodePage.CP := CurrentCP;
554 FConSettings.ClientCodePage.Encoding := CurrentEncoding;
558 function TZCodePagedObject.ZDbcString(const Ansi: RawByteString;
559 const Encoding: TZCharEncoding = ceDefault): String;
561 TempEncoding, UseEncoding: TZCharEncoding;
563 if Encoding = ceDefault then
564 if not Assigned(FConSettings.ClientCodePage) then
565 raise Exception.Create('CodePage-Informations not Assigned!')
567 UseEncoding := FConSettings.ClientCodePage^.Encoding
569 UseEncoding := Encoding;
572 if not FConSettings.AutoEncode and ( FConSettings.ClientCodePage^.Encoding = UseEncoding ) then
577 TempEncoding := FConSettings^.ClientCodePage^.Encoding;
578 FConSettings.ClientCodePage^.Encoding := UseEncoding;
579 Result := ZDbcString(Ansi, FConSettings);
580 FConSettings^.ClientCodePage^.Encoding := TempEncoding;
584 function TZCodePagedObject.ZDbcUnicodeString(const AStr: RawByteString): ZWideString;
586 {$IFNDEF WITH_LCONVENCODING}
587 Result := ZRawToUnicode(AStr, FConSettings.ClientCodePage.CP);
589 case Consettings.ClientCodePage.Encoding of
591 Result := UTF8Decode(ConSettings.DbcConvertFunc(AStr)); //!!!!SLOW, Job down twice (Ansi up to wide to UTF8 to Wide)
593 Result := UTF8ToString(AStr)
598 function TZCodePagedObject.ZDbcString(const AStr: ZWideString; const Encoding: TZCharEncoding = ceDefault): String;
599 {$IFDEF WITH_FPC_STRING_CONVERSATION}
601 TempAnsi: RawByteString;
607 if not ConSettings.AutoEncode then
608 Result := String(AStr)
610 {$IFDEF WITH_LCONVENCODING}
611 Result := UTF8Encode(AStr);
613 {$IFDEF WITH_FPC_STRING_CONVERSATION}
615 //avoid string conversion -> move memory
616 TempAnsi := ZUnicodeToRaw(AStr, FConSettings.CTRL_CP);
617 SetLength(Result, Length(TempAnsi));
618 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
621 Result := ZUnicodeToRaw(AStr, FConSettings.CTRL_CP);
627 function TZCodePagedObject.ZDbcUnicodeString(const AStr: RawByteString;
628 const FromCP: Word): ZWideString;
630 {$IFNDEF WITH_LCONVENCODING}
631 Result := ZRawToUnicode(AStr, FromCP);
633 if FromCP = zCP_UTF8 then
634 Result := UTF8Decode(AStr)
636 if FromCP = ConSettings.ClientCodePage.CP then
637 Result := UTF8Decode(ConSettings.DbcConvertFunc(AStr))
639 Result := WideString(AStr); //default WideString cast, can't convert
643 {$IFDEF WITH_RAWBYTESTRING}
644 function TZCodePagedObject.ZDbcUnicodeString(const AStr: String; const FromCP: Word): ZWideString;
649 {$IFNDEF WITH_LCONVENCODING}
650 Result := ZRawToUnicode(AStr, FromCP);
652 if FromCP = zCP_UTF8 then
653 Result := UTF8Decode(AStr)
655 if FromCP = ConSettings.ClientCodePage.CP then
656 Result := UTF8Decode(ConSettings.DbcConvertFunc(AStr))
658 Result := WideString(AStr); //default WideString cast, can't convert
666 Now use the new Functions to get encoded Strings instead of
667 hard-Coded Compiler-Directives or UTF8Encode/Decode:
669 function ZPlainString(const Str: String; const Encoding: TZCharEncoding = ceDefault): AnsiString;
671 These functions do auto arrange the in/out-coming AnsiStrings in
672 dependency of the used CharacterSet and the database uses whithout
673 String-DataLoss!! (if possible -> UTF8 is save).
674 @param AStr: the String which has to be handled.
675 @param Encoding is set to Default-Character-Set we've choosen bevor (on conecting)
676 Change this if you need some Transtations to a specified Encoding.
677 Example: CharacterSet was set to Latin1 and some "special"-String MUST BE
678 UTF8 instead of Latin1. (SSL-Keys eventualy)
680 function TZCodePagedObject.ZPlainString(const AStr: String;
681 ConSettings: PZConSettings): RawByteString;
682 {$IFDEF WITH_FPC_STRING_CONVERSATION}
684 TempAnsi: RawByteString;
687 case ConSettings.ClientCodePage.Encoding of
690 Result := UTF8Encode(AStr);
692 if ConSettings.AutoEncode then
693 if DetectUTF8Encoding(AStr) in [etUTF8, etUSASCII] then
696 if ( ConSettings.CTRL_CP = zCP_UTF8 ) or (ConSettings.CTRL_CP = zCP_UTF8) then //avoid "no success" for expected Codepage UTF8 of the Controls
697 {$IFDEF WITH_FPC_STRING_CONVERSATION}
699 //avoid string conversion -> move memory
700 TempAnsi := AnsiToUTF8(AStr);
701 SetLength(Result, Length(TempAnsi));
702 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
705 Result := AnsiToUTF8(AStr)
708 {$IFDEF WITH_FPC_STRING_CONVERSATION}
710 //avoid string conversion -> move memory
711 TempAnsi := StringToAnsiEx(AStr, ConSettings.CTRL_CP, zCP_UTF8);
712 SetLength(Result, Length(TempAnsi));
713 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
716 {$IFDEF WITH_LCONVENCODING}
717 Result := AnsiToUTF8(AStr)
719 Result := StringToAnsiEx(AStr, ConSettings.CTRL_CP, zCP_UTF8)
728 Result := StringToAnsiEx(AStr, ConSettings.ClientCodePage.CP);
730 if ConSettings.AutoEncode then
731 case DetectUTF8Encoding(AStr) of
732 etUSASCII: Result := AStr;
734 {$IFDEF WITH_LCONVENCODING}
735 if ConSettings.CTRL_CP = ConSettings.ClientCodePage.CP then
738 Result := ConSettings.PlainConvertFunc(AnsiToUTF8(AStr));
743 {$IFDEF WITH_LCONVENCODING}
744 Result := ConSettings.PlainConvertFunc(AStr);
746 {$IFDEF WITH_FPC_STRING_CONVERSATION}
748 if ConSettings.ClientCodePage.CP = zCP_NONE then
749 TempAnsi := UTF8ToAnsi(AStr) //hope it's compatible we don't know the server CP here!!
751 TempAnsi := StringToAnsiEx(AStr, zCP_UTF8, ConSettings.ClientCodePage.CP);
752 //avoid string conversion -> move memory
753 SetLength(Result, Length(TempAnsi));
754 Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));
757 if ConSettings.ClientCodePage.CP = zCP_NONE then
758 Result := UTF8ToAnsi(AStr) //hope it's compatible we don't know the server CP here!!
760 Result := StringToAnsiEx(AStr, zCP_UTF8, ConSettings.ClientCodePage.CP);
771 function TZCodePagedObject.ZPlainString(const AStr: String; ConSettings: PZConSettings; const ToCP: Word): RawByteString;
774 CurrentEncoding: TZCharEncoding;
776 if ToCP = ConSettings.ClientCodePage.CP then
777 Result := ZPlainString(AStr, ConSettings)
780 CurrentCP := ConSettings.ClientCodePage.CP;
781 CurrentEncoding := ConSettings.ClientCodePage.Encoding;
782 ConSettings.ClientCodePage.CP := ToCP;
783 if ( ToCP = zCP_UTF8 ) then
784 ConSettings.ClientCodePage.Encoding := ceUTF8
786 ConSettings.ClientCodePage.Encoding := ceAnsi;
787 Result := ZPlainString(AStr, ConSettings);
788 ConSettings.ClientCodePage.CP := CurrentCP;
789 ConSettings.ClientCodePage.Encoding := CurrentEncoding;
793 function TZCodePagedObject.ZPlainString(const AStr: String;
794 const Encoding: TZCharEncoding = ceDefault): RawByteString;
796 TempEncoding, UseEncoding: TZCharEncoding;
798 if Encoding = ceDefault then
799 if not Assigned(FConSettings.ClientCodePage) then
800 raise Exception.Create('CodePage-Informations not Assigned!')
802 UseEncoding := FConSettings.ClientCodePage^.Encoding
804 UseEncoding := Encoding;
807 if not FConSettings.AutoEncode and ( FConSettings.ClientCodePage^.Encoding = UseEncoding ) then
812 TempEncoding := FConSettings.ClientCodePage.Encoding;
813 FConSettings.ClientCodePage.Encoding := UseEncoding;
814 Result := ZPlainString(AStr, FConSettings);
815 FConSettings.ClientCodePage.Encoding := TempEncoding;
819 function TZCodePagedObject.ZPlainString(const AStr: WideString;
820 const Encoding: TZCharEncoding = ceDefault): RawByteString;
822 TempEncoding, UseEncoding: TZCharEncoding;
824 if Encoding = ceDefault then
825 if not Assigned(FConSettings.ClientCodePage) then
826 raise Exception.Create('CodePage-Informations not Assigned!')
828 UseEncoding := FConSettings.ClientCodePage^.Encoding
830 UseEncoding := Encoding;
832 TempEncoding := FConSettings.ClientCodePage.Encoding;
833 FConSettings.ClientCodePage.Encoding := UseEncoding;
834 Result := ZPlainString(AStr, FConSettings);
835 FConSettings.ClientCodePage.Encoding := TempEncoding;
838 function TZCodePagedObject.ZPlainString(const AStr: WideString;
839 ConSettings: PZConSettings): RawByteString;
841 {$IFDEF WITH_LCONVENCODING}
842 Result := ConSettings.PlainConvertFunc(UTF8Encode(AStr));
844 Result := ZUnicodeToRaw(AStr, ConSettings^.ClientCodePage^.CP);
848 function TZCodePagedObject.ZPlainString(const AStr: WideString; ConSettings: PZConSettings; const ToCP: Word): RawByteString;
851 CurrentEncoding: TZCharEncoding;
853 if ToCP = ConSettings.ClientCodePage.CP then
854 Result := ZPlainString(AStr, ConSettings)
857 CurrentCP := ConSettings.ClientCodePage.CP;
858 CurrentEncoding := ConSettings.ClientCodePage.Encoding;
859 ConSettings.ClientCodePage.CP := ToCP;
860 if ( ToCP = zCP_UTF8 ) then
861 ConSettings.ClientCodePage.Encoding := ceUTF8
863 ConSettings.ClientCodePage.Encoding := ceAnsi;
864 Result := ZPlainString(AStr, ConSettings);
865 ConSettings.ClientCodePage.CP := CurrentCP;
866 ConSettings.ClientCodePage.Encoding := CurrentEncoding;
870 function TZCodePagedObject.ZPlainUnicodeString(const AStr: String): WideString;
875 if FConSettings.AutoEncode then
876 case DetectUTF8Encoding(AStr) of
877 etUTF8, etUSASCII: Result := UTF8Decode(AStr);
879 Result := WideString(AStr);
882 {$IFDEF WITH_LCONVENCODING}
883 Result := UTF8ToString(AStr);
885 Result := ZRawToUnicode(AStr, FConSettings.CTRL_CP);
890 procedure TZCodePagedObject.SetConSettingsFromInfo(Info: TStrings);
892 if Assigned(Info) and Assigned(FConSettings) then
895 ConSettings.CTRL_CP := ZDefaultSystemCodePage;
896 if Info.values['controls_cp'] = 'GET_ACP' then
897 ConSettings.CPType := cGET_ACP
899 ConSettings.CPType := cCP_UTF16;
900 ConSettings.AutoEncode := True;
902 {$IF defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER) or defined(WITH_LCONVENCODING)}
903 ConSettings.AutoEncode := Info.Values['AutoEncodeStrings'] = 'ON'; //compatibitity Option for existing Applications;
905 ConSettings.AutoEncode := False;
907 if Info.values['controls_cp'] = 'GET_ACP' then
909 ConSettings.CPType := cGET_ACP;
910 ConSettings.CTRL_CP := ZDefaultSystemCodePage;
913 if Info.values['controls_cp'] = 'CP_UTF8' then
915 ConSettings.CPType := cCP_UTF8;
916 ConSettings.CTRL_CP := zCP_UTF8;
919 if Info.values['controls_cp'] = 'CP_UTF16' then
921 {$IF defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER) or defined(WITH_LCONVENCODING)}
922 ConSettings.CPType := {$IFDEF WITH_WIDEFIELDS}cCP_UTF16{$ELSE}cCP_UTF8{$ENDIF};
923 ConSettings.CTRL_CP := ZDefaultSystemCodePage;
924 ConSettings.AutoEncode := True;
926 if ConSettings.ClientCodePage.Encoding = ceUTF8 then
928 ConSettings.CPType := {$IFDEF WITH_WIDEFIELDS}cCP_UTF16{$ELSE}cCP_UTF8{$ENDIF};
929 ConSettings.CTRL_CP := zCP_UTF8;
930 ConSettings.AutoEncode := True;
934 ConSettings.CPType := cCP_UTF8;
935 ConSettings.CTRL_CP := zCP_UTF8;
936 ConSettings.AutoEncode := False;
940 else // nothing was found set defaults
943 ConSettings.CPType := cCP_UTF8;
944 ConSettings.CTRL_CP := zCP_UTF8;
946 ConSettings.CPType := cGET_ACP;
947 ConSettings.CTRL_CP := GetACP;
954 destructor TZCodePagedObject.Destroy;
959 {$IFDEF WITH_LCONVENCODING}
960 function NoConvert(const s: string): string;
969 function LoadLibrary(ModuleName: PChar): HMODULE;
971 Result := dynlibs.LoadLibrary(ModuleName);
974 function FreeLibrary(Module: HMODULE): LongBool;
976 Result := dynlibs.FreeLibrary(Module);
979 function GetProcAddress(Module: HMODULE; Proc: PChar): Pointer;
981 Result := dynlibs.GetProcAddress(Module,Proc)
987 function Hash(S : AnsiString) : LongWord;
989 thehash,g,I : LongWord;
992 For I:=1 to Length(S) do { 0 terminated }
994 thehash:=thehash shl 4;
996 {$DEFINE OverFlowCheckEnabled}
997 {$OVERFLOWCHECKS OFF}
999 inc(theHash,Ord(S[i]));
1000 {$IFDEF OverFlowCheckEnabled}
1001 {$OVERFLOWCHECKS ON}
1003 g:=thehash and LongWord($f shl 28);
1006 thehash:=thehash xor (g shr 24);
1007 thehash:=thehash xor g;
1016 function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
1021 Result:=AnsiLowerCase(S);
1022 P:=PChar(pointer(Result));
1023 PE:=P+Length(Result);
1026 while (P<PE) and CharInSet(P^, WordDelims) do
1030 while (P<PE) and not (CharInSet(P^, WordDelims)) do
1036 {$IFNDEF WITH_CHARINSET}
1037 function CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean;
1039 result := C in Charset;
1042 function CharInSet(C: WideChar; const CharSet: TSysCharSet): Boolean;
1044 result := Char(C) in Charset;
1048 {$IFDEF ZUTF8ToString}
1049 function UTF8ToString(const s: RawByteString): ZWideString;
1051 Result := UTF8Decode(s);
1053 {$UNDEF ZUTF8ToString}
1058 case ConSettingsDummy.CPType of
1059 cCP_UTF16, cGET_ACP: ConSettingsDummy.CTRL_CP := ZDefaultSystemCodePage;
1060 cCP_UTF8: ConSettingsDummy.CTRL_CP := zCP_UTF8;
1062 SetConvertFunctions(@ConSettingsDummy);