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