1 // Copyright 2010-2018, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // UserDicStorageInterface provides interface for accessing data 31 // storage of the user dictionary. Subclasses determine how to save 32 // dictionary data on a disk. 33 34 // The followings are not responsibility of UserDicStorageInterface 35 // and supposed to be performed by its client. 36 // 37 // (1) Validation of input values. 38 // Subclasses that implement the interface of 39 // UserDicStorageInterface are supposed to perform only minimal 40 // validation of input value, for example a subclass that saves 41 // dictionary data in a tab-separated text file usually doesn't 42 // accept input with a tab or new line character and should check 43 // input for them. However, UserDicStorageInterface and its 44 // subclasses don't care about any more complicated 45 // application-level validity of data like an acceptable POS set, 46 // character encoding and so on. The class takes input value as it 47 // is. 48 // 49 // (2) Duplicate entry elimination. 50 // UserDicStorageInterface treats an entry in it with a unique 51 // integer key. This means it doesn't take into account any actual 52 // attribute of the entry when distinguishing it from another. If 53 // any kind of duplicate elimination is necessary, it should be done 54 // before the value is passed to the class. 55 // 56 // (3) Importing a dictionary file of Mozc or third party IMEs. 57 // UserDicStorageInterface provides CreateDictionary() and 58 // AddEntry(). Clients of the class can import an external 59 // dictionary file using the two member functions. 60 61 #ifndef MOZC_DICTIONARY_USER_DICTIONARY_STORAGE_H_ 62 #define MOZC_DICTIONARY_USER_DICTIONARY_STORAGE_H_ 63 64 #include <memory> 65 #include <string> 66 67 #include "base/port.h" 68 #include "protocol/user_dictionary_storage.pb.h" 69 70 namespace mozc { 71 72 class Mutex; 73 class ProcessMutex; 74 75 class UserDictionaryStorage { 76 public: 77 typedef user_dictionary::UserDictionary UserDictionary; 78 typedef user_dictionary::UserDictionary::Entry UserDictionaryEntry; 79 80 // Instance of base class generated by Protocol Buffers compiler. 81 // Regular inheritance strongly discouraged. 82 user_dictionary::UserDictionaryStorage user_dictionary_storage_base; 83 84 enum UserDictionaryStorageErrorType { 85 USER_DICTIONARY_STORAGE_NO_ERROR = 0, // default 86 FILE_NOT_EXISTS, 87 BROKEN_FILE, 88 SYNC_FAILURE, 89 TOO_BIG_FILE_BYTES, 90 INVALID_DICTIONARY_ID, 91 INVALID_CHARACTERS_IN_DICTIONARY_NAME, 92 EMPTY_DICTIONARY_NAME, 93 DUPLICATED_DICTIONARY_NAME, 94 TOO_LONG_DICTIONARY_NAME, 95 TOO_MANY_DICTIONARIES, 96 TOO_MANY_ENTRIES, 97 EXPORT_FAILURE, 98 UNKNOWN_ERROR, 99 ERROR_TYPE_SIZE 100 }; 101 102 explicit UserDictionaryStorage(const string &filename); 103 virtual ~UserDictionaryStorage(); 104 105 // return the filename of user dictionary 106 const string &filename() const; 107 108 // Return true if data tied with this object already 109 // exists. Otherwise, it means that the space for the data is used 110 // for the first time. 111 bool Exists() const; 112 113 // Load user dictionary from the file. 114 // NOTE: If the file is not existent, nothing is updated. 115 // Therefore if the file is deleted after first load(), 116 // second load() does nothing so the content loaded by first load() 117 // is kept as is. 118 bool Load(); 119 120 // Serialzie user dictionary to local file. 121 // Need to call Lock() the dictionary before calling Save(). 122 bool Save(); 123 124 // Lock the dictionary so that other processes/threads cannot 125 // execute mutable operations on this dictionary. 126 bool Lock(); 127 128 // release the lock 129 bool UnLock(); 130 131 // Export a dictionary to a file in TSV format. 132 bool ExportDictionary(uint64 dic_id, const string &file_name); 133 134 // Create a new dictionary with a specified name. Returns the id of 135 // the new instance via new_dic_id. 136 137 bool CreateDictionary(const string &dic_name, uint64 *new_dic_id); 138 139 // Delete a dictionary. 140 bool DeleteDictionary(uint64 dic_id); 141 142 // Rename a dictionary. 143 bool RenameDictionary(uint64 dic_id, const string &dic_name); 144 145 // return the index of "dic_id" 146 // return -1 if no dictionary is found. 147 int GetUserDictionaryIndex(uint64 dic_id) const; 148 149 // return mutable UserDictionary corresponding to dic_id 150 UserDictionary *GetUserDictionary(uint64 dic_id); 151 152 // Searches a dictionary from a dictionary name, and the dictionary id is 153 // stored in "dic_id". 154 // Returns false if the name is not found. 155 bool GetUserDictionaryId(const string &dic_name, uint64 *dic_id); 156 157 // return last error type. 158 // You can obtain the reason of the error of dictionary operation. 159 UserDictionaryStorageErrorType GetLastError() const; 160 161 // Add new entry to the auto registered dictionary. 162 bool AddToAutoRegisteredDictionary(const string &key, 163 const string &value, 164 UserDictionary::PosType pos); 165 166 // Converts syncable dictionaries to unsyncable dictionaries. 167 // The name of default sync dictionary is renamed to locale-independent name 168 // like other unsyncable dictionaries. 169 // This method deletes syncable dictionaries which are marked as removed or 170 // don't have any dictionary entries. 171 // Returns true if this method converts some dictionaries. 172 bool ConvertSyncDictionariesToNormalDictionaries(); 173 174 // return the number of dictionaries with "synclbe" being true. 175 static int CountSyncableDictionaries( 176 const user_dictionary::UserDictionaryStorage &storage); 177 178 // maxium number of dictionaries this storage can hold 179 static size_t max_dictionary_size(); 180 181 // maximum number of entries one dictionary can hold 182 static size_t max_entry_size(); 183 184 static string default_sync_dictionary_name(); 185 186 private: 187 // Return true if this object can accept the given dictionary name. 188 // This changes the internal state. 189 bool IsValidDictionaryName(const string &name); 190 191 // Load the data from file_name actually. 192 bool LoadInternal(); 193 194 string file_name_; 195 bool locked_; 196 UserDictionaryStorageErrorType last_error_type_; 197 std::unique_ptr<Mutex> local_mutex_; 198 std::unique_ptr<ProcessMutex> process_mutex_; 199 }; 200 201 } // namespace mozc 202 203 #endif // MOZC_DICTIONARY_USER_DICTIONARY_STORAGE_H_ 204