t-suw****@users*****
t-suw****@users*****
2008年 9月 20日 (土) 14:03:05 JST
Index: AquaSKK/BIM.cpp
diff -u AquaSKK/BIM.cpp:1.18 AquaSKK/BIM.cpp:1.19
--- AquaSKK/BIM.cpp:1.18 Mon Dec 17 23:48:49 2007
+++ AquaSKK/BIM.cpp Sat Sep 20 14:03:05 2008
@@ -1,5 +1,5 @@
/*
- $Id: BIM.cpp,v 1.18 2007/12/17 14:48:49 t-suwa Exp $
+ $Id: BIM.cpp,v 1.19 2008/09/20 05:03:05 t-suwa Exp $
MacOS X implementation of the SKK input method.
@@ -351,10 +351,11 @@
}
break;
case 0x66: // p
+ (*inSessionHandle)->imsession_input_mode->handleCg();
if(SKKConfig::UseEisuuToSetHenkanPoint()) {
return (*inSessionHandle)->imsession_input_mode->handleInput(SKKConfig::SetHenkanPointKey());
} else {
- return true;
+ return true;
}
break;
case 0x68: // ©È
Index: AquaSKK/ChangeLog
diff -u AquaSKK/ChangeLog:1.60 AquaSKK/ChangeLog:1.61
--- AquaSKK/ChangeLog:1.60 Sun Jan 20 14:17:50 2008
+++ AquaSKK/ChangeLog Sat Sep 20 14:03:05 2008
@@ -1,3 +1,13 @@
+2008-09-20 Tomotaka SUWA <t.suw****@mac*****>
+
+ * Package/Makefile: Disk Image ã®èªåçæå¦çã追å
+
+ * BIM.cpp: ããªæªç¢ºå®ç¶æ
ã§è±æ°ãã¼ã«ãã ASCII ã¢ã¼ãé·ç§»å¾ã«å
¥å
+ ä¸è½ã¨ãªãä¸å
·åãä¿®æ£(ãã£ã³ã»ã«ã®å¯ä½ç¨ãã)
+
+ * SKKDictionary.*: ãã¦ã³ãã¼ãããè¾æ¸ãå°ããããå ´åã«ã¯ç¡è¦ãã
+ ããã«ä¿®æ£
+
2008-01-20 Tomotaka SUWA <t.suw****@mac*****>
* AquaSKK 3.6 ãªãªã¼ã¹ã
Index: AquaSKK/SKKDictionary.cpp
diff -u AquaSKK/SKKDictionary.cpp:1.17 AquaSKK/SKKDictionary.cpp:1.18
--- AquaSKK/SKKDictionary.cpp:1.17 Mon Nov 19 23:13:36 2007
+++ AquaSKK/SKKDictionary.cpp Sat Sep 20 14:03:05 2008
@@ -1,5 +1,5 @@
/*
- $Id: SKKDictionary.cpp,v 1.17 2007/11/19 14:13:36 t-suwa Exp $
+ $Id: SKKDictionary.cpp,v 1.18 2008/09/20 05:03:05 t-suwa Exp $
MacOS X implementation of the SKK input method.
@@ -134,6 +134,16 @@
ofs_ << pair.first << " " << pair.second << std::endl;
}
};
+
+ int FileSize(const std::string& path) {
+ struct stat st;
+
+ if(stat(path.c_str(), &st) == 0) {
+ return st.st_size;
+ }
+
+ return 0;
+ }
};
// ======================================================================
@@ -304,7 +314,7 @@
// ãã¦ã³ãã¼ãç¨ã®ã¹ã¬ãããèµ°ããã
pthread_t pth = 0;
- if(pthread_create(&pth, NULL, SKKAutoUpdateDictionary::download, this) == 0) {
+ if(pthread_create(&pth, NULL, SKKAutoUpdateDictionary::watch_dog_timer, this) == 0) {
pthread_detach(pth);
} else {
std::cerr << "pthread_create() failed: " << errno << std::endl;
@@ -313,63 +323,122 @@
// ----------------------------------------------------------------------
-void* SKKAutoUpdateDictionary::download(void* param) {
+void* SKKAutoUpdateDictionary::watch_dog_timer(void* param) {
SKKAutoUpdateDictionary* obj = reinterpret_cast<SKKAutoUpdateDictionary*>(param);
while(true) {
- socket_stream session(obj->host_.c_str(), 80);
- if(session) {
- // è¾æ¸ã®æ´æ°æ¥ä»ãåå¾
- char timestamp[64];
- struct stat st;
- if(stat(obj->path_.c_str(), &st) != 0) {
- st.st_mtime = 0;
- }
- strftime(timestamp, sizeof(timestamp), "%a, %d %b %Y %T %Z", gmtime(&st.st_mtime));
-
- // ãªã¯ã¨ã¹ã
- session << "GET " << obj->url_ << " HTTP/1.1" << std::endl;
- session << "Host: " << obj->host_ << std::endl;
- session << "If-Modified-Since: " << timestamp << std::endl;
- session << "Connection: close" << std::endl;
- session << std::endl;
-
- // æ´æ°ãããè¾æ¸ã®ãµã¤ãºãåå¾ãã
- std::string response;
- int length = 0;
- while(std::getline(session, response) && response != "\r") {
- if(response.find("Content-Length") != std::string::npos) {
- std::istringstream buf(response);
- buf >> response >> length;
- }
- }
-
- // æ´æ°ããã¦ãããªããã¦ã³ãã¼ããã
- if(length) {
- std::string path(obj->path_);
- path += ".download";
- std::ofstream ofs(path.c_str());
- while(std::getline(session, response)) {
- ofs << response << std::endl;
- }
- ofs.close();
-
- // å®å
¨ã«ãã¦ã³ãã¼ãã§ããããªãã¼ã
- if(stat(path.c_str(), &st) == 0 && st.st_size == length) {
- rename(path.c_str(), obj->path_.c_str());
- obj->reloadContainer();
- std::cerr << "SKKAutoUpdateDictionary: " << obj->path_ << " has been updated" << std::endl;
- }
- }
- } else {
- std::cerr << "SKKAutoUpdateDictionary: can't connect to [" << obj->host_ << "]" << std::endl;
- }
+ socket_stream http(obj->host_.c_str(), 80);
+
+ if(obj->request(http)) {
+ int length = obj->content_length(http);
+
+ if(obj->download(http, length)) {
+ obj->reloadContainer();
+ std::cerr << "SKKAutoUpdateDictionary: " << obj->path_
+ << " has been updated" << std::endl;
+ }
+ }
// 10 åééã§ã6 æéçµéããã®ããã§ãã¯ãã
- for(time_t nextTime = time(0) + skkdic::DOWNLOAD_INTERVAL; time(0) < nextTime; sleep(skkdic::SAVE_TIMEOUT)) {
+ for(time_t nextTime = time(0) + skkdic::DOWNLOAD_INTERVAL;
+ time(0) < nextTime;
+ sleep(skkdic::SAVE_TIMEOUT)) {
// ããããªãã¨ãOS ãã¹ãªã¼ãã¢ã¼ããã復帰ããæã«æããªã
}
}
+
+ return 0;
+}
+
+bool SKKAutoUpdateDictionary::request(std::iostream& http) {
+ char timestamp[64];
+ struct stat st;
+
+ if(stat(path_.c_str(), &st) != 0) {
+ st.st_mtime = 0;
+ }
+
+ // HTTP æ¥ä»ãçæãã(RFC 822, updated by RFC 1123)
+ //
+ // ä¾) "Sun, 06 Nov 1994 08:49:37 GMT"
+ strftime(timestamp, sizeof(timestamp),
+ "%a, %d %b %Y %T GMT", gmtime(&st.st_mtime));
+
+ http << "GET " << url_ << " HTTP/1.1\r\n";
+ http << "Host: " << host_ << "\r\n";
+ http << "If-Modified-Since: " << timestamp << "\r\n";
+ http << "Connection: close\r\n";
+ http << "\r\n" << std::flush;
+
+ return http;
+}
+
+int SKKAutoUpdateDictionary::content_length(std::iostream& http) {
+ int length = 0;
+ std::string response;
+
+ while(std::getline(http, response) && response != "\r") {
+ if(response.find("HTTP/1.1") != std::string::npos) {
+ std::istringstream buf(response);
+
+ // "HTTP/1.1 200" ãæå¾
ãã
+ buf >> response >> response;
+ if(response != "200") {
+ while(std::getline(http, response)) {}
+ break;
+ }
+ }
+
+ if(response.find("Content-Length") != std::string::npos) {
+ std::istringstream buf(response);
+ buf >> response >> length;
+ }
+ }
+
+ return length;
+}
+
+bool SKKAutoUpdateDictionary::download(std::iostream& http, int length) {
+ std::string tmp_path = path_ + ".download";
+ if(length) {
+ std::string line;
+ std::ofstream ofs(tmp_path.c_str());
+
+ while(std::getline(http, line)) {
+ ofs << line << std::endl;
+ }
+ } else {
+ return false;
+ }
+
+ // ãã¦ã³ãã¼ãã«å¤±æãããï¼
+ int new_size = skkdic::FileSize(tmp_path);
+ if(new_size != length) {
+ std::cerr << "SKKAutoUpdateDictionary::download(): size conflict: expected="
+ << length << ", actual=" << new_size << std::endl;
+ return false;
+ }
+
+
+ // æ¢åã®è¾æ¸ã¨æ¯è¼ãã¦å°ããããªããï¼
+ int old_size = skkdic::FileSize(path_);
+ if(old_size != 0) {
+ const int safety_margin = 32 * 1024; // 32KB
+
+ if(new_size + safety_margin < old_size) {
+ std::cerr << "SKKAutoUpdateDictionary::download(): too small: size="
+ << new_size << std::endl;
+ return false;
+ }
+ }
+
+ if(rename(tmp_path.c_str(), path_.c_str()) != 0) {
+ std::cerr << "SKKAutoUpdateDictionary::download(): rename failed: errno="
+ << errno << std::endl;
+ return false;
+ }
+
+ return true;
}
// ======================================================================
Index: AquaSKK/SKKDictionary.h
diff -u AquaSKK/SKKDictionary.h:1.10 AquaSKK/SKKDictionary.h:1.11
--- AquaSKK/SKKDictionary.h:1.10 Mon Dec 18 00:05:41 2006
+++ AquaSKK/SKKDictionary.h Sat Sep 20 14:03:05 2008
@@ -1,5 +1,5 @@
/*
- $Id: SKKDictionary.h,v 1.10 2006/12/17 15:05:41 t-suwa Exp $
+ $Id: SKKDictionary.h,v 1.11 2008/09/20 05:03:05 t-suwa Exp $
MacOS X implementation of the SKK input method.
@@ -68,7 +68,10 @@
std::string host_;
std::string url_;
- static void* download(void* param);
+ static void* watch_dog_timer(void* param);
+ bool request(std::iostream& http);
+ int content_length(std::iostream& http);
+ bool download(std::iostream& http, int length);
public:
SKKAutoUpdateDictionary();