Tomotaka SUWA
t-suw****@users*****
2005年 11月 15日 (火) 00:37:13 JST
Index: AquaSKK/ChangeLog diff -u AquaSKK/ChangeLog:1.14 AquaSKK/ChangeLog:1.15 --- AquaSKK/ChangeLog:1.14 Wed Nov 9 00:02:24 2005 +++ AquaSKK/ChangeLog Tue Nov 15 00:37:13 2005 @@ -1,3 +1,17 @@ +2005-11-15 Tomotaka SUWA <t.suw****@mac*****> + + * SKKDictionary.cpp (SKKUserDictionary::registerOkuriAri, + SKKUserDictionary::registerOkuriNasi, + SKKUserDictionary::removeOkuriAri, + SKKUserDictionary::removeOkuriNasi): std::map.find ÅÅÉeXg + ·éæ¤ÉC³B + + * DMDictionary.*: KotoeriDictionary ðÇÁBSÌIÉt@N^ + OB + + * SKKDictionary.cpp (SKKUserDictionary::save): XVª¶µÄ©ç + 10 ªÈãoßµ½êÉàÛ¶·éæ¤ÉC³B + 2005-11-08 Tomotaka SUWA <t.suw****@mac*****> * AquaSKK.pbproj/project.pbxproj: UserDicSaver.* ðrhÝè©ç Index: AquaSKK/DMDictionary.cpp diff -u AquaSKK/DMDictionary.cpp:1.3 AquaSKK/DMDictionary.cpp:1.4 --- AquaSKK/DMDictionary.cpp:1.3 Wed Nov 9 00:02:24 2005 +++ AquaSKK/DMDictionary.cpp Tue Nov 15 00:37:13 2005 @@ -1,5 +1,5 @@ /* - $Id: DMDictionary.cpp,v 1.3 2005/11/08 15:02:24 t-suwa Exp $ + $Id: DMDictionary.cpp,v 1.4 2005/11/14 15:37:13 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -26,180 +26,139 @@ #include <Carbon/Carbon.h> #include <iostream> -#include <fstream> #include <vector> +#include <algorithm> +#include "CppCFData.h" #include "CppCFString.h" #include "OkuriganaEntry.h" -#include "Dictionary.h" #include "DMDictionary.h" -#include "CppCFData.h" - -#if 0 -# define D_PRINTF printf -#else -# define D_PRINTF if(0)printf -#endif - -static OSErr FilePathToFSSpec(CFStringRef filePath, FSSpec *apSpec); -DMDictionary::DMDictionary(const std::vector<CppCFString>& kotoeri_dic_file) { - load(kotoeri_dic_file); -} - -DMDictionary::~DMDictionary() { - closeDictionary(); -} - -void DMDictionary::changeDictionaryFile(const std::vector<CppCFString>& kotoeri_dic_file) { - closeDictionary(); - load(kotoeri_dic_file); -} +static OSErr FilePathToFSSpec(CFStringRef filePath, FSSpec* apSpec); -int DMDictionary::countOkuriAri() { - return 0; -} - -int DMDictionary::countOkuriNasi() { - int result = 0; - - for(std::vector<dicinfo>::iterator i = dics_.begin(); i != dics_.end(); ++ i) { - ItemCount numItems; - if(DCMCountRecord(i->id, &numItems) == noErr) { - result += numItems; - } +DMDictionary::KotoeriDictionary::KotoeriDictionary(const CFStringRef path) + : path_(0), isRegistered_(false), id_(0) { + path_ = CFStringCreateCopy(kCFAllocatorDefault, path); + if(!path_) { + std::cerr << "KotoeriDictionary: CFStringCreateCopy() failed" << std::endl; + return; } - return result; -} - -std::vector<OkuriganaEntry> DMDictionary::findOkuriAri(const CppCFString& root) -{ - // ±Æ¦è«ÉÍuè èvͶݵȢ - return std::vector<OkuriganaEntry>(); -} - -std::vector<CppCFString> DMDictionary::findOkuriNasi(const CppCFString& query) -{ - // ¶ÝµÈ¯êÎóÌvectorðÔ·B - D_PRINTF("KOTOERI_DIC - QUERY: %s\n",query.toCString(kCFStringEncodingShiftJIS)); - //«ªêÂàÈ¢H - if(dics_.empty()) { - return std::vector<CppCFString>(); - } - return findRecord(query); -} - -void DMDictionary::load(const std::vector<CppCFString>& dicFiles) { - for(std::vector<CppCFString>::const_iterator ite = dicFiles.begin(); - ite != dicFiles.end(); ++ ite) { - openDictionary(*ite); - } - - std::cerr << "DMDictionary(Kotoeri Dictionaries)" << std::endl - << " okuri-ari: " << countOkuriAri() << " entries." - << std::endl - << " okuri-nasi: " << countOkuriNasi() << " entries." - << std::endl << std::endl; -} - -void DMDictionary::openDictionary(const CppCFString& fpath) { FSSpec spec; - dicinfo info; - - if(FilePathToFSSpec(fpath.getString(), &spec) != noErr) { + if(FilePathToFSSpec(path_, &spec) != noErr) { return; } - info.isRegistered = false; - if(DCMGetDictionaryIDFromFile(&spec, &info.id) != noErr) { + if(DCMGetDictionaryIDFromFile(&spec, &id_) != noErr) { std::cerr << "DCMGetDictionaryIDFromFile() failed" << std::endl; - if(DCMRegisterDictionaryFile(&spec, &info.id) != noErr) { + if(DCMRegisterDictionaryFile(&spec, &id_) != noErr) { std::cerr << "DCMRegisterDictionaryFile() failed" << std::endl; return; } - info.isRegistered = true; + isRegistered_ = true; + } +} + +DMDictionary::KotoeriDictionary::~KotoeriDictionary() { + if(isRegistered_) { + DCMUnregisterDictionary(id_); } - if(DCMOpenDictionary(info.id, 0, NULL, &info.ref) != noErr) { + if(path_) { + CFRelease(path_); + } +} + +bool DMDictionary::KotoeriDictionary::Find(const CFStringRef key, + DCMFoundRecordIterator* iterator) { + DCMDictionaryRef ref; + if(DCMOpenDictionary(id_, 0, NULL, &ref) != noErr) { std::cerr << "DCMOpenDictionary() failed" << std::endl; - return; + return false; + } + + // R[hðõ + OSStatus status; + DCMFieldTag dataFieldTagList[] = { kDCMJapaneseHyokiTag }; + ByteCount length = CFStringGetLength(key) * sizeof(UniChar); + status = DCMFindRecords(ref, // Dictionary reference + kDCMJapaneseYomiTag, // key field tag + length, // key data length + CFStringGetCharactersPtr(key), // key data + kDCMFindMethodExactMatch, // find method + 1, // number of data field + dataFieldTagList, // data field tag list + 0, 0, // search all records + iterator); // found result + + DCMCloseDictionary(ref); + + return (status == noErr); +} + +const bool DMDictionary::KotoeriDictionary::IsGood() const { + return (id_ != 0); +} + +const int DMDictionary::KotoeriDictionary::Count() const { + ItemCount numItems; + if(DCMCountRecord(id_, &numItems) == noErr) { + return numItems; } - dics_.push_back(info); + return 0; } -void DMDictionary::closeDictionary() { - struct local { - static void CloseDictionary(const dicinfo info) { - DCMCloseDictionary(info.ref); - if(info.isRegistered) { - DCMUnregisterDictionary(info.id); - } - } - }; - std::for_each(dics_.begin(), dics_.end(), local::CloseDictionary); - dics_.clear(); +const void DMDictionary::KotoeriDictionary::Description() const { + char buf[1024]; + CFStringGetCString(path_, buf, sizeof(buf), kCFStringEncodingUTF8); + std::cerr << "Kotoeri Dictionary(" << buf << ")" << std::endl + << " okuri-ari: 0 entries." << std::endl + << " okuri-nasi: " << Count() << " entries." + << std::endl << std::endl; } -bool DMDictionary::checkDictionary(const CFStringRef fpath) { - bool result = false; - DCMDictionaryID id; - DCMDictionaryRef ref; - bool isRegistered = false; - FSSpec spec; +// ------------------------------------------------------------------ - if(FilePathToFSSpec(fpath, &spec) != noErr) { - return result; - } +DMDictionary::DMDictionary(const std::vector<CppCFString>& kotoeri_dic_file) { + load(kotoeri_dic_file); +} - if(DCMGetDictionaryIDFromFile(&spec, &id) != noErr) { - if(DCMRegisterDictionaryFile(&spec, &id) != noErr) { - return result; - } - isRegistered = true; - } +DMDictionary::~DMDictionary() { + unload(); +} - if(DCMOpenDictionary(id, 0, NULL, &ref) == noErr) { - DCMCloseDictionary(ref); - result = true; - } +int DMDictionary::countOkuriAri() { + return 0; +} + +int DMDictionary::countOkuriNasi() { + int result = 0; - if(isRegistered) DCMUnregisterDictionary(id); + for(KotoeriDictionaryIterator i = dics_.begin(); i != dics_.end(); ++ i) { + result += (*i)->Count(); + } return result; } -std::vector<CppCFString> DMDictionary::findRecord(const CppCFString& query) { +std::vector<OkuriganaEntry> DMDictionary::findOkuriAri(const CppCFString& str) { + // ±Æ¦è«ÉÍuè èvͶݵȢ + return std::vector<OkuriganaEntry>(); +} + +std::vector<CppCFString> DMDictionary::findOkuriNasi(const CppCFString& str) { OSStatus status; - DCMFieldTag dataFieldTagList[] = { kDCMJapaneseHyokiTag }; - DCMFoundRecordIterator iterator; - CFStringRef strRef = query.getString(); - ByteCount length = CFStringGetLength(strRef) * sizeof(UniChar); - const UniChar* textPtr = CFStringGetCharactersPtr(strRef); std::vector<CppCFString> result; - for(std::vector<dicinfo>::iterator i = dics_.begin(); i != dics_.end(); ++ i) { - // R[hðõ - status = DCMFindRecords(i->ref, // Dictionary reference - kDCMJapaneseYomiTag, // key field tag - length, // key data length - textPtr, // key data - kDCMFindMethodExactMatch, // find method - 1, // number of data field - dataFieldTagList, // data field tag list - 0, 0, // search all records - &iterator); // found result - if(status != noErr) continue; + for(KotoeriDictionaryIterator i = dics_.begin(); i != dics_.end(); ++ i) { + DCMFoundRecordIterator iterator; + if(!(*i)->Find(str.getString(), &iterator)) continue; while(true) { - AERecord dataList; - DCMUniqueID uniqueID; ByteCount keySize; - UniChar foundKeyStr[kMaxKanjiLengthInAppleJapaneseDictionary]; - - Size actualSize; - DescType actualType; - UniChar dataBuffer[kMaxKanjiLengthInAppleJapaneseDictionary]; + char foundKeyStr[kMaxKanjiLengthInAppleJapaneseDictionary]; + DCMUniqueID uniqueID; + AERecord dataList; // Get one record from result list status = DCMIterateFoundRecord(iterator, // found result @@ -210,46 +169,73 @@ &dataList); // AERecordf[^ if(status != noErr) break; + + DescType actualType; + char dataBuffer[kMaxKanjiLengthInAppleJapaneseDictionary]; + Size actualSize; // Get one data from AERecord status = AEGetKeyPtr(&dataList, - kDCMJapaneseHyokiTag, 'utxt', + kDCMJapaneseHyokiTag, + 'utxt', &actualType, - &dataBuffer, + dataBuffer, kMaxKanjiLengthInAppleJapaneseDictionary, &actualSize); + // Dispose data AERecord AEDisposeDesc(&dataList); - CppCFData data((const char*)dataBuffer, actualSize); - - // CppCFString foundStr(dataBuffer, actualSize / sizeof(UniChar)); - CppCFString foundStr(data.getData()); + if(status != noErr) break; - char buf[kMaxKanjiLengthInAppleJapaneseDictionary*4]; - bool f; - - f = CFStringGetCString(foundStr.getString(), buf, sizeof(buf), - kCFStringEncodingShiftJIS); - - if(strlen(buf) > 0) { - result.push_back(foundStr); - } + // ÊÉÇÁ·é + result.push_back(CppCFData(dataBuffer, actualSize).getData()); } DCMDisposeRecordIterator(iterator); } - D_PRINTF("KOTOERI_REPLY: %s\n", - join(' ', result).toCString(kCFStringEncodingShiftJIS)); - return result; } -static OSErr FilePathToFSSpec(CFStringRef filePath, FSSpec *apSpec) { +void DMDictionary::changeDictionaryFile(const std::vector<CppCFString>& dics) { + unload(); + load(dics); +} + +bool DMDictionary::checkDictionary(const CFStringRef path) { + return KotoeriDictionary(path).IsGood(); +} + +// ------------------------------------------------------------------ + +void DMDictionary::load(const std::vector<CppCFString>& dics) { + for(std::vector<CppCFString>::const_iterator ite = dics.begin(); + ite != dics.end(); ++ ite) { + KotoeriDictionary* dic = new KotoeriDictionary(ite->getString()); + if(dic->IsGood()) { + dics_.push_back(dic); + dic->Description(); + } else { + delete dic; + } + } +} + +void DMDictionary::unload() { + struct local { + static void DeleteObject(const KotoeriDictionary* ptr) { + delete ptr; + } + }; + std::for_each(dics_.begin(), dics_.end(), local::DeleteObject); + dics_.clear(); +} + +static OSErr FilePathToFSSpec(CFStringRef filePath, FSSpec* apSpec) { FSRef fileRef; - OSErr err = noErr; + OSErr err = !noErr; CFURLRef cfUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, - (CFStringRef)filePath, + filePath, kCFURLPOSIXPathStyle, false); if(CFURLGetFSRef(cfUrl, &fileRef)) { @@ -259,9 +245,6 @@ NULL, apSpec, NULL); - - if(err) - return err; } CFRelease(cfUrl); Index: AquaSKK/DMDictionary.h diff -u AquaSKK/DMDictionary.h:1.3 AquaSKK/DMDictionary.h:1.4 --- AquaSKK/DMDictionary.h:1.3 Wed Nov 9 00:02:24 2005 +++ AquaSKK/DMDictionary.h Tue Nov 15 00:37:13 2005 @@ -1,5 +1,5 @@ /* - $Id: DMDictionary.h,v 1.3 2005/11/08 15:02:24 t-suwa Exp $ + $Id: DMDictionary.h,v 1.4 2005/11/14 15:37:13 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -33,16 +33,26 @@ class CppCFString; class DMDictionary: public Dictionary { - struct dicinfo { - bool isRegistered; - DCMDictionaryID id; - DCMDictionaryRef ref; + class KotoeriDictionary { + CFStringRef path_; + bool isRegistered_; + DCMDictionaryID id_; + + public: + KotoeriDictionary(const CFStringRef path); + ~KotoeriDictionary(); + + bool Find(const CFStringRef key, DCMFoundRecordIterator* iterator); + const bool IsGood() const; + const int Count() const; + const void Description() const; }; - std::vector<dicinfo> dics_; + typedef std::vector<KotoeriDictionary*> KotoeriDictionaryContainer; + typedef KotoeriDictionaryContainer::iterator KotoeriDictionaryIterator; + KotoeriDictionaryContainer dics_; + void load(const std::vector<CppCFString>& dicFiles); - void openDictionary(const CppCFString& fpath); - void closeDictionary(); - std::vector<CppCFString> DMDictionary::findRecord(const CppCFString& query); + void unload(); public: DMDictionary(const std::vector<CppCFString>& kotoeri_dic_file); @@ -54,5 +64,5 @@ virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query); void changeDictionaryFile(const std::vector<CppCFString>& kotoeri_dic_file); - bool DMDictionary::checkDictionary(const CFStringRef fpath); + bool checkDictionary(const CFStringRef fpath); }; Index: AquaSKK/SKKDictionary.cpp diff -u AquaSKK/SKKDictionary.cpp:1.5 AquaSKK/SKKDictionary.cpp:1.6 --- AquaSKK/SKKDictionary.cpp:1.5 Wed Nov 9 00:02:24 2005 +++ AquaSKK/SKKDictionary.cpp Tue Nov 15 00:37:13 2005 @@ -1,5 +1,5 @@ /* - $Id: SKKDictionary.cpp,v 1.5 2005/11/08 15:02:24 t-suwa Exp $ + $Id: SKKDictionary.cpp,v 1.6 2005/11/14 15:37:13 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -28,6 +28,7 @@ #include <fstream> #include <cerrno> #include <cstring> +#include <ctime> #include <unistd.h> #include <pthread.h> #include <sys/stat.h> @@ -210,7 +211,7 @@ candidates->insert(candidates->end(), entries.begin(), entries.end()); okuri_nasi_unparsed.erase(ite); } - std::cerr << fpath_ << std::endl + std::cerr << "SKK Dictionary(" << fpath_ << ")" << std::endl << " okuri-ari: " << countOkuriAri() << " entries." << std::endl << " okuri-nasi: " << countOkuriNasi() << " entries." @@ -240,10 +241,13 @@ // ------------------------------------------------------------------ +// [U[«ðÛ¶·×«XVñÌèl const int SKK_JISYO_SAVE_COUNT = 50; -SKKUserDictionary::SKKUserDictionary(const std::string& fpath) - : fpath_(fpath), updateCount_(0) { +// [U[«ðÛ¶·×«XVÔuÌèl(10 ª) +const int SKK_JISYO_SAVE_TIMEOUT = 10 * 60; + +SKKUserDictionary::SKKUserDictionary(const std::string& fpath) : fpath_(fpath) { load(); } @@ -429,7 +433,7 @@ candidates->insert(candidates->end(), entries.begin(), entries.end()); okuri_nasi_unparsed.erase(ite); } - std::cerr << fpath_ << std::endl + std::cerr << "SKK User Dictionary(" << fpath_ << ")" << std::endl << " okuri-ari: " << countOkuriAri() << " entries." << std::endl << " okuri-nasi: " << countOkuriNasi() << " entries." @@ -440,8 +444,8 @@ const CppCFString& okuri, const CppCFString& kanji) { // è¼¼LèB - std::vector<OkuriganaEntry>* candidates = okuri_ari_table[index]; - if(candidates == NULL) { + std::vector<OkuriganaEntry>* candidates; + if(okuri_ari_table.find(index) == okuri_ari_table.end()) { candidates = new std::vector<OkuriganaEntry>; okuri_ari_table[index] = candidates; @@ -450,6 +454,8 @@ entry.add(kanji); candidates->push_back(entry); } else { + candidates = okuri_ari_table[index]; + // ChJ[hÌæªÉ»Ì¿ðÇÁ·éB for(std::vector<OkuriganaEntry>::iterator ite = candidates->begin(); ite != candidates->end(); ite ++) { @@ -493,10 +499,12 @@ void SKKUserDictionary::registerOkuriNasi(const CppCFString& index, const CppCFString& kanji) { - std::vector<CppCFString>* candidates = okuri_nasi_table[index]; - if(candidates == NULL) { + std::vector<CppCFString>* candidates; + if(okuri_nasi_table.find(index) == okuri_nasi_table.end()) { candidates = new std::vector<CppCFString>; okuri_nasi_table[index] = candidates; + } else { + candidates = okuri_nasi_table[index]; } // ùɱ̿ªo^³êÄ¢êÎA»êðÁ·B @@ -518,8 +526,11 @@ void SKKUserDictionary::removeOkuriAri(const CppCFString& index, const CppCFString& kanji) { // è¼¼ è + if(okuri_ari_table.find(index) == okuri_ari_table.end()) { + return; + } + std::vector<OkuriganaEntry>* candidates = okuri_ari_table[index]; - if(candidates == NULL) return; // SÄÌOkuriganaEntry©çA¿ªkanjiÅ éàÌðTµÄ»êðÁ·B for(std::vector<OkuriganaEntry>::iterator entry = candidates->begin(); @@ -540,8 +551,11 @@ void SKKUserDictionary::removeOkuriNasi(const CppCFString& index, const CppCFString& kanji) { + if(okuri_nasi_table.find(index) == okuri_nasi_table.end()) { + return; + } + std::vector<CppCFString>* candidates = okuri_nasi_table[index]; - if(candidates == NULL) return; unsigned size = candidates->size(); for(unsigned i = 0;i < size;i++) { @@ -557,17 +571,26 @@ } void SKKUserDictionary::save(bool force) { + static int updateCount = 0; + static std::time_t startOfUpdate = std::time(0); + // XVJE^[ðñ·(SKK_JISYO_SAVE_COUNT ÜÅ¢Æ 0 ÉZbg) - updateCount_ = (updateCount_ + 1) % SKK_JISYO_SAVE_COUNT; + updateCount = (updateCount + 1) % SKK_JISYO_SAVE_COUNT; + + // XVJn©çoßµ½ÔðZo + std::time_t elapsedTime = std::time(0) - startOfUpdate; // Û¶·é^C~OÅÍÈ¢H - if(!force && updateCount_ != 0) { + if(!force && updateCount != 0 && elapsedTime < SKK_JISYO_SAVE_TIMEOUT) { return; } + // Ç¿çÌðàZbg·é + updateCount = 0; + startOfUpdate = std::time(0); + std::string dic_tmp_path = fpath_ + ".tmp"; std::ofstream ofs(dic_tmp_path.c_str()); - if(!ofs) { std::cerr << "SKKUserDictionary::save(): can't open [" << dic_tmp_path << "]" << std::endl; Index: AquaSKK/SKKDictionary.h diff -u AquaSKK/SKKDictionary.h:1.4 AquaSKK/SKKDictionary.h:1.5 --- AquaSKK/SKKDictionary.h:1.4 Wed Nov 9 00:02:24 2005 +++ AquaSKK/SKKDictionary.h Tue Nov 15 00:37:13 2005 @@ -1,5 +1,5 @@ /* - $Id: SKKDictionary.h,v 1.4 2005/11/08 15:02:24 t-suwa Exp $ + $Id: SKKDictionary.h,v 1.5 2005/11/14 15:37:13 t-suwa Exp $ --------- MacOS X implementation of the SKK input method. @@ -61,7 +61,6 @@ // SKK [U[« class SKKUserDictionary: public UserDictionary { std::string fpath_; - int updateCount_; std::map<CppCFString, std::vector<OkuriganaEntry>*> okuri_ari_table; std::map<CppCFString, std::vector<CppCFString>*> okuri_nasi_table; std::vector<std::string> okuri_ari_unparsed;