zeoslib  UNKNOWN
 All Files
ZVariant.pas
Go to the documentation of this file.
1 {*********************************************************}
2 { }
3 { Zeos Database Objects }
4 { Variant Processing Classes }
5 { }
6 { Originally written by Sergey Seroukhov }
7 { }
8 {*********************************************************}
9 
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
12 { }
13 { License Agreement: }
14 { }
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. }
20 { }
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. }
39 { }
40 { }
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) }
45 { }
46 { http://www.sourceforge.net/projects/zeoslib. }
47 { }
48 { }
49 { Zeos Development Group. }
50 {********************************************************@}
51 
52 unit ZVariant;
53 
54 interface
55 
56 {$I ZCore.inc}
57 
58 uses
59  {$IFNDEF FPC}
60  Windows, //need for inline
61  {$ENDIF}
62  Classes, SysUtils, Types, ZCompatibility, ZClasses, ZSysUtils;
63 
64 const
65  {** Precision for float values comparison }
66  FLOAT_COMPARE_PRECISION = 1.0e-5;
67  FLOAT_COMPARE_PRECISION_SINGLE = 1.5e-5;
68 
69  {FPC - Compatibility for SQLite (currently) }
70  JULIAN_DAY_DISTANCE = 2415018.5; //distance from "julian day 0" (January 1, 4713 BC 12:00AM) to "1899-12-30 00:00AM"}
71 
72 type
73  {** Defines variant types. }
74  TZVariantType = (vtNull, vtBoolean, vtInteger, vtFloat, vtBytes,
75  vtString, vtAnsiString, vtUTF8String, vtRawByteString, vtUnicodeString, //String Types
76  vtDateTime, vtPointer, vtInterface);
77 
78  {** Defines a variant structure. }
79  TZVariant = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record
80  VType: TZVariantType;
81  VString: String;
82  VAnsiString: AnsiString;
83  VRawByteString: RawByteString;
84  VUTF8String: UTF8String;
85  VUnicodeString: ZWideString;
86  VBytes: TByteDynArray;
87  VInterface: IZInterface;
88  case TZVariantType of
89  vtBoolean: (VBoolean: Boolean);
90  vtInteger: (VInteger: Int64);
91  vtFloat: (VFloat: Extended);
92  VtDateTime: (VDateTime: Double); // M.A. was TDateTime
93  VtPointer: (VPointer: Pointer);
94  end;
95 
96  PZVariant = ^TZVariant;
97 
98  {** Defines an array of variants. }
99  TZVariantDynArray = array of TZVariant;
100 
101  {** Defines a variant processing exception. }
102  EZVariantException = class (Exception);
103 
104  {** Defines an interface for variant data. }
105  {** Defines a Variant Manager interface. }
106  IZVariantManager = interface (IZInterface)
107  ['{DAA373D9-1A98-4AA8-B65E-4C23167EE83F}']
108 
109  function IsNull(const Value: TZVariant): Boolean;
110  procedure SetNull(var Value: TZVariant);
111 
112  function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;
113  procedure Assign(const SrcValue: TZVariant; var DstValue: TZVariant);
114  function Clone(const Value: TZVariant): TZVariant;
115  function Compare(const Value1, Value2: TZVariant): Integer;
116 
117  function GetAsBoolean(const Value: TZVariant): Boolean;
118  function GetAsBytes(const Value: TZVariant): TByteDynArray;
119  function GetAsInteger(const Value: TZVariant): Int64;
120  function GetAsFloat(const Value: TZVariant): Extended;
121  function GetAsString(const Value: TZVariant): String;
122  function GetAsAnsiString(const Value: TZVariant): AnsiString;
123  function GetAsRawByteString(const Value: TZVariant): RawByteString; overload;
124  function GetAsUTF8String(const Value: TZVariant): UTF8String;
125  function GetAsUnicodeString(const Value: TZVariant): ZWideString;
126  function GetAsDateTime(const Value: TZVariant): TDateTime;
127  function GetAsPointer(const Value: TZVariant): Pointer;
128  function GetAsInterface(const Value: TZVariant): IZInterface;
129 
130  procedure SetAsBoolean(var Value: TZVariant; Data: Boolean);
131  procedure SetAsBytes(var Value: TZVariant; const Data: TByteDynArray);
132  procedure SetAsInteger(var Value: TZVariant; Data: Int64);
133  procedure SetAsFloat(var Value: TZVariant; Data: Extended);
134  procedure SetAsString(var Value: TZVariant; const Data: String);
135  procedure SetAsAnsiString(var Value: TZVariant; const Data: AnsiString);
136  procedure SetAsUTF8String(var Value: TZVariant; const Data: UTF8String);
137  procedure SetAsRawByteString(var Value: TZVariant; const Data: RawByteString);
138  procedure SetAsUnicodeString(var Value: TZVariant; const Data: ZWideString);
139  procedure SetAsDateTime(var Value: TZVariant; Data: TDateTime);
140  procedure SetAsPointer(var Value: TZVariant; Data: Pointer);
141  procedure SetAsInterface(var Value: TZVariant; Data: IZInterface);
142 
143  function OpAdd(const Value1, Value2: TZVariant): TZVariant;
144  function OpSub(const Value1, Value2: TZVariant): TZVariant;
145  function OpMul(const Value1, Value2: TZVariant): TZVariant;
146  function OpDiv(const Value1, Value2: TZVariant): TZVariant;
147  function OpMod(const Value1, Value2: TZVariant): TZVariant;
148  function OpPow(const Value1, Value2: TZVariant): TZVariant;
149  function OpAnd(const Value1, Value2: TZVariant): TZVariant;
150  function OpOr(const Value1, Value2: TZVariant): TZVariant;
151  function OpXor(const Value1, Value2: TZVariant): TZVariant;
152  function OpNot(const Value: TZVariant): TZVariant;
153  function OpNegative(const Value: TZVariant): TZVariant;
154  function OpEqual(const Value1, Value2: TZVariant): TZVariant;
155  function OpNotEqual(const Value1, Value2: TZVariant): TZVariant;
156  function OpMore(const Value1, Value2: TZVariant): TZVariant;
157  function OpLess(const Value1, Value2: TZVariant): TZVariant;
158  function OpMoreEqual(const Value1, Value2: TZVariant): TZVariant;
159  function OpLessEqual(const Value1, Value2: TZVariant): TZVariant;
160  end;
161 
162  {** Implements a variant manager with strict convertion rules. }
163  TZDefaultVariantManager = class (TInterfacedObject, IZVariantManager)
164  private
165  ZAnsiToUTF8: TZAnsiToUTF8;
166  ZUTF8ToAnsi: TZUTF8ToAnsi;
167  ZUTF8ToString: TZUTF8ToString;
168  ZStringToUTF8: TZStringToUTF8;
169  FSystemCodePage: Word;
170  protected
171  procedure RaiseTypeMismatchError;
172  procedure RaiseUnsupportedOperation;
173  public
174  constructor Create;
175  function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;
176  virtual;
177  procedure Assign(const SrcValue: TZVariant; var DstValue: TZVariant);
178  function Clone(const Value: TZVariant): TZVariant;
179  function Compare(const Value1, Value2: TZVariant): Integer;
180 
181  function IsNull(const Value: TZVariant): Boolean;
182  procedure SetNull(var Value: TZVariant);
183 
184  function GetAsBoolean(const Value: TZVariant): Boolean;
185  function GetAsBytes(const Value: TZVariant): TByteDynArray;
186  function GetAsInteger(const Value: TZVariant): Int64;
187  function GetAsFloat(const Value: TZVariant): Extended;
188  function GetAsString(const Value: TZVariant): String;
189  function GetAsAnsiString(const Value: TZVariant): AnsiString;
190  function GetAsUTF8String(const Value: TZVariant): UTF8String;
191  function GetAsRawByteString(const Value: TZVariant): RawByteString; overload;
192  function GetAsUnicodeString(const Value: TZVariant): ZWideString;
193  function GetAsDateTime(const Value: TZVariant): TDateTime;
194  function GetAsPointer(const Value: TZVariant): Pointer;
195  function GetAsInterface(const Value: TZVariant): IZInterface;
196 
197  procedure SetAsBoolean(var Value: TZVariant; Data: Boolean);
198  procedure SetAsBytes(var Value: TZVariant; const Data: TByteDynArray);
199  procedure SetAsInteger(var Value: TZVariant; Data: Int64);
200  procedure SetAsFloat(var Value: TZVariant; Data: Extended);
201  procedure SetAsString(var Value: TZVariant; const Data: String);
202  procedure SetAsAnsiString(var Value: TZVariant; const Data: AnsiString);
203  procedure SetAsUTF8String(var Value: TZVariant; const Data: UTF8String);
204  procedure SetAsRawByteString(var Value: TZVariant; const Data: RawByteString);
205  procedure SetAsUnicodeString(var Value: TZVariant; const Data: ZWideString);
206  procedure SetAsDateTime(var Value: TZVariant; Data: TDateTime);
207  procedure SetAsPointer(var Value: TZVariant; Data: Pointer);
208  procedure SetAsInterface(var Value: TZVariant; Data: IZInterface);
209 
210  function OpAdd(const Value1, Value2: TZVariant): TZVariant;
211  function OpSub(const Value1, Value2: TZVariant): TZVariant;
212  function OpMul(const Value1, Value2: TZVariant): TZVariant;
213  function OpDiv(const Value1, Value2: TZVariant): TZVariant;
214  function OpMod(const Value1, Value2: TZVariant): TZVariant;
215  function OpPow(const Value1, Value2: TZVariant): TZVariant;
216  function OpAnd(const Value1, Value2: TZVariant): TZVariant;
217  function OpOr(const Value1, Value2: TZVariant): TZVariant;
218  function OpXor(const Value1, Value2: TZVariant): TZVariant;
219  function OpNot(const Value: TZVariant): TZVariant;
220  function OpNegative(const Value: TZVariant): TZVariant;
221  function OpEqual(const Value1, Value2: TZVariant): TZVariant;
222  function OpNotEqual(const Value1, Value2: TZVariant): TZVariant;
223  function OpMore(const Value1, Value2: TZVariant): TZVariant;
224  function OpLess(const Value1, Value2: TZVariant): TZVariant;
225  function OpMoreEqual(const Value1, Value2: TZVariant): TZVariant;
226  function OpLessEqual(const Value1, Value2: TZVariant): TZVariant;
227  end;
228 
229  {** Implements a variant manager with soft convertion rules. }
230  TZSoftVariantManager = class (TZDefaultVariantManager)
231  public
232  function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;
233  override;
234  end;
235 
236  IZClientVariantManager = Interface(IZVariantManager)
237  ['{73A1A2C7-7C38-4620-B7FE-2426BF839BE5}']
238  function GetAsRawByteString(const Value: TZVariant; const RawCP: Word): RawByteString; overload;
239  End;
240 
241  {** Implements a variant manager with connection related convertion rules. }
242  TZClientVariantManager = class (TZDefaultVariantManager, IZClientVariantManager)
243  private
244  FConSettings: PZConSettings;
245  public
246  constructor Create(const ConSettings: PZConSettings);
247  function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;
248  override;
249  function GetAsRawByteString(const Value: TZVariant; const RawCP: Word): RawByteString; overload;
250  end;
251 
252 type
253 
254  {** Represents any value interface. }
255  IZAnyValue = interface (IZClonnable)
256  ['{E81988B3-FD0E-4524-B658-B309B02F0B6A}']
257 
258  function IsNull: Boolean;
259  function GetValue: TZVariant;
260 
261  function GetBoolean: Boolean;
262  function GetBytes: TByteDynArray;
263  function GetInteger: Int64;
264  function GetFloat: Extended;
265  function GetString: String;
266  function GetAnsiString: AnsiString;
267  function GetUTF8String: UTF8String;
268  function GetUnicodeString: ZWideString;
269  function GetDateTime: TDateTime;
270  end;
271 
272  {** Implements an any value object. }
273  TZAnyValue = class(TZAbstractObject, IZAnyValue, IZComparable)
274  private
275  FValue: TZVariant;
276  public
277  constructor Create(const Value: TZVariant);
278  constructor CreateWithBoolean(Value: Boolean);
279  constructor CreateWithInteger(Value: Int64);
280  constructor CreateWithFloat(Value: Extended);
281  constructor CreateWithString(const Value: String);
282  {$IFDEF UNICODE}
283  // unicodeType is a (dummy) default parameter to avoid
284  // the problem described in https://forums.codegear.com/thread.jspa?messageID=65681
285  // when dcc creates header (.hpp)-files for c++ builder. Both 'String' and
286  // 'UnicodeString' translate into 'UnicodeString' in C++ builder 2009/2010, and
287  // CreateWithString and CreateWithUnicodeString would result in duplicate
288  // C++ constructors.
289  constructor CreateWithUnicodeString(const Value: String; unicodeType: Boolean=true);
290  {$ELSE}
291  constructor CreateWithUnicodeString(const Value: WideString);
292  {$ENDIF}
293  constructor CreateWithDateTime(Value: TDateTime);
294 
295  function IsNull: Boolean;
296  function GetValue: TZVariant;
297 
298  function GetBoolean: Boolean;
299  function GetBytes: TByteDynArray;
300  function GetInteger: Int64;
301  function GetFloat: Extended;
302  function GetString: String;
303  function GetAnsiString: AnsiString;
304  function GetUTF8String: UTF8String;
305  function GetUnicodeString: ZWideString;
306  function GetDateTime: TDateTime;
307 
308  function Equals(const Value: IZInterface): Boolean; override;
309  function Clone: IZInterface; override;
310  function ToString: string; override;
311  end;
312 
313 {**
314  Encodes a custom variant value into standard variant.
315  @param Value a custom variant value to be encoded.
316  @returns an encoded standard variant.
317 }
318 function EncodeVariant(const Value: TZVariant): Variant;
319 
320 {**
321  Encodes an array of custom variant values into array of standard variants.
322  @param Value an array of custom variant values to be encoded.
323  @returns an encoded array of standard variants.
324 }
325 function EncodeVariantArray(const Value: TZVariantDynArray): Variant;
326 
327 {**
328  Decodes a standard variant value into custom variant.
329  @param Value a standard variant value to be decoded.
330  @returns an decoded custom variant.
331 }
332 function DecodeVariant(const Value: Variant): TZVariant;
333 
334 {**
335  Decodes an array of standard variant values into array of custom variants.
336  @param Value an array of standard variant values to be decoded.
337  @returns an decoded array of custom variants.
338 }
339 function DecodeVariantArray(const Value: Variant): TZVariantDynArray;
340 
341 {**
342  Encodes null into a custom variant.
343  @returns an decoded custom variant.
344 }
345 function EncodeNull : TZVariant;
346 {**
347  Encodes a boolean into a custom variant.
348  @param Value a boolean value to be encoded.
349  @returns an encoded custom variant.
350 }
351 function EncodeBoolean(const Value: Boolean): TZVariant;
352 {**
353  Encodes a Byte array into a custom variant.
354  @param Value a boolean value to be encoded.
355  @returns an encoded custom variant.
356 }
357 function EncodeBytes(const Value: TByteDynArray): TZVariant;
358 {**
359  Encodes an integer into a custom variant.
360  @param Value an intger value to be encoded.
361  @returns an encoded custom variant.
362 }
363 function EncodeInteger(const Value: Int64): TZVariant;
364 {**
365  Encodes a float into a custom variant.
366  @param Value a float value to be encoded.
367  @returns an encoded custom variant.
368 }
369 function EncodeFloat(const Value: Extended): TZVariant;
370 {**
371  Encodes a String into a custom variant.
372  @param Value a String value to be encoded.
373  @returns an encoded custom variant.
374 }
375 function EncodeString(const Value: String): TZVariant;
376 {**
377  Encodes a AnsiString into a custom variant.
378  @param Value a AnsiString value to be encoded.
379  @returns an encoded custom variant.
380 }
381 function EncodeAnsiString(const Value: AnsiString): TZVariant;
382 {**
383  Encodes a UTF8String into a custom variant.
384  @param Value a UTF8String value to be encoded.
385  @returns an encoded custom variant.
386 }
387 function EncodeUTF8String(const Value: UTF8String): TZVariant;
388 {**
389  Encodes a RawByteString into a custom variant.
390  @param Value a RawByteString value to be encoded.
391  @param CP the CoodePage of the Value string.
392  @returns an encoded custom variant.
393 }
394 function EncodeRawByteString(const Value: RawByteString): TZVariant;
395 {**
396  Encodes a unicodestring into a custom variant.
397  @param Value a unicodestring value to be encoded.
398  @returns an encoded custom variant.
399 }
400 function EncodeUnicodeString(const Value: ZWideString): TZVariant;
401 {**
402  Encodes a TDateTime into a custom variant.
403  @param Value a TDateTime value to be encoded.
404  @returns an encoded custom variant.
405 }
406 function EncodeDateTime(const Value: TDateTime): TZVariant;
407 {**
408  Encodes a pointer into a custom variant.
409  @param Value a pointer value to be encoded.
410  @returns an encoded custom variant.
411 }
412 function EncodePointer(const Value: Pointer): TZVariant;
413 {**
414  Encodes an interface into a custom variant.
415  @param Value an interface value to be encoded.
416  @returns an encoded custom variant.
417 }
418 function EncodeInterface(const Value: IZInterface): TZVariant;
419 
420 var
421  {** Declares a default variant manager with strict convertion rules. }
422  DefVarManager: IZVariantManager;
423 
424  {** Declares a variant manager with soft convertion rules. }
425  SoftVarManager: IZVariantManager;
426 
427  {** A NULL Variant Value. }
428  NullVariant: TZVariant;
429 
430 implementation
431 
432 uses
433  Variants, Math, ZMessages, ZEncoding
434  {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}, AnsiStrings{$ENDIF};
435 
436 { TZDefaultVariantManager }
437 
438 {**
439  Constructs this object and assignes the main properties.
440 }
441 constructor TZDefaultVariantManager.Create;
442 begin
443  inherited;
444  FSystemCodePage := ZDefaultSystemCodePage;
445  if ZCompatibleCodePages(zCP_UTF8, FSystemCodePage) then
446  begin
447  ZAnsiToUTF8 := @ZMoveAnsiToUTF8;
448  ZUTF8ToAnsi := @ZMoveUTF8ToAnsi;
449  ZUTF8ToString := @ZMoveUTF8ToString;
450  ZStringToUTF8 := @ZMoveStringToUTF8;
451  end
452  else
453  begin
454  ZAnsiToUTF8 := @ZConvertAnsiToUTF8;
455  ZUTF8ToAnsi := @ZConvertUTF8ToAnsi;
456  ZUTF8ToString := @ZConvertUTF8ToString;
457  ZStringToUTF8 := @ZConvertStringToUTF8;
458  end;
459 end;
460 
461 {**
462  Assignes one variant value to another one.
463  @param SrcValue a source variant value.
464  @param DstValue a destination variant value.
465 }
466 procedure TZDefaultVariantManager.Assign(const SrcValue: TZVariant;
467  var DstValue: TZVariant);
468 begin
469  DstValue.VType := SrcValue.VType;
470  case SrcValue.VType of
471  vtBoolean: DstValue.VBoolean := SrcValue.VBoolean;
472  vtBytes: DstValue.VBytes := SrcValue.VBytes;
473  vtInteger: DstValue.VInteger := SrcValue.VInteger;
474  vtFloat: DstValue.VFloat := SrcValue.VFloat;
475  vtString: DstValue.VString := SrcValue.VString;
476  vtAnsiString: DstValue.VAnsiString := SrcValue.VAnsiString;
477  vtRawByteString: DstValue.VRawByteString := SrcValue.VRawByteString;
478  vtUTF8String: DstValue.VUTF8String := SrcValue.VUTF8String;
479  vtUnicodeString: DstValue.VUnicodeString := SrcValue.VUnicodeString;
480  vtDateTime: DstValue.VDateTime := SrcValue.VDateTime;
481  vtPointer: DstValue.VPointer := SrcValue.VPointer;
482  vtInterface: DstValue.VInterface := SrcValue.VInterface;
483  end;
484 end;
485 
486 {**
487  Clones a variant value.
488  @param Value a source variant value.
489  @returns a clonned variant value.
490 }
491 function TZDefaultVariantManager.Clone(const Value: TZVariant): TZVariant;
492 begin
493  Assign(Value, Result);
494 end;
495 
496 {**
497  Raises a type mismatch exception.
498 }
499 procedure TZDefaultVariantManager.RaiseTypeMismatchError;
500 begin
501  raise EZVariantException.Create(STypesMismatch);
502 end;
503 
504 {**
505  Raises an unsupported operation exception.
506 }
507 procedure TZDefaultVariantManager.RaiseUnsupportedOperation;
508 begin
509  raise EZVariantException.Create(SUnsupportedOperation);
510 end;
511 
512 {**
513  Converts a specified variant value to a new type.
514  @param Value a variant value to be converted.
515  @param NewType a type of the result variant value.
516  @returns a converted variant value.
517 }
518 function TZDefaultVariantManager.Convert(const Value: TZVariant;
519  NewType: TZVariantType): TZVariant;
520 begin
521  Result.VType := NewType;
522  case NewType of
523  vtBoolean:
524  case Value.VType of
525  vtNull:
526  Result.VBoolean := False;
527  vtBoolean:
528  Result.VBoolean := Value.VBoolean;
529  else
530  RaiseTypeMismatchError;
531  end;
532  vtBytes:
533  case Value.VType of
534  vtNull:
535  Result.VBytes := nil;
536  vtBytes:
537  Result.VBytes := Value.VBytes;
538  vtString:
539  Result.VBytes := StrToBytes(Value.VString);
540  vtAnsiString:
541  Result.VBytes := StrToBytes(Value.VAnsiString);
542  vtRawByteString:
543  Result.VBytes := StrToBytes(Value.VRawByteString);
544  vtUTF8String:
545  Result.VBytes := StrToBytes(Value.VUTF8String);
546  vtUnicodeString:
547  Result.VBytes := StrToBytes(Value.VUnicodeString);
548  else
549  RaiseTypeMismatchError;
550  end;
551  vtInteger:
552  case Value.VType of
553  vtNull:
554  Result.VInteger := 0;
555  vtBoolean:
556  if Value.VBoolean then
557  Result.VInteger := 1
558  else
559  Result.VInteger := 0;
560  vtInteger:
561  Result.VInteger := Value.VInteger;
562  else
563  RaiseTypeMismatchError;
564  end;
565  vtFloat:
566  case Value.VType of
567  vtNull:
568  Result.VFloat := 0;
569  vtBoolean:
570  if Value.VBoolean then
571  Result.VFloat := 1
572  else
573  Result.VFloat := 0;
574  vtInteger:
575  Result.VFloat := Value.VInteger;
576  vtFloat:
577  Result.VFloat := Value.VFloat;
578  else
579  RaiseTypeMismatchError;
580  end;
581  vtString:
582  case Value.VType of
583  vtNull:
584  Result.VString := '';
585  vtBytes:
586  Result.VString := {$IFDEF UNICODE}String{$ENDIF}(BytesToStr(Value.VBytes));
587  vtString:
588  Result.VString := Value.VString;
589  vtAnsiString:
590  Result.VString := {$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString);
591  vtUTF8String:
592  Result.VString := ZUTF8ToString(Value.VUTF8String, FSystemCodePage);
593  vtUnicodeString:
594  Result.VString := {$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString);
595  else
596  RaiseTypeMismatchError;
597  end;
598  vtAnsiString:
599  case Value.VType of
600  vtNull:
601  Result.VAnsiString := '';
602  vtBytes:
603  Result.VAnsiString := BytesToStr(Value.VBytes);
604  vtString:
605  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(Value.VString);
606  vtAnsiString:
607  Result.VAnsiString := Value.VAnsiString;
608  vtUTF8String:
609  Result.VAnsiString := ZUTF8ToAnsi(Value.VUTF8String);
610  vtUnicodeString:
611  Result.VAnsiString := AnsiString(Value.VUnicodeString);
612  else
613  RaiseTypeMismatchError;
614  end;
615  vtUTF8String:
616  case Value.VType of
617  vtNull:
618  Result.VUTF8String := '';
619  vtBytes:
620  ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result.VUTF8String);
621  vtString:
622  Result.VUTF8String := ZStringToUTF8(Value.VString, FSystemCodePage);
623  vtAnsiString:
624  Result.VUTF8String := ZAnsiToUTF8(Value.VAnsiString);
625  vtUTF8String:
626  Result.VUTF8String := Value.VUTF8String;
627  vtUnicodeString:
628  {$IFDEF WITH_RAWBYTESTRING}
629  Result.VUTF8String := UTF8String(Value.VUnicodeString);
630  {$ELSE}
631  Result.VUTF8String := UTF8Encode(Value.VUnicodeString);
632  {$ENDIF}
633  else
634  RaiseTypeMismatchError;
635  end;
636  vtRawByteString:
637  case Value.VType of
638  vtNull:
639  Result.VRawByteString := '';
640  vtBytes:
641  ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result.VRawByteString);
642  vtRawByteString:
643  Result.VRawByteString := Value.VRawByteString;
644  else
645  RaiseTypeMismatchError;
646  end;
647  vtUnicodeString:
648  case Value.VType of
649  vtNull:
650  Result.VUnicodeString := '';
651  vtString:
652  Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(Value.VString); //Cast ansi to Wide/Unicode
653  vtAnsiString:
654  Result.VUnicodeString := ZWideString(Value.VAnsiString); //Cast ansi to Wide/Unicode
655  vtUTF8String:
656  Result.VUnicodeString :=
657  {$IFDEF WITH_RAWBYTESTRING}
658  ZWideString(Value.VUTF8String);
659  {$ELSE}
660  UTF8ToString(PAnsiChar(Value.VUTF8String));
661  {$ENDIF}
662  vtUnicodeString:
663  Result.VUnicodeString := Value.VUnicodeString;
664  else
665  RaiseTypeMismatchError;
666  end;
667  vtDateTime:
668  case Value.VType of
669  vtNull:
670  Result.VDateTime := 0;
671  vtDateTime:
672  Result.VDateTime := Value.VDateTime;
673  else
674  RaiseTypeMismatchError;
675  end;
676  vtPointer:
677  case Value.VType of
678  vtNull:
679  Result.VPointer := nil;
680  vtPointer:
681  Result.VPointer := Value.VPointer;
682  else
683  RaiseTypeMismatchError;
684  end;
685  vtInterface:
686  case Value.VType of
687  vtNull:
688  Result.VInterface := nil;
689  vtInterface:
690  Result.VInterface := Value.VInterface;
691  else
692  RaiseTypeMismatchError;
693  end;
694  end;
695 end;
696 
697 {**
698  Compares two variant values.
699  @param Value1 the first variant value.
700  @param Value2 the second variant value.
701  @return <0 if Value1 < Value 2, =0 if Value1 = Value2, >0 if Value1 > Value2
702 }
703 function TZDefaultVariantManager.Compare(const Value1,
704  Value2: TZVariant): Integer;
705 var
706  TempFloat: Extended;
707  TempDateTime: TDateTime;
708 begin
709  case Value1.VType of
710  vtNull:
711  begin
712  if IsNull(Value2) then
713  Result := 0
714  else
715  Result := -1;
716  end;
717  vtBoolean:
718  begin
719  if GetAsBoolean(Value2) then
720  begin
721  if Value1.VBoolean then
722  Result := 0
723  else
724  Result := -1;
725  end
726  else
727  begin
728  if Value1.VBoolean then
729  Result := 1
730  else
731  Result := 0;
732  end;
733  end;
734  vtInteger:
735  Result := Value1.VInteger - GetAsInteger(Value2);
736  vtFloat:
737  begin
738  TempFloat := GetAsFloat(Value2);
739  if Value1.VFloat - TempFloat < -FLOAT_COMPARE_PRECISION then
740  Result := -1
741  else if Value1.VFloat - TempFloat > FLOAT_COMPARE_PRECISION then
742  Result := 1
743  else
744  Result := 0;
745  end;
746 { TODO -oEgonHugeist -cOptimierung :
747  String typed needs to be reviewed for a more optimal way.
748  Simple ByteCompare instead of functions which are codepage dependent should be faster, thought. }
749  vtString:
750  Result := AnsiStrComp(PChar(Value1.VString), PChar(GetAsString(Value2)));
751  vtAnsiString:
752  Result := {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrComp(PAnsiChar(Value1.VAnsiString), PAnsiChar(GetAsAnsiString(Value2)));
753  vtUTF8String:
754  Result := {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrComp(PAnsiChar(GetAsAnsiString(Value1)), PAnsiChar(GetAsAnsiString(Value2)));
755  vtRawByteString:
756  Result := {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrComp(PAnsiChar(GetAsAnsiString(Value1)), PAnsiChar(GetAsAnsiString(Value2)));
757  vtUnicodeString:
758 {$IFNDEF FPC}
759  {$IFDEF UNICODE}
760  Result := AnsiCompareStr(Value1.VUnicodeString, GetAsUnicodeString(Value2));
761  {$ELSE}
762  Result := WideCompareStr(Value1.VUnicodeString, GetAsUnicodeString(Value2));
763  {$ENDIF}
764 {$ELSE}
765  Result := AnsiCompareStr(AnsiString(Value1.VUnicodeString), GetAsString(Value2));
766 {$ENDIF}
767  vtDateTime:
768  begin
769  TempDateTime := GetAsDateTime(Value2);
770  if Value1.VDateTime < TempDateTime then
771  Result := -1
772  else if Value1.VDateTime > TempDateTime then
773  Result := 1
774  else
775  Result := 0;
776  end;
777  vtPointer:
778  Result := sign(NativeInt(Value1.VPointer) - GetAsInteger(Value2));
779  else
780  Result := 0;
781  end;
782 end;
783 
784 {**
785  Checks is the specified value NULL.
786  @param Value a value to be checked.
787  @returns <code>True</code> if variant has NULL value.
788 }
789 function TZDefaultVariantManager.IsNull(const Value: TZVariant): Boolean;
790 begin
791  Result := Value.VType = vtNull;
792 end;
793 
794 {**
795  Sets the NULL value to specified variant.
796  @param Value variant value to be set to NULL.
797 }
798 procedure TZDefaultVariantManager.SetNull(var Value: TZVariant);
799 begin
800  Value := EncodeNull;
801 end;
802 
803 {**
804  Gets a variant to boolean value.
805  @param Value a variant to be converted.
806  @param a result value.
807 }
808 function TZDefaultVariantManager.GetAsBoolean(
809  const Value: TZVariant): Boolean;
810 begin
811  Result := Convert(Value, vtBoolean).VBoolean;
812 end;
813 
814 {**
815  Gets a variant to boolean value.
816  @param Value a variant to be converted.
817  @param a result value.
818 }
819 function TZDefaultVariantManager.GetAsBytes(
820  const Value: TZVariant): TByteDynArray;
821 begin
822  Result := Convert(Value, vtBytes).VBytes;
823 end;
824 {**
825  Gets a variant to integer value.
826  @param Value a variant to be converted.
827  @param a result value.
828 }
829 function TZDefaultVariantManager.GetAsInteger(
830  const Value: TZVariant): Int64;
831 begin
832  Result := Convert(Value, vtInteger).VInteger;
833 end;
834 
835 {**
836  Gets a variant to float value.
837  @param Value a variant to be converted.
838  @param a result value.
839 }
840 function TZDefaultVariantManager.GetAsFloat(
841  const Value: TZVariant): Extended;
842 begin
843  Result := Convert(Value, vtFloat).VFloat;
844 end;
845 
846 {**
847  Gets a variant to string value.
848  @param Value a variant to be converted.
849  @param a result value.
850 }
851 function TZDefaultVariantManager.GetAsString(
852  const Value: TZVariant): String;
853 begin
854  Result := Convert(Value, vtString).VString;
855 end;
856 
857 {**
858  Gets a variant to string value.
859  @param Value a variant to be converted.
860  @param a result value.
861 }
862 function TZDefaultVariantManager.GetAsAnsiString(
863  const Value: TZVariant): AnsiString;
864 begin
865  Result := Convert(Value, vtAnsiString).VAnsiString;
866 end;
867 
868 function TZDefaultVariantManager.GetAsUTF8String(const Value: TZVariant): UTF8String;
869 begin
870  Result := Convert(Value, vtUTF8String).VUTF8String;
871 end;
872 
873 function TZDefaultVariantManager.GetAsRawByteString(const Value: TZVariant): RawByteString;
874 begin
875  Result := Convert(Value, vtRawByteString).VRawByteString;
876 end;
877 
878 {**
879  Gets a variant to unicode string value.
880  @param Value a variant to be converted.
881  @param a result value.
882 }
883 function TZDefaultVariantManager.GetAsUnicodeString(
884  const Value: TZVariant): ZWideString;
885 begin
886  Result := Convert(Value, vtUnicodeString).VUnicodeString;
887 end;
888 
889 {**
890  Gets a variant to date and time value.
891  @param Value a variant to be converted.
892  @param a result value.
893 }
894 function TZDefaultVariantManager.GetAsDateTime(
895  const Value: TZVariant): TDateTime;
896 begin
897  Result := Convert(Value, vtDateTime).VDateTime;
898 end;
899 
900 {**
901  Gets a variant to pointer value.
902  @param Value a variant to be converted.
903  @param a result value.
904 }
905 function TZDefaultVariantManager.GetAsPointer(
906  const Value: TZVariant): Pointer;
907 begin
908  Result := Convert(Value, vtPointer).VPointer;
909 end;
910 
911 {**
912  Gets a variant to interface value.
913  @param Value a variant to be converted.
914  @param a result value.
915 }
916 function TZDefaultVariantManager.GetAsInterface(
917  const Value: TZVariant): IZInterface;
918 begin
919  Result := Convert(Value, vtInterface).VInterface;
920 end;
921 
922 {**
923  Assignes a boolean value to variant.
924  @param Value a variant to store the value.
925  @param Data a value to be assigned.
926 }
927 procedure TZDefaultVariantManager.SetAsBoolean(var Value: TZVariant;
928  Data: Boolean);
929 begin
930  Value := EncodeBoolean(Data);
931 end;
932 
933 {**
934  Assignes a Byte array value to variant.
935  @param Value a variant to store the value.
936  @param Data a value to be assigned.
937 }
938 procedure TZDefaultVariantManager.SetAsBytes(var Value: TZVariant;
939  const Data: TByteDynArray);
940 begin
941  Value := EncodeBytes(Data);
942 end;
943 
944 {**
945  Assignes an integer value to variant.
946  @param Value a variant to store the value.
947  @param Data a value to be assigned.
948 }
949 procedure TZDefaultVariantManager.SetAsInteger(var Value: TZVariant;
950  Data: Int64);
951 begin
952  Value := EncodeInteger(Data);
953 end;
954 
955 {**
956  Assignes a float value to variant.
957  @param Value a variant to store the value.
958  @param Data a value to be assigned.
959 }
960 procedure TZDefaultVariantManager.SetAsFloat(var Value: TZVariant;
961  Data: Extended);
962 begin
963  Value := EncodeFloat(Data);
964 end;
965 
966 {**
967  Assignes a String value to variant.
968  @param Value a variant to store the value.
969  @param Data a value to be assigned.
970 }
971 procedure TZDefaultVariantManager.SetAsString(var Value: TZVariant;
972  const Data: String);
973 begin
974  Value := EncodeString(Data);
975 end;
976 
977 {**
978  Assignes a AnsiString value to variant.
979  @param Value a variant to store the value.
980  @param Data a value to be assigned.
981 }
982 procedure TZDefaultVariantManager.SetAsAnsiString(var Value: TZVariant;
983  const Data: AnsiString);
984 begin
985  Value := EncodeAnsiString(Data);
986 end;
987 
988 {**
989  Assignes a UTF8string value to variant.
990  @param Value a variant to store the value.
991  @param Data a value to be assigned.
992 }
993 procedure TZDefaultVariantManager.SetAsUTF8String(var Value: TZVariant;
994  const Data: UTF8String);
995 begin
996  Value := EncodeUTF8String(Data);
997 end;
998 
999 {**
1000  Assignes a RawByteString value to variant.
1001  @param Value a variant to store the value.
1002  @param Data a value to be assigned.
1003  @param CP the CodePage of the Data string
1004 }
1005 procedure TZDefaultVariantManager.SetAsRawByteString(var Value: TZVariant;
1006  const Data: RawByteString);
1007 begin
1008  Value := EncodeRawByteString(Data);
1009 end;
1010 
1011 {**
1012  Assignes a unicode string value to variant.
1013  @param Value a variant to store the value.
1014  @param Data a value to be assigned.
1015 }
1016 procedure TZDefaultVariantManager.SetAsUnicodeString(var Value: TZVariant;
1017  const Data: ZWideString);
1018 begin
1019  Value := EncodeUnicodeString(Data);
1020 end;
1021 
1022 {**
1023  Assignes a datetime value to variant.
1024  @param Value a variant to store the value.
1025  @param Data a value to be assigned.
1026 }
1027 procedure TZDefaultVariantManager.SetAsDateTime(var Value: TZVariant;
1028  Data: TDateTime);
1029 begin
1030  Value := EncodeDateTime(Data);
1031 end;
1032 
1033 {**
1034  Assignes a pointer value to variant.
1035  @param Value a variant to store the value.
1036  @param Data a value to be assigned.
1037 }
1038 procedure TZDefaultVariantManager.SetAsPointer(var Value: TZVariant;
1039  Data: Pointer);
1040 begin
1041  Value := EncodePointer(Data);
1042 end;
1043 
1044 {**
1045  Assignes a interface value to variant.
1046  @param Value a variant to store the value.
1047  @param Data a value to be assigned.
1048 }
1049 procedure TZDefaultVariantManager.SetAsInterface(var Value: TZVariant;
1050  Data: IZInterface);
1051 begin
1052  Value := EncodeInterface(Data);
1053 end;
1054 
1055 {**
1056  Performs '+' operation.
1057  @param Value1 the first variant argument.
1058  @param Value2 the second variant argument.
1059  @returns an operation result.
1060 }
1061 function TZDefaultVariantManager.OpAdd(const Value1,
1062  Value2: TZVariant): TZVariant;
1063 begin
1064  case Value1.VType of
1065  vtNull: Result := EncodeNull;
1066  vtInteger: Result := EncodeInteger(Value1.VInteger + GetAsInteger(Value2));
1067  vtFloat: Result := EncodeFloat(Value1.VFloat + GetAsFloat(Value2));
1068  vtString: Result := EncodeString(Value1.VString + GetAsString(Value2));
1069  vtAnsiString: Result := EncodeAnsiString(Value1.VAnsiString + GetAsAnsiString(Value2));
1070  vtUTF8String: Result := EncodeUTF8String(Value1.VUTF8String + GetAsUTF8String(Value2));
1071  vtRawByteString: Result := EncodeRawByteString(Value1.VRawByteString + GetAsRawByteString(Value2));
1072  vtUnicodeString: Result := EncodeUnicodeString(Value1.VUnicodeString + GetAsUnicodeString(Value2));
1073  vtDateTime: Result := EncodeDateTime(Value1.VDateTime + GetAsDateTime(Value2));
1074  else RaiseUnsupportedOperation;
1075  end;
1076 end;
1077 
1078 {**
1079  Performs '&' operation.
1080  @param Value1 the first variant argument.
1081  @param Value2 the second variant argument.
1082  @returns an operation result.
1083 }
1084 function TZDefaultVariantManager.OpAnd(const Value1,
1085  Value2: TZVariant): TZVariant;
1086 begin
1087  case Value1.VType of
1088  vtNull: Result := EncodeNull;
1089  vtBoolean: Result := EncodeBoolean(Value1.VBoolean and GetAsBoolean(Value2));
1090  vtInteger: Result := EncodeInteger(Value1.VInteger and GetAsInteger(Value2));
1091  else RaiseUnsupportedOperation;
1092  end;
1093 end;
1094 
1095 {**
1096  Performs '/' operation.
1097  @param Value1 the first variant argument.
1098  @param Value2 the second variant argument.
1099  @returns an operation result.
1100 }
1101 function TZDefaultVariantManager.OpDiv(const Value1,
1102  Value2: TZVariant): TZVariant;
1103 begin
1104  case Value1.VType of
1105  vtNull: Result := EncodeNull;
1106  vtInteger: Result := EncodeInteger(Value1.VInteger div GetAsInteger(Value2));
1107  vtFloat: Result := EncodeFloat(Value1.VFloat / GetAsFloat(Value2));
1108  else RaiseUnsupportedOperation;
1109  end;
1110 end;
1111 
1112 {**
1113  Performs '=' operation.
1114  @param Value1 the first variant argument.
1115  @param Value2 the second variant argument.
1116  @returns an operation result.
1117 }
1118 function TZDefaultVariantManager.OpEqual(const Value1,
1119  Value2: TZVariant): TZVariant;
1120 begin
1121  Result := EncodeBoolean(Compare(Value1, Value2) = 0);
1122 end;
1123 
1124 {**
1125  Performs '<' operation.
1126  @param Value1 the first variant argument.
1127  @param Value2 the second variant argument.
1128  @returns an operation result.
1129 }
1130 function TZDefaultVariantManager.OpLess(const Value1,
1131  Value2: TZVariant): TZVariant;
1132 begin
1133  Result := EncodeBoolean(Compare(Value1, Value2) < 0);
1134 end;
1135 
1136 {**
1137  Performs '<=' operation.
1138  @param Value1 the first variant argument.
1139  @param Value2 the second variant argument.
1140  @returns an operation result.
1141 }
1142 function TZDefaultVariantManager.OpLessEqual(const Value1,
1143  Value2: TZVariant): TZVariant;
1144 begin
1145  Result := EncodeBoolean(Compare(Value1, Value2) <= 0);
1146 end;
1147 
1148 {**
1149  Performs '%' operation.
1150  @param Value1 the first variant argument.
1151  @param Value2 the second variant argument.
1152  @returns an operation result.
1153 }
1154 function TZDefaultVariantManager.OpMod(const Value1,
1155  Value2: TZVariant): TZVariant;
1156 begin
1157  case Value1.VType of
1158  vtNull: Result := EncodeNull;
1159  vtInteger: Result := EncodeInteger(Value1.VInteger mod GetAsInteger(Value2));
1160  else RaiseUnsupportedOperation;
1161  end;
1162 end;
1163 
1164 {**
1165  Performs '>' operation.
1166  @param Value1 the first variant argument.
1167  @param Value2 the second variant argument.
1168  @returns an operation result.
1169 }
1170 function TZDefaultVariantManager.OpMore(const Value1,
1171  Value2: TZVariant): TZVariant;
1172 begin
1173  Result := EncodeBoolean(Compare(Value1, Value2) > 0);
1174 end;
1175 
1176 {**
1177  Performs '>=' operation.
1178  @param Value1 the first variant argument.
1179  @param Value2 the second variant argument.
1180  @returns an operation result.
1181 }
1182 function TZDefaultVariantManager.OpMoreEqual(const Value1,
1183  Value2: TZVariant): TZVariant;
1184 begin
1185  Result := EncodeBoolean(Compare(Value1, Value2) >= 0);
1186 end;
1187 
1188 {**
1189  Performs '*' operation.
1190  @param Value1 the first variant argument.
1191  @param Value2 the second variant argument.
1192  @returns an operation result.
1193 }
1194 function TZDefaultVariantManager.OpMul(const Value1,
1195  Value2: TZVariant): TZVariant;
1196 begin
1197  case Value1.VType of
1198  vtNull: Result := EncodeNull;
1199  vtInteger: Result := EncodeInteger(Value1.VInteger * GetAsInteger(Value2));
1200  vtFloat: Result := EncodeFloat(Value1.VFloat * GetAsFloat(Value2));
1201  else RaiseUnsupportedOperation;
1202  end;
1203 end;
1204 
1205 {**
1206  Performs unary '-' operation.
1207  @param Value the variant argument.
1208  @returns an operation result.
1209 }
1210 function TZDefaultVariantManager.OpNegative(const Value: TZVariant): TZVariant;
1211 begin
1212  case Value.VType of
1213  vtNull: Result := EncodeNull;
1214  vtInteger: Result := EncodeInteger(-Value.VInteger);
1215  vtFloat: Result := EncodeFloat(-Value.VFloat);
1216  else RaiseUnsupportedOperation;
1217  end;
1218 end;
1219 
1220 {**
1221  Performs '~' operation.
1222  @param Value the variant argument.
1223  @returns an operation result.
1224 }
1225 function TZDefaultVariantManager.OpNot(const Value: TZVariant): TZVariant;
1226 begin
1227  case Value.VType of
1228  vtNull: Result := EncodeNull;
1229  vtBoolean: Result := EncodeBoolean(not Value.VBoolean);
1230  vtInteger: Result := EncodeInteger(not Value.VInteger);
1231  else RaiseUnsupportedOperation;
1232  end;
1233 end;
1234 
1235 {**
1236  Performs '<>' operation.
1237  @param Value1 the first variant argument.
1238  @param Value2 the second variant argument.
1239  @returns an operation result.
1240 }
1241 function TZDefaultVariantManager.OpNotEqual(const Value1,
1242  Value2: TZVariant): TZVariant;
1243 begin
1244  Result := EncodeBoolean(Compare(Value1, Value2) <> 0);
1245 end;
1246 
1247 {**
1248  Performs '|' operation.
1249  @param Value1 the first variant argument.
1250  @param Value2 the second variant argument.
1251  @returns an operation result.
1252 }
1253 function TZDefaultVariantManager.OpOr(const Value1,
1254  Value2: TZVariant): TZVariant;
1255 begin
1256  case Value1.VType of
1257  vtNull: SetNull(Result);
1258  vtBoolean: Result := EncodeBoolean(Value1.VBoolean or GetAsBoolean(Value2));
1259  vtInteger: Result := EncodeInteger(Value1.VInteger or GetAsInteger(Value2));
1260  else RaiseUnsupportedOperation;
1261  end;
1262 end;
1263 
1264 {**
1265  Performs '^' operation.
1266  @param Value1 the first variant argument.
1267  @param Value2 the second variant argument.
1268  @returns an operation result.
1269 }
1270 function TZDefaultVariantManager.OpPow(const Value1,
1271  Value2: TZVariant): TZVariant;
1272 begin
1273  case Value1.VType of
1274  vtNull: Result := EncodeNull;
1275  vtInteger: Result := EncodeFloat(Power(Value1.VInteger, GetAsInteger(Value2)));
1276  vtFloat: Result := EncodeFloat(Power(Value1.VFloat, GetAsFloat(Value2)));
1277  else RaiseUnsupportedOperation;
1278  end;
1279 end;
1280 
1281 {**
1282  Performs '-' operation.
1283  @param Value1 the first variant argument.
1284  @param Value2 the second variant argument.
1285  @returns an operation result.
1286 }
1287 function TZDefaultVariantManager.OpSub(const Value1,
1288  Value2: TZVariant): TZVariant;
1289 begin
1290  case Value1.VType of
1291  vtNull: Result := EncodeNull;
1292  vtInteger: Result := EncodeInteger(Value1.VInteger - GetAsInteger(Value2));
1293  vtFloat: Result := EncodeFloat(Value1.VFloat - GetAsFloat(Value2));
1294  else RaiseUnsupportedOperation;
1295  end;
1296 end;
1297 
1298 {**
1299  Performs '^' operation.
1300  @param Value1 the first variant argument.
1301  @param Value2 the second variant argument.
1302  @returns an operation result.
1303 }
1304 function TZDefaultVariantManager.OpXor(const Value1,
1305  Value2: TZVariant): TZVariant;
1306 var
1307  TempBool1, TempBool2: Boolean;
1308  TempInteger1, TempInteger2: Int64;
1309 begin
1310  case Value1.VType of
1311  vtNull: Result := EncodeNull;
1312  vtBoolean:
1313  begin
1314  TempBool1 := Value1.VBoolean;
1315  TempBool2 := GetAsBoolean(Value2);
1316  Result := EncodeBoolean((TempBool1 and not TempBool2)
1317  or (not TempBool1 and TempBool2));
1318  end;
1319  vtInteger:
1320  begin
1321  TempInteger1 := Value1.VInteger;
1322  TempInteger2 := GetAsInteger(Value2);
1323  Result := EncodeInteger((TempInteger1 and not TempInteger2)
1324  or (not TempInteger1 and TempInteger2));
1325  end;
1326  else RaiseUnsupportedOperation;
1327  end;
1328 end;
1329 
1330 { TZSoftVariantManager }
1331 
1332 {**
1333  Converts a specified variant value to a new type.
1334  @param Value a variant value to be converted.
1335  @param NewType a type of the result variant value.
1336  @returns a converted variant value.
1337 }
1338 function TZSoftVariantManager.Convert(const Value: TZVariant;
1339  NewType: TZVariantType): TZVariant;
1340 begin
1341  Result.VType := NewType;
1342  case NewType of
1343  vtBoolean:
1344  case Value.VType of
1345  vtNull:
1346  Result.VBoolean := False;
1347  vtBoolean:
1348  Result.VBoolean := Value.VBoolean;
1349  vtInteger:
1350  Result.VBoolean := Value.VInteger <> 0;
1351  vtFloat:
1352  Result.VBoolean := Value.VFloat <> 0;
1353  vtString:
1354  Result.VBoolean := StrToBoolEx(Value.VString);
1355  vtAnsiString:
1356  Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));
1357  vtUTF8String:
1358  Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String));
1359  vtRawByteString:
1360  Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString));
1361  vtUnicodeString:
1362  Result.VBoolean := StrToBoolEx({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));
1363  vtDateTime:
1364  Result.VBoolean := Value.VDateTime <> 0;
1365  vtPointer:
1366  RaiseTypeMismatchError;
1367  vtInterface:
1368  RaiseTypeMismatchError;
1369  end;
1370  vtBytes:
1371  case Value.VType of
1372  vtNull:
1373  Result.VBytes := nil;
1374  vtBytes:
1375  Result.VBytes := Value.VBytes;
1376  vtString:
1377  Result.VBytes := StrToBytes(Value.VString);
1378  vtAnsiString:
1379  Result.VBytes := StrToBytes(Value.VAnsiString);
1380  vtRawByteString:
1381  Result.VBytes := StrToBytes(Value.VRawByteString);
1382  vtUTF8String:
1383  Result.VBytes := StrToBytes(Value.VUTF8String);
1384  vtUnicodeString:
1385  Result.VBytes := StrToBytes(Value.VUnicodeString);
1386  else
1387  RaiseTypeMismatchError;
1388  end;
1389  vtInteger:
1390  case Value.VType of
1391  vtNull:
1392  Result.VInteger := 0;
1393  vtBoolean:
1394  if Value.VBoolean then
1395  Result.VInteger := 1
1396  else
1397  Result.VInteger := 0;
1398  vtInteger:
1399  Result.VInteger := Value.VInteger;
1400  vtFloat:
1401  Result.VInteger := Trunc(Value.VFloat);
1402  vtString:
1403  Result.VInteger := StrToInt64Def(Value.VString, 0);
1404  vtAnsiString:
1405  Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);
1406  vtUTF8String:
1407  Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);
1408  vtRawByteString:
1409  Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString), 0);
1410  vtUnicodeString:
1411  Result.VInteger := StrToInt64Def({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString), 0);
1412  vtDateTime:
1413  Result.VInteger := Trunc(Value.VDateTime);
1414  vtPointer:
1415  Result.VInteger := NativeInt(Value.VPointer);
1416  vtInterface:
1417  RaiseTypeMismatchError;
1418  end;
1419  vtFloat:
1420  case Value.VType of
1421  vtNull:
1422  Result.VFloat := 0;
1423  vtBoolean:
1424  if Value.VBoolean then
1425  Result.VFloat := 1
1426  else
1427  Result.VFloat := 0;
1428  vtInteger:
1429  Result.VFloat := Value.VInteger;
1430  vtFloat:
1431  Result.VFloat := Value.VFloat;
1432  vtString:
1433  Result.VFloat := SqlStrToFloatDef(Value.VString, 0);
1434  vtAnsiString:
1435  Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);
1436  vtUTF8String:
1437  Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);
1438  vtRawByteString:
1439  Result.VFloat := SqlStrToFloatDef(Value.VRawByteString, 0);
1440  vtUnicodeString:
1441  Result.VFloat := SqlStrToFloatDef(AnsiString(Value.VUnicodeString), 0);
1442  vtDateTime:
1443  Result.VFloat := Value.VDateTime;
1444  else
1445  RaiseTypeMismatchError;
1446  end;
1447  vtString:
1448  case Value.VType of
1449  vtNull:
1450  Result.VString := '';
1451  vtBoolean:
1452  if Value.VBoolean then
1453  Result.VString := 'TRUE'
1454  else
1455  Result.VString := 'FALSE';
1456  vtBytes:
1457  ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result.VString);
1458  vtInteger:
1459  Result.VString := IntToStr(Value.VInteger);
1460  vtFloat:
1461  Result.VString := FloatToSqlStr(Value.VFloat);
1462  vtString:
1463  Result.VString := Value.VString;
1464  vtAnsiString:
1465  Result.VString := {$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString);
1466  vtUTF8String:
1467  Result.VString := ZUTF8ToString(Value.VUTF8String, FSystemCodePage);
1468  vtUnicodeString:
1469  Result.VString := Value.VUnicodeString; //hint: VarArrayOf(['Test']) returns allways varOleStr which is type WideString don't change that again
1470  vtDateTime:
1471  Result.VString := DateTimeToAnsiSQLDate(Value.VDateTime);
1472  // gto: Not a real threat, as it's converting dates (unicode safe)
1473  else
1474  RaiseTypeMismatchError;
1475  end;
1476  vtAnsiString:
1477  case Value.VType of
1478  vtNull:
1479  Result.VAnsiString := '';
1480  vtBoolean:
1481  if Value.VBoolean then
1482  Result.VAnsiString := 'TRUE'
1483  else
1484  Result.VAnsiString := 'FALSE';
1485  vtInteger:
1486  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(Value.VInteger));
1487  vtFloat:
1488  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(FloatToSqlStr(Value.VFloat));
1489  vtString:
1490  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(Value.VString);
1491  vtAnsiString:
1492  Result.VAnsiString := Value.VAnsiString;
1493  vtUTF8String:
1494  Result.VAnsiString := ZUTF8ToAnsi(Value.VUTF8String);
1495  vtUnicodeString:
1496  Result.VAnsiString := AnsiString(Value.VUnicodeString);
1497  vtDateTime:
1498  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));
1499  else
1500  RaiseTypeMismatchError;
1501  end;
1502  vtUTF8String:
1503  case Value.VType of
1504  vtNull:
1505  Result.VUTF8String := '';
1506  vtBoolean:
1507  if Value.VBoolean then
1508  Result.VUTF8String := 'TRUE'
1509  else
1510  Result.VUTF8String := 'FALSE';
1511  vtInteger:
1512  Result.VUTF8String := UTF8String(IntToStr(Value.VInteger));
1513  vtFloat:
1514  Result.VUTF8String := UTF8String(FloatToSqlStr(Value.VFloat));
1515  vtString:
1516  Result.VUTF8String := ZStringToUTF8(Value.VString, FSystemCodePage);
1517  vtAnsiString:
1518  Result.VUTF8String := ZAnsiToUTF8(Value.VAnsiString);
1519  vtUTF8String:
1520  Result.VUTF8String := Value.VUTF8String;
1521  vtUnicodeString:
1522  {$IFDEF WITH_RAWBYTESTRING}
1523  Result.VUTF8String := UTF8String(Value.VUnicodeString);
1524  {$ELSE}
1525  Result.VUTF8String := UTF8Encode(Value.VUnicodeString);
1526  {$ENDIF}
1527  vtDateTime:
1528  Result.VUTF8String := UTF8String(DateTimeToAnsiSQLDate(Value.VDateTime));
1529  else
1530  RaiseTypeMismatchError;
1531  end;
1532  vtUnicodeString:
1533  case Value.VType of
1534  vtNull:
1535  Result.VUnicodeString := '';
1536  vtBoolean:
1537  if Value.VBoolean then
1538  Result.VUnicodeString := 'TRUE'
1539  else
1540  Result.VUnicodeString := 'FALSE';
1541  vtInteger:
1542  Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(IntToStr(Value.VInteger));
1543  vtFloat:
1544  Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(FloatToSqlStr(Value.VFloat));
1545  vtString:
1546  Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(Value.VString);
1547  vtAnsiString:
1548  Result.VUnicodeString := ZWideString(Value.VAnsiString);
1549  vtUTF8String:
1550  Result.VUnicodeString := {$IFDEF UNICODE}UTF8ToString{$ELSE}UTF8Decode{$ENDIF}(PAnsiChar(Value.VUTF8String));
1551  vtUnicodeString:
1552  Result.VUnicodeString := Value.VUnicodeString;
1553  vtDateTime:
1554  Result.VUnicodeString := ZWideString(DateTimeToAnsiSQLDate(Value.VDateTime));
1555  else
1556  RaiseTypeMismatchError;
1557  end;
1558  vtDateTime:
1559  case Value.VType of
1560  vtNull:
1561  Result.VDateTime := 0;
1562  vtBoolean:
1563  RaiseTypeMismatchError;
1564  vtInteger:
1565  Result.VDateTime := Value.VInteger;
1566  vtFloat:
1567  Result.VDateTime := Value.VFloat;
1568  vtString:
1569  Result.VDateTime := AnsiSQLDateToDateTime(Value.VString);
1570  vtAnsiString:
1571  Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));
1572  vtUTF8String:
1573  Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String));
1574  vtRawByteString:
1575  Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString));
1576  vtUnicodeString:
1577  Result.VDateTime := AnsiSQLDateToDateTime({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));
1578  vtDateTime:
1579  Result.VDateTime := Value.VDateTime;
1580  else
1581  RaiseTypeMismatchError;
1582  end;
1583  vtPointer:
1584  case Value.VType of
1585  vtNull:
1586  Result.VPointer := nil;
1587  vtBoolean:
1588  RaiseTypeMismatchError;
1589  vtInteger:
1590  Result.VPointer := Pointer(Value.VInteger);
1591  else
1592  RaiseTypeMismatchError;
1593  end;
1594  vtInterface:
1595  case Value.VType of
1596  vtNull:
1597  Result.VInterface := nil;
1598  vtInterface:
1599  Result.VInterface := Value.VInterface;
1600  else
1601  end;
1602  end;
1603 end;
1604 
1605 { TZClientVariantManager }
1606 
1607 {**
1608  Constructs this object and assignes the main properties.
1609  @param ClientCodePage the current ClientCodePage.
1610 }
1611 constructor TZClientVariantManager.Create(const ConSettings: PZConSettings);
1612 begin
1613  inherited Create; //Set all standart converters functions
1614 
1615  FConSettings := ConSettings;
1616 end;
1617 
1618 {**
1619  Converts a specified variant value to a new type.
1620  @param Value a variant value to be converted.
1621  @param NewType a type of the result variant value.
1622  @returns a converted variant value.
1623 }
1624 function TZClientVariantManager.Convert(const Value: TZVariant;
1625  NewType: TZVariantType): TZVariant;
1626 begin
1627  Result.VType := NewType;
1628  case NewType of
1629  vtBoolean:
1630  case Value.VType of
1631  vtNull:
1632  Result.VBoolean := False;
1633  vtBoolean:
1634  Result.VBoolean := Value.VBoolean;
1635  vtInteger:
1636  Result.VBoolean := Value.VInteger <> 0;
1637  vtFloat:
1638  Result.VBoolean := Value.VFloat <> 0;
1639  vtString:
1640  Result.VBoolean := StrToBoolEx(Value.VString);
1641  vtAnsiString:
1642  Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));
1643  vtUTF8String:
1644  Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String));
1645  vtRawByteString:
1646  Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString));
1647  vtUnicodeString:
1648  Result.VBoolean := StrToBoolEx({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));
1649  vtDateTime:
1650  Result.VBoolean := Value.VDateTime <> 0;
1651  else
1652  RaiseTypeMismatchError;
1653  end;
1654  vtBytes:
1655  case Value.VType of
1656  vtNull:
1657  Result.VBytes := nil;
1658  vtBytes:
1659  Result.VBytes := Value.VBytes;
1660  vtString:
1661  Result.VBytes := StrToBytes(Value.VString);
1662  vtAnsiString:
1663  Result.VBytes := StrToBytes(Value.VAnsiString);
1664  vtRawByteString:
1665  Result.VBytes := StrToBytes(Value.VRawByteString);
1666  vtUTF8String:
1667  Result.VBytes := StrToBytes(Value.VUTF8String);
1668  vtUnicodeString:
1669  Result.VBytes := StrToBytes(Value.VUnicodeString);
1670  else
1671  RaiseTypeMismatchError;
1672  end;
1673  vtInteger:
1674  case Value.VType of
1675  vtNull:
1676  Result.VInteger := 0;
1677  vtBoolean:
1678  if Value.VBoolean then
1679  Result.VInteger := 1
1680  else
1681  Result.VInteger := 0;
1682  vtInteger:
1683  Result.VInteger := Value.VInteger;
1684  vtFloat:
1685  Result.VInteger := Trunc(Value.VFloat);
1686  vtString:
1687  Result.VInteger := StrToInt64Def(Value.VString, 0);
1688  vtAnsiString:
1689  Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);
1690  vtUTF8String:
1691  Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);
1692  vtRawByteString:
1693  Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString), 0);
1694  vtUnicodeString:
1695  Result.VInteger := StrToInt64Def({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString), 0);
1696  vtDateTime:
1697  Result.VInteger := Trunc(Value.VDateTime);
1698  vtPointer:
1699  Result.VInteger := NativeInt(Value.VPointer);
1700  vtInterface:
1701  RaiseTypeMismatchError;
1702  end;
1703  vtFloat:
1704  case Value.VType of
1705  vtNull:
1706  Result.VFloat := 0;
1707  vtBoolean:
1708  if Value.VBoolean then
1709  Result.VFloat := 1
1710  else
1711  Result.VFloat := 0;
1712  vtInteger:
1713  Result.VFloat := Value.VInteger;
1714  vtFloat:
1715  Result.VFloat := Value.VFloat;
1716  vtString:
1717  Result.VFloat := SqlStrToFloatDef(Value.VString, 0);
1718  vtAnsiString:
1719  Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);
1720  vtUTF8String:
1721  Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);
1722  vtRawByteString:
1723  Result.VFloat := SqlStrToFloatDef(Value.VRawByteString, 0);
1724  vtUnicodeString:
1725  Result.VFloat := SqlStrToFloatDef({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString), 0);
1726  vtDateTime:
1727  Result.VFloat := Value.VDateTime;
1728  else
1729  RaiseTypeMismatchError;
1730  end;
1731  vtString:
1732  case Value.VType of
1733  vtNull:
1734  Result.VString := '';
1735  vtBoolean:
1736  if Value.VBoolean then
1737  Result.VString := 'TRUE'
1738  else
1739  Result.VString := 'FALSE';
1740  vtBytes:
1741  Result.VString := {$IFDEF UNICODE}String{$ENDIF}(BytesToStr(Value.VBytes));
1742  vtInteger:
1743  Result.VString := IntToStr(Value.VInteger);
1744  vtFloat:
1745  Result.VString := FloatToSqlStr(Value.VFloat);
1746  vtString:
1747  Result.VString := Value.VString;
1748  vtAnsiString:
1749  Result.VString := FConSettings^.ConvFuncs.ZAnsiToString(Value.VAnsiString, FConSettings^.CTRL_CP);
1750  vtUTF8String:
1751  Result.VString := FConSettings^.ConvFuncs.ZUTF8ToString(Value.VUTF8String, FConSettings^.CTRL_CP);
1752  vtRawByteString:
1753  Result.VString := FConSettings^.ConvFuncs.ZRawToString(Value.VRawByteString, FConSettings^.ClientCodePage^.CP, FConSettings^.CTRL_CP);
1754  vtUnicodeString:
1755  //hint: VarArrayOf(['Test']) returns allways varOleStr which is type WideString don't change that again
1756  //this hint means a cast instead of convert. The user should better use WideString constants!
1757  Result.VString := FConSettings^.ConvFuncs.ZUnicodeToString(Value.VUnicodeString, FConSettings^.CTRL_CP);
1758  vtDateTime:
1759  Result.VString := DateTimeToAnsiSQLDate(Value.VDateTime);
1760  else
1761  RaiseTypeMismatchError;
1762  end;
1763  vtAnsiString:
1764  case Value.VType of
1765  vtNull:
1766  Result.VAnsiString := '';
1767  vtBoolean:
1768  if Value.VBoolean then
1769  Result.VAnsiString := 'TRUE'
1770  else
1771  Result.VAnsiString := 'FALSE';
1772  vtInteger:
1773  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(Value.VInteger));
1774  vtFloat:
1775  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(FloatToSqlStr(Value.VFloat));
1776  vtString:
1777  Result.VAnsiString := FConSettings^.ConvFuncs.ZStringToAnsi(Value.VString, FConSettings^.CTRL_CP);
1778  vtAnsiString:
1779  Result.VAnsiString := Value.VAnsiString;
1780  vtUTF8String:
1781  Result.VAnsiString := FConSettings^.ConvFuncs.ZUTF8ToAnsi(Value.VUTF8String);
1782  vtRawByteString:
1783  Result.VAnsiString := FConSettings^.ConvFuncs.ZRawToAnsi(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);
1784  vtUnicodeString:
1785  Result.VAnsiString := AnsiString(Value.VUnicodeString);
1786  vtDateTime:
1787  Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));
1788  else
1789  RaiseTypeMismatchError;
1790  end;
1791  vtUTF8String:
1792  case Value.VType of
1793  vtNull:
1794  Result.VUTF8String := '';
1795  vtBoolean:
1796  if Value.VBoolean then
1797  Result.VUTF8String := 'TRUE'
1798  else
1799  Result.VUTF8String := 'FALSE';
1800  vtInteger:
1801  Result.VUTF8String := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ENDIF}(IntToStr(Value.VInteger));
1802  vtFloat:
1803  Result.VUTF8String := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ENDIF}(FloatToSqlStr(Value.VFloat));
1804  vtString:
1805  Result.VUTF8String := FConSettings^.ConvFuncs.ZStringToUTF8(Value.VString, FConSettings^.CTRL_CP);
1806  vtAnsiString:
1807  Result.VUTF8String := FConSettings^.ConvFuncs.ZAnsiToUTF8(Value.VAnsiString);
1808  vtUTF8String:
1809  Result.VUTF8String := Value.VUTF8String;
1810  vtRawByteString:
1811  Result.VUTF8String := FConSettings^.ConvFuncs.ZRawToUTF8(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);
1812  vtUnicodeString:
1813  {$IFDEF WITH_RAWBYTESTRING}
1814  Result.VUTF8String := UTF8String(Value.VUnicodeString);
1815  {$ELSE}
1816  Result.VUTF8String := UTF8Encode(Value.VUnicodeString);
1817  {$ENDIF}
1818  vtDateTime:
1819  Result.VUTF8String := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));
1820  else
1821  RaiseTypeMismatchError;
1822  end;
1823  vtRawByteString:
1824  case Value.VType of
1825  vtNull:
1826  Result.VRawByteString := '';
1827  vtBoolean:
1828  if Value.VBoolean then
1829  Result.VRawByteString := 'TRUE'
1830  else
1831  Result.VRawByteString := 'FALSE';
1832  vtInteger:
1833  Result.VRawByteString := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(IntToStr(Value.VInteger));
1834  vtFloat:
1835  Result.VRawByteString := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(FloatToSqlStr(Value.VFloat));
1836  vtString:
1837  Result.VRawByteString := FConSettings^.ConvFuncs.ZStringToRaw(Value.VString, FConSettings^.CTRL_CP, FConSettings^.ClientCodePage^.CP);
1838  vtAnsiString:
1839  Result.VRawByteString := FConSettings^.ConvFuncs.ZAnsiToRaw(Value.VAnsiString, FConSettings^.ClientCodePage^.CP);
1840  vtUTF8String:
1841  Result.VRawByteString := FConSettings^.ConvFuncs.ZUTF8ToRaw(Value.VUTF8String, FConSettings^.ClientCodePage^.CP);
1842  vtRawByteString:
1843  Result.VRawByteString := Value.VRawByteString;
1844  vtUnicodeString:
1845  Result.VRawByteString := FConSettings^.ConvFuncs.ZUnicodeToRaw(Value.VUnicodeString, FConSettings^.ClientCodePage^.CP);
1846  vtDateTime:
1847  Result.VRawByteString := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));
1848  else
1849  RaiseTypeMismatchError;
1850  end;
1851  vtUnicodeString:
1852  case Value.VType of
1853  vtNull:
1854  Result.VUnicodeString := '';
1855  vtBoolean:
1856  if Value.VBoolean then
1857  Result.VUnicodeString := 'TRUE'
1858  else
1859  Result.VUnicodeString := 'FALSE';
1860  vtInteger:
1861  Result.VUnicodeString := ZWideString(IntToStr(Value.VInteger));
1862  vtFloat:
1863  Result.VUnicodeString := ZWideString(FloatToSqlStr(Value.VFloat));
1864  vtString:
1865  Result.VUnicodeString := FConSettings^.ConvFuncs.ZStringToUnicode(Value.VString, FConSettings^.CTRL_CP);
1866  vtAnsiString:
1867  Result.VUnicodeString := ZWideString(Value.VAnsiString);
1868  vtUTF8String:
1869  Result.VUnicodeString := {$IFDEF UNICODE}UTF8ToString{$ELSE}UTF8Decode{$ENDIF}(PAnsiChar(Value.VUTF8String));
1870  vtRawByteString:
1871  Result.VUnicodeString := FConSettings^.ConvFuncs.ZRawToUnicode(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);
1872  vtUnicodeString:
1873  Result.VUnicodeString := Value.VUnicodeString;
1874  vtDateTime:
1875  Result.VUnicodeString := ZWideString(DateTimeToAnsiSQLDate(Value.VDateTime));
1876  else
1877  RaiseTypeMismatchError;
1878  end;
1879  vtDateTime:
1880  case Value.VType of
1881  vtNull:
1882  Result.VDateTime := 0;
1883  vtInteger:
1884  Result.VDateTime := Value.VInteger;
1885  vtFloat:
1886  Result.VDateTime := Value.VFloat;
1887  vtString:
1888  Result.VDateTime := AnsiSQLDateToDateTime(Value.VString);
1889  vtAnsiString:
1890  Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));
1891  vtUTF8String:
1892  Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF WITH_RAWBYTESTRING}String{$ENDIF}(Value.VUTF8String));
1893  vtRawByteString:
1894  Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF WITH_RAWBYTESTRING}String{$ENDIF}(Value.VRawByteString));
1895  vtUnicodeString:
1896  Result.VDateTime := AnsiSQLDateToDateTime({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));
1897  vtDateTime:
1898  Result.VDateTime := Value.VDateTime;
1899  else
1900  RaiseTypeMismatchError;
1901  end;
1902  vtPointer:
1903  case Value.VType of
1904  vtNull:
1905  Result.VPointer := nil;
1906  vtBoolean:
1907  RaiseTypeMismatchError;
1908  vtInteger:
1909  Result.VPointer := Pointer(Value.VInteger);
1910  else
1911  RaiseTypeMismatchError;
1912  end;
1913  vtInterface:
1914  case Value.VType of
1915  vtNull:
1916  Result.VInterface := nil;
1917  vtInterface:
1918  Result.VInterface := Value.VInterface;
1919  else RaiseTypeMismatchError;
1920  end;
1921  end;
1922 end;
1923 
1924 {$WARNINGS OFF} //suppress [Pascal Warning] ZVariant.pas(1926): W1035 Return value of function 'TZClientVariantManager.GetAsRawByteString' might be undefined
1925 function TZClientVariantManager.GetAsRawByteString(const Value: TZVariant;
1926  const RawCP: Word): RawByteString;
1927 var US: ZWideString;
1928 begin
1929  case Value.VType of
1930  vtNull:
1931  Result := '';
1932  vtBoolean:
1933  if Value.VBoolean then
1934  Result := 'TRUE'
1935  else
1936  Result := 'FALSE';
1937  vtBytes:
1938  ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result);
1939  vtInteger:
1940  Result := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(IntToStr(Value.VInteger));
1941  vtFloat:
1942  Result := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(FloatToSqlStr(Value.VFloat));
1943  vtString:
1944  Result := ZConvertStringToRawWithAutoEncode(Value.VString, FConSettings^.CTRL_CP, RawCP);
1945  vtAnsiString:
1946  if ZCompatibleCodePages(ZDefaultSystemCodePage, RawCP) then
1947  Result := ZMoveAnsiToRaw(Value.VAnsiString, RawCP)
1948  else
1949  Result := ZConvertAnsiToRaw(Value.VAnsiString, RawCP);
1950  vtUTF8String:
1951  if ZCompatibleCodePages(zCP_UTF8, RawCP) then
1952  Result := ZMoveUTF8ToRaw(Value.VUTF8String, RawCP)
1953  else
1954  Result := ZConvertUTF8ToRaw(Value.VUTF8String, RawCP);
1955  vtRawByteString:
1956  if ZCompatibleCodePages(FConSettings^.ClientCodePage^.CP, RawCP) then
1957  Result := Value.VRawByteString
1958  else
1959  begin
1960  US := ZRawToUnicode(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);
1961  Result := ZUnicodeToRaw(US, RawCP);
1962  end;
1963  vtUnicodeString:
1964  Result := ZUnicodeToRaw(Value.VUnicodeString, RawCP);
1965  vtDateTime:
1966  Result := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));
1967  else
1968  RaiseTypeMismatchError;
1969  end;
1970 end;
1971 {$WARNINGS ON}
1972 
1973 { TZAnyValue }
1974 
1975 {**
1976  Constructs this object and assignes the main properties.
1977  @param Value an any value.
1978 }
1979 constructor TZAnyValue.Create(const Value: TZVariant);
1980 begin
1981  FValue := Value;
1982 end;
1983 
1984 {**
1985  Constructs this object and assignes the main properties.
1986  @param Value a boolean value.
1987 }
1988 constructor TZAnyValue.CreateWithBoolean(Value: Boolean);
1989 begin
1990  FValue := EncodeBoolean(Value);
1991 end;
1992 
1993 {**
1994  Constructs this object and assignes the main properties.
1995  @param Value a datetime value.
1996 }
1997 constructor TZAnyValue.CreateWithDateTime(Value: TDateTime);
1998 begin
1999  FValue := EncodeDateTime(Value);
2000 end;
2001 
2002 {**
2003  Constructs this object and assignes the main properties.
2004  @param Value a float value.
2005 }
2006 constructor TZAnyValue.CreateWithFloat(Value: Extended);
2007 begin
2008  FValue := EncodeFloat(Value);
2009 end;
2010 
2011 {**
2012  Constructs this object and assignes the main properties.
2013  @param Value a integer value.
2014 }
2015 constructor TZAnyValue.CreateWithInteger(Value: Int64);
2016 begin
2017  FValue := EncodeInteger(Value);
2018 end;
2019 
2020 {**
2021  Constructs this object and assignes the main properties.
2022  @param Value a string value.
2023 }
2024 constructor TZAnyValue.CreateWithString(const Value: String);
2025 begin
2026  FValue := EncodeString(Value);
2027 end;
2028 
2029 {**
2030  Constructs this object and assignes the main properties.
2031  @param Value a unicode string value.
2032 }
2033 {$IFDEF UNICODE}
2034 constructor TZAnyValue.CreateWithUnicodeString(const Value: String; unicodeType : Boolean = true);
2035 {$ELSE}
2036 constructor TZAnyValue.CreateWithUnicodeString(const Value: WideString);
2037 {$ENDIF}
2038 begin
2039  FValue := EncodeUnicodeString(Value);
2040 end;
2041 
2042 {**
2043  Clones an object instance.
2044  @return a clonned object instance.
2045 }
2046 function TZAnyValue.Clone: IZInterface;
2047 begin
2048  Result := TZAnyValue.Create(FValue);
2049 end;
2050 
2051 {**
2052  Compares this and another property.
2053  @return <code>True</code> is properties are equal.
2054 }
2055 function TZAnyValue.Equals(const Value: IZInterface): Boolean;
2056 var
2057  Temp: IZAnyValue;
2058 begin
2059  if Value <> nil then
2060  begin
2061  if Value.QueryInterface(IZAnyValue, Temp) = 0 then
2062  begin
2063  Result := SoftVarManager.Compare(FValue, Temp.GetValue) = 0;
2064  Temp := nil;
2065  end
2066  else
2067  Result := inherited Equals(Value);
2068  end
2069  else
2070  Result := False;
2071 end;
2072 
2073 {**
2074  Gets a stored any value.
2075  @return a stored any value.
2076 }
2077 function TZAnyValue.GetValue: TZVariant;
2078 begin
2079  Result := FValue;
2080 end;
2081 
2082 {**
2083  Converts this object into the string representation.
2084  @return a string representation for this object.
2085 }
2086 function TZAnyValue.ToString: string;
2087 begin
2088  Result := GetString;
2089 end;
2090 
2091 {**
2092  Checks is the stored value contains NULL.
2093  @returns <code>True</code> if NULL is stored.
2094 }
2095 function TZAnyValue.IsNull: Boolean;
2096 begin
2097  Result := SoftVarManager.IsNull(FValue);
2098 end;
2099 
2100 {**
2101  Gets a stored value converted to double.
2102  @return a stored value converted to double.
2103 }
2104 function TZAnyValue.GetFloat: Extended;
2105 begin
2106  Result := SoftVarManager.GetAsFloat(FValue);
2107 end;
2108 
2109 {**
2110  Gets a stored value converted to integer.
2111  @return a stored value converted to integer.
2112 }
2113 function TZAnyValue.GetInteger: Int64;
2114 begin
2115  Result := SoftVarManager.GetAsInteger(FValue);
2116 end;
2117 
2118 {**
2119  Gets a stored value converted to String.
2120  @return a stored value converted to string.
2121 }
2122 function TZAnyValue.GetString: String;
2123 begin
2124  Result := SoftVarManager.GetAsString(FValue);
2125 end;
2126 
2127 {**
2128  Gets a stored value converted to AnsiString.
2129  @return a stored value converted to string.
2130 }
2131 function TZAnyValue.GetAnsiString: AnsiString;
2132 begin
2133  Result := SoftVarManager.GetAsAnsiString(FValue);
2134 end;
2135 
2136 {**
2137  Gets a stored value converted to AnsiString.
2138  @return a stored value converted to string.
2139 }
2140 function TZAnyValue.GetUTF8String: UTF8String;
2141 begin
2142  Result := SoftVarManager.GetAsUTF8String(FValue);
2143 end;
2144 
2145 {**
2146  Gets a stored value converted to boolean.
2147  @return a stored value converted to boolean.
2148 }
2149 function TZAnyValue.GetBoolean: Boolean;
2150 begin
2151  Result := SoftVarManager.GetAsBoolean(FValue);
2152 end;
2153 
2154 {**
2155  Gets a stored value converted to byte array.
2156  @return a stored value converted to a byte array.
2157 }
2158 function TZAnyValue.GetBytes: TByteDynArray;
2159 begin
2160  Result := SoftVarManager.GetAsBytes(FValue);
2161 end;
2162 
2163 {**
2164  Gets a stored value converted to unicode string.
2165  @return a stored value converted to unicode string.
2166 }
2167 function TZAnyValue.GetUnicodeString: ZWideString;
2168 begin
2169  Result := SoftVarManager.GetAsUnicodeString(FValue);
2170 end;
2171 
2172 {**
2173  Gets a stored value converted to datetime.
2174  @return a stored value converted to datetime.
2175 }
2176 function TZAnyValue.GetDateTime: TDateTime;
2177 begin
2178  Result := SoftVarManager.GetAsDateTime(FValue);
2179 end;
2180 
2181 {**
2182  Encodes a custom variant value into standard variant.
2183  @param Value a custom variant value to be encoded.
2184  @returns an encoded standard variant.
2185 }
2186 function EncodeVariant(const Value: TZVariant): Variant;
2187 begin
2188  case Value.VType of
2189  vtBoolean: Result := Value.VBoolean;
2190  vtBytes: Result := BytesToVar(Value.VBytes);
2191  vtInteger:
2192  if (Value.VInteger > -MaxInt) and (Value.VInteger < MaxInt) then
2193  Result := Integer(Value.VInteger)
2194  else
2195 {$ifdef fpc}
2196  Result := Value.VInteger;
2197 {$else}
2198  Result := IntToStr(Value.VInteger);
2199 {$endif}
2200  vtFloat: Result := Value.VFloat;
2201  vtString: Result := Value.VString;
2202  vtAnsiString: Result := Value.VAnsiString;
2203  vtUTF8String: Result := Value.VUTF8String;
2204  vtRawByteString: Result := Value.VRawByteString;
2205  vtUnicodeString: Result := Value.VUnicodeString;
2206  vtDateTime: Result := Value.VDateTime;
2207  vtPointer:
2208  {$ifdef fpc}
2209  Result := NativeInt(Value.VPointer);
2210  {$else}
2211  Result := NativeUInt(Value.VPointer);
2212  {$endif}
2213  vtInterface: Result := Value.VInterface;
2214  else
2215  Result := Null;
2216  end;
2217 end;
2218 
2219 {**
2220  Encodes an array of custom variant values into array of standard variants.
2221  @param Value an array of custom variant values to be encoded.
2222  @returns an encoded array of standard variants.
2223 }
2224 function EncodeVariantArray(const Value: TZVariantDynArray): Variant;
2225 var
2226  I, L: Integer;
2227 begin
2228  L := Length(Value);
2229  Result := VarArrayCreate([0, L - 1], varVariant);
2230  for I := 0 to L - 1 do
2231  Result[I] := EncodeVariant(Value[I]);
2232 end;
2233 
2234 {**
2235  Decodes a standard variant value into custom variant.
2236  @param Value a standard variant value to be decoded.
2237  @returns an decoded custom variant.
2238 }
2239 function DecodeVariant(const Value: Variant): TZVariant;
2240 begin
2241  case VarType(Value) of
2242  varSmallint, varInteger, varByte:
2243  Result := EncodeInteger(Integer(Value));
2244  varBoolean: Result := EncodeBoolean(Value);
2245  varString: Result := EncodeString(Value);
2246  {$IFDEF UNICODE}
2247  varUString: Result := EncodeUnicodeString(Value);
2248  {$ENDIF}
2249  varSingle, varDouble, varCurrency:
2250  Result := EncodeFloat(Value);
2251  varUnknown: Result := EncodeInterface(Value);
2252  varOleStr:
2253  Result := EncodeUnicodeString(Value);
2254  varDate: Result := EncodeDateTime(Value);
2255  varShortInt, varWord, varLongWord:
2256  Result := EncodeInteger(Value);
2257  varInt64{$IFDEF BDS5_UP},varUInt64{$ENDIF}:
2258  Result := EncodeInteger(Value);
2259  else
2260  Result := EncodeNull;
2261  end;
2262 end;
2263 
2264 {**
2265  Decodes an array of standard variant values into array of custom variants.
2266  @param Value an array of standard variant values to be decoded.
2267  @returns an decoded array of custom variants.
2268 }
2269 function DecodeVariantArray(const Value: Variant): TZVariantDynArray;
2270 var
2271  I, L, H: Integer;
2272 begin
2273  if VarIsArray(Value) then
2274  begin
2275  L := VarArrayLowBound(Value, 1);
2276  H := VarArrayHighBound(Value, 1);
2277  SetLength(Result, H - L + 1);
2278  for I := L to H do
2279  Result[I - L] := DecodeVariant(Value[I]);
2280  end
2281  else
2282  begin
2283  SetLength(Result, 1);
2284  Result[0] := DecodeVariant(Value);
2285  end;
2286 end;
2287 
2288 {**
2289  Creates a null variant.
2290 }
2291 function EncodeNull: TZVariant;
2292 begin
2293  Result.VType := vtNull;
2294 end;
2295 
2296 {**
2297  Creates a boolean variant.
2298  @param Value a value to be assigned.
2299 }
2300 function EncodeBoolean(const Value: Boolean): TZVariant;
2301 begin
2302  Result.VType := vtBoolean;
2303  Result.VBoolean := Value;
2304 end;
2305 
2306 {**
2307  Creates a bytes array variant.
2308  @param Value a value to be assigned.
2309 }
2310 function EncodeBytes(const Value: TByteDynArray): TZVariant;
2311 begin
2312  Result.VType := vtBytes;
2313  Result.VBytes := Value;
2314 end;
2315 
2316 {**
2317  Creates a integer variant.
2318  @param Value a value to be assigned.
2319 }
2320 function EncodeInteger(const Value: Int64): TZVariant;
2321 begin
2322  Result.VType := vtInteger;
2323  Result.VInteger := Value;
2324 end;
2325 
2326 {**
2327  Creates a float variant.
2328  @param Value a value to be assigned.
2329 }
2330 function EncodeFloat(const Value: Extended): TZVariant;
2331 begin
2332  Result.VType := vtFloat;
2333  Result.VFloat := Value;
2334 end;
2335 
2336 {**
2337  Creates a AnsiString variant.
2338  @param Value a value to be assigned.
2339 }
2340 function EncodeString(const Value: String): TZVariant;
2341 begin
2342  Result.VType := vtString;
2343  Result.VString := Value;
2344 end;
2345 
2346 {**
2347  Creates a AnsiString variant.
2348  @param Value a value to be assigned.
2349 }
2350 function EncodeAnsiString(const Value: AnsiString): TZVariant;
2351 begin
2352  Result.VType := vtAnsiString;
2353  Result.VAnsiString := Value;
2354 end;
2355 
2356 {**
2357  Creates a UTF8String variant.
2358  @param Value a value to be assigned.
2359 }
2360 function EncodeUTF8String(const Value: UTF8String): TZVariant;
2361 begin
2362  Result.VType := vtUTF8String;
2363  Result.VUTF8String := Value;
2364 end;
2365 
2366 {**
2367  Creates a UTF8String variant.
2368  @param Value a value to be assigned.
2369 }
2370 function EncodeRawByteString(const Value: RawByteString): TZVariant;
2371 begin
2372  Result.VType := vtRawByteString;
2373  Result.VRawByteString := Value;
2374 end;
2375 
2376 {**
2377  Creates a UnicodeString variant.
2378  @param Value a value to be assigned.
2379 }
2380 function EncodeUnicodeString(const Value: ZWideString): TZVariant;
2381 begin
2382  Result.VType := vtUnicodeString;
2383  Result.VUnicodeString := Value;
2384 end;
2385 
2386 {**
2387  Creates a TDateTime variant.
2388  @param Value a value to be assigned.
2389 }
2390 function EncodeDateTime(const Value: TDateTime): TZVariant;
2391 begin
2392  Result.VType := vtDateTime;
2393  Result.VDateTime := Value;
2394 end;
2395 
2396 {**
2397  Creates a pointer variant.
2398  @param Value a value to be assigned.
2399 }
2400 function EncodePointer(const Value: Pointer): TZVariant;
2401 begin
2402  Result.VType := vtPointer;
2403  Result.VPointer := Value;
2404 end;
2405 
2406 {**
2407  Creates an Interface variant.
2408  @param Value a value to be assigned.
2409 }
2410 function EncodeInterface(const Value: IZInterface): TZVariant;
2411 begin
2412  Result.VType := vtInterface;
2413  Result.VInterface := Value;
2414 end;
2415 
2416 initialization
2417  DefVarManager := TZDefaultVariantManager.Create;
2418  SoftVarManager := TZSoftVariantManager.Create;
2419  NullVariant := EncodeNull;
2420 finalization
2421  DefVarManager := nil;
2422  SoftVarManager := nil;
2423 end.
2424 
2425