| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856 |
- {
- This file is part of the Free Component Library
- Implementation of TJSONConfig class
- Copyright (c) 2007 Michael Van Canneyt [email protected]
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {
- TJSONConfig enables applications to use JSON files for storing their
- configuration data
- }
- {$IFDEF FPC}
- {$MODE objfpc}
- {$H+}
- {$ENDIF}
- {$IFNDEF FPC_DOTTEDUNITS}
- unit jsonConf;
- {$ENDIF FPC_DOTTEDUNITS}
- interface
- {$IFDEF FPC_DOTTEDUNITS}
- uses
- System.SysUtils, System.Classes, FpJson.Data, FpJson.Scanner, FpJson.Parser;
- {$ELSE FPC_DOTTEDUNITS}
- uses
- SysUtils, Classes, fpjson, jsonscanner, jsonparser;
- {$ENDIF FPC_DOTTEDUNITS}
- Const
- DefaultJSONOptions = [joUTF8,joComments,joBOMCheck];
- type
- EJSONConfigError = class(Exception);
- (* ********************************************************************
- "APath" is the path and name of a value: A JSON configuration file
- is hierachical. "/" is the path delimiter, the part after the last
- "/" is the name of the value. The path components will be mapped
- to nested JSON objects, with the name equal to the part. In practice
- this means that "/my/path/value" will be written as:
- {
- "my" : {
- "path" : {
- "value" : Value
- }
- }
- }
- ******************************************************************** *)
- { TJSONConfig }
- TJSONConfig = class(TComponent)
- private
- FFilename: String;
- FFormatIndentSize: Integer;
- FFormatoptions: TFormatOptions;
- FFormatted: Boolean;
- FJSONOptions: TJSONOptions;
- FKey: TJSONObject;
- procedure DoSetFilename(const AFilename: String; ForceReload: Boolean);
- procedure SetFilename(const AFilename: String);
- procedure SetJSONOptions(AValue: TJSONOptions);
- Function StripSlash(Const P : UnicodeString) : UnicodeString;
- protected
- FJSON: TJSONObject;
- FModified: Boolean;
- Procedure LoadFromFile(Const AFileName : String);
- Procedure LoadFromStream(S : TStream); virtual;
- procedure Loaded; override;
- function FindNodeForValue(const APath: UnicodeString; aExpectedType: TJSONDataClass; out AParent: TJSONObject; out ElName: UnicodeString): TJSONData;
- function FindPath(Const APath: UnicodeString; AllowCreate : Boolean) : TJSONObject;
- function FindObject(Const APath: UnicodeString; AllowCreate : Boolean) : TJSONObject;
- function FindObject(Const APath: UnicodeString; AllowCreate : Boolean;Out ElName : UnicodeString) : TJSONObject;
- function FindElement(Const APath: UnicodeString; CreateParent : Boolean; AllowObject : Boolean = False) : TJSONData;
- function FindElement(Const APath: UnicodeString; CreateParent : Boolean; out AParent : TJSONObject; Out ElName : UnicodeString; AllowObject : Boolean = False) : TJSONData;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- Procedure Reload;
- procedure Clear;
- procedure Flush; // Writes the JSON file
- procedure OpenKey(const aPath: UnicodeString; AllowCreate : Boolean);
- procedure CloseKey;
- procedure ResetKey;
- Procedure EnumSubKeys(Const APath : UnicodeString; List : TStrings);
- Procedure EnumValues(Const APath : UnicodeString; List : TStrings);
- function GetValue(const APath: UnicodeString; const ADefault: UnicodeString): UnicodeString; overload;
- function GetValue(const APath: RawByteString; const ADefault: RawByteString): UnicodeString; overload;
- function GetValue(const APath: UnicodeString; ADefault: Integer): Integer; overload;
- function GetValue(const APath: RawByteString; ADefault: Integer): Integer; overload;
- function GetValue(const APath: UnicodeString; ADefault: Int64): Int64; overload;
- function GetValue(const APath: RawByteString; ADefault: Int64): Int64; overload;
- function GetValue(const APath: UnicodeString; ADefault: Boolean): Boolean; overload;
- function GetValue(const APath: RawByteString; ADefault: Boolean): Boolean; overload;
- function GetValue(const APath: UnicodeString; ADefault: Double): Double; overload;
- function GetValue(const APath: RawByteString; ADefault: Double): Double; overload;
- Function GetValue(const APath: UnicodeString; AValue: TStrings; Const ADefault: String) : Boolean; overload;
- Function GetValue(const APath: RawByteString; AValue: TStrings; Const ADefault: String) : Boolean; overload;
- Function GetValue(const APath: UnicodeString; AValue: TStrings; Const ADefault: TStrings): Boolean; overload;
- procedure SetValue(const APath: UnicodeString; const AValue: UnicodeString); overload;
- procedure SetValue(const APath: RawByteString; const AValue: RawByteString); overload;
- procedure SetValue(const APath: UnicodeString; AValue: Integer); overload;
- procedure SetValue(const APath: UnicodeString; AValue: Int64); overload;
- procedure SetValue(const APath: UnicodeString; AValue: Boolean); overload;
- procedure SetValue(const APath: UnicodeString; AValue: Double); overload;
- procedure SetValue(const APath: UnicodeString; AValue: TStrings; AsObject : Boolean = False); overload;
- procedure SetDeleteValue(const APath: UnicodeString; const AValue, DefValue: UnicodeString); overload;
- procedure SetDeleteValue(const APath: UnicodeString; AValue, DefValue: Integer); overload;
- procedure SetDeleteValue(const APath: UnicodeString; AValue, DefValue: Int64); overload;
- procedure SetDeleteValue(const APath: UnicodeString; AValue, DefValue: Boolean); overload;
- procedure DeletePath(const APath: UnicodeString);
- procedure DeleteValue(const APath: UnicodeString);
- property Modified: Boolean read FModified;
- published
- Property Filename: String read FFilename write SetFilename;
- Property Formatted : Boolean Read FFormatted Write FFormatted;
- Property FormatOptions : TFormatOptions Read FFormatoptions Write FFormatOptions Default DefaultFormat;
- Property FormatIndentsize : Integer Read FFormatIndentSize Write FFormatIndentSize Default DefaultIndentSize;
- Property JSONOptions : TJSONOptions Read FJSONOptions Write SetJSONOptions Default DefaultJSONOptions;
- end;
- // ===================================================================
- implementation
- Resourcestring
- SErrInvalidJSONFile = '"%s" is not a valid JSON configuration file.';
- SErrCouldNotOpenKey = 'Could not open key "%s".';
- SErrCannotNotReplaceKey = 'A (sub)key with name "%s" already exists.';
- constructor TJSONConfig.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FJSON:=TJSONObject.Create;
- FKey:=FJSON;
- FFormatOptions:=DefaultFormat;
- FFormatIndentsize:=DefaultIndentSize;
- FJSONOptions:=DefaultJSONOptions;
- end;
- destructor TJSONConfig.Destroy;
- begin
- if Assigned(FJSON) then
- begin
- Flush;
- FreeANdNil(FJSON);
- end;
- inherited Destroy;
- end;
- procedure TJSONConfig.Clear;
- begin
- FJSON.Clear;
- FKey:=FJSON;
- end;
- procedure TJSONConfig.Flush;
- Var
- F : TFileStream;
- S : TJSONStringType;
-
- begin
- if Modified then
- begin
- F:=TFileStream.Create(FileName,fmCreate);
- Try
- if Formatted then
- S:=FJSON.FormatJSON(Formatoptions,FormatIndentSize)
- else
- S:=FJSON.AsJSON;
- if S>'' then
- F.WriteBuffer(S[1],Length(S));
- Finally
- F.Free;
- end;
- FModified := False;
- end;
- end;
- function TJSONConfig.FindObject(const APath: UnicodeString; AllowCreate: Boolean
- ): TJSONObject;
- Var
- Dummy : UnicodeString;
- begin
- Result:=FindObject(APath,AllowCreate,Dummy);
- end;
- function TJSONConfig.FindObject(const APath: UnicodeString; AllowCreate: Boolean;
- out ElName: UnicodeString): TJSONObject;
- Var
- S,El : UnicodeString;
- P,I : Integer;
- T : TJSonObject;
-
- begin
- // Writeln('Looking for : ', APath);
- S:=APath;
- If Pos('/',S)=1 then
- Result:=FJSON
- else
- Result:=FKey;
- Repeat
- P:=Pos('/',S);
- If (P<>0) then
- begin
- // Only real paths, ignore double slash
- If (P<>1) then
- begin
- El:=Copy(S,1,P-1);
- If (Result.Count=0) then
- I:=-1
- else
- I:=Result.IndexOfName(UTF8Encode(El));
- If (I=-1) then
- // No element with this name.
- begin
- If AllowCreate then
- begin
- // Create new node.
- T:=Result;
- Result:=TJSonObject.Create;
- T.Add(UTF8Encode(El),Result);
- end
- else
- Result:=Nil
- end
- else
- // Node found, check if it is an object
- begin
- if (Result.Items[i].JSONtype=jtObject) then
- Result:=Result.Objects[UTF8Encode(el)]
- else
- begin
- // Writeln(el,' type wrong');
- If AllowCreate then
- begin
- // Writeln('Creating ',el);
- Result.Delete(I);
- T:=Result;
- Result:=TJSonObject.Create;
- T.Add(UTF8Encode(El),Result);
- end
- else
- Result:=Nil
- end;
- end;
- end;
- Delete(S,1,P);
- end;
- Until (P=0) or (Result=Nil);
- ElName:=S;
- end;
- function TJSONConfig.FindElement(const APath: UnicodeString; CreateParent: Boolean; AllowObject : Boolean = False): TJSONData;
- Var
- O : TJSONObject;
- ElName : UnicodeString;
-
- begin
- Result:=FindElement(APath,CreateParent,O,ElName,AllowObject);
- end;
- function TJSONConfig.FindElement(const APath: UnicodeString;
- CreateParent: Boolean; out AParent: TJSONObject; out ElName: UnicodeString;
- AllowObject : Boolean = False): TJSONData;
- Var
- I : Integer;
- begin
- Result:=Nil;
- Aparent:=FindObject(APath,CreateParent,ElName);
- If Assigned(Aparent) then
- begin
- // Writeln('Found parent, looking for element:',elName);
- I:=AParent.IndexOfName(UTF8Encode(ElName));
- // Writeln('Element index is',I);
- If (I<>-1) And ((AParent.items[I].JSONType<>jtObject) or AllowObject) then
- Result:=AParent.Items[i];
- end;
- // Writeln('Find ',aPath,' in "',FJSON.AsJSOn,'" : ',Elname,' : ',Result<>NIl);
- end;
- function TJSONConfig.GetValue(const APath: RawByteString; const ADefault: RawByteString): UnicodeString;
- begin
- Result:=GetValue(UTF8Decode(aPath),UTF8Decode(ADefault));
- end;
- function TJSONConfig.GetValue(const APath: UnicodeString; const ADefault: UnicodeString): UnicodeString;
- var
- El : TJSONData;
-
- begin
- El:=FindElement(StripSlash(APath),False);
- If Assigned(El) then
- Result:=El.AsUnicodeString
- else
- Result:=ADefault;
- end;
- function TJSONConfig.GetValue(const APath: RawByteString; ADefault: Integer): Integer;
- begin
- Result:=GetValue(UTF8Decode(aPath),ADefault);
- end;
- function TJSONConfig.GetValue(const APath: UnicodeString; ADefault: Integer): Integer;
- var
- El : TJSONData;
-
- begin
- El:=FindElement(StripSlash(APath),False);
- If Not Assigned(el) then
- Result:=ADefault
- else if (el is TJSONNumber) then
- Result:=El.AsInteger
- else
- Result:=StrToIntDef(El.AsString,ADefault);
- end;
- function TJSONConfig.GetValue(const APath: RawByteString; ADefault: Int64): Int64;
- begin
- Result:=GetValue(UTF8Decode(aPath),ADefault);
- end;
- function TJSONConfig.GetValue(const APath: UnicodeString; ADefault: Int64): Int64;
- var
- El : TJSONData;
- begin
- El:=FindElement(StripSlash(APath),False);
- If Not Assigned(el) then
- Result:=ADefault
- else if (el is TJSONNumber) then
- Result:=El.AsInt64
- else
- Result:=StrToInt64Def(El.AsString,ADefault);
- end;
- function TJSONConfig.GetValue(const APath: RawByteString; ADefault: Boolean): Boolean;
- begin
- Result:=GetValue(UTF8Decode(aPath),ADefault);
- end;
- function TJSONConfig.GetValue(const APath: UnicodeString; ADefault: Boolean): Boolean;
- var
- El : TJSONData;
-
- begin
- El:=FindElement(StripSlash(APath),False);
- If Not Assigned(el) then
- Result:=ADefault
- else if (el is TJSONBoolean) then
- Result:=El.AsBoolean
- else
- Result:=StrToBoolDef(El.AsString,ADefault);
- end;
- function TJSONConfig.GetValue(const APath: RawByteString; ADefault: Double): Double;
- begin
- Result:=GetValue(UTF8Decode(aPath),ADefault);
- end;
- function TJSONConfig.GetValue(const APath: UnicodeString; ADefault: Double): Double;
- var
- El : TJSONData;
- begin
- El:=FindElement(StripSlash(APath),False);
- If Not Assigned(el) then
- Result:=ADefault
- else if (el is TJSONNumber) then
- Result:=El.AsFloat
- else
- Result:=StrToFloatDef(El.AsString,ADefault);
- end;
- function TJSONConfig.GetValue(const APath: RawByteString; AValue: TStrings;
- const ADefault: String): Boolean;
- begin
- Result:=GetValue(UTF8Decode(aPath),AValue, ADefault);
- end;
- function TJSONConfig.GetValue(const APath: UnicodeString; AValue: TStrings;
- const ADefault: String): Boolean;
- var
- El : TJSONData;
- D : TJSONEnum;
- begin
- AValue.Clear;
- El:=FindElement(StripSlash(APath),False,True);
- Result:=Assigned(el);
- If Not Result then
- begin
- AValue.Text:=ADefault;
- exit;
- end;
- Case El.JSONType of
- jtArray:
- For D in El do
- if D.Value.JSONType in ActualValueJSONTypes then
- AValue.Add(D.Value.AsString);
- jtObject:
- For D in El do
- if D.Value.JSONType in ActualValueJSONTypes then
- AValue.Add(D.Key+'='+D.Value.AsString);
- else
- AValue.Text:=EL.AsString
- end;
- end;
- function TJSONConfig.GetValue(const APath: UnicodeString; AValue: TStrings;
- const ADefault: TStrings): Boolean;
- begin
- Result:=GetValue(APath,AValue,'');
- If Not Result then
- AValue.Assign(ADefault);
- end;
- procedure TJSONConfig.SetValue(const APath: UnicodeString; const AValue: UnicodeString);
- var
- El : TJSONData;
- ElName : UnicodeString;
- O : TJSONObject;
-
- begin
- El:=FindNodeForValue(aPath,TJSONString,O,elName);
- If Not Assigned(el) then
- begin
- El:=TJSONString.Create(AValue);
- O.Add(UTF8Encode(ElName),El);
- end
- else
- El.AsUnicodeString:=AValue;
- FModified:=True;
- end;
- procedure TJSONConfig.SetValue(const APath: RawByteString;
- const AValue: RawByteString);
- begin
- SetValue(UTF8Decode(APath),UTF8Decode(AValue));
- end;
- procedure TJSONConfig.SetDeleteValue(const APath: UnicodeString; const AValue, DefValue: UnicodeString);
- begin
- if AValue = DefValue then
- DeleteValue(APath)
- else
- SetValue(APath, AValue);
- end;
- procedure TJSONConfig.SetValue(const APath: UnicodeString; AValue: Integer);
- var
- El : TJSONData;
- ElName : UnicodeString;
- O : TJSONObject;
- begin
- El:=FindNodeForValue(aPath,TJSONIntegerNumber,O,elName);
- If Not Assigned(el) then
- begin
- El:=TJSONIntegerNumber.Create(AValue);
- O.Add(UTF8Encode(ElName),El);
- end
- else
- El.AsInteger:=AValue;
- FModified:=True;
- end;
- procedure TJSONConfig.SetValue(const APath: UnicodeString; AValue: Int64);
- var
- El : TJSONData;
- ElName : UnicodeString;
- O : TJSONObject;
- begin
- El:=FindNodeForValue(aPath,TJSONInt64Number,O,elName);
- If Not Assigned(el) then
- begin
- El:=TJSONInt64Number.Create(AValue);
- O.Add(UTF8Encode(ElName),El);
- end
- else
- El.AsInt64:=AValue;
- FModified:=True;
- end;
- procedure TJSONConfig.SetDeleteValue(const APath: UnicodeString; AValue,
- DefValue: Integer);
- begin
- if AValue = DefValue then
- DeleteValue(APath)
- else
- SetValue(APath, AValue);
- end;
- procedure TJSONConfig.SetDeleteValue(const APath: UnicodeString; AValue,
- DefValue: Int64);
- begin
- if AValue = DefValue then
- DeleteValue(APath)
- else
- SetValue(APath, AValue);
- end;
- procedure TJSONConfig.SetValue(const APath: UnicodeString; AValue: Boolean);
- var
- El : TJSONData;
- ElName : UnicodeString;
- O : TJSONObject;
- begin
- El:=FindNodeForValue(aPath,TJSONBoolean,O,elName);
- If Not Assigned(el) then
- begin
- El:=TJSONBoolean.Create(AValue);
- O.Add(UTF8Encode(ElName),El);
- end
- else
- El.AsBoolean:=AValue;
- FModified:=True;
- end;
- procedure TJSONConfig.SetValue(const APath: UnicodeString; AValue: Double);
- var
- El : TJSONData;
- ElName : UnicodeString;
- O : TJSONObject;
- begin
- El:=FindNodeForValue(aPath,TJSONFloatNumber,O,elName);
- If Not Assigned(el) then
- begin
- El:=TJSONFloatNumber.Create(AValue);
- O.Add(UTF8Encode(ElName),El);
- end
- else
- El.AsFloat:=AValue;
- FModified:=True;
- end;
- procedure TJSONConfig.SetValue(const APath: UnicodeString; AValue: TStrings; AsObject : Boolean = False);
- var
- El : TJSONData;
- ElName : UnicodeString;
- O : TJSONObject;
- I : integer;
- A : TJSONArray;
- N,V : String;
- begin
- if AsObject then
- El:=FindNodeForValue(aPath,TJSONObject,O,elName)
- else
- El:=FindNodeForValue(aPath,TJSONArray,O,elName);
- If Not Assigned(el) then
- begin
- if AsObject then
- El:=TJSONObject.Create
- else
- El:=TJSONArray.Create;
- O.Add(UTF8Encode(ElName),El);
- end;
- if Not AsObject then
- begin
- A:=El as TJSONArray;
- A.Clear;
- For N in Avalue do
- A.Add(N);
- end
- else
- begin
- O:=El as TJSONObject;
- For I:=0 to AValue.Count-1 do
- begin
- AValue.GetNameValue(I,N,V);
- O.Add(N,V);
- end;
- end;
- FModified:=True;
- end;
- procedure TJSONConfig.SetDeleteValue(const APath: UnicodeString; AValue,
- DefValue: Boolean);
- begin
- if AValue = DefValue then
- DeleteValue(APath)
- else
- SetValue(APath,AValue);
- end;
- procedure TJSONConfig.DeletePath(const APath: UnicodeString);
- Var
- P : UnicodeString;
- L : integer;
- Node : TJSONObject;
- ElName : UnicodeString;
-
- begin
- P:=StripSlash(APath);
- L:=Length(P);
- If (L>0) then
- begin
- Node := FindObject(P,False,ElName);
- If Assigned(Node) then
- begin
- L:=Node.IndexOfName(UTF8Encode(ElName));
- If (L<>-1) then
- Node.Delete(L);
- end;
- end;
- FModified:=True;
- end;
- procedure TJSONConfig.DeleteValue(const APath: UnicodeString);
- begin
- DeletePath(APath);
- end;
- procedure TJSONConfig.Reload;
- begin
- if Length(Filename) > 0 then
- DoSetFilename(Filename,True);
- end;
- procedure TJSONConfig.Loaded;
- begin
- inherited Loaded;
- Reload;
- end;
- function TJSONConfig.FindNodeForValue(const APath: UnicodeString; aExpectedType : TJSONDataClass; out AParent: TJSONObject; out ElName: UnicodeString): TJSONData;
- var
- I : Integer;
- begin
- Result:=FindElement(StripSlash(APath),True,aParent,ElName,True);
- if Assigned(Result) and Not Result.InheritsFrom(aExpectedType) then
- begin
- I:=aParent.IndexOfName(UTF8Encode(elName));
- aParent.Delete(i);
- Result:=Nil;
- end;
- end;
- function TJSONConfig.FindPath(const APath: UnicodeString; AllowCreate: Boolean
- ): TJSONObject;
-
- Var
- P : UnicodeString;
- L : Integer;
-
- begin
- P:=APath;
- L:=Length(P);
- If (L=0) or (P[L]<>'/') then
- P:=P+'/';
- Result:=FindObject(P,AllowCreate);
- end;
- procedure TJSONConfig.DoSetFilename(const AFilename: String; ForceReload: Boolean);
- begin
- if (not ForceReload) and (FFilename = AFilename) then
- exit;
- FFilename := AFilename;
- if csLoading in ComponentState then
- exit;
- Flush;
- If Not FileExists(AFileName) then
- Clear
- else
- LoadFromFile(AFileName);
- end;
- procedure TJSONConfig.SetFilename(const AFilename: String);
- begin
- DoSetFilename(AFilename, False);
- end;
- procedure TJSONConfig.SetJSONOptions(AValue: TJSONOptions);
- begin
- if FJSONOptions=AValue then Exit;
- FJSONOptions:=AValue;
- if csLoading in ComponentState then
- exit;
- if (FFileName<>'') then
- Reload;
- end;
- function TJSONConfig.StripSlash(const P: UnicodeString): UnicodeString;
- Var
- L : Integer;
- begin
- L:=Length(P);
- If (L>0) and (P[l]='/') then
- Result:=Copy(P,1,L-1)
- else
- Result:=P;
- end;
- procedure TJSONConfig.LoadFromFile(const AFileName: String);
- Var
- F : TFileStream;
- begin
- F:=TFileStream.Create(AFileName,fmopenRead or fmShareDenyWrite);
- try
- LoadFromStream(F);
- finally
- F.Free;
- end;
- end;
- procedure TJSONConfig.LoadFromStream(S: TStream);
- Var
- P : TJSONParser;
- J : TJSONData;
- begin
- P:=TJSONParser.Create(S,FJSONOptions);
- try
- J:=P.Parse;
- If (J is TJSONObject) then
- begin
- FreeAndNil(FJSON);
- FJSON:=J as TJSONObject;
- FKey:=FJSON;
- end
- else
- begin
- FreeAndNil(J);
- Raise EJSONConfigError.CreateFmt(SErrInvalidJSONFile,[FileName]);
- end;
- finally
- P.Free;
- end;
- end;
- procedure TJSONConfig.CloseKey;
- begin
- ResetKey;
- end;
- procedure TJSONConfig.OpenKey(const aPath: UnicodeString; AllowCreate: Boolean);
- Var
- P : UnicodeString;
- L : Integer;
-
- begin
- P:=APath;
- L:=Length(P);
- If (L=0) then
- FKey:=FJSON
- else
- begin
- if (P[L]<>'/') then
- P:=P+'/';
- FKey:=FindObject(P,AllowCreate);
- If (FKey=Nil) Then
- Raise EJSONConfigError.CreateFmt(SErrCouldNotOpenKey,[APath]);
- end;
- end;
- procedure TJSONConfig.ResetKey;
- begin
- FKey:=FJSON;
- end;
- procedure TJSONConfig.EnumSubKeys(const APath: UnicodeString; List: TStrings);
- Var
- AKey : TJSONObject;
- I : Integer;
-
- begin
- AKey:=FindPath(APath,False);
- If Assigned(AKey) then
- begin
- For I:=0 to AKey.Count-1 do
- If AKey.Items[i] is TJSONObject then
- List.Add(AKey.Names[i]);
- end;
- end;
- procedure TJSONConfig.EnumValues(const APath: UnicodeString; List: TStrings);
- Var
- AKey : TJSONObject;
- I : Integer;
- begin
- AKey:=FindPath(APath,False);
- If Assigned(AKey) then
- begin
- For I:=0 to AKey.Count-1 do
- If Not (AKey.Items[i] is TJSONObject) then
- List.Add(AKey.Names[i]);
- end;
- end;
- end.
|