////////////////////////////////////////////////////////////////////// // Mini INI File Crackers // Written by Jonathan A. Foster // Started June 1st, 2021 // Copyright JF Possibilities, Inc. All rights reserved. // Used with permission in the "Poor Man's IDS" project // // This set of classes is to prvide easy access to reading config data // from INI files. I'm going to take some liberty with the origianl // M$ format and allow groups to parse specialized text formats, not // just name/value pairs. ////////////////////////////////////////////////////////////////////// #ifndef __JFP_MINIINI_H__ #define __JFP_MINIINI_H__ #include #include #include "strutil.h" ////////////////////////////////////////////////////////////////////// // The base abstract group class // // Subclass and override this class to create a parser for the kind of // data you want in your group. ////////////////////////////////////////////////////////////////////// struct MiniINI; struct MiniINIgroup { // vals: By convention the content of the group // this is overriden to handle the parsing of lines in this group // it must ignore whitespace and remarks, if allowed in the group's // format. virtual void add(const std::string &in) = 0; // This is overridden to dump the group back out to a file virtual std::ostream &save(std::ostream &out) const = 0; // cause we need the destructor virtual too! virtual ~MiniINIgroup() {} }; inline std::ostream &operator<<(std::ostream &out, const MiniINIgroup &ini) { return ini.save(out); } ////////////////////////////////////////////////////////////////////// // The typical collection of name+value pairs ////////////////////////////////////////////////////////////////////// struct MiniINIvars: public MiniINIgroup { NameVal vals; // name val pairs /// Get a value setting it to def if not found /// /// This looks for name in vals. If found that value is returned. Otherwise /// the def is set in vals for the name. This means it will be saved at /// next writing. Def defaults to empty string. If you don't want to auto- /// create the value in the config file then use the appropriate methods of /// vals. virtual std::string get(const std::string &name, const std::string &def); /// Get a value NOT adding it to vals if not found /// /// This looks for name in vals. If found that value is returned. Otherwise /// "" is returned but the name is not added to vals. virtual std::string get(const std::string &name) const; /// Get an int from vals /// /// This will convert the string value, if found in vals, to an int and make /// sure its within bounds. If its not in bounds or doesn't exist or is an /// an empty string them def is returned. The vals is not modified. /// /// For safety values are limited to 9 digits plus sign, since this is a safe /// range for converting to 32 bit ints. virtual int geti(const std::string &name, int def=0, int min=-999999999, int max=999999999) const; /// parse an INI line into a name value pair virtual void add(const std::string &in); /// write all name value pairs from vals to out virtual std::ostream &save(std::ostream &out) const; }; ////////////////////////////////////////////////////////////////////// // A raw collection of lines in a group ////////////////////////////////////////////////////////////////////// struct MiniINIlines: public MiniINIgroup { StringList vals; // the raw lines of this group virtual void add(const std::string &in);// add an incoming line virtual std::ostream &save(std::ostream &out) const; }; ////////////////////////////////////////////////////////////////////// // The main INI container that contains all groups // // Fill groups with a list of group objects and their associated // names. Call load() to read the groups from an INI file. Only the // group with names specified in groups will be read. Their content // parsed according to the group's rules. save() will write it back // out again. No attempt to preserve whitespace and remarks is made. ////////////////////////////////////////////////////////////////////// typedef std::map INIgroupList; struct MiniINI { // This is a list of groups allowed in the INI and after load() those // groups will contain the data from the INI and they will be written // on save(). // // This must be initialized with MiniINIgroup* objects so that it knows // how to process groups. No attempt is made to manage memory allocation. INIgroupList groups; // Load the file and parse into groups[]. If a group is encountered that // was not specified in groups[] it is ignored, and will be lost on // save(). Same for pre-group content. virtual void load(const std::string &fname); // Save the groups[] into the file. No attempt is made to preserve // whitespace or remarks. This is the "mini INI". Preserving thoee // requires a more complicated and thus less "mini" implementation. virtual void save(const std::string &fname); // A virtual NOP destructor... because its recommended. virtual ~MiniINI() {} }; #endif