{ -------------------------------------------------------------------------- }
{ BigIni.PAS                                                      eh20000401 }
{ Version 3.08                                                               }
{    Delphi 3/4/5 Version                                                    }
{    for a Delphi 1/2 version, please see homepage url below                 }
{ Unit to read/write *.ini files even greater than 64 kB                     }
{ (till today, the KERNEL.DLL and KERNEL32.DLL do it NOT).                   }

{ (c) Edy Hinzen 1996-2000 - Freeware                                        }
{ Mailto:[email protected]                 (thanks for the resonance yet!)       }
{ http://www.Hinzen.de                 (where you find the latest version)   }

{ -------------------------------------------------------------------------- }
{ The TBigIniFile object is designed to work like TIniFile from the Borland  }
{ unit called IniFiles.                                                      }
{ Opposite to the Borland-routines, these are declared virtual!              }
{ Please note that no exception-handling is coded here.                      }
{ The following procedures/functions were added:                             }
{    procedure FlushFile              write data to disk                     }
{    procedure ReadAll                copy entire contents to TStrings-object}
{    procedure AppendFromFile         appends from other *.ini               }
{    property  SectionNames                                                  }
{ -------------------------------------------------------------------------- }
{ The TBiggerIniFile object is a child object with some functions that came  }
{ in handy at my projects:                                                   }
{    property  TextBufferSize                                                }
{    procedure WriteSectionValues(const aSection: string; const aStrings: TStrings);}
{              analog to ReadSectionValues, replace/write all lines from     }
{              aStrings into specified section                               }
{    procedure ReadNumberedList(const Section: string;                       }
{                               aStrings: TStrings;                          }
{                               Deflt: String);                              }
{    procedure WriteNumberedList(const Section: string;                      }
{                               aStrings: TStrings);                         }
{    function   ReadColor(const aSection, aKey: string;                      }
{                         aDefault: TColor): TColor;                         }
{    procedure  WriteColor(const aSection, aKey: string;                     }
{                          aValue: TColor); virtual;                         }
{ -------------------------------------------------------------------------- }
{ The TAppIniFile object is a child again.                                   }
{ It's constructor create has no parameters. The filename is the application's}
{  exename with with extension '.ini' (instead of '.exe).                    }
{    constructor Create;                                                     }
{ -------------------------------------------------------------------------- }

{ ========================================================================== }
{   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.                     }
{ ========================================================================== }

{ Programmer's note:                                                         }
{ Okay, this is NOT the fastest code of the world... (the kernel-functions   }
{ xxxxPrivateProfileString aren't, either!). I wrote it as a subproject of   }
{ my EditCdPlayer.EXE which never seems to become finished ...               }
{ Meanwhile, I hope that Microsoft will write new KERNEL routines.           }

{ Version history                                                            }
{ 1.10 faster read by replaceing TStringlist with simple ReadLn instructions }
{      improved FindItemIndex by storing last results                        }
{ 1.20 Ignore duplicate sections                                             }
{      improved (for this use) TStringList child TSectionList                }
{ 1.21 fixed 1.20 bug in case of empty file                                  }
{ 1.22 added ReadNumberedList and WriteNumberedList                          }
{ 1.23 Delphi 1.0 backward compatibility e.g. local class TStringList        }
{ 1.24 added AppendFromFile                                                  }
{ 2.00 Changed compare-routines of aSection Parameters to AnsiCompareText    }
{      to handle case insensitive search in languages with special chars;    }
{      some efforts to increase speed                                        }
{      * new web and e-mail address *                                        }
{ 2.01 implemented modifications/suggestions from Gyula M�sz�ros,            }
{      Budapest, Hungary - [email protected]                        }
{procedure TIniFile.ReadSections(aStrings: TStrings);                         }
{    - The extra 16K file buffer is removeable                               }
{      see property TextBufferSize                                           }
{    - comment lines (beginning with ';') can be ignored                     }
{      set property FlagDropCommentLines to True                             }
{    - invalid lines (which do not contain an '=' sign) can be ignored       }
{      set property FlagFilterOutInvalid to True                             }
{    - white spaces around the '='-sign can be dropped                       }
{      set property FlagDropWhiteSpace to True                               }
{    - surrounding single or double apostrophes from keys can be dropped     }
{      set property FlagDropApostrophes to True                              }
{ 2.01 (continued)                                                           }
{      property SectionNames is now part of TBigIni (instead of TBiggerIni   }
{      added procedure ReadSections (seems new in Delphi 3)                  }
{ 2.02 fixed WriteNumberedList bug                                           }
{      added DeleteKey                                                       }
{      changed Pos() calls to AnsiPos()                                      }
{ 2.03 minor corrections                                                     }
{ 2.04 new flag FlagTrimRight                                                }
{      set it true to strip off white spaces at end of line                  }
{ 2.05 fixed bug in EraseSection                                             }
{ 2.06 For Win32 apps, TAppIniFile now creates ini-filename in correct mixed }
{      case                                                                  }
{      added HasChanged-check routine in WriteNumberedList                   }
{ 2.07 added note [1] and [2]                                                }
{      used new function ListIdentical instead of property named text within }
{      WriteNumberedList for backward-compatibility                          }
{ 3.01 fixed another bug in EraseSection (variable FPrevSectionIndex)        }
{ 3.02 dropped some $IFDEFS related to prior (Delphi 1/2) compatibility code }
{ 3.03 added ReadColor / WriteColor                                          }
{ 3.04 added notice about incombatibility with TMemIniFile.ReadSectionValues }
{ 3.05 fixed TTextBufferSize vs. IniBufferSize bug                           }
{ 3.06 added TBigIniFile.HasSection                                          }
{ 3.07 fixed ClearSectionList bug (variable FPrevIndex)                      }
{ 3.08 fixed EraseDuplicates memory-bug                                      }
{ -------------------------------------------------------------------------- }

{ -------------------------------------------------------------------------- }
{ Question: how can I set these properties _before_ the file is opened?      }
{ Answer: call create with empty filename, look at this sample:              }
{       myIniFile := TBigIniFile.Create('');                                 }
{       myIniFile.FlagDropCommentLines := True;                              }
{       myIniFile.FileName := ('my.ini');                                    }
{........................................................................... }
{ Question: how can I write comment lines into the file?                     }
{ Answer: like this:                                                         }
{       tempStringList := TStringList.Create;                                }
{       tempStringList.Add('; this is a comment line.');                     }
{       BiggerIniFile.WriteSectionValues('important note',TempStringList);   }
{       BiggerIniFile.FlushFile;                                             }
{       tempStringList.Free;                                                 }
{ -------------------------------------------------------------------------- }