Develop and Download Open Source Software

Browse Subversion Repository

Contents of /common/AccessProperty.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 354 - (show annotations) (download) (as text)
Sun Apr 13 13:21:39 2008 UTC (15 years, 11 months ago) by satofumi
File MIME type: text/x-c++src
File size: 4434 byte(s)
RemoveFile の Windows 実装
1 /*!
2 \file
3 \brief 属性情報の読み出しと変更
4
5 \author Satofumi KAMIMURA
6
7 $Id$
8
9 \todo 余力あらば umask を適切に設定する
10 \todo getline() と eof() を併用しないよう、他の実装を変更していく
11 */
12
13 #include "AccessProperty.h"
14 #include "DetectOS.h"
15 #include <sys/stat.h>
16 #include <string>
17 #include <fstream>
18 #include <map>
19 #include <boost/xpressive/xpressive.hpp>
20 #ifdef WINDOWS_OS
21 #include <windows.h>
22 #endif
23
24 using namespace beego;
25 using namespace boost::xpressive;
26
27
28 struct AccessProperty::pImpl {
29 std::string error_message_; //!< エラー状態
30 bool read_; //!< 読み込み済みの場合 true
31 time_t ctime_; //!< 読み出し時の時刻
32 std::string path_; //!< 読み出したファイルパス
33 typedef std::map<std::string,std::string> PropertyMap;
34 PropertyMap properties_;
35
36 pImpl(const char* fname)
37 : error_message_("no error."), read_(false), ctime_(0), path_(fname) {
38 }
39
40 time_t getChangeTime(void) {
41
42 struct stat buf;
43 if (stat(path_.c_str(), &buf) < 0) {
44 return 0;
45 }
46 return buf.st_ctime;
47 }
48
49 bool readfile(void) {
50
51 // 読み出し処理
52 // - 先頭が '#' で始まる場合は読み飛ばす
53 // - 「key = value」において、value 以降は読み飛ばす
54
55 std::ifstream fin(path_.c_str());
56 if (! fin.is_open()) {
57 return false;
58 }
59
60 // 要素の読み出し
61 sregex pattern = sregex::compile("^(.+?)\\s*=\\s*\"(.+?)\"\\s*$");
62 std::string line;
63 while (getline(fin, line)) {
64 if (line.empty() || line[0] == '#') {
65 continue;
66 }
67
68 smatch match;
69 if (regex_search(line, match, pattern)) {
70 // 格納
71 properties_[match[1]] = match[2];
72 }
73 }
74
75 read_ = true;
76 ctime_ = getChangeTime();
77 return true;
78 }
79
80 bool save(void) {
81
82 // !!! readfile() と重複が多いが、仕方ないよなぁ...
83
84 // 出力ファイルの生成
85 #if defined(WINDOWS_OS)
86 const char* temp_name = _tempnam(NULL, "access_property_");
87 #else
88 char temp_name[] = "access_property_XXXXXX";
89 mkstemp(temp_name);
90 #endif
91 std::ofstream fout(temp_name);
92
93 // 既存ファイルの読み出し
94 std::ifstream fin(path_.c_str());
95 if (! fin.is_open()) {
96 return false;
97 }
98
99 // 要素の読み出しと置換
100 sregex pattern = sregex::compile("^(.+?)\\s*=\\s*\"?(.+?)\"?\\s*$");
101 std::string line;
102 while (getline(fin, line)) {
103 smatch match;
104 if (regex_search(line, match, pattern)) {
105
106 // 格納されているキーワードなら、置き換える
107 const std::string& key = match[1];
108 PropertyMap::iterator p = properties_.find(key);
109 if (p != properties_.end()) {
110 fout << key << " = \"" << p->second << '"' << std::endl;
111
112 // キーの登録削除
113 properties_.erase(key);
114
115 continue;
116 }
117 }
118 fout << line << std::endl;
119 }
120
121 // 未保存の項目を保存する
122 for (PropertyMap::iterator it = properties_.begin();
123 it != properties_.end(); ++it) {
124 fout << it->first << " = " << it->second << std::endl;
125 }
126
127 // ファイルを置換する
128 fin.close();
129 fout.close();
130 #if defined(WINDOWS_OS)
131 // !!! RemoveFile() を使うべき
132 DeleteFileA(path_.c_str());
133 #endif
134 return (rename(temp_name, path_.c_str()) == 0) ? true : false;
135 }
136 };
137
138
139 AccessProperty::AccessProperty(const char* fname) : pimpl(new pImpl(fname)) {
140 pimpl->readfile();
141 }
142
143
144 AccessProperty::~AccessProperty(void) {
145 }
146
147
148 const char* AccessProperty::what(void) {
149 return pimpl->error_message_.c_str();
150 }
151
152
153 #if 0
154 void AccessProperty::operator=(const char* value) {
155 pimpl->value_ = value;
156 }
157
158
159 AccessProperty& AccessProperty::operator[](const char* key) {
160
161 pimpl->properties_[key] = pimpl->value_;
162 fprintf(stderr, " [%s] = %s\n", key, pimpl->value_.c_str());
163
164 return *this;
165 }
166 #endif
167
168
169 std::string& AccessProperty::operator[](const char* key) const {
170 return pimpl->properties_[key];
171 }
172
173
174 bool AccessProperty::reload(void) {
175 if (! pimpl->read_) {
176 // !!! error_message_ を更新
177 return false;
178 }
179
180 return pimpl->readfile();
181 }
182
183
184 bool AccessProperty::save(void) {
185 if (! pimpl->read_) {
186 // !!! error_message_ を更新
187 return false;
188 }
189
190 return pimpl->save();
191 }
192
193
194 bool AccessProperty::isChangedByOther(void) {
195 if (! pimpl->read_) {
196 // !!! error_message_ を更新
197 return false;
198 }
199
200 // 最終時刻を読み出し、読み込んだ時刻と違っていたら、true を返す
201 time_t now_ctime = pimpl->getChangeTime();
202 return (now_ctime != pimpl->ctime_) ? true : false;
203 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26