[aquaskk-changes 478] CVS update: AquaSKK

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();


aquaskk-changes メーリングリストの案内