mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 09:29:26 +02:00
* TJSONIniFile class added
git-svn-id: trunk@36913 -
This commit is contained in:
parent
9bff5e1d2f
commit
25e85d1772
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -2532,6 +2532,7 @@ packages/fcl-json/examples/confdemo.lpi svneol=native#text/plain
|
|||||||
packages/fcl-json/examples/confdemo.pp svneol=native#text/plain
|
packages/fcl-json/examples/confdemo.pp svneol=native#text/plain
|
||||||
packages/fcl-json/examples/demoformat.pp svneol=native#text/plain
|
packages/fcl-json/examples/demoformat.pp svneol=native#text/plain
|
||||||
packages/fcl-json/examples/demortti.pp svneol=native#text/plain
|
packages/fcl-json/examples/demortti.pp svneol=native#text/plain
|
||||||
|
packages/fcl-json/examples/ini2json.pp svneol=native#text/plain
|
||||||
packages/fcl-json/examples/parsedemo.lpi svneol=native#text/plain
|
packages/fcl-json/examples/parsedemo.lpi svneol=native#text/plain
|
||||||
packages/fcl-json/examples/parsedemo.pp svneol=native#text/plain
|
packages/fcl-json/examples/parsedemo.pp svneol=native#text/plain
|
||||||
packages/fcl-json/examples/simpledemo.lpi svneol=native#text/plain
|
packages/fcl-json/examples/simpledemo.lpi svneol=native#text/plain
|
||||||
@ -2542,10 +2543,12 @@ packages/fcl-json/src/fpjson.pp svneol=native#text/plain
|
|||||||
packages/fcl-json/src/fpjsonrtti.pp svneol=native#text/plain
|
packages/fcl-json/src/fpjsonrtti.pp svneol=native#text/plain
|
||||||
packages/fcl-json/src/fpjsontopas.pp svneol=native#text/plain
|
packages/fcl-json/src/fpjsontopas.pp svneol=native#text/plain
|
||||||
packages/fcl-json/src/jsonconf.pp svneol=native#text/plain
|
packages/fcl-json/src/jsonconf.pp svneol=native#text/plain
|
||||||
|
packages/fcl-json/src/jsonini.pp svneol=native#text/plain
|
||||||
packages/fcl-json/src/jsonparser.pp svneol=native#text/plain
|
packages/fcl-json/src/jsonparser.pp svneol=native#text/plain
|
||||||
packages/fcl-json/src/jsonreader.pp svneol=native#text/plain
|
packages/fcl-json/src/jsonreader.pp svneol=native#text/plain
|
||||||
packages/fcl-json/src/jsonscanner.pp svneol=native#text/plain
|
packages/fcl-json/src/jsonscanner.pp svneol=native#text/plain
|
||||||
packages/fcl-json/tests/jsonconftest.pp svneol=native#text/plain
|
packages/fcl-json/tests/jsonconftest.pp svneol=native#text/plain
|
||||||
|
packages/fcl-json/tests/tcjsonini.pp svneol=native#text/plain
|
||||||
packages/fcl-json/tests/tcjsontocode.pp svneol=native#text/plain
|
packages/fcl-json/tests/tcjsontocode.pp svneol=native#text/plain
|
||||||
packages/fcl-json/tests/testcomps.pp svneol=native#text/plain
|
packages/fcl-json/tests/testcomps.pp svneol=native#text/plain
|
||||||
packages/fcl-json/tests/testjson.lpi svneol=native#text/plain
|
packages/fcl-json/tests/testjson.lpi svneol=native#text/plain
|
||||||
|
22
packages/fcl-json/examples/ini2json.pp
Normal file
22
packages/fcl-json/examples/ini2json.pp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
program ini2json;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
{$h+1}
|
||||||
|
|
||||||
|
uses sysutils,jsonini;
|
||||||
|
|
||||||
|
var
|
||||||
|
fin,fout : string;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (ParamCount<1) then
|
||||||
|
begin
|
||||||
|
Writeln('Usage : ',ExtractFileName(ParamStr(0)),' infile [outfile]');
|
||||||
|
Halt(1);
|
||||||
|
end;
|
||||||
|
Fin:=ParamStr(1);
|
||||||
|
FOut:=ParamStr(2);
|
||||||
|
If (Fout='') then
|
||||||
|
Fout:=ChangeFileExt(Fin,'.json');
|
||||||
|
TJSONIniFile.ConvertIni(Fin,Fout,False);
|
||||||
|
end.
|
@ -76,10 +76,19 @@ begin
|
|||||||
AddUnit('jsonparser');
|
AddUnit('jsonparser');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
T:=P.Targets.AddUnit('jsonini.pp');
|
||||||
|
T.ResourceStrings:=true;
|
||||||
|
with T.Dependencies do
|
||||||
|
begin
|
||||||
|
AddUnit('fpjson');
|
||||||
|
AddUnit('jsonparser');
|
||||||
|
end;
|
||||||
|
|
||||||
P.ExamplePath.Add('examples');
|
P.ExamplePath.Add('examples');
|
||||||
T:=P.Targets.AddExampleProgram('confdemo.pp');
|
T:=P.Targets.AddExampleProgram('confdemo.pp');
|
||||||
T:=P.Targets.AddExampleProgram('parsedemo.pp');
|
T:=P.Targets.AddExampleProgram('parsedemo.pp');
|
||||||
T:=P.Targets.AddExampleProgram('simpledemo.pp');
|
T:=P.Targets.AddExampleProgram('simpledemo.pp');
|
||||||
|
T:=P.Targets.AddExampleProgram('ini2json.pp');
|
||||||
|
|
||||||
// simpledemo.lpi
|
// simpledemo.lpi
|
||||||
// confdemo.lpi
|
// confdemo.lpi
|
||||||
|
548
packages/fcl-json/src/jsonini.pp
Normal file
548
packages/fcl-json/src/jsonini.pp
Normal file
@ -0,0 +1,548 @@
|
|||||||
|
unit jsonini;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
{$h+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, inifiles, fpjson, jsonscanner, jsonparser, dateutils;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TJSONIniFile }
|
||||||
|
|
||||||
|
TJSONIniFile = class(TCustomIniFile)
|
||||||
|
Private
|
||||||
|
FJSON: TJSONObject;
|
||||||
|
FCacheUpdates: Boolean;
|
||||||
|
FDirty : Boolean;
|
||||||
|
FStream: TStream;
|
||||||
|
procedure SetCacheUpdates(const AValue: Boolean);
|
||||||
|
protected
|
||||||
|
Function GetRoot : TJSONObject;
|
||||||
|
Function GetSection(Const ASectionName : String; AllowCreate : Boolean) : TJSONObject;
|
||||||
|
Function GetKeyData(Const ASectionName,AKeyName : String) : TJSONData;
|
||||||
|
// Return true if an existing item was replaced
|
||||||
|
Function SetKeyData(Const ASectionName,AKeyName : String; AData : TJSONData) : Boolean;
|
||||||
|
procedure MaybeUpdateFile;
|
||||||
|
property Dirty : Boolean Read FDirty;
|
||||||
|
public
|
||||||
|
constructor Create(const AFileName: string; AOptions : TIniFileOptions = []); override; overload;
|
||||||
|
constructor Create(AStream: TStream; AOptions : TJSONOptions); overload;
|
||||||
|
destructor Destroy; override;
|
||||||
|
Class Procedure ConvertIni(Const AIniFile,AJSONFile : String; StringsOnly : Boolean = True);
|
||||||
|
function ReadString(const Section, Ident, Default: string): string; override;
|
||||||
|
function ReadInteger(const Section, Ident: string; Default: Longint): Longint; override;
|
||||||
|
function ReadInt64(const Section, Ident: string; Default: Int64): Int64; override;
|
||||||
|
function ReadBool(const Section, Ident: string; Default: Boolean): Boolean; override;
|
||||||
|
function ReadDate(const Section, Ident: string; Default: TDateTime): TDateTime; override;
|
||||||
|
function ReadDateTime(const Section, Ident: string; Default: TDateTime): TDateTime; override;
|
||||||
|
function ReadFloat(const Section, Ident: string; Default: Double): Double; override;
|
||||||
|
function ReadTime(const Section, Ident: string; Default: TDateTime): TDateTime; override;
|
||||||
|
procedure WriteString(const Section, Ident, Value: String); override;
|
||||||
|
procedure WriteDate(const Section, Ident: string; Value: TDateTime); override;
|
||||||
|
procedure WriteDateTime(const Section, Ident: string; Value: TDateTime); override;
|
||||||
|
procedure WriteFloat(const Section, Ident: string; Value: Double); override;
|
||||||
|
procedure WriteTime(const Section, Ident: string; Value: TDateTime); override;
|
||||||
|
procedure WriteInteger(const Section, Ident: string; Value: Longint); override;
|
||||||
|
procedure WriteInt64(const Section, Ident: string; Value: Int64); override;
|
||||||
|
procedure WriteBool(const Section, Ident: string; Value: Boolean); override;
|
||||||
|
procedure ReadSection(const Section: string; Strings: TStrings); override;
|
||||||
|
procedure ReadSections(Strings: TStrings); override;
|
||||||
|
procedure ReadSectionValues(const Section: string; Strings: TStrings; AOptions : TSectionValuesOptions = [svoIncludeInvalid]); overload; override;
|
||||||
|
procedure EraseSection(const Section: string); override;
|
||||||
|
procedure DeleteKey(const Section, Ident: String); override;
|
||||||
|
procedure UpdateFile; override; overload;
|
||||||
|
procedure UpdateFile(Const AFileName : string); overload;
|
||||||
|
property Stream: TStream read FStream;
|
||||||
|
property CacheUpdates : Boolean read FCacheUpdates write SetCacheUpdates;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{ TJSONIniFile }
|
||||||
|
|
||||||
|
procedure TJSONIniFile.SetCacheUpdates(const AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FCacheUpdates and not AValue and FDirty then
|
||||||
|
UpdateFile;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.GetRoot: TJSONObject;
|
||||||
|
begin
|
||||||
|
Result:=FJSON;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.GetSection(const ASectionName: String; AllowCreate: Boolean): TJSONObject;
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : Integer;
|
||||||
|
R : TJSONObject;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=Nil;
|
||||||
|
R:=GetRoot;
|
||||||
|
I:=R.IndexOfName(ASectionName,True);
|
||||||
|
if (I<>-1) and (R.Items[i].JSONType=jtObject) then
|
||||||
|
Result:=R.Items[i] as TJSONObject
|
||||||
|
else if AllowCreate then
|
||||||
|
begin
|
||||||
|
if (I<>-1) then
|
||||||
|
R.Delete(I);
|
||||||
|
Result:=TJSONObject.Create;
|
||||||
|
R.Add(ASectionName,Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.GetKeyData(const ASectionName, AKeyName: String): TJSONData;
|
||||||
|
|
||||||
|
Var
|
||||||
|
O : TJSONObject;
|
||||||
|
I : integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=Nil;
|
||||||
|
O:=GetSection(ASectionName,False);
|
||||||
|
if Assigned(O) then
|
||||||
|
begin
|
||||||
|
I:=O.IndexOfName(AKeyName,True);
|
||||||
|
if (I<>-1) and (O.Items[i].JSONType in ActualValueJSONTypes) then
|
||||||
|
Result:=O.Items[i];
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.SetKeyData(const ASectionName, AKeyName: String; AData: TJSONData): Boolean;
|
||||||
|
Var
|
||||||
|
O : TJSONObject;
|
||||||
|
I : integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
O:=GetSection(ASectionName,true);
|
||||||
|
I:=O.IndexOfName(AKeyName,True);
|
||||||
|
Result:=(I<>-1);
|
||||||
|
if Result then
|
||||||
|
O.Delete(I);
|
||||||
|
O.Add(aKeyName,AData);
|
||||||
|
FDirty:=True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.MaybeUpdateFile;
|
||||||
|
begin
|
||||||
|
If FCacheUpdates then
|
||||||
|
FDirty:=True
|
||||||
|
else
|
||||||
|
UpdateFile;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TJSONIniFile.Create(const AFileName: string; AOptions : TIniFileOptions = []);
|
||||||
|
|
||||||
|
Var
|
||||||
|
F : TFileStream;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Inherited Create(AFileName,AOptions);
|
||||||
|
if Not FileExists(AFileName) then
|
||||||
|
FJSON:=TJSONObject.Create
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
F:=TFileStream.Create(AFileName,fmOpenRead or fmShareDenyWrite);
|
||||||
|
try
|
||||||
|
Create(F,[joUTF8,joComments,joIgnoreTrailingComma]);
|
||||||
|
finally
|
||||||
|
F.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TJSONIniFile.Create(AStream: TStream; AOptions: TJSONOptions);
|
||||||
|
|
||||||
|
Var
|
||||||
|
P : TJSONParser;
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=Nil;
|
||||||
|
P:=TJSONParser.Create(AStream,AOptions);
|
||||||
|
try
|
||||||
|
D:=P.Parse;
|
||||||
|
if (D is TJSONObject) then
|
||||||
|
begin
|
||||||
|
FJSON:=D as TJSONObject;
|
||||||
|
D:=Nil;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
FJSON:=TJSONObject.Create;
|
||||||
|
finally
|
||||||
|
D.Free;
|
||||||
|
P.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TJSONIniFile.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FJSON);
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TJSONIniFile.ConvertIni(const AIniFile, AJSONFile: String; StringsOnly: Boolean = true);
|
||||||
|
|
||||||
|
Var
|
||||||
|
SIni : TMemIniFile;
|
||||||
|
Dini : TJSONIniFile;
|
||||||
|
S,K : TStrings;
|
||||||
|
SN,KN,V : String;
|
||||||
|
I6 : Int64;
|
||||||
|
F : Double;
|
||||||
|
B : Boolean;
|
||||||
|
DT : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
S:=Nil;
|
||||||
|
K:=Nil;
|
||||||
|
Dini:=Nil;
|
||||||
|
SIni:=TMemIniFile.Create(AIniFile);
|
||||||
|
try
|
||||||
|
DIni:=Self.Create(AJSONFile);
|
||||||
|
S:=TStringList.Create;
|
||||||
|
K:=TStringList.Create;
|
||||||
|
SIni.ReadSections(S);
|
||||||
|
For SN in S do
|
||||||
|
begin
|
||||||
|
SIni.ReadSection(SN,K);
|
||||||
|
For KN in K do
|
||||||
|
begin
|
||||||
|
V:=Sini.ReadString(SN,KN,'');
|
||||||
|
if StringsOnly then
|
||||||
|
Dini.WriteString(SN,KN,V)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
If TryStrToInt64(V,I6) then
|
||||||
|
Dini.WriteInt64(SN,KN,I6)
|
||||||
|
else If TryStrToFloat(V,F) then
|
||||||
|
Dini.WriteFloat(SN,KN,F)
|
||||||
|
else If TryStrToBool(V,B) then
|
||||||
|
Dini.WriteBool(SN,KN,B)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
DT:=SIni.ReadTime(SN,KN,-1);
|
||||||
|
B:=DT<>-1;
|
||||||
|
if B then
|
||||||
|
DIni.WriteTime(SN,KN,DT)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
DT:=SIni.ReadDate(SN,KN,0);
|
||||||
|
B:=DT<>0;
|
||||||
|
if B then
|
||||||
|
DIni.WriteDate(SN,KN,DT)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
DT:=SIni.ReadDateTime(SN,KN,0);
|
||||||
|
B:=DT<>0;
|
||||||
|
if B then
|
||||||
|
DIni.WriteDateTime(SN,KN,DT)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Not B then
|
||||||
|
Dini.WriteString(SN,KN,V)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Dini.UpdateFile;
|
||||||
|
finally
|
||||||
|
FreeAndNil(S);
|
||||||
|
FreeAndNil(K);
|
||||||
|
FreeAndNil(Dini);
|
||||||
|
FreeAndNil(Sini);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadString(const Section, Ident, Default: string): string;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if D.JSONType in StructuredJSONTypes then
|
||||||
|
Result:=D.AsJSON
|
||||||
|
else
|
||||||
|
Result:=D.AsString;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadInteger(const Section, Ident: string; Default: Longint): Longint;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else
|
||||||
|
if D.JSONType=jtNumber then
|
||||||
|
Result:=D.AsInteger
|
||||||
|
else
|
||||||
|
if not TryStrToInt(D.AsString,Result) then
|
||||||
|
Result:=Default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadInt64(const Section, Ident: string; Default: Int64): Int64;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else
|
||||||
|
if D.JSONType=jtNumber then
|
||||||
|
Result:=D.AsInt64
|
||||||
|
else
|
||||||
|
if not TryStrToInt64(D.AsString,Result) then
|
||||||
|
Result:=Default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadBool(const Section, Ident: string; Default: Boolean): Boolean;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else
|
||||||
|
// Avoid exception frame
|
||||||
|
if D.JSONType=jtBoolean then
|
||||||
|
Result:=D.AsBoolean
|
||||||
|
else
|
||||||
|
try
|
||||||
|
Result:=D.AsBoolean;
|
||||||
|
except
|
||||||
|
Result:=Default;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadDate(const Section, Ident: string; Default: TDateTime): TDateTime;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else if D.JSONType=jtNumber then
|
||||||
|
Result:=TDateTime(D.AsFloat)
|
||||||
|
else
|
||||||
|
Result:=ScanDateTime('yyyy"-"mm"-"dd',D.AsString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadDateTime(const Section, Ident: string; Default: TDateTime): TDateTime;
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else if D.JSONType=jtNumber then
|
||||||
|
Result:=TDateTime(D.AsFloat)
|
||||||
|
else
|
||||||
|
Result:=ScanDateTime('yyyy"-"mm"-"dd"T"hh":"nn":"ss"."zzz',D.AsString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadFloat(const Section, Ident: string; Default: Double): Double;
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
C : Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else
|
||||||
|
if D.JSONType=jtNumber then
|
||||||
|
Result:=D.AsFloat
|
||||||
|
else
|
||||||
|
// Localized
|
||||||
|
if not TryStrToFloat(D.AsString,Result) then
|
||||||
|
begin
|
||||||
|
// Not localized
|
||||||
|
Val(D.AsString,Result,C);
|
||||||
|
if (C<>0) then
|
||||||
|
Result:=Default;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniFile.ReadTime(const Section, Ident: string; Default: TDateTime): TDateTime;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=GetKeyData(Section,Ident);
|
||||||
|
if Not Assigned(D) then
|
||||||
|
Result:=Default
|
||||||
|
else if D.JSONType=jtNumber then
|
||||||
|
Result:=Frac(TDateTime(D.AsFloat))
|
||||||
|
else
|
||||||
|
Result:=ScanDateTime('"0000-00-00T"hh":"nn":"ss"."zzz',D.AsString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteString(const Section, Ident, Value: String);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(Value));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteDate(const Section, Ident: string; Value: TDateTime);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(FormatDateTime('yyyy"-"mm"-"dd"T"00":"00":"00.zzz',Value)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteDateTime(const Section, Ident: string; Value: TDateTime);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(FormatDateTime('yyyy"-"mm"-"dd"T"hh":"nn":"ss.zzz',Value)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteFloat(const Section, Ident: string; Value: Double);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(Value));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteTime(const Section, Ident: string; Value: TDateTime);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(FormatDateTime('0000"-"00"-"00"T"hh":"nn":"ss.zzz',Value)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteInteger(const Section, Ident: string; Value: Longint);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(Value));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteInt64(const Section, Ident: string; Value: Int64);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(Value));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.WriteBool(const Section, Ident: string; Value: Boolean);
|
||||||
|
begin
|
||||||
|
SetKeyData(Section,Ident,CreateJSON(Value));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.ReadSection(const Section: string; Strings: TStrings);
|
||||||
|
Var
|
||||||
|
O : TJSONObject;
|
||||||
|
E : TJSONEnum;
|
||||||
|
|
||||||
|
begin
|
||||||
|
O:=GetSection(Section,False);
|
||||||
|
if Assigned(O) then
|
||||||
|
For E in O do
|
||||||
|
If (E.Value.JSONType in ActualValueJSONTypes) then
|
||||||
|
Strings.Add(E.Key);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.ReadSections(Strings: TStrings);
|
||||||
|
|
||||||
|
Var
|
||||||
|
R : TJSONObject;
|
||||||
|
E : TJSONEnum;
|
||||||
|
|
||||||
|
begin
|
||||||
|
R:=GetRoot;
|
||||||
|
for E in R do
|
||||||
|
if E.Value.JSONType=jtObject then
|
||||||
|
Strings.Add(E.Key);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.ReadSectionValues(const Section: string; Strings: TStrings; AOptions: TSectionValuesOptions);
|
||||||
|
|
||||||
|
Var
|
||||||
|
O : TJSONObject;
|
||||||
|
E : TJSONEnum;
|
||||||
|
V : TJSONStringType;
|
||||||
|
|
||||||
|
begin
|
||||||
|
O:=GetSection(Section,False);
|
||||||
|
if Assigned(O) then
|
||||||
|
For E in O do
|
||||||
|
begin
|
||||||
|
If (E.Value.JSONType in ActualValueJSONTypes) then
|
||||||
|
begin
|
||||||
|
V:=E.Value.AsString;
|
||||||
|
Strings.Add(E.Key+'='+V);
|
||||||
|
end
|
||||||
|
else if (svoIncludeInvalid in AOptions) then
|
||||||
|
begin
|
||||||
|
V:=E.Value.AsJSON;
|
||||||
|
Strings.Add(E.Key+'='+V);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.EraseSection(const Section: string);
|
||||||
|
|
||||||
|
Var
|
||||||
|
I : Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
I:=GetRoot.IndexOfName(Section,True);
|
||||||
|
if (I<>-1) then
|
||||||
|
begin
|
||||||
|
GetRoot.Delete(I);
|
||||||
|
MaybeUpdateFile;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.DeleteKey(const Section, Ident: String);
|
||||||
|
|
||||||
|
Var
|
||||||
|
O : TJSONObject;
|
||||||
|
I : integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
O:=GetSection(Section,False);
|
||||||
|
if O<>Nil then
|
||||||
|
begin
|
||||||
|
I:=O.IndexOfName(Ident,True);
|
||||||
|
if I<>-1 then
|
||||||
|
begin
|
||||||
|
O.Delete(I);
|
||||||
|
MaybeUpdateFile;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.UpdateFile;
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
If (FileName<>'') then
|
||||||
|
UpdateFile(FileName)
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniFile.UpdateFile(const AFileName: string);
|
||||||
|
|
||||||
|
Var
|
||||||
|
S : TJSONStringType;
|
||||||
|
|
||||||
|
begin
|
||||||
|
With TFileStream.Create(AFileName,fmCreate) do
|
||||||
|
try
|
||||||
|
S:=FJSON.FormatJSON();
|
||||||
|
WriteBuffer(S[1],Length(S));
|
||||||
|
finally
|
||||||
|
Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
620
packages/fcl-json/tests/tcjsonini.pp
Normal file
620
packages/fcl-json/tests/tcjsonini.pp
Normal file
@ -0,0 +1,620 @@
|
|||||||
|
unit tcjsonini;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, fpcunit, testregistry, fpjson, inifiles, jsonini;
|
||||||
|
|
||||||
|
Type
|
||||||
|
|
||||||
|
{ TJSONIniTest }
|
||||||
|
|
||||||
|
TJSONIniTest = Class(TTestCase)
|
||||||
|
private
|
||||||
|
FFileContent: TJSONData;
|
||||||
|
Fini: TJSONIniFile;
|
||||||
|
FStrings: TStrings;
|
||||||
|
FTestFile: String;
|
||||||
|
procedure AssertValue(const aSection, Akey, avalue: string);
|
||||||
|
procedure CreateIni;
|
||||||
|
function GetIni: TJSONIniFile;
|
||||||
|
function GetO: TJSONObject;
|
||||||
|
Protected
|
||||||
|
procedure HaveFile;
|
||||||
|
Procedure ReLoad;
|
||||||
|
procedure NoFileYet;
|
||||||
|
procedure RemoveFile;
|
||||||
|
Procedure Setup; override;
|
||||||
|
Procedure TearDown; override;
|
||||||
|
Procedure ReadFile;
|
||||||
|
Procedure WriteFile;
|
||||||
|
Procedure SampleFile;
|
||||||
|
Property TestFile : String Read FTestFile;
|
||||||
|
Property FileContent : TJSONData Read FFileContent Write FFileContent;
|
||||||
|
Property ObjFileContent : TJSONObject Read GetO;
|
||||||
|
Property Ini : TJSONIniFile Read GetIni;
|
||||||
|
Property Strings : TStrings Read FStrings;
|
||||||
|
Published
|
||||||
|
Procedure TestEmpty;
|
||||||
|
Procedure TestReadEmpty;
|
||||||
|
Procedure TestReadEmptyValue;
|
||||||
|
Procedure TestReadEmptyObject;
|
||||||
|
Procedure TestRead1EmptySection;
|
||||||
|
Procedure TestReadSections;
|
||||||
|
procedure TestReadSection;
|
||||||
|
procedure TestReadSectionValues;
|
||||||
|
Procedure TestReadString;
|
||||||
|
Procedure TestReadInteger;
|
||||||
|
Procedure TestReadInt64;
|
||||||
|
Procedure TestReadFloat;
|
||||||
|
Procedure TestReadBoolean;
|
||||||
|
Procedure TestReadDate;
|
||||||
|
Procedure TestReadTime;
|
||||||
|
Procedure TestReadDateTime;
|
||||||
|
Procedure TestEraseSection;
|
||||||
|
Procedure TestEraseSectionCaseMismatch;
|
||||||
|
Procedure TestDeleteKey;
|
||||||
|
Procedure TestDeleteKeySectionCaseMismatch;
|
||||||
|
Procedure TestDeleteKeyKeyCaseMismatch;
|
||||||
|
Procedure TestWriteString;
|
||||||
|
Procedure TestWriteInteger;
|
||||||
|
Procedure TestWriteBoolean;
|
||||||
|
Procedure TestWriteDate;
|
||||||
|
Procedure TestWriteDateTime;
|
||||||
|
Procedure TestWriteTime;
|
||||||
|
Procedure TestConvertIni;
|
||||||
|
Procedure TestConvertIniString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{ TJSONIniTest }
|
||||||
|
|
||||||
|
function TJSONIniTest.GetIni: TJSONIniFile;
|
||||||
|
begin
|
||||||
|
If FIni=Nil then
|
||||||
|
begin
|
||||||
|
Fini:=TJSONIniFile.Create(TestFile);
|
||||||
|
end;
|
||||||
|
Result:=FIni;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TJSONIniTest.GetO: TJSONObject;
|
||||||
|
begin
|
||||||
|
Result:=FFileContent as TJSONObject;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.Setup;
|
||||||
|
begin
|
||||||
|
Inherited;
|
||||||
|
FTestFile:=TestName+'.json';
|
||||||
|
If FileExists(FTestFile) then
|
||||||
|
DeleteFile(FTestFile);
|
||||||
|
FStrings:=TStringList.Create;
|
||||||
|
// Do nothing
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TearDown;
|
||||||
|
begin
|
||||||
|
If FileExists(FTestFile) then
|
||||||
|
DeleteFile(FTestFile);
|
||||||
|
FreeAndNil(FFileContent);
|
||||||
|
FreeAndNil(FIni);
|
||||||
|
FreeAndNil(FStrings);
|
||||||
|
Inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.ReadFile;
|
||||||
|
|
||||||
|
Var
|
||||||
|
F : TFileStream;
|
||||||
|
|
||||||
|
begin
|
||||||
|
FreeAndNil(FFileContent);
|
||||||
|
AssertTrue('Test File '+TestFile+' exists.',FileExists(TestFile));
|
||||||
|
F:=TFileStream.Create(TestFile,fmOpenRead or fmShareDenyWrite);
|
||||||
|
try
|
||||||
|
FileContent:=GetJSON(F);
|
||||||
|
finally
|
||||||
|
F.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.WriteFile;
|
||||||
|
|
||||||
|
Var
|
||||||
|
F : TFileStream;
|
||||||
|
S : TJSONStringType;
|
||||||
|
|
||||||
|
begin
|
||||||
|
F:=TFileStream.Create(TestFile,fmCreate);
|
||||||
|
try
|
||||||
|
S:=FFileContent.AsJSON;
|
||||||
|
F.WriteBuffer(S[1],Length(S));
|
||||||
|
finally
|
||||||
|
F.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.SampleFile;
|
||||||
|
|
||||||
|
begin
|
||||||
|
FileContent:=TJSONObject.Create([
|
||||||
|
'a',TJSONObject.Create([
|
||||||
|
'i',1,
|
||||||
|
'i6',TJSONInt64Number.Create(Maxint*2),
|
||||||
|
'f',1.2,
|
||||||
|
's','test',
|
||||||
|
'si','1',
|
||||||
|
'si6',IntToStr(int64(MaxInt*2)),
|
||||||
|
'sf','1.2',
|
||||||
|
'dt','2001-05-06T23:24:25.678',
|
||||||
|
'id',Round(EncodeDate(2001,05,06)),
|
||||||
|
'fd',EncodeDate(2001,05,06),
|
||||||
|
't','0000-00-00T12:13:14.567',
|
||||||
|
'ft',Frac(EncodeTime(12,13,14,567)),
|
||||||
|
'fdt',EncodeDate(2001,05,06)+EncodeTime(23,24,25,678),
|
||||||
|
'd','2001-05-06',
|
||||||
|
'b',true,
|
||||||
|
'n',Nil,
|
||||||
|
'o',TJSONObject.Create
|
||||||
|
]),
|
||||||
|
'B',TJSONObject.Create([
|
||||||
|
'I',1,
|
||||||
|
'F',1.2,
|
||||||
|
'S','test',
|
||||||
|
'SI','1',
|
||||||
|
'SF','1.2',
|
||||||
|
'DT','2001-05-06T23:24:25.678',
|
||||||
|
'T','0000-00-00T12:13:14.567',
|
||||||
|
'D','2001-05-06',
|
||||||
|
'B',true,
|
||||||
|
'N',Nil,
|
||||||
|
'O',TJSONObject.Create
|
||||||
|
]),
|
||||||
|
'NO','not'
|
||||||
|
]);
|
||||||
|
WriteFile;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestEmpty;
|
||||||
|
begin
|
||||||
|
AssertFalse('No test file',FileExists(testfile));
|
||||||
|
AssertNull('No ini',Fini);
|
||||||
|
AssertNull('No file content',FFileContent);
|
||||||
|
AssertNotNull('Have strings',Strings);
|
||||||
|
AssertEquals('Have empty strings',0,Strings.Count);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadEmpty;
|
||||||
|
begin
|
||||||
|
Ini.ReadSections(Strings);
|
||||||
|
AssertEquals('No sections',0,Strings.Count);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadEmptyValue;
|
||||||
|
begin
|
||||||
|
FileContent:=TJSONString.Create('me');
|
||||||
|
WriteFile;
|
||||||
|
Ini.ReadSections(Strings);
|
||||||
|
AssertEquals('No sections',0,Strings.Count);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadEmptyObject;
|
||||||
|
begin
|
||||||
|
FileContent:=TJSONObject.Create();
|
||||||
|
WriteFile;
|
||||||
|
Ini.ReadSections(Strings);
|
||||||
|
AssertEquals('No sections',0,Strings.Count);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestRead1EmptySection;
|
||||||
|
begin
|
||||||
|
FileContent:=TJSONObject.Create(['empty',TJSONOBject.Create]);
|
||||||
|
WriteFile;
|
||||||
|
Ini.ReadSections(Strings);
|
||||||
|
AssertEquals('1 sections',1,Strings.Count);
|
||||||
|
AssertEquals('Section name','empty',Strings[0]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadSections;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.ReadSections(Strings);
|
||||||
|
AssertEquals('2 sections',2,Strings.Count);
|
||||||
|
AssertEquals('Section name 0','a',Strings[0]);
|
||||||
|
AssertEquals('Section name 1','B',Strings[1]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadSection;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.ReadSection('a',Strings);
|
||||||
|
// Only valid values are reported
|
||||||
|
AssertEquals('value count',(FileContent as TJSONObject).Objects['a'].Count-2,Strings.Count);
|
||||||
|
AssertEquals('value names','i,i6,f,s,si,si6,sf,dt,id,fd,t,ft,fdt,d,b',Strings.CommaText);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadSectionValues;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONEnum;
|
||||||
|
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.ReadSectionValues('a',Strings,[]);
|
||||||
|
// Only valid values are reported
|
||||||
|
AssertEquals('value count',(FileContent as TJSONObject).Objects['a'].Count-2,Strings.Count);
|
||||||
|
for D in (FileContent as TJSONObject).Objects['a'] do
|
||||||
|
if D.Value.JSONType in ActualValueJSONTypes then
|
||||||
|
AssertEquals('value '+D.key,D.Value.AsString,Strings.Values[D.Key]);
|
||||||
|
Strings.Clear;
|
||||||
|
Ini.ReadSectionValues('a',Strings);
|
||||||
|
// All valid values are reported
|
||||||
|
AssertEquals('value count',(FileContent as TJSONObject).Objects['a'].Count,Strings.Count);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadString;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK','test',Ini.ReadString('a','s','nono'));
|
||||||
|
AssertEquals('Value, key case not OK','test',Ini.ReadString('a','S','nono'));
|
||||||
|
AssertEquals('Value, section case not OK','test',Ini.ReadString('A','s','nono'));
|
||||||
|
AssertEquals('Value, section not exist','nono',Ini.ReadString('C','s','nono'));
|
||||||
|
AssertEquals('Value, key not exist','nono',Ini.ReadString('a','Z','nono'));
|
||||||
|
AssertEquals('Value, key not string','1',Ini.ReadString('a','i','nono'));
|
||||||
|
AssertEquals('Value, key not valid value','nono',Ini.ReadString('a','o','nono'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadInteger;
|
||||||
|
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK',1,Ini.ReadInteger('a','i',2));
|
||||||
|
AssertEquals('Value, key case not OK',1,Ini.ReadInteger('a','I',2));
|
||||||
|
AssertEquals('Value, section case not OK',1,Ini.ReadInteger('A','i',2));
|
||||||
|
AssertEquals('Value, section not exist',2,Ini.ReadInteger('C','i',2));
|
||||||
|
AssertEquals('Value, key not exist',2,Ini.ReadInteger('a','Z',2));
|
||||||
|
AssertEquals('Value, key not integer',2,Ini.ReadInteger('a','s',2));
|
||||||
|
AssertEquals('Value, key not integer, but convertable to integer',1,Ini.ReadInteger('a','si',2));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadInt64;
|
||||||
|
Var
|
||||||
|
I6 : Int64;
|
||||||
|
begin
|
||||||
|
I6:=MaxInt*2;
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK',i6,Ini.ReadInt64('a','i6',2));
|
||||||
|
AssertEquals('Value, key case not OK',i6,Ini.ReadInt64('a','I6',2));
|
||||||
|
AssertEquals('Value, section case not OK',i6,Ini.ReadInt64('A','i6',2));
|
||||||
|
AssertEquals('Value, section not exist',2,Ini.ReadInt64('C','i',2));
|
||||||
|
AssertEquals('Value, key not exist',2,Ini.ReadInt64('a','Z',2));
|
||||||
|
AssertEquals('Value, key not integer',2,Ini.ReadInt64('a','s',2));
|
||||||
|
AssertEquals('Value, key not integer, but convertable to int64',I6,Ini.ReadInt64('a','si6',2));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadFloat;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK',1.2,Ini.ReadFloat('a','f',2.3));
|
||||||
|
AssertEquals('Value, key case not OK',1.2,Ini.ReadFloat('a','F',2.3));
|
||||||
|
AssertEquals('Value, section case not OK',1.2,Ini.ReadFloat('A','f',2.3));
|
||||||
|
AssertEquals('Value, section not exist',2.3,Ini.ReadFloat('C','f',2.3));
|
||||||
|
AssertEquals('Value, key not exist',2.3,Ini.ReadFloat('a','Z',2.3));
|
||||||
|
AssertEquals('Value, key not float',2.3,Ini.ReadFloat('a','s',2.3));
|
||||||
|
AssertEquals('Value, key not float, but convertable to float',1.2,Ini.ReadFloat('a','sf',2.3));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadBoolean;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK',True,Ini.ReadBool('a','b',False));
|
||||||
|
AssertEquals('Value, key case not OK',True,Ini.ReadBool('a','B',False));
|
||||||
|
AssertEquals('Value, section case not OK',True,Ini.ReadBool('A','b',False));
|
||||||
|
AssertEquals('Value, section not exist',True,Ini.ReadBool('C','b',True));
|
||||||
|
AssertEquals('Value, key not exist',True,Ini.ReadBool('a','Z',True));
|
||||||
|
AssertEquals('Value, key not bool but integer',True,Ini.ReadBool('a','i',false));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadDate;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D,DD : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=EncodeDate(2001,05,06);
|
||||||
|
DD:=EncodeDate(1999,11,12);
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK',D,Ini.ReadDate('a','d',DD));
|
||||||
|
AssertEquals('Value, key case not OK',D,Ini.ReadDate('a','D',DD));
|
||||||
|
AssertEquals('Value, section case not OK',D,Ini.ReadDate('A','d',DD));
|
||||||
|
AssertEquals('Value, section not exist',DD,Ini.ReadDate('C','d',DD));
|
||||||
|
AssertEquals('Value, date as integer',D,Ini.ReadDate('a','id',DD));
|
||||||
|
AssertEquals('Value, date as float',D,Ini.ReadDate('a','fd',DD));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadTime;
|
||||||
|
|
||||||
|
Var
|
||||||
|
T,DT : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
T:=EncodeTime(12,13,14,567);
|
||||||
|
DT:=EncodeTime(1,2,3,4);
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK',T,Ini.ReadTime('a','t',DT));
|
||||||
|
AssertEquals('Value, key case not OK',T,Ini.ReadTime('a','T',DT));
|
||||||
|
AssertEquals('Value, section case not OK',T,Ini.ReadTime('A','t',DT));
|
||||||
|
AssertEquals('Value, section not exist',DT,Ini.ReadTime('C','t',DT));
|
||||||
|
AssertEquals('Value, key exist as float',T,Ini.ReadTime('a','ft',DT));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestReadDateTime;
|
||||||
|
Var
|
||||||
|
DT,DDT : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
DT:=EncodeDate(2001,05,06)+EncodeTime(23,24,25,678);
|
||||||
|
DDT:=EncodeDate(1999,11,12)+EncodeTime(1,2,3,4);
|
||||||
|
SampleFile;
|
||||||
|
AssertEquals('Value, case OK',DT,Ini.ReadDateTime('a','dt',DDT));
|
||||||
|
AssertEquals('Value, key case not OK',DT,Ini.ReadDateTime('a','DT',DDT));
|
||||||
|
AssertEquals('Value, section case not OK',DT,Ini.ReadDateTime('A','dt',DDT));
|
||||||
|
AssertEquals('Value, section not exist',DDT,Ini.ReadDateTime('C','dt',DDT));
|
||||||
|
AssertEquals('Value, key exist as float',DT,Ini.ReadDateTime('a','fdt',DDT));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestEraseSection;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.EraseSection('B');
|
||||||
|
Ini.UpdateFile;
|
||||||
|
ReadFile;
|
||||||
|
AssertEquals('No more section',-1,ObjFileContent.IndexOfName('B'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestEraseSectionCaseMismatch;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.EraseSection('b');
|
||||||
|
Ini.UpdateFile;
|
||||||
|
ReadFile;
|
||||||
|
AssertEquals('No more section',-1,ObjFileContent.IndexOfName('B'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestDeleteKey;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.DeleteKey('a','i');
|
||||||
|
Ini.UpdateFile;
|
||||||
|
ReadFile;
|
||||||
|
AssertEquals('No more key',-1,ObjFileContent.Objects['a'].IndexOfName('i'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestDeleteKeySectionCaseMismatch;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.DeleteKey('A','i');
|
||||||
|
Ini.UpdateFile;
|
||||||
|
ReadFile;
|
||||||
|
AssertEquals('No more key',-1,ObjFileContent.Objects['a'].IndexOfName('i'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestDeleteKeyKeyCaseMismatch;
|
||||||
|
begin
|
||||||
|
SampleFile;
|
||||||
|
Ini.DeleteKey('a','I');
|
||||||
|
Ini.UpdateFile;
|
||||||
|
ReadFile;
|
||||||
|
AssertEquals('No more key',-1,ObjFileContent.Objects['a'].IndexOfName('i'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.AssertValue(const aSection,Akey,avalue : string);
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TJSONData;
|
||||||
|
|
||||||
|
begin
|
||||||
|
ini.UpdateFile;
|
||||||
|
ReadFile;
|
||||||
|
D:=ObjFileContent.FindPath(asection+'.'+akey);
|
||||||
|
AssertNotNull('Have value at '+asection+'.'+akey,D);
|
||||||
|
AssertEquals('Correct value at '+asection+'.'+akey,AValue,D.AsString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.NoFileYet;
|
||||||
|
|
||||||
|
begin
|
||||||
|
AssertFalse('File not exist yet',FileExists(TestFile));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.HaveFile;
|
||||||
|
|
||||||
|
begin
|
||||||
|
AssertTrue('Test file exists',FileExists(TestFile));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.ReLoad;
|
||||||
|
begin
|
||||||
|
FreeAndNil(Fini);
|
||||||
|
AssertNotNull(Ini);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.RemoveFile;
|
||||||
|
begin
|
||||||
|
if FileExists(TestFile) then
|
||||||
|
AssertTrue('Deleted file',DeleteFile(TestFile));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestWriteString;
|
||||||
|
begin
|
||||||
|
Ini.WriteString('a','i','string');
|
||||||
|
NoFileYet;
|
||||||
|
AssertValue('a','i','string');
|
||||||
|
Ini.CacheUpdates:=False;
|
||||||
|
Ini.WriteString('a','i','string2');
|
||||||
|
HaveFile;
|
||||||
|
AssertValue('a','i','string2');
|
||||||
|
Reload;
|
||||||
|
AssertEquals('Can read value','string2',Ini.ReadString('a','i',''));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestWriteInteger;
|
||||||
|
begin
|
||||||
|
Ini.Writeinteger('a','i',2);
|
||||||
|
NoFileYet;
|
||||||
|
AssertValue('a','i','2');
|
||||||
|
Ini.CacheUpdates:=False;
|
||||||
|
Ini.WriteInteger('a','i',3);
|
||||||
|
HaveFile;
|
||||||
|
AssertValue('a','i','3');
|
||||||
|
Reload;
|
||||||
|
AssertEquals('Can read value',3,Ini.ReadInteger('a','i',0));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestWriteBoolean;
|
||||||
|
begin
|
||||||
|
Ini.WriteBool('a','i',true);
|
||||||
|
NoFileYet;
|
||||||
|
AssertValue('a','i','True');
|
||||||
|
Ini.CacheUpdates:=False;
|
||||||
|
Ini.WriteBool('a','i2',true);
|
||||||
|
HaveFile;
|
||||||
|
AssertValue('a','i2','True');
|
||||||
|
Reload;
|
||||||
|
AssertEquals('Can read value',True,Ini.ReadBool('a','i2',false));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestWriteDate;
|
||||||
|
Var
|
||||||
|
D : TDateTime;
|
||||||
|
begin
|
||||||
|
D:=EncodeDate(2001,2,3);
|
||||||
|
Ini.WriteDate('a','i',D);
|
||||||
|
NoFileYet;
|
||||||
|
AssertValue('a','i','2001-02-03T00:00:00.000');
|
||||||
|
Ini.CacheUpdates:=False;
|
||||||
|
Ini.WriteDate('a','i',D+1);
|
||||||
|
HaveFile;
|
||||||
|
AssertValue('a','i','2001-02-04T00:00:00.000');
|
||||||
|
Reload;
|
||||||
|
AssertEquals('Can read value',D+1,Ini.ReadDate('a','i',0));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestWriteDateTime;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=EncodeDate(2001,2,3)+EncodeTime(12,13,14,567);
|
||||||
|
Ini.WriteDateTime('a','i',D);
|
||||||
|
NoFileYet;
|
||||||
|
AssertValue('a','i','2001-02-03T12:13:14.567');
|
||||||
|
Ini.CacheUpdates:=False;
|
||||||
|
Ini.WriteDateTime('a','i',D+1);
|
||||||
|
HaveFile;
|
||||||
|
AssertValue('a','i','2001-02-04T12:13:14.567');
|
||||||
|
Reload;
|
||||||
|
AssertEquals('Can read value',D+1,Ini.ReadDateTime('a','i',0));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestWriteTime;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D,D2 : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=EncodeTime(12,13,14,567);
|
||||||
|
D2:=EncodeTime(13,14,15,678);
|
||||||
|
Ini.WriteTime('a','i',D);
|
||||||
|
NoFileYet;
|
||||||
|
AssertValue('a','i','0000-00-00T12:13:14.567');
|
||||||
|
Ini.CacheUpdates:=False;
|
||||||
|
Ini.WriteTime('a','i',D2);
|
||||||
|
HaveFile;
|
||||||
|
AssertValue('a','i','0000-00-00T13:14:15.678');
|
||||||
|
Reload;
|
||||||
|
AssertEquals('Can read value',D2,Ini.ReadTime('a','i',0));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.CreateIni;
|
||||||
|
|
||||||
|
Var
|
||||||
|
M : TMemIniFile;
|
||||||
|
D,DT,T : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=EncodeDate(2001,2,3);
|
||||||
|
T:=EncodeTime(12,13,14,567);
|
||||||
|
DT:=D+T;
|
||||||
|
if FileExists(TestName+'.ini') then
|
||||||
|
DeleteFile(TestName+'.ini');
|
||||||
|
M:=TMemIniFile.Create(TestName+'.ini');
|
||||||
|
try
|
||||||
|
M.WriteString('a','s','c');
|
||||||
|
M.WriteInteger('a','i',2);
|
||||||
|
M.WriteBool('a','b',True);
|
||||||
|
M.WriteInt64('a','i6',Maxint*2);
|
||||||
|
M.WriteDate('a','d',D);
|
||||||
|
M.WriteTime('a','t',T);
|
||||||
|
M.WriteDateTime('a','dt',DT);
|
||||||
|
M.WriteFloat('a','f',1.23);
|
||||||
|
M.UpdateFile;
|
||||||
|
finally
|
||||||
|
M.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestConvertIni;
|
||||||
|
|
||||||
|
Var
|
||||||
|
D,DT,T : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=EncodeDate(2001,2,3);
|
||||||
|
T:=EncodeTime(12,13,14,567);
|
||||||
|
DT:=D+T;
|
||||||
|
CreateIni;
|
||||||
|
TJSONIniFile.ConvertIni(TestName+'.ini',TestFile,False);
|
||||||
|
AssertEquals('String','c',Ini.ReadString('a','s',''));
|
||||||
|
AssertEquals('Integer',2,Ini.ReadInteger('a','i',1));
|
||||||
|
AssertEquals('Bool',True,Ini.ReadBool('a','b',False));
|
||||||
|
AssertEquals('Int64',Int64(Maxint*2),Ini.ReadInt64('a','i6',Maxint*2));
|
||||||
|
AssertEquals('Date',D, Ini.ReadDate('a','d',0));
|
||||||
|
AssertEquals('Time',T,Ini.ReadTime('a','t',0));
|
||||||
|
AssertEquals('DateTime',DT,Ini.ReadDateTime('a','dt',0));
|
||||||
|
AssertEquals('Float',1.23,Ini.ReadFloat('a','f',0));
|
||||||
|
if FileExists(TestName+'.ini') then
|
||||||
|
DeleteFile(TestName+'.ini');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TJSONIniTest.TestConvertIniString;
|
||||||
|
Var
|
||||||
|
D,DT,T : TDateTime;
|
||||||
|
|
||||||
|
begin
|
||||||
|
D:=EncodeDate(2001,2,3);
|
||||||
|
T:=EncodeTime(12,13,14,567);
|
||||||
|
DT:=D+T;
|
||||||
|
CreateIni;
|
||||||
|
TJSONIniFile.ConvertIni(TestName+'.ini',TestFile,True);
|
||||||
|
AssertEquals('String','c',Ini.ReadString('a','s',''));
|
||||||
|
AssertEquals('Integer',2,Ini.ReadInteger('a','i',1));
|
||||||
|
AssertEquals('Bool',True,Ini.ReadBool('a','b',False));
|
||||||
|
AssertEquals('Int64',Int64(Maxint*2),Ini.ReadInt64('a','i6',Maxint*2));
|
||||||
|
AssertEquals('Date',DateToStr(D), Ini.ReadString('a','d',''));
|
||||||
|
AssertEquals('Time',TimeToStr(T),Ini.ReadString('a','t',''));
|
||||||
|
AssertEquals('DateTime',DateTimeToStr(DT),Ini.ReadString('a','dt',''));
|
||||||
|
AssertEquals('Float',1.23,Ini.ReadFloat('a','f',0));
|
||||||
|
if FileExists(TestName+'.ini') then
|
||||||
|
DeleteFile(TestName+'.ini');
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
RegisterTest(TJSONIniTest);
|
||||||
|
end.
|
||||||
|
|
@ -22,7 +22,7 @@
|
|||||||
<RunParams>
|
<RunParams>
|
||||||
<local>
|
<local>
|
||||||
<FormatVersion Value="1"/>
|
<FormatVersion Value="1"/>
|
||||||
<CommandLineParams Value="--suite=TTestParser.TestArray"/>
|
<CommandLineParams Value="--suite=TJSONIniTest.TestConvertIni"/>
|
||||||
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
|
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
|
||||||
</local>
|
</local>
|
||||||
</RunParams>
|
</RunParams>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<PackageName Value="FCL"/>
|
<PackageName Value="FCL"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="6">
|
<Units Count="8">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="testjson.pp"/>
|
<Filename Value="testjson.pp"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
@ -56,6 +56,14 @@
|
|||||||
<Filename Value="testjsonreader.pp"/>
|
<Filename Value="testjsonreader.pp"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit5>
|
</Unit5>
|
||||||
|
<Unit6>
|
||||||
|
<Filename Value="../src/jsonini.pp"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit6>
|
||||||
|
<Unit7>
|
||||||
|
<Filename Value="tcjsonini.pp"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit7>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
@ -79,9 +87,11 @@
|
|||||||
<Exceptions Count="2">
|
<Exceptions Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Name Value="EConvertError"/>
|
<Name Value="EConvertError"/>
|
||||||
|
<Enabled Value="False"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
<Item2>
|
<Item2>
|
||||||
<Name Value="EJSON"/>
|
<Name Value="EJSON"/>
|
||||||
|
<Enabled Value="False"/>
|
||||||
</Item2>
|
</Item2>
|
||||||
</Exceptions>
|
</Exceptions>
|
||||||
</Debugging>
|
</Debugging>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
program testjson;
|
program testjson;
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, testjsondata, testjsonparser, testjsonrtti, consoletestrunner, testjsonreader;
|
Classes, testjsondata, testjsonparser, testjsonrtti, consoletestrunner, testjsonreader, jsonini, tcjsonini;
|
||||||
|
|
||||||
type
|
type
|
||||||
{ TLazTestRunner }
|
{ TLazTestRunner }
|
||||||
|
Loading…
Reference in New Issue
Block a user