25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
6.2 KiB

  1. unit uutlVariantObject;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, variants;
  6. function VarObject: TVarType; inline;
  7. function VarIsObject(const aValue: Variant): Boolean; inline;
  8. function VarAsObject(const aValue: Variant): Variant; inline;
  9. operator :=(const aValue: TObject): Variant; inline;
  10. operator :=(const aValue: Variant): TObject; inline;
  11. implementation
  12. type
  13. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  14. TutlVariantObject = class(TCustomVariantType)
  15. public
  16. function IsClear (const V: TVarData): Boolean; override;
  17. procedure Cast (var Dest: TVarData; const Source: TVarData); override;
  18. procedure CastTo (var Dest: TVarData; const Source: TVarData; const aVarType: TVarType); override;
  19. procedure Clear (var V: TVarData); override;
  20. procedure Copy (var Dest: TVarData; const Source: TVarData; const Indirect: Boolean); override;
  21. public
  22. class function FromObject(const aObj: TObject): Variant;
  23. class function ToObject (const aVar: Variant): TObject;
  24. end;
  25. var
  26. VariantObject: TutlVariantObject;
  27. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  28. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  29. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  30. function VarObject: TVarType;
  31. begin
  32. result := VariantObject.VarType;
  33. end;
  34. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. function VarIsObject(const aValue: Variant): Boolean;
  36. begin
  37. result := (TVarData(aValue).vtype = VarObject);
  38. end;
  39. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  40. function VarAsObject(const aValue: Variant): Variant;
  41. begin
  42. if not VarIsObject(aValue)
  43. then VarCast(result, aValue, VarObject)
  44. else result := aValue;
  45. end;
  46. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  47. operator := (const aValue: TObject): Variant;
  48. begin
  49. result := TutlVariantObject.FromObject(aValue);
  50. end;
  51. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  52. operator := (const aValue: Variant): TObject;
  53. begin
  54. result := TutlVariantObject.ToObject(aValue);
  55. end;
  56. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. //TutlVariantObject/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. function TutlVariantObject.IsClear(const V: TVarData): Boolean;
  60. begin
  61. result := (V.vpointer = nil);
  62. end;
  63. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. procedure TutlVariantObject.Cast(var Dest: TVarData; const Source: TVarData);
  65. begin
  66. RaiseCastError;
  67. end;
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. procedure TutlVariantObject.CastTo(var Dest: TVarData; const Source: TVarData; const aVarType: TVarType);
  70. var
  71. tmp: TVarData;
  72. begin
  73. if (Source.vtype <> VarType) then
  74. RaiseCastError;
  75. case aVarType of
  76. varolestr:
  77. VarDataFromOleStr(Dest, WideString(Format('$%p', [Source.vpointer])));
  78. varstring:
  79. VarDataFromStr(Dest, Format('$%p', [Source.vpointer]));
  80. else
  81. VarDataInit(tmp{%H-});
  82. try
  83. tmp.vtype := varqword;
  84. tmp.vqword := QWord(Source.vpointer);
  85. VarDataCastTo(Dest, tmp, aVarType);
  86. finally
  87. VarDataClear(tmp);
  88. end;
  89. end;
  90. end;
  91. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  92. procedure TutlVariantObject.Copy(var Dest: TVarData; const Source: TVarData; const Indirect: Boolean);
  93. begin
  94. if (Dest.vtype <> varempty) and (Dest.vtype <> Source.vtype) then
  95. RaiseInvalidOp;
  96. Dest := Source;
  97. end;
  98. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  99. procedure TutlVariantObject.Clear(var V: TVarData);
  100. begin
  101. V.vpointer := nil;
  102. end;
  103. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. class function TutlVariantObject.FromObject(const aObj: TObject): Variant;
  105. begin
  106. TVarData(result).vtype := VarObject;
  107. TVarData(result).vpointer := aObj;
  108. end;
  109. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  110. class function TutlVariantObject.ToObject(const aVar: Variant): TObject;
  111. var
  112. v: Variant;
  113. begin
  114. v := VarAsObject(aVar);
  115. result := TObject(TVarData(v).vpointer);
  116. end;
  117. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  120. initialization
  121. VariantObject := TutlVariantObject.Create;
  122. finalization
  123. FreeAndNil(VariantObject);
  124. end.