1 2 #ifndef __INI_HPP__ 3 #define __INI_HPP__ 4 5 /* "Species" - a CoreWars evolver. Copyright (C) 2003 'Varfar' 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 1, or (at your option) any later 10 * version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 23 #include <iostream> 24 #include <string> 25 26 /** 27 * 28 * this INI parsing thingy is designed to work with binary streams, 29 * coping internally with either \n or \r\n line endings 30 * 31 **/ 32 33 /******************************************************************* 34 * class KeyValuePair 35 * sequentially parses lines and splits them into key-value pairs 36 * to parse, >> from an input stream in a loop while isValid() 37 *******************************************************************/ 38 39 class KeyValuePair { operator >>(std::istream & is,KeyValuePair & kvp)40 friend std::istream &operator>>(std::istream &is,KeyValuePair &kvp) { return kvp.fromSerial(is); } 41 public: 42 KeyValuePair(); 43 ~KeyValuePair(); 44 // error states 45 enum KVP_ERROR { 46 VALUE_NOT_INT, 47 VALUE_NOT_BOOL, 48 VALUE_NOT_FLOAT, 49 VALUE_NOT_DOUBLE, 50 KEY_NOT_VALID, 51 KEY_HAS_NO_CATEGORY, 52 KVP_ERROR_LAST 53 }; 54 static const char *ERROR_MSG(const KVP_ERROR err); 55 // something to check? isValid() const56 bool isValid() const { return valid; } 57 // is a key? is(const std::string & key) const58 bool is(const std::string &key) const { return is(key.c_str()); } 59 bool is(const char *key) const; 60 // get key 61 void getKeyAsString(std::string &key); // will set key to error message if not a valid line 62 const char *getKeyAsChar(); // copy to your own var before you manipulate or save for later! 63 // keys can be categorised by being of the form "category.key" so "guidence.range" makes 64 // more sense hasCategory() const65 bool hasCategory() const { return hascategory; } // simply returns if has a category isCategory(const std::string & category) const66 bool isCategory(const std::string &category) const { return isCategory(category.c_str()); } 67 bool isCategory(const char *category); 68 bool hasSubCategory(); // more categories? category.category...key 69 bool getSubCategory(); // will divide the current key into category.key; returns hasCategory() now 70 // get key; will throw KVP_ERROR in error conditions 71 void getCategoryAsString(std::string &category); 72 const char *getCategoryAsChar() const; // copy to your own var before you manipulate or save for later! 73 // check values isValue(const std::string & val) const74 bool isValue(const std::string &val) const { return isValue(val.c_str()); } 75 bool isValue(const char *val) const; 76 // get value (where a default is set, will return def if parse failed); else will throw KVP_ERROR 77 void getValueAsString(std::string &value); 78 const char *getValueAsChar(); // copy your own var before manipulate or save for later! 79 int getValueAsInt(int def=0); 80 float getValueAsFloat(float def=0.0f,bool percent_allowed=true); 81 double getValueAsDouble(double def=0.0,bool percent_allowed=true); 82 bool getValueAsBool(bool def=true); 83 // misc getLineNum() const84 unsigned int getLineNum() const { return linenum; } 85 static const int MAX_KVP_LINE_LEN = 132; 86 protected: 87 bool valid, // should key and value be used? 88 hascategory; // has a category? 89 unsigned int linenum; 90 char line[MAX_KVP_LINE_LEN], *key, *value, *category; 91 std::istream &fromSerial(std::istream & is); 92 }; 93 94 class INIFile { 95 public: 96 INIFile(std::istream &is); 97 bool seek(const std::string §ion); // returns success 98 KeyValuePair *get(const std::string &key); // returns null if no such key 99 protected: 100 static const int NO_SECTION = -1; 101 std::istream *_is; 102 int _section_ofs; 103 char _section[KeyValuePair::MAX_KVP_LINE_LEN]; 104 KeyValuePair _kvp; 105 bool _bad_stream; 106 }; 107 108 #endif // ifndef __INI_HPP__ 109 110