在第一部分中,列出了Properties的定义的头文件。这个文件中的load及loadXML接口参数是一样的。当初设计这个类的时候,主要是读ini格式的文件,后来又有了读XML格式文件的需求,才增加了loadXML的函数。这样以增加函数接口来扩展功能的方式显得比较丑陋,同时也说明,Properties的设计不能满足于读不同文件格式的需要。下面是针对这个问题,作出的重新的设计:
1
2 /* xtl/Properties.h
3 Author: ZhangTao
4 Date: Nov 6,
2008
5 */
6
7 # ifndef Properties_h
8 # define Properties_h
9
10 # include <algorithm>
11 # include
<iterator>
12
13 # include <iostream>
14 #
include <fstream>
15 # include <string>
16 #
include <map>
17
18 # include "xtl/except.h"
19
20 namespace std {
21 // <map> member output operator
22
template<typename _U, typename _V>
23 ostream& operator<<
(ostream& os, const pair<_U, _V>& val) {
24 return os
<< val.first << " = " << val.second;
25 }
26
27
// <map> output operator, ie. all members in <map> output to
<ostream>
28 template<typename _U, typename _V>
29
ostream& operator<< (ostream& os, const map<_U, _V>&
val) {
30 copy(val.begin(), val.end(), ostream_iterator< pair<_U,
_V> >(os, "/n"));
31 return os;
32 }
33 } // end of
<namespace std>
34
35 namespace xtl {
36
37 typedef
std::map<std::string, std::string> PropMap;
38
39
template<typename _Loader>
40 class Properties : public PropMap
{
41 public:
42 Properties() {};
43 Properties(const char*
fname, const char* section = "") {
44 load(fname, section);
45
}
46 Properties(std::istream& is, const char* section = "")
{
47 load(is, section);
48 }
49
50 void load(const
char* fname, const char* section = "") {
51 std::ifstream
ifs(fname);
52
53 if ( !ifs )
54 throw_fmtException("can
not read <%s>", fname);
55
56 load(ifs, section);
57
}
58
59 void load(std::istream& is, const char* section = "")
{
60 loadFunc(*this, is, section);
61 }
62
63 const
std::string& getProperty(const std::string& key) const {
64
static const std::string EmptyStr;
65
66 const_iterator it =
find(key);
67
68 return it == end()? EmptyStr :
it->second;
69 }
70
71 void list(std::ostream& os)
const {
72 os << *this;
73 }
74
75
private:
76 _Loader loadFunc; // load map data template function
77
78 }; // end of <class Properties>
79
80
81 } // end of
<namespace xtl>
82
83 # endif /* end of <ifndef Properties_h>
*/
84
- IniProps的定义头文件:
/* xtl/IniProps.h
Author: ZhangTao
Date: June 28, 2009
*/
# ifndef IniProps_h
# define IniProps_h
# include "xtl/Properties.h"
namespace xtl {
class IniPropsLoad {
public:
void operator() (PropMap&
props, std::istream& is, const char* section);
};
typedef Properties<IniPropsLoad> IniProps;
} // end of <namespace xtl>