1
0
mirror of synced 2024-09-07 21:45:03 +00:00

Added: Variant support for X2UtPersist (defaults to String, handled explicitly by the XML implementation)

This commit is contained in:
Mark van Renswoude 2011-03-07 09:05:09 +00:00
parent c5ae6a8cef
commit cb92eabcf1
5 changed files with 360 additions and 112 deletions

View File

@ -93,12 +93,21 @@ type
procedure DeleteKey(const AName: String); virtual; abstract;
procedure DeleteSection(const AName: String); virtual; abstract;
{ IX2PersistReader2 }
function ReadVariant(const AName: string; out AValue: Variant): Boolean; virtual;
{ IX2PersistWriter2 }
function WriteVariant(const AName: Variant; const AValue: Variant): Boolean; virtual;
end;
implementation
uses
SysUtils,
Variants,
X2UtStrings;
@ -108,7 +117,8 @@ type
reference counting to go through this class. }
TX2PersistSectionFilerProxy = class(TInterfacedObject, IInterface,
IX2PersistFiler, IX2PersistReader,
IX2PersistWriter)
IX2PersistWriter, IX2PersistReader2,
IX2PersistWriter2)
private
FFiler: IX2PersistFiler;
FSectionCount: Integer;
@ -150,6 +160,13 @@ type
procedure DeleteKey(const AName: String);
procedure DeleteSection(const AName: String);
{ IX2PersistReader2 }
function ReadVariant(const AName: string; out AValue: Variant): Boolean;
{ IX2PersistWriter2 }
function WriteVariant(const AName: Variant; const AValue: Variant): Boolean;
public
constructor Create(const AFiler: IX2PersistFiler; const ASection: String);
destructor Destroy; override;
@ -319,6 +336,7 @@ var
stringValue: String;
int64Value: Int64;
objectProp: TObject;
variantValue: Variant;
begin
{ Only read writable properties }
@ -363,8 +381,8 @@ begin
end;
tkVariant:
if ReadString(APropInfo^.Name, stringValue) then
SetVariantProp(AObject, APropInfo, stringValue);
if ReadVariant(APropInfo^.Name, variantValue) then
SetVariantProp(AObject, APropInfo, variantValue);
tkInt64:
if ReadInt64(APropInfo^.Name, int64Value) then
@ -471,8 +489,7 @@ begin
tkVariant:
begin
stringValue := GetVariantProp(AObject, APropInfo);
WriteString(APropInfo^.Name, stringValue);
WriteVariant(APropInfo^.Name, GetVariantProp(AObject, APropInfo));
end;
tkInt64:
@ -602,6 +619,25 @@ begin
end;
function TX2CustomPersistFiler.ReadVariant(const AName: string; out AValue: Variant): Boolean;
var
stringValue: string;
begin
AValue := Unassigned;
Result := ReadString(AName, stringValue);
if Result then
AValue := stringValue;
end;
function TX2CustomPersistFiler.WriteVariant(const AName, AValue: Variant): Boolean;
begin
Result := WriteString(AName, AValue);
end;
{ TX2PersistSectionFilerProxy }
constructor TX2PersistSectionFilerProxy.Create(const AFiler: IX2PersistFiler; const ASection: String);
var
@ -680,7 +716,7 @@ end;
procedure TX2PersistSectionFilerProxy.EndSection;
begin
if Assigned(Filer) then
Filer.EndSection ;
Filer.EndSection;
end;
@ -759,6 +795,17 @@ begin
end;
function TX2PersistSectionFilerProxy.ReadVariant(const AName: string; out AValue: Variant): Boolean;
var
reader2: IX2PersistReader2;
begin
Result := False;
if Assigned(Filer) and Supports(Filer, IX2PersistReader2, reader2) then
Result := reader2.ReadVariant(AName, AValue);
end;
procedure TX2PersistSectionFilerProxy.Write(AObject: TObject);
begin
if Assigned(Filer) then
@ -798,6 +845,17 @@ begin
end;
function TX2PersistSectionFilerProxy.WriteVariant(const AName, AValue: Variant): Boolean;
var
writer2: IX2PersistWriter2;
begin
Result := False;
if Assigned(Filer) and Supports(Filer, IX2PersistWriter2, writer2) then
Result := writer2.WriteVariant(AName, AValue);
end;
function TX2PersistSectionFilerProxy.WriteInt64(const AName: String; AValue: Int64): Boolean;
begin
Result := False;

View File

