diff --git a/X2UtPersist.pas b/X2UtPersist.pas index 60ed1a8..0afaa57 100644 --- a/X2UtPersist.pas +++ b/X2UtPersist.pas @@ -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; diff --git a/X2UtPersistIntf.pas b/X2UtPersistIntf.pas index 18178f5..3bbdd7a 100644 --- a/X2UtPersistIntf.pas +++ b/X2UtPersistIntf.pas @@ -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. diff --git a/X2UtPersistXML.pas b/X2UtPersistXML.pas index 35e21e5..1fa5377 100644 --- a/X2UtPersistXML.pas +++ b/X2UtPersistXML.pas @@ -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; diff --git a/X2UtPersistXMLBinding.pas b/X2UtPersistXMLBinding.pas index 9e97070..3ea6444 100644 --- a/X2UtPersistXMLBinding.pas +++ b/X2UtPersistXMLBinding.pas @@ -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; diff --git a/XSD/PersistXML.xsd b/XSD/PersistXML.xsd index 201037c..22d24a8 100644 --- a/XSD/PersistXML.xsd +++ b/XSD/PersistXML.xsd @@ -5,16 +5,18 @@ - - - - - - - - - + + + + + + + + + + +