summaryrefslogtreecommitdiff
path: root/hfpd/configfile.h
blob: de17e6ca23ae52c7268c238d54cb84af48ade0ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* -*- C++ -*- */
/*
 * Software Bluetooth Hands-Free Implementation
 *
 * Copyright (C) 2006-2008 Sam Revitch <samr7@cs.washington.edu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#if !defined(__HFPD_CONFIGFILE_H__)
#define __HFPD_CONFIGFILE_H__

#include <libhfp/list.h>
#include <libhfp/events.h>

/*
 * Configuration file parser/writer for hfpd
 * _REALLY_ basic, not meant to store large information sets
 * The file format is essentially .INI
 */

class ConfigFile {
	struct Tuple {
		libhfp::ListItem	links;
		const char		*key;
		const char		*value;
		int			layer;
		int			lowest_layer;

		void *operator new(size_t, Tuple *&tupp) { return tupp; }
	};

	struct Section {
		libhfp::ListItem	m_links;
		const char		*m_name;
		libhfp::ListItem	m_tuples;

		void *operator new(size_t, Section *&secp) { return secp; }
	};

	libhfp::ListItem		m_sections;

	Section *CreateSection(const char *name, int len);
	Tuple *CreateTuple(Section *secp,
			   const char *name, const char *value);
	Section *FindSection(const char *name);
	Tuple *FindTuple(Section *secp, const char *name);
	void DeleteSection(Section *secp);
	void DeleteTuple(Tuple *tupp);
	void DeleteAll(void);

	struct Context {
		int		layer;
		int		fh;
		Section		*cursec;
		const char	*filename;
		int		lineno;
	};

	bool ReadLoop(Context *ctxp);
	int ExtractLineLoop(Context *ctxp, char *buf, int len, bool last);
	bool ParseLine(Context *ctxp, char *buf);

public:

	ConfigFile(void) {}
	~ConfigFile() { Clear(); }

	void Clear(void) { DeleteAll(); }
	bool Load(const char *path, int layer);
	bool Save(const char *path, int min_layer,
		  libhfp::ErrorInfo *error = 0);
	bool Create(const char *path);

	bool Get(const char *section, const char *key,
		 const char *&value, const char *defaultval);
	bool Get(const char *section, const char *key,
		 int &value, int defaultval);
	bool Get(const char *section, const char *key,
		 unsigned int &value, unsigned int defaultval);
	bool Get(const char *section, const char *key,
		 float &value, float defaultval);
	bool Get(const char *section, const char *key,
		 bool &value, bool defaultval);
	bool Set(const char *section, const char *key, const char *value,
		 libhfp::ErrorInfo *error = 0);
	bool Set(const char *section, const char *key, int value,
		 libhfp::ErrorInfo *error = 0);
	bool Set(const char *section, const char *key, unsigned int value,
		 libhfp::ErrorInfo *error = 0);
	bool Set(const char *section, const char *key, float value,
		 libhfp::ErrorInfo *error = 0);
	bool Set(const char *section, const char *key, bool value,
		 libhfp::ErrorInfo *error = 0);

	bool Delete(const char *section, const char *key,
		    libhfp::ErrorInfo *error = 0) {
		return Set(section, key, (const char *) 0, error);
	}

	class Iterator {
		friend class ConfigFile;
		ConfigFile::Section *sec;
		ConfigFile::Tuple *tup;
	public:
		Iterator() : sec(0), tup(0) {}
		const char *GetSection(void) const
			{ return sec ? sec->m_name : 0; }
		const char *GetKey(void) const
			{ return sec ? tup->key : 0; }
		const char *GetValue(void) const
			{ return sec ? tup->value : 0; }
		const bool GetValueBool(void) const;
	};

	bool First(ConfigFile::Iterator &it);
	bool FirstInSection(ConfigFile::Iterator &it, const char *secname);
	bool Next(ConfigFile::Iterator &it);
	bool Prev(ConfigFile::Iterator &it);
};

#endif /* !defined(__HFPD_CONFIGFILE_H__) */