@ -83,6 +83,18 @@ type
end;
IX2PersistReader2 = interface(IX2PersistReader)
['{50566396-7D47-4975-BD01-465366F9216F}']
function ReadVariant(const AName: String; out AValue: Variant): Boolean;
end;
IX2PersistWriter2 = interface(IX2PersistWriter)
['{AAC47A18-A5F9-47D3-AF00-A06E1779268C}']
function WriteVariant(const AName, AValue: Variant): Boolean;
end;
implementation
end.

View File

@ -38,8 +38,7 @@ type
FSection: IXMLSection;
FSectionStack: TInterfaceList;
protected
function ReadValue(const AName: string; out AValue: string): Boolean;
function WriteValue(const AName: string; const AValue: string): Boolean;
function GetValue(const AName: string; out AValue: IXMLvalue; AWriting: Boolean): Boolean;
public
function BeginSection(const AName: String): Boolean; override;
procedure EndSection; override;
@ -53,6 +52,7 @@ type
function ReadFloat(const AName: String; out AValue: Extended): Boolean; override;
function ReadString(const AName: String; out AValue: String): Boolean; override;
function ReadInt64(const AName: String; out AValue: Int64): Boolean; override;
function ReadVariant(const AName: string; out AValue: Variant): Boolean; override;
function ReadStream(const AName: string; AStream: TStream): Boolean; override;
@ -61,9 +61,11 @@ type
function WriteFloat(const AName: String; AValue: Extended): Boolean; override;
function WriteString(const AName, AValue: String): Boolean; override;
function WriteInt64(const AName: String; AValue: Int64): Boolean; override;
function WriteVariant(const AName: Variant; const AValue: Variant): Boolean; override;
function WriteStream(const AName: string; AStream: TStream): Boolean; override;
procedure DeleteKey(const AName: string); override;
procedure DeleteSection(const AName: string); override;
@ -86,14 +88,11 @@ type
implementation
uses
SysUtils,
Variants,
X2UtStrings;
const
RegistrySeparator = '\';
{ Wrapper functions }
function ReadFromXML(AObject: TObject; const AFileName: string): Boolean;
begin
@ -197,11 +196,11 @@ begin
begin
lastItem := Pred(SectionStack.Count);
if lastItem < 0 then
FSection := Configuration
if lastItem > 0 then
FSection := (SectionStack[Pred(lastItem)] as IXMLSection)
else
FSection := (SectionStack[Pred(lastItem)] as IXMLSection);
FSection := Configuration;
SectionStack.Delete(lastItem);
end;
end;
@ -227,40 +226,71 @@ begin
end;
function TX2UtPersistXMLFiler.ReadValue(const AName: string; out AValue: string): Boolean;
function TX2UtPersistXMLFiler.GetValue(const AName: string; out AValue: IXMLvalue; AWriting: Boolean): Boolean;
var
valueIndex: Integer;
begin
AValue := nil;
Result := False;
AValue := '';
for valueIndex := 0 to Pred(Section.value.Count) do
if SameText(Section.value[valueIndex].name, AName) then
begin
AValue := Section.value[valueIndex].Text;
AValue := Section.value[valueIndex];
Result := True;
Break;
end;
if AWriting then
begin
if not Result then
begin
AValue := Section.value.Add;
AValue.name := AName;
end;
AValue.ChildNodes.Clear;
Result := True;
end;
end;
function TX2UtPersistXMLFiler.ReadInteger(const AName: String; out AValue: Integer): Boolean;
var
value: string;
value: IXMLvalue;
begin
AValue := 0;
Result := ReadValue(AName, value) and TryStrToInt(value, AValue);
Result := GetValue(AName, value, False) and (value.Hasinteger);
if Result then
AValue := value.integer;
end;
function TX2UtPersistXMLFiler.ReadFloat(const AName: String; out AValue: Extended): Boolean;
var
value: string;
value: IXMLvalue;
begin
AValue := 0;
Result := ReadValue(AName, value) and TryStrToFloat(value, AValue);
Result := GetValue(AName, value, False) and (value.Hasfloat);
if Result then
AValue := value.float;
end;
function TX2UtPersistXMLFiler.ReadVariant(const AName: string; out AValue: Variant): Boolean;
var
value: IXMLvalue;
begin
Result := GetValue(AName, value, False) and (value.Hasvariant);
if Result then
begin
if value.variantIsNil then
AValue := Null
else
AValue := value.variant;
end;
end;
@ -272,62 +302,83 @@ end;
function TX2UtPersistXMLFiler.ReadString(const AName: String; out AValue: String): Boolean;
var
value: string;
value: IXMLvalue;
begin
Result := ReadValue(AName, value);
Result := GetValue(AName, value, False) and (value.Has_string);
if Result then
AValue := value._string;
end;
function TX2UtPersistXMLFiler.ReadInt64(const AName: String; out AValue: Int64): Boolean;
var
value: string;
begin
AValue := 0;
Result := ReadValue(AName, value) and TryStrToInt64(value, AValue);
end;
function TX2UtPersistXMLFiler.WriteValue(const AName, AValue: string): Boolean;
var
value: IXMLvalue;
valueIndex: Integer;
begin
Result := False;
value := nil;
for valueIndex := 0 to Pred(Section.value.Count) do
if SameText(Section.value[valueIndex].name, AName) then
begin
value := Section.value[valueIndex];
Break;
end;
if not Assigned(value) then
begin
value := Section.value.Add;
value.name := AName;
end;
if Assigned(value) then
begin
value.Text := AValue;
Result := True;
end;
Result := GetValue(AName, value, False) and (value.Hasint64);
if Result then
AValue := value.int64;
end;
function TX2UtPersistXMLFiler.WriteInteger(const AName: String; AValue: Integer): Boolean;
var
value: IXMLvalue;
begin
Result := WriteValue(AName, IntToStr(AValue));
Result := GetValue(AName, value, True);
if Result then
value.integer := AValue;
end;
function TX2UtPersistXMLFiler.WriteFloat(const AName: String; AValue: Extended): Boolean;
var
value: IXMLvalue;
begin
Result := WriteValue(AName, FloatToStr(AValue));
Result := GetValue(AName, value, True);
if Result then
value.float := AValue;
end;
function TX2UtPersistXMLFiler.WriteString(const AName, AValue: String): Boolean;
var
value: IXMLvalue;
begin
Result := GetValue(AName, value, True);
if Result then
value._string := AValue;
end;
function TX2UtPersistXMLFiler.WriteInt64(const AName: String; AValue: Int64): Boolean;
var
value: IXMLvalue;
begin
Result := GetValue(AName, value, True);
if Result then
value.int64 := AValue;
end;
function TX2UtPersistXMLFiler.WriteVariant(const AName, AValue: Variant): Boolean;
var
value: IXMLvalue;
begin
Result := GetValue(AName, value, True);
if Result then
begin
if VarIsNull(AValue) or VarIsClear(AValue) then
value.variantIsNil := True
else
value.variant := AValue;
end;
end;
@ -337,18 +388,6 @@ begin
end;
function TX2UtPersistXMLFiler.WriteString(const AName, AValue: String): Boolean;
begin
Result := WriteValue(AName, AValue);
end;
function TX2UtPersistXMLFiler.WriteInt64(const AName: String; AValue: Int64): Boolean;
begin
Result := WriteValue(AName, IntToStr(AValue));
end;
procedure TX2UtPersistXMLFiler.DeleteKey(const AName: string);
var
valueIndex: Integer;

View File

@ -1,7 +1,7 @@
{
X2Software XML Data Binding
Generated on: 18-2-2011 15:23:30
Generated on: 3-3-2011 12:45:23
Generated from: P:\test\X2Utils\XSD\PersistXML.xsd
}
unit X2UtPersistXMLBinding;
@ -18,12 +18,12 @@ type
IXMLSection = interface;
IXMLvalueList = interface;
IXMLsectionList = interface;
IXMLvalue = interface;
IXMLValue = interface;
IXMLConfiguration = interface;
{ Interfaces for PersistXML }
IXMLSection = interface(IXMLNode)
['{37E1BD74-261B-44DA-BA06-162DBE32160C}']
['{810C68EC-1138-4B89-A164-9F9B03970771}']
function Getsection: IXMLsectionList;
function Getvalue: IXMLvalueList;
function GetHasname: Boolean;
@ -38,16 +38,16 @@ type
end;
IXMLvalueList = interface(IXMLNodeCollection)
['{267C86A8-44E3-4532-8ABE-15B1EDBFD78D}']
function Get_value(Index: Integer): IXMLvalue;
function Add: IXMLvalue;
function Insert(Index: Integer): IXMLvalue;
['{93139658-6A8B-46DE-B7B9-734A6A94762A}']
function Get_value(Index: Integer): IXMLValue;
function Add: IXMLValue;
function Insert(Index: Integer): IXMLValue;
property value[Index: Integer]: IXMLvalue read Get_value; default;
property value[Index: Integer]: IXMLValue read Get_value; default;
end;
IXMLsectionList = interface(IXMLNodeCollection)
['{2C43C489-F92B-4E8F-873F-3825FC294945}']
['{C6BFF503-B4F0-492B-9B60-B97140D59782}']
function Get_section(Index: Integer): IXMLSection;
function Add: IXMLSection;
function Insert(Index: Integer): IXMLSection;
@ -55,19 +55,47 @@ type
property section[Index: Integer]: IXMLSection read Get_section; default;
end;
IXMLvalue = interface(IXMLNode)
['{63A166DE-F145-4A3E-941B-6A937DE0B783}']
IXMLValue = interface(IXMLNode)
['{3F92F545-4FA7-43AD-A623-113BD9100FE2}']
function GetHasinteger: Boolean;
function Getinteger: Integer;
function GetHasfloat: Boolean;
function Getfloat: Double;
function GetHas_string: Boolean;
function Get_string: WideString;
function GetHasvariant: Boolean;
function GetvariantIsNil: Boolean;
function Getvariant: WideString;
function GetHasint64: Boolean;
function Getint64: Int64;
function GetHasname: Boolean;
function Getname: WideString;
procedure Setinteger(const Value: Integer);
procedure Setfloat(const Value: Double);
procedure Set_string(const Value: WideString);
procedure SetvariantIsNil(const Value: Boolean);
procedure Setvariant(const Value: WideString);
procedure Setint64(const Value: Int64);
procedure Setname(const Value: WideString);
property Hasinteger: Boolean read GetHasinteger;
property integer: Integer read Getinteger write Setinteger;
property Hasfloat: Boolean read GetHasfloat;
property float: Double read Getfloat write Setfloat;
property Has_string: Boolean read GetHas_string;
property _string: WideString read Get_string write Set_string;
property Hasvariant: Boolean read GetHasvariant;
property variantIsNil: Boolean read GetvariantIsNil write SetvariantIsNil;
property variant: WideString read Getvariant write Setvariant;
property Hasint64: Boolean read GetHasint64;
property int64: Int64 read Getint64 write Setint64;
property Hasname: Boolean read GetHasname;
property name: WideString read Getname write Setname;
end;
IXMLConfiguration = interface(IXMLSection)
['{81AAD8C2-F976-4203-B9D6-646408E5DE8A}']
['{AE639E63-960C-445F-89D8-53866535F725}']
procedure XSDValidateDocument;
end;
@ -92,9 +120,9 @@ type
public
procedure AfterConstruction; override;
protected
function Get_value(Index: Integer): IXMLvalue;
function Add: IXMLvalue;
function Insert(Index: Integer): IXMLvalue;
function Get_value(Index: Integer): IXMLValue;
function Add: IXMLValue;
function Insert(Index: Integer): IXMLValue;
end;
TXMLsectionList = class(TXMLNodeCollection, IXMLsectionList)
@ -106,11 +134,28 @@ type
function Insert(Index: Integer): IXMLSection;
end;
TXMLvalue = class(TXMLNode, IXMLvalue)
TXMLValue = class(TXMLNode, IXMLValue)
protected
function GetHasinteger: Boolean;
function Getinteger: Integer;
function GetHasfloat: Boolean;
function Getfloat: Double;
function GetHas_string: Boolean;
function Get_string: WideString;
function GetHasvariant: Boolean;
function GetvariantIsNil: Boolean;
function Getvariant: WideString;
function GetHasint64: Boolean;
function Getint64: Int64;
function GetHasname: Boolean;
function Getname: WideString;
procedure Setinteger(const Value: Integer);
procedure Setfloat(const Value: Double);
procedure Set_string(const Value: WideString);
procedure SetvariantIsNil(const Value: Boolean);
procedure Setvariant(const Value: WideString);
procedure Setint64(const Value: Int64);
procedure Setname(const Value: WideString);
end;
@ -169,9 +214,9 @@ begin
RegisterChildNode('section', TXMLSection);
Fsection := CreateCollection(TXMLsectionList, IXMLSection, 'section') as IXMLsectionList;
RegisterChildNode('section', TXMLSection);
RegisterChildNode('value', TXMLvalue);
Fvalue := CreateCollection(TXMLvalueList, IXMLvalue, 'value') as IXMLvalueList;
RegisterChildNode('value', TXMLvalue);
RegisterChildNode('value', TXMLValue);
Fvalue := CreateCollection(TXMLvalueList, IXMLValue, 'value') as IXMLvalueList;
RegisterChildNode('value', TXMLValue);
inherited;
end;
@ -203,27 +248,27 @@ end;
procedure TXMLvalueList.AfterConstruction;
begin
RegisterChildNode('value', TXMLvalue);
RegisterChildNode('value', TXMLValue);
ItemTag := 'value';
ItemInterface := IXMLvalue;
ItemInterface := IXMLValue;
inherited;
end;
function TXMLvalueList.Get_value(Index: Integer): IXMLvalue;
function TXMLvalueList.Get_value(Index: Integer): IXMLValue;
begin
Result := (List[Index] as IXMLvalue);
Result := (List[Index] as IXMLValue);
end;
function TXMLvalueList.Add: IXMLvalue;
function TXMLvalueList.Add: IXMLValue;
begin
Result := (AddItem(-1) as IXMLvalue);
Result := (AddItem(-1) as IXMLValue);
end;
function TXMLvalueList.Insert(Index: Integer): IXMLvalue;
function TXMLvalueList.Insert(Index: Integer): IXMLValue;
begin
Result := (AddItem(Index) as IXMLvalue);
Result := (AddItem(Index) as IXMLValue);
end;
procedure TXMLsectionList.AfterConstruction;
@ -251,18 +296,110 @@ begin
Result := (AddItem(Index) as IXMLSection);
end;
function TXMLvalue.GetHasname: Boolean;
function TXMLValue.GetHasinteger: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('integer'));
end;
function TXMLValue.Getinteger: Integer;
begin
Result := ChildNodes['integer'].NodeValue;
end;
function TXMLValue.GetHasfloat: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('float'));
end;
function TXMLValue.Getfloat: Double;
begin
Result := XMLToFloat(ChildNodes['float'].NodeValue);
end;
function TXMLValue.GetHas_string: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('string'));
end;
function TXMLValue.Get_string: WideString;
begin
Result := ChildNodes['string'].Text;
end;
function TXMLValue.GetHasvariant: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('variant'));
end;
function TXMLValue.GetvariantIsNil: Boolean;
begin
Result := GetNodeIsNil(ChildNodes['variant']);
end;
function TXMLValue.Getvariant: WideString;
begin
Result := ChildNodes['variant'].Text;
end;
function TXMLValue.GetHasint64: Boolean;
begin
Result := Assigned(ChildNodes.FindNode('int64'));
end;
function TXMLValue.Getint64: Int64;
begin
Result := ChildNodes['int64'].NodeValue;
end;
function TXMLValue.GetHasname: Boolean;
begin
Result := Assigned(AttributeNodes.FindNode('name'));
end;
function TXMLvalue.Getname: WideString;
function TXMLValue.Getname: WideString;
begin
Result := AttributeNodes['name'].Text;
end;
procedure TXMLvalue.Setname(const Value: WideString);
procedure TXMLValue.Setinteger(const Value: Integer);
begin
ChildNodes['integer'].NodeValue := Value;
end;
procedure TXMLValue.Setfloat(const Value: Double);
begin
ChildNodes['float'].NodeValue := FloatToXML(Value);
end;
procedure TXMLValue.Set_string(const Value: WideString);
begin
ChildNodes['string'].NodeValue := Value;
end;
procedure TXMLValue.SetvariantIsNil(const Value: Boolean);
begin
SetNodeIsNil(ChildNodes['variant'], Value);
end;
procedure TXMLValue.Setvariant(const Value: WideString);
begin
ChildNodes['variant'].NodeValue := Value;
end;
procedure TXMLValue.Setint64(const Value: Int64);
begin
ChildNodes['int64'].NodeValue := Value;
end;
procedure TXMLValue.Setname(const Value: WideString);
begin
SetAttribute('name', Value);
end;

View File

@ -5,16 +5,18 @@
<xs:complexType name="Section">
<xs:sequence>
<xs:element name="section" type="Section" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="value" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:complexContent>
<xs:extension base="xs:anyType">
<xs:attribute name="name" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="value" type="Value" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:complexType name="Value">
<xs:choice>
<xs:element name="integer" type="xs:int"/>
<xs:element name="float" type="xs:float"/>
<xs:element name="string" type="xs:string"/>
<xs:element name="variant" type="xs:string" nillable="true"/>
<xs:element name="int64" type="xs:long"/>
</xs:choice>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
</xs:schema>