565 lines
16 KiB
ObjectPascal
565 lines
16 KiB
ObjectPascal
unit SpkXMLIni;
|
|
|
|
{$mode ObjFpc}
|
|
{$H+}
|
|
|
|
{$DEFINE SPKXMLINI}
|
|
|
|
interface
|
|
|
|
uses SpkXMLParser, classes, sysutils;
|
|
|
|
type TSpkXMLIni = class(TObject)
|
|
private
|
|
FParser : TSpkXMLParser;
|
|
FAutoConvert : boolean;
|
|
protected
|
|
public
|
|
constructor Create; overload;
|
|
constructor Create(filename : string); overload;
|
|
destructor Destroy; override;
|
|
procedure LoadFromFile(filename : string);
|
|
procedure SaveToFile(filename : string);
|
|
procedure SaveToStream(AStream : TStream);
|
|
procedure LoadFromStream(AStream : TStream);
|
|
procedure Clear;
|
|
procedure DeleteKey(const Section, Ident: string);
|
|
procedure EraseSection(const Section: string);
|
|
function ReadString(const Section, Ident, Default: string): string;
|
|
procedure WriteString(const Section, Ident, Value: string);
|
|
function ReadBool (const Section, Ident: String; Default: Boolean): Boolean;
|
|
function ReadDate (const Section, Ident: string; Default: TDateTime): TDateTime;
|
|
function ReadDateTime (const Section, Ident: String; Default: TDateTime): TDateTime;
|
|
function ReadFloat (const Section, Ident: String; Default: Double): Double;
|
|
function ReadInteger(const Section, Ident: String; Default: Longint): Longint;
|
|
function ReadTime (const Section, Ident: String; Default: TDateTime): TDateTime;
|
|
function SectionExists (const Section: String): Boolean;
|
|
procedure WriteBool(const Section, Ident: String; Value: Boolean);
|
|
procedure WriteDate(const Section, Ident: String; Value: TDateTime);
|
|
procedure WriteDateTime(const Section, Ident: String; Value: TDateTime);
|
|
procedure WriteFloat(const Section, Ident: String; Value: Double);
|
|
procedure WriteInteger(const Section, Ident: String; Value: Longint);
|
|
procedure WriteTime(const Section, Ident: String; Value: TDateTime);
|
|
function ValueExists(const section, ident : string) : boolean;
|
|
procedure WriteStrings(const Section, Ident : String; Value : TStrings);
|
|
procedure ReadStrings(const Section, Ident : String; Target : TStrings);
|
|
procedure ReadSection (const Section: string; Strings: TStrings);
|
|
procedure ReadSections(Strings: TStrings);
|
|
procedure ReadSectionValues(const Section: string; Strings: TStrings);
|
|
|
|
property AutoConvert : boolean read FAutoConvert write FAutoConvert;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TSpkXMLIni }
|
|
|
|
constructor TSpkXMLIni.create;
|
|
|
|
begin
|
|
inherited create;
|
|
FParser:=TSpkXMLParser.create;
|
|
FAutoConvert:=true;
|
|
end;
|
|
|
|
constructor TSpkXMLIni.create(filename : string);
|
|
|
|
begin
|
|
inherited create;
|
|
self.LoadFromFile(filename);
|
|
end;
|
|
|
|
destructor TSpkXMLIni.destroy;
|
|
|
|
begin
|
|
FParser.free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.LoadFromFile(filename : string);
|
|
|
|
begin
|
|
try
|
|
FParser.LoadFromFile(filename);
|
|
except
|
|
self.clear;
|
|
end;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.LoadFromStream(AStream: TStream);
|
|
begin
|
|
FParser.LoadFromStream(AStream);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.SaveToFile(filename : string);
|
|
|
|
begin
|
|
FParser.SaveToFile(filename);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.SaveToStream(AStream: TStream);
|
|
begin
|
|
FParser.SaveToStream(AStream);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.Clear;
|
|
|
|
begin
|
|
FParser.Clear;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.DeleteKey(const Section, Ident: string);
|
|
|
|
var node : TSpkXMLNode;
|
|
subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node<>nil then
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode<>nil then
|
|
begin
|
|
node.delete(node.IndexOf(subnode));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.EraseSection(const Section: string);
|
|
|
|
var node : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node<>nil then
|
|
Fparser.Delete(FParser.IndexOf(node));
|
|
end;
|
|
|
|
function TSpkXMLIni.ReadString(const Section, Ident, Default: string): string;
|
|
|
|
var node, subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then result:=Default else
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode=nil then result:=Default else
|
|
begin
|
|
if subnode.Parameters.ParamByName['type',false]<>nil then
|
|
begin
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].Value)='STRING' then
|
|
result:=subnode.text else
|
|
begin
|
|
if FAutoConvert then
|
|
try
|
|
result:=subnode.text;
|
|
except
|
|
result:=Default;
|
|
end else raise exception.create('Invalid object type!');
|
|
end;
|
|
end else result:=subnode.Text;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteString(const Section, Ident, Value: string);
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Parameters.ParamByName['type',true].value:='string';
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Text:=Value;
|
|
end;
|
|
|
|
function TSpkXMLIni.ReadBool (const Section, Ident: String; Default: Boolean): Boolean;
|
|
|
|
var node, subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then result:=Default else
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode=nil then result:=Default else
|
|
begin
|
|
if subnode.Parameters.ParamByName['type',false]<>nil then
|
|
begin
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].Value)='BOOLEAN' then
|
|
begin
|
|
if (uppercase(subnode.text)='TRUE') or (subnode.text='1') then result:=true else result:=false;
|
|
end else
|
|
begin
|
|
if FAutoConvert then
|
|
try
|
|
if (uppercase(subnode.text)='TRUE') or (subnode.text='1') then result:=true else result:=false;
|
|
except
|
|
result:=Default;
|
|
end else raise exception.create('Invalid object type!');
|
|
end;
|
|
end else
|
|
try
|
|
if (uppercase(subnode.text)='TRUE') or (subnode.text='1') then result:=true else result:=false;
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSpkXMLIni.ReadDate (const Section, Ident: string; Default: TDateTime): TDateTime;
|
|
|
|
var node, subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then result:=Default else
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode=nil then result:=Default else
|
|
begin
|
|
if subnode.Parameters.ParamByName['type',false]<>nil then
|
|
begin
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].Value)='DATE' then
|
|
begin
|
|
try
|
|
result:=StrToDate(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end else
|
|
begin
|
|
if FAutoConvert then
|
|
try
|
|
result:=StrToDate(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end else raise exception.create('Invalid object type!');
|
|
end;
|
|
end else
|
|
try
|
|
result:=StrToDate(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSpkXMLIni.ReadDateTime (const Section, Ident: String; Default: TDateTime): TDateTime;
|
|
|
|
var node, subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then result:=Default else
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode=nil then result:=Default else
|
|
begin
|
|
if subnode.Parameters.ParamByName['type',false]<>nil then
|
|
begin
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].Value)='DATETIME' then
|
|
begin
|
|
try
|
|
result:=StrToDateTime(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end else
|
|
begin
|
|
if FAutoConvert then
|
|
try
|
|
result:=StrToDateTime(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end else raise exception.create('Invalid object type!');
|
|
end;
|
|
end else
|
|
try
|
|
result:=StrToDateTime(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSpkXMLIni.ReadFloat (const Section, Ident: String; Default: Double): Double;
|
|
|
|
var node, subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then result:=Default else
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode=nil then result:=Default else
|
|
begin
|
|
if subnode.Parameters.ParamByName['type',false]<>nil then
|
|
begin
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].Value)='FLOAT' then
|
|
begin
|
|
try
|
|
result:=StrToFloat(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end else
|
|
begin
|
|
if FAutoConvert then
|
|
try
|
|
result:=StrToFloat(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end else raise exception.create('Invalid object type!');
|
|
end;
|
|
end else
|
|
try
|
|
result:=StrToFloat(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSpkXMLIni.ReadInteger(const Section, Ident: String; Default: Longint): Longint;
|
|
|
|
var node, subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then result:=Default else
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode=nil then result:=Default else
|
|
begin
|
|
if subnode.Parameters.ParamByName['type',false]<>nil then
|
|
begin
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].Value)='FLOAT' then
|
|
begin
|
|
try
|
|
result:=StrToInt(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end else
|
|
begin
|
|
if FAutoConvert then
|
|
try
|
|
result:=StrToInt(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end else raise exception.create('Invalid object type!');
|
|
end;
|
|
end else
|
|
try
|
|
result:=StrToInt(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSpkXMLIni.ReadTime (const Section, Ident: String; Default: TDateTime): TDateTime;
|
|
|
|
var node, subnode : TSpkXMLNode;
|
|
|
|
begin
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then result:=Default else
|
|
begin
|
|
subnode:=node.NodeByName[Ident,false];
|
|
if subnode=nil then result:=Default else
|
|
begin
|
|
if subnode.Parameters.ParamByName['type',false]<>nil then
|
|
begin
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].Value)='TIME' then
|
|
begin
|
|
try
|
|
result:=StrToTime(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end else
|
|
begin
|
|
if FAutoConvert then
|
|
try
|
|
result:=StrToTime(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end else raise exception.create('Invalid object type!');
|
|
end;
|
|
end else
|
|
try
|
|
result:=StrToTime(subnode.text);
|
|
except
|
|
result:=Default;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TSpkXMLIni.SectionExists (const Section: String): Boolean;
|
|
|
|
begin
|
|
result:=FParser.NodeByName[Section,false]<>nil;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteBool(const Section, Ident: String; Value: Boolean);
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Parameters.ParamByName['type',true].Value:='boolean';
|
|
if Value then FParser.NodeByName[Section,true].NodeByName[Ident,true].Text:='true' else
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].text:='false';
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteDate(const Section, Ident: String; Value: TDateTime);
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Parameters.ParamByName['type',true].Value:='date';
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Text:=DateToStr(Value);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteDateTime(const Section, Ident: String; Value: TDateTime);
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Parameters.ParamByName['type',true].Value:='datetime';
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Text:=DateTimeToStr(Value);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteFloat(const Section, Ident: String; Value: Double);
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Parameters.ParamByName['type',true].Value:='float';
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Text:=FloatToStr(Value);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteInteger(const Section, Ident: String; Value: Longint);
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Parameters.ParamByName['type',true].Value:='integer';
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Text:=IntToStr(Value);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteTime(const Section, Ident: String; Value: TDateTime);
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Parameters.ParamByName['type',true].Value:='time';
|
|
FParser.NodeByName[Section,true].NodeByName[Ident,true].Text:=TimeToStr(Value);
|
|
end;
|
|
|
|
function TSpkXMLIni.ValueExists(const section, ident : string) : boolean;
|
|
|
|
begin
|
|
result:=FParser.NodeByName[section,false]<>nil;
|
|
if result then
|
|
result:=result and (FParser.NodeByName[section,false].NodeByName[ident,false]<>nil);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.WriteStrings(const Section, Ident : String; Value : TStrings);
|
|
|
|
var node,subnode : TSpkXMLNode;
|
|
i : integer;
|
|
|
|
begin
|
|
self.DeleteKey(Section,Ident);
|
|
node:=FParser.NodeByName[Section,true];
|
|
subnode:=node.NodeByName[ident,true];
|
|
subnode.Parameters.ParamByName['type',true].value:='strings';
|
|
subnode.parameters.parambyname['count',true].value:=IntToStr(Value.count);
|
|
for i:=0 to value.count-1 do
|
|
begin
|
|
subnode.NodeByName['line'+IntToStr(i),true].text:=Value[i];
|
|
end;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.ReadStrings(const Section, Ident : String; Target : TStrings);
|
|
|
|
var node, subnode, line : TSpkXMLNode;
|
|
i,count : integer;
|
|
|
|
begin
|
|
target.clear;
|
|
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node=nil then exit;
|
|
|
|
subnode:=node.NodeByName[ident,false];
|
|
if subnode=nil then exit;
|
|
|
|
if subnode.Parameters.ParamByName['type',false]=nil then exit;
|
|
if uppercase(subnode.Parameters.ParamByName['type',false].value)<>'STRINGS' then exit;
|
|
|
|
if subnode.parameters.parambyname['count',false]=nil then exit;
|
|
|
|
try
|
|
count:=StrToInt(subnode.parameters.parambyname['count',false].Value);
|
|
except
|
|
exit
|
|
end;
|
|
|
|
for i:=0 to count-1 do
|
|
begin
|
|
line:=subnode.NodeByName['line'+IntToStr(i),false];
|
|
if line=nil then
|
|
begin
|
|
target.Clear;
|
|
exit;
|
|
end;
|
|
target.Add(line.Text);
|
|
end;
|
|
end;
|
|
|
|
procedure TSpkXMLIni.ReadSection(const Section: string; Strings: TStrings);
|
|
|
|
var i : integer;
|
|
node : TSpkXMLNode;
|
|
|
|
begin
|
|
if FParser.NodeByName[Section,false]=nil then exit;
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node.Count=0 then exit;
|
|
for i:=0 to node.Count-1 do
|
|
Strings.Add(node.NodeByIndex[i].Name);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.ReadSections(Strings: TStrings);
|
|
|
|
var i : integer;
|
|
|
|
begin
|
|
if FParser.count=0 then exit;
|
|
for i:=0 to FParser.count-1 do
|
|
Strings.add(FParser.NodeByIndex[i].Name);
|
|
end;
|
|
|
|
procedure TSpkXMLIni.ReadSectionValues(const Section: string; Strings: TStrings);
|
|
|
|
var i : integer;
|
|
node : TSpkXMLNode;
|
|
|
|
begin
|
|
if FParser.NodeByName[Section,false]=nil then exit;
|
|
node:=FParser.NodeByName[Section,false];
|
|
if node.Count=0 then exit;
|
|
for i:=0 to node.count-1 do
|
|
begin
|
|
{$I-}
|
|
if (node.NodeByIndex[i].Parameters.ParamByName['type',false]<>nil) and
|
|
(uppercase(node.NodeByIndex[i].Parameters.ParamByName['type',false].Value)='STRINGS') then
|
|
Strings.add('[TStrings]')
|
|
else
|
|
Strings.add(node.NodeByIndex[i].Text);
|
|
end;
|
|
end;
|
|
|
|
end.
|