You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
6.7 KiB

  1. unit uutlVariantProperty;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, variants, typinfo;
  6. function VarProperty: TVarType; inline;
  7. function VarIsProperty(const aValue: Variant): Boolean; inline;
  8. function VarAsProperty(const aValue: Variant): Variant; inline;
  9. operator :=(const aValue: PPropInfo): Variant;
  10. operator :=(const aValue: Variant): PPropInfo;
  11. implementation
  12. type
  13. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  14. TutlVariantPropInfo = 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 FromPropInfo(const aPropInfo: PPropInfo): Variant;
  23. class function ToPropInfo (const aValue: Variant): PPropInfo;
  24. end;
  25. var
  26. VariantProperty: TutlVariantPropInfo;
  27. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  28. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  29. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  30. function VarProperty: TVarType;
  31. begin
  32. result := VariantProperty.VarType;
  33. end;
  34. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. function VarIsProperty(const aValue: Variant): Boolean;
  36. begin
  37. result := (VarType(aValue) = VarProperty);
  38. end;
  39. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  40. function VarAsProperty(const aValue: Variant): Variant;
  41. begin
  42. if not VarIsProperty(aValue)
  43. then VarCast(result, aValue, VarProperty)
  44. else result := aValue;
  45. end;
  46. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  47. operator := (const aValue: PPropInfo): Variant;
  48. begin
  49. result := TutlVariantPropInfo.FromPropInfo(aValue);
  50. end;
  51. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  52. operator := (const aValue: Variant): PPropInfo;
  53. begin
  54. result := TutlVariantPropInfo.ToPropInfo(aValue);
  55. end;
  56. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. //TutlVariantProperty///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. function TutlVariantPropInfo.IsClear(const V: TVarData): Boolean;
  60. begin
  61. result := not Assigned(V.vpointer);
  62. end;
  63. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. procedure TutlVariantPropInfo.Cast(var Dest: TVarData; const Source: TVarData);
  65. begin
  66. RaiseCastError;
  67. end;
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. procedure TutlVariantPropInfo.CastTo(var Dest: TVarData; const Source: TVarData; const aVarType: TVarType);
  70. begin
  71. if (Source.vtype <> VarType) then
  72. RaiseCastError;
  73. case aVarType of
  74. varolestr:
  75. if IsClear(Source)
  76. then VarDataFromOleStr(Dest, '')
  77. else VarDataFromOleStr(Dest, WideString(PPropInfo(Source.vpointer)^.Name));
  78. varstring:
  79. if IsClear(Source)
  80. then VarDataFromStr(Dest, '')
  81. else VarDataFromStr(Dest, PPropInfo(Source.vpointer)^.Name);
  82. else
  83. RaiseCastError;
  84. end;
  85. end;
  86. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. procedure TutlVariantPropInfo.Clear(var V: TVarData);
  88. begin
  89. if Assigned(V.vpointer) then begin
  90. Dispose(PPropInfo(V.vpointer));
  91. V.vpointer := nil;
  92. end;
  93. end;
  94. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  95. procedure TutlVariantPropInfo.Copy(var Dest: TVarData; const Source: TVarData; const Indirect: Boolean);
  96. begin
  97. if (Dest.vtype <> varempty) and (Dest.vtype <> Source.vtype) then
  98. RaiseInvalidOp;
  99. Dest.vtype := Source.vtype;
  100. if Assigned(Source.vpointer) then begin
  101. if not Assigned(Dest.vpointer) then
  102. Dest.vpointer := New(PPropInfo);
  103. PPropInfo(Dest.vpointer)^ := PPropInfo(Source.vpointer)^;
  104. end else if Assigned(Dest.vpointer) then begin
  105. Dispose(PPropInfo(Dest.vpointer));
  106. Dest.vpointer := nil;
  107. end;
  108. end;
  109. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  110. class function TutlVariantPropInfo.FromPropInfo(const aPropInfo: PPropInfo): Variant;
  111. begin
  112. with TVarData(result) do begin
  113. vPointer := new(PPropInfo);
  114. vType := VarProperty;
  115. PPropInfo(vPointer)^ := aPropInfo^;
  116. end;
  117. end;
  118. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. class function TutlVariantPropInfo.ToPropInfo(const aValue: Variant): PPropInfo;
  120. begin
  121. with TVarData(aValue) do begin
  122. result := PPropInfo(vpointer);
  123. end;
  124. end;
  125. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  126. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  127. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  128. initialization
  129. VariantProperty := TutlVariantPropInfo.Create;
  130. finalization
  131. FreeAndNil(VariantProperty);
  132. end.