123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- {
- Copyright 2014 Stas'M Corp.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- }
- unit LiteINI;
- interface
- uses
- SysUtils;
- type
- SList = Array of String;
- INIValue = record
- Name: String;
- Value: String;
- end;
- INISection = record
- Name: String;
- Values: Array of INIValue;
- end;
- INIFile = Array of INISection;
- procedure SListClear(var List: SList);
- function SListAppend(var List: SList; S: String): Integer;
- function SListFind(List: SList; Value: String): Integer;
- function INIFindSection(INI: INIFile; Section: String): Integer;
- function INIFindValue(INI: INIFile; Section: Integer; Value: String): Integer;
- function INIAddSection(var INI: INIFile; Section: String): Integer;
- function INIAddValue(var INI: INIFile; Section: Integer; ValueName, Value: String): Integer;
- procedure INIUnload(var INI: INIFile);
- procedure INILoad(var INI: INIFile; FileName: String);
- function INISectionExists(INI: INIFile; Section: String): Boolean;
- function INIValueExists(INI: INIFile; Section: String; Value: String): Boolean;
- function INIReadSectionLowAPI(INI: INIFile; Section: Integer; var List: SList): Boolean;
- function INIReadSection(INI: INIFile; Section: String): SList;
- function INIReadStringLowAPI(INI: INIFile; Section, Value: Integer; var Str: String): Boolean;
- function INIReadString(INI: INIFile; Section, Value, Default: String): String;
- function INIReadInt(INI: INIFile; Section, Value: String; Default: Integer): Integer;
- function INIReadDWord(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
- function INIReadIntHex(INI: INIFile; Section, Value: String; Default: Integer): Integer;
- function INIReadDWordHex(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
- function INIReadBool(INI: INIFile; Section, Value: String; Default: Boolean): Boolean;
- function INIReadBytes(INI: INIFile; Section, Value: String): TBytes;
- function INIReadBytesDef(INI: INIFile; Section, Value: String; Default: TBytes): TBytes;
- implementation
- procedure SListClear(var List: SList);
- begin
- SetLength(List, 0);
- end;
- function SListAppend(var List: SList; S: String): Integer;
- begin
- SetLength(List, Length(List) + 1);
- List[Length(List) - 1] := S;
- Result := Length(List) - 1;
- end;
- function SListFind(List: SList; Value: String): Integer;
- var
- I: Integer;
- begin
- Result := -1;
- for I := 0 to Length(List) - 1 do
- if List[I] = Value then begin
- Result := I;
- Break;
- end;
- end;
- function INIFindSection(INI: INIFile; Section: String): Integer;
- var
- I: Integer;
- begin
- Result := -1;
- for I := 0 to Length(INI) - 1 do
- if INI[I].Name = Section then begin
- Result := I;
- Exit;
- end;
- end;
- function INIFindValue(INI: INIFile; Section: Integer; Value: String): Integer;
- var
- I: Integer;
- begin
- Result := -1;
- if (Section < 0) or (Section >= Length(INI)) then
- Exit;
- for I := 0 to Length(INI[Section].Values) - 1 do
- if INI[Section].Values[I].Name = Value then begin
- Result := I;
- Exit;
- end;
- end;
- function INIAddSection(var INI: INIFile; Section: String): Integer;
- begin
- Result := INIFindSection(INI, Section);
- if Result >= 0 then
- Exit;
- Result := Length(INI);
- SetLength(INI, Result + 1);
- INI[Result].Name := Section;
- SetLength(INI[Result].Values, 0);
- end;
- function INIAddValue(var INI: INIFile; Section: Integer; ValueName, Value: String): Integer;
- var
- I: Integer;
- begin
- Result := -1;
- if (Section < 0) or (Section >= Length(INI)) then
- Exit;
- I := INIFindValue(INI, Section, ValueName);
- if I = -1 then begin
- Result := Length(INI[Section].Values);
- SetLength(INI[Section].Values, Result + 1);
- INI[Section].Values[Result].Name := ValueName;
- INI[Section].Values[Result].Value := Value;
- end else begin
- INI[Section].Values[I].Value := Value;
- Result := I;
- end;
- end;
- procedure INIUnload(var INI: INIFile);
- begin
- SetLength(INI, 0);
- end;
- procedure INILoad(var INI: INIFile; FileName: String);
- var
- F: TextFile;
- S, ValueName, Value: String;
- INIList: SList;
- I, Sect: Integer;
- begin
- INIUnload(INI);
- if not FileExists(FileName) then
- Exit;
- AssignFile(F, FileName);
- Reset(F);
- // Read and filter lines
- while not EOF(F) do begin
- Readln(F, S);
- if (Pos(';', S) <> 1)
- and (Pos('#', S) <> 1)
- and (
- ((Pos('[', S) > 0) and (Pos(']', S) > 0)) or
- (Pos('=', S) > 0)
- )
- then
- SListAppend(INIList, S);
- end;
- CloseFile(F);
- // Parse 2 (parse format)
- Sect := -1;
- for I := 0 to Length(INIList) - 1 do begin
- S := Trim(INIList[I]);
- if Length(S) >= 2 then
- if (S[1] = '[') and (S[Length(S)] = ']') then begin
- S := Trim(Copy(S, 2, Length(S) - 2));
- Sect := INIAddSection(INI, S);
- Continue;
- end;
- S := INIList[I];
- if Pos('=', S) > 0 then begin
- ValueName := Trim(Copy(S, 1, Pos('=', S) - 1));
- Value := Copy(S, Pos('=', S) + 1, Length(S) - Pos('=', S));
- if Sect = -1 then
- Sect := INIAddSection(INI, '');
- INIAddValue(INI, Sect, ValueName, Value);
- end;
- end;
- end;
- function INISectionExists(INI: INIFile; Section: String): Boolean;
- begin
- Result := INIFindSection(INI, Section) > -1;
- end;
- function INIValueExists(INI: INIFile; Section: String; Value: String): Boolean;
- var
- Sect: Integer;
- begin
- Sect := INIFindSection(INI, Section);
- Result := INIFindValue(INI, Sect, Value) > -1;
- end;
- function INIReadSectionLowAPI(INI: INIFile; Section: Integer; var List: SList): Boolean;
- var
- I: Integer;
- begin
- Result := False;
- SetLength(List, 0);
- if (Section < 0) or (Section >= Length(INI)) then
- Exit;
- for I := 0 to Length(INI[Section].Values) - 1 do
- SListAppend(List, INI[Section].Values[I].Name);
- Result := True;
- end;
- function INIReadSection(INI: INIFile; Section: String): SList;
- var
- Sect: Integer;
- begin
- Sect := INIFindSection(INI, Section);
- INIReadSectionLowAPI(INI, Sect, Result);
- end;
- function INIReadStringLowAPI(INI: INIFile; Section, Value: Integer; var Str: String): Boolean;
- begin
- Result := False;
- if (Section < 0) or (Section >= Length(INI)) then
- Exit;
- if (Value < 0) or (Value >= Length(INI[Section].Values)) then
- Exit;
- Str := INI[Section].Values[Value].Value;
- Result := True;
- end;
- function INIReadString(INI: INIFile; Section, Value, Default: String): String;
- var
- Sect, Val: Integer;
- begin
- Sect := INIFindSection(INI, Section);
- Val := INIFindValue(INI, Sect, Value);
- if not INIReadStringLowAPI(INI, Sect, Val, Result) then
- Result := Default;
- end;
- function INIReadInt(INI: INIFile; Section, Value: String; Default: Integer): Integer;
- var
- S: String;
- E: Integer;
- begin
- S := INIReadString(INI, Section, Value, '');
- Val(S, Result, E);
- if E <> 0 then
- Result := Default;
- end;
- function INIReadDWord(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
- var
- S: String;
- E: Integer;
- begin
- S := INIReadString(INI, Section, Value, '');
- Val(S, Result, E);
- if E <> 0 then
- Result := Default;
- end;
- function INIReadIntHex(INI: INIFile; Section, Value: String; Default: Integer): Integer;
- var
- S: String;
- E: Integer;
- begin
- S := INIReadString(INI, Section, Value, '');
- Val('$'+S, Result, E);
- if E <> 0 then
- Result := Default;
- end;
- function INIReadDWordHex(INI: INIFile; Section, Value: String; Default: Cardinal): Cardinal;
- var
- S: String;
- E: Integer;
- begin
- S := INIReadString(INI, Section, Value, '');
- Val('$'+S, Result, E);
- if E <> 0 then
- Result := Default;
- end;
- function INIReadBool(INI: INIFile; Section, Value: String; Default: Boolean): Boolean;
- var
- S: String;
- I: Cardinal;
- E: Integer;
- begin
- S := INIReadString(INI, Section, Value, '');
- Val(S, I, E);
- if E <> 0 then
- Result := Default
- else
- Result := I > 0;
- end;
- function StringToBytes(S: String; var B: TBytes): Boolean;
- var
- I: Integer;
- begin
- Result := False;
- if Odd(Length(S)) then
- Exit;
- SetLength(B, Length(S) div 2);
- for I := 0 to Length(B) - 1 do begin
- B[I] := 0;
- case S[(I*2)+2] of
- '0': ;
- '1': B[I] := B[I] or $1;
- '2': B[I] := B[I] or $2;
- '3': B[I] := B[I] or $3;
- '4': B[I] := B[I] or $4;
- '5': B[I] := B[I] or $5;
- '6': B[I] := B[I] or $6;
- '7': B[I] := B[I] or $7;
- '8': B[I] := B[I] or $8;
- '9': B[I] := B[I] or $9;
- 'A','a': B[I] := B[I] or $A;
- 'B','b': B[I] := B[I] or $B;
- 'C','c': B[I] := B[I] or $C;
- 'D','d': B[I] := B[I] or $D;
- 'E','e': B[I] := B[I] or $E;
- 'F','f': B[I] := B[I] or $F;
- else Exit;
- end;
- case S[(I*2)+1] of
- '0': ;
- '1': B[I] := B[I] or $10;
- '2': B[I] := B[I] or $20;
- '3': B[I] := B[I] or $30;
- '4': B[I] := B[I] or $40;
- '5': B[I] := B[I] or $50;
- '6': B[I] := B[I] or $60;
- '7': B[I] := B[I] or $70;
- '8': B[I] := B[I] or $80;
- '9': B[I] := B[I] or $90;
- 'A','a': B[I] := B[I] or $A0;
- 'B','b': B[I] := B[I] or $B0;
- 'C','c': B[I] := B[I] or $C0;
- 'D','d': B[I] := B[I] or $D0;
- 'E','e': B[I] := B[I] or $E0;
- 'F','f': B[I] := B[I] or $F0;
- else Exit;
- end;
- end;
- Result := True;
- end;
- function INIReadBytes(INI: INIFile; Section, Value: String): TBytes;
- var
- S: String;
- begin
- S := INIReadString(INI, Section, Value, '');
- if not StringToBytes(S, Result) then
- SetLength(Result, 0);
- end;
- function INIReadBytesDef(INI: INIFile; Section, Value: String; Default: TBytes): TBytes;
- var
- S: String;
- begin
- S := INIReadString(INI, Section, Value, '');
- if not StringToBytes(S, Result) then
- Result := Default;
- end;
- end.
|