• R/O
  • SSH
  • HTTPS

clxcpp: 提交


Commit MetaInfo

修訂578 (tree)
時間2009-12-25 17:20:09
作者cielquis

Log Message

clx version 0.16.1

Change Summary

差異

--- tags/release_0.16.1/ini.h (nonexistent)
+++ tags/release_0.16.1/ini.h (revision 578)
@@ -0,0 +1,234 @@
1+/* ------------------------------------------------------------------------- */
2+/*
3+ * ini.h
4+ *
5+ * Copyright (c) 2004 - 2009, clown. All rights reserved.
6+ *
7+ * Redistribution and use in source and binary forms, with or without
8+ * modification, are permitted provided that the following conditions
9+ * are met:
10+ *
11+ * - Redistributions of source code must retain the above copyright
12+ * notice, this list of conditions and the following disclaimer.
13+ * - Redistributions in binary form must reproduce the above copyright
14+ * notice, this list of conditions and the following disclaimer in the
15+ * documentation and/or other materials provided with the distribution.
16+ * - No names of its contributors may be used to endorse or promote
17+ * products derived from this software without specific prior written
18+ * permission.
19+ *
20+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+ *
32+ * Last-modified: Tue 24 Nov 2009 03:51:00 JST
33+ */
34+/* ------------------------------------------------------------------------- */
35+#ifndef CLX_INI_H
36+#define CLX_INI_H
37+
38+#include <iostream>
39+#include <string>
40+#include <vector>
41+#include <map>
42+#include <fstream>
43+#include <stdexcept>
44+#include "exception.h"
45+#include "literal.h"
46+#include "lexical_cast.h"
47+#include "salgorithm.h"
48+#include "container_wrapper.h"
49+
50+namespace clx {
51+ /* --------------------------------------------------------------------- */
52+ // ini_container
53+ /* --------------------------------------------------------------------- */
54+ template <
55+ class Type,
56+ class CharT,
57+ class Traits = std::char_traits<CharT>
58+ >
59+ class ini_container : public map_wrapper<std::basic_string<CharT, Traits>, Type> {
60+ public:
61+ typedef CharT char_type;
62+ typedef std::basic_string<CharT, Traits> string_type;
63+
64+ typedef map_wrapper<std::basic_string<CharT, Traits>, Type> super;
65+ typedef typename super::container container;
66+ typedef typename container::size_type size_type;
67+ typedef typename container::key_type key_type;
68+ typedef typename container::mapped_type mapped_type;
69+ typedef typename container::value_type value_type;
70+ typedef typename container::iterator iterator;
71+ typedef typename container::const_iterator const_iterator;
72+
73+ ini_container() : super() {}
74+
75+ virtual ~ini_container() throw() {}
76+
77+ bool insert(const key_type& s) {
78+ std::vector<string_type> v;
79+ split_if(s, v, is_any_of(LITERAL("=")));
80+ if (v.empty()) return false;
81+
82+ string_type key = v.at(0);
83+ string_type val;
84+ if (v.size() >= 2) val = v.at(1);
85+
86+ value_type elem(key, lexical_cast<mapped_type>(val));
87+ std::pair<iterator, bool> ret = this->member.insert(elem);
88+ return ret.second;
89+ }
90+
91+ bool exist(const key_type& x) const {
92+ return this->member.find(x) != this->member.end();
93+ }
94+ };
95+
96+ /* --------------------------------------------------------------------- */
97+ // basic_ini
98+ /* --------------------------------------------------------------------- */
99+ template <
100+ class Type,
101+ class CharT = char,
102+ class Traits = std::char_traits<CharT>
103+ >
104+ class basic_ini : public map_wrapper<std::basic_string<CharT, Traits>,
105+ ini_container<Type, CharT, Traits> > {
106+ private:
107+ typedef map_wrapper<std::basic_string<CharT, Traits>,
108+ ini_container<Type, CharT, Traits> > super;
109+ public:
110+ typedef CharT char_type;
111+ typedef std::basic_string<CharT, Traits> string_type;
112+
113+ typedef string_type key_type;
114+ typedef Type value_type;
115+
116+ typedef ini_container<Type, CharT, Traits> subcontainer;
117+ typedef typename subcontainer::iterator sub_iterator;
118+ typedef typename subcontainer::const_iterator const_sub_iterator;
119+
120+ basic_ini() : super() {}
121+
122+ template <class Ch, class Tr>
123+ explicit basic_ini(std::basic_istream<Ch, Tr>& sin) : super() {
124+ this->read(sin);
125+ }
126+
127+ explicit basic_ini(const string_type& path) : super() {
128+ this->read(path);
129+ }
130+
131+ explicit basic_ini(const char_type* path) : super() {
132+ this->read(path);
133+ }
134+
135+ virtual ~basic_ini() throw() {}
136+
137+ template <class Ch, class Tr>
138+ basic_ini& read(std::basic_istream<Ch, Tr>& sin) {
139+ const char_type semi = LITERAL(';');
140+ const char_type lb = LITERAL('[');
141+ const char_type rb = LITERAL(']');
142+
143+ string_type cur;
144+ size_t n = 0;
145+
146+ string_type tmp;
147+ while (std::getline(sin, tmp)) {
148+ chomp(tmp);
149+ ++n;
150+
151+ if (tmp.empty() || tmp.at(0) == semi) continue;
152+ else if (tmp.at(0) == lb) { // section
153+ size_t last = tmp.find(rb);
154+ if (last == string_type::npos) throw syntax_error(n, "expected ']' token");
155+ cur = tmp.substr(1, last - 1);
156+ this->insert(cur);
157+ }
158+ else { // parser and insert the string "key=value"
159+ if (cur.empty()) throw syntax_error(n, "expected section name");
160+ if (!this->member[cur].insert(tmp)) throw syntax_error(n, "unknown error");
161+ }
162+ }
163+
164+ return *this;
165+ }
166+
167+ basic_ini& read(const char_type* path) {
168+ std::basic_ifstream<CharT, Traits> fs(path);
169+ if (fs.fail()) {
170+ std::basic_stringstream<CharT, Traits> msg;
171+ msg << path << ": no such file or directory";
172+ throw std::runtime_error(msg.str());
173+ }
174+ return this->read(fs);
175+ }
176+
177+ basic_ini& read(const string_type& path) {
178+ if (path.empty()) return *this;
179+ return this->read(path.c_str());
180+ }
181+
182+ template <class Ch, class Tr>
183+ basic_ini& write(std::basic_ostream<Ch, Tr>& out) {
184+ for (typename super::iterator pos = this->member.begin(); pos != this->member.end(); ++pos) {
185+ out << LITERAL("[") << pos->first << LITERAL("]") << std::endl;
186+ for (typename subcontainer::iterator it = pos->second.begin();
187+ it != pos->second.end(); ++it) {
188+ out << it->first << LITERAL("=") << it->second << std::endl;
189+ }
190+ }
191+ return *this;
192+ }
193+
194+ basic_ini& write(const char_type* path) {
195+ std::basic_ofstream<CharT, Traits> ofs(path);
196+ if (ofs.fail()) {
197+ std::basic_stringstream<CharT, Traits> msg;
198+ msg << path << ": cannot open the file";
199+ throw std::runtime_error(msg.str());
200+ }
201+ return this->write(ofs);
202+ }
203+
204+ basic_ini& write(const string_type& path) {
205+ if (path.empty()) return *this;
206+ return this->write(path.c_str());
207+ }
208+
209+ // make new section
210+ bool insert(const key_type& section) {
211+ std::pair<typename super::iterator, bool> ret;
212+ std::pair<key_type, subcontainer> elem(section, subcontainer());
213+ ret = this->member.insert(elem);
214+ return ret.second;
215+ }
216+
217+ bool exist(const key_type& section) const {
218+ return this->member.find(section) != this->member().end();
219+ }
220+
221+ bool exist(const key_type& section, const key_type& key) const {
222+ typename super::const_iterator p = this->member.find(section);
223+ if (p == this->member.end()) return false;
224+ return p->second.exist(key);
225+ }
226+ };
227+
228+ typedef basic_ini<std::basic_string<char> > ini;
229+#ifdef CLX_USE_WCHAR
230+ typedef basic_ini<std::basic_string<wchar_t> > wini;
231+#endif // CLX_USE_WCHAR
232+}
233+
234+#endif // CLX_INI_H
Added: svn:executable
Show on old repository browser