1 /*
2 ** configfile.h
3 **
4 **---------------------------------------------------------------------------
5 ** Copyright 1998-2008 Randy Heit
6 ** All rights reserved.
7 **
8 ** Redistribution and use in source and binary forms, with or without
9 ** modification, are permitted provided that the following conditions
10 ** are met:
11 **
12 ** 1. Redistributions of source code must retain the above copyright
13 **    notice, this list of conditions and the following disclaimer.
14 ** 2. Redistributions in binary form must reproduce the above copyright
15 **    notice, this list of conditions and the following disclaimer in the
16 **    documentation and/or other materials provided with the distribution.
17 ** 3. The name of the author may not be used to endorse or promote products
18 **    derived from this software without specific prior written permission.
19 **
20 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 **---------------------------------------------------------------------------
31 **
32 */
33 
34 #ifndef __CONFIGFILE_H__
35 #define __CONFIGFILE_H__
36 
37 #include <stdio.h>
38 #include "zstring.h"
39 
40 class FConfigFile
41 {
42 public:
43 	FConfigFile ();
44 	FConfigFile (const char *pathname);
45 	FConfigFile (const FConfigFile &other);
46 	virtual ~FConfigFile ();
47 
48 	void ClearConfig ();
49 	FConfigFile &operator= (const FConfigFile &other);
50 
HaveSections()51 	bool HaveSections () { return Sections != NULL; }
52 	void CreateSectionAtStart (const char *name);
53 	void MoveSectionToStart (const char *name);
54 	void SetSectionNote (const char *section, const char *note);
55 	void SetSectionNote (const char *note);
56 	bool SetSection (const char *section, bool allowCreate=false);
57 	bool SetFirstSection ();
58 	bool SetNextSection ();
59 	const char *GetCurrentSection () const;
60 	void ClearCurrentSection ();
61 	bool DeleteCurrentSection ();
62 	void ClearKey (const char *key);
63 
64 	bool SectionIsEmpty ();
65 	bool NextInSection (const char *&key, const char *&value);
66 	const char *GetValueForKey (const char *key) const;
67 	void SetValueForKey (const char *key, const char *value, bool duplicates=false);
68 
GetPathName()69 	const char *GetPathName () const { return PathName.GetChars(); }
70 	void ChangePathName (const char *path);
71 
72 	void LoadConfigFile ();
73 	bool WriteConfigFile () const;
74 
75 protected:
76 	virtual void WriteCommentHeader (FILE *file) const;
77 
78 	virtual char *ReadLine (char *string, int n, void *file) const;
79 	bool ReadConfig (void *file);
80 	static const char *GenerateEndTag(const char *value);
81 	void RenameSection(const char *oldname, const char *newname) const;
82 
83 	bool OkayToWrite;
84 	bool FileExisted;
85 
86 private:
87 	struct FConfigEntry
88 	{
89 		char *Value;
90 		FConfigEntry *Next;
91 		char Key[1];	// + length of key
92 
93 		void SetValue (const char *val);
94 	};
95 	struct FConfigSection
96 	{
97 		FString SectionName;
98 		FConfigEntry *RootEntry;
99 		FConfigEntry **LastEntryPtr;
100 		FConfigSection *Next;
101 		FString Note;
102 		//char Name[1];	// + length of name
103 	};
104 
105 	FConfigSection *Sections;
106 	FConfigSection **LastSectionPtr;
107 	FConfigSection *CurrentSection;
108 	FConfigEntry *CurrentEntry;
109 	FString PathName;
110 
111 	FConfigSection *FindSection (const char *name) const;
112 	FConfigEntry *FindEntry (FConfigSection *section, const char *key) const;
113 	FConfigSection *NewConfigSection (const char *name);
114 	FConfigEntry *NewConfigEntry (FConfigSection *section, const char *key, const char *value);
115 	FConfigEntry *ReadMultiLineValue (void *file, FConfigSection *section, const char *key, const char *terminator);
116 	void SetSectionNote (FConfigSection *section, const char *note);
117 
118 public:
119 	class Position
120 	{
121 		friend class FConfigFile;
122 
123 		FConfigSection *Section;
124 		FConfigEntry *Entry;
125 	};
126 
127 	void GetPosition (Position &pos) const;
128 	void SetPosition (const Position &pos);
129 };
130 
131 #endif //__CONFIGFILE_H__
132