Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: third_party/prediction/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp

Issue 1247903003: Add spellcheck and word suggestion to the prediction service (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "third_party/prediction/suggest/policyimpl/dictionary/structure/v4/ver4 _dict_buffers.h"
18
19 #include <cerrno>
20 #include <cstring>
21 #include <fcntl.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <vector>
25
26 #include "third_party/prediction/suggest/policyimpl/dictionary/utils/byte_array_ utils.h"
27 #include "third_party/prediction/suggest/policyimpl/dictionary/utils/dict_file_w riting_utils.h"
28 #include "third_party/prediction/suggest/policyimpl/dictionary/utils/file_utils. h"
29 #include "third_party/prediction/utils/byte_array_view.h"
30
31 namespace latinime {
32
33 /* static */ Ver4DictBuffers::Ver4DictBuffersPtr
34 Ver4DictBuffers::openVer4DictBuffers(
35 const char* const dictPath,
36 MmappedBuffer::MmappedBufferPtr&& headerBuffer,
37 const FormatUtils::FORMAT_VERSION formatVersion) {
38 if (!headerBuffer) {
39 ASSERT(false);
40 AKLOGE("The header buffer must be valid to open ver4 dict buffers.");
41 return Ver4DictBuffersPtr(nullptr);
42 }
43 // TODO: take only dictDirPath, and open both header and trie files in the
44 // constructor below
45 const bool isUpdatable = headerBuffer->isUpdatable();
46 MmappedBuffer::MmappedBufferPtr bodyBuffer = MmappedBuffer::openBuffer(
47 dictPath, Ver4DictConstants::BODY_FILE_EXTENSION, isUpdatable);
48 if (!bodyBuffer) {
49 return Ver4DictBuffersPtr(nullptr);
50 }
51 std::vector<uint8_t*> buffers;
52 std::vector<int> bufferSizes;
53 const ReadWriteByteArrayView buffer = bodyBuffer->getReadWriteByteArrayView();
54 int position = 0;
55 while (position < static_cast<int>(buffer.size())) {
56 const int bufferSize =
57 ByteArrayUtils::readUint32AndAdvancePosition(buffer.data(), &position);
58 const ReadWriteByteArrayView subBuffer =
59 buffer.subView(position, bufferSize);
60 buffers.push_back(subBuffer.data());
61 bufferSizes.push_back(subBuffer.size());
62 position += bufferSize;
63 if (bufferSize < 0 || position < 0 ||
64 position > static_cast<int>(buffer.size())) {
65 AKLOGE("The dict body file is corrupted.");
66 return Ver4DictBuffersPtr(nullptr);
67 }
68 }
69 if (buffers.size() !=
70 Ver4DictConstants::NUM_OF_CONTENT_BUFFERS_IN_BODY_FILE) {
71 AKLOGE("The dict body file is corrupted.");
72 return Ver4DictBuffersPtr(nullptr);
73 }
74 return Ver4DictBuffersPtr(
75 new Ver4DictBuffers(std::move(headerBuffer), std::move(bodyBuffer),
76 formatVersion, buffers, bufferSizes));
77 }
78
79 bool Ver4DictBuffers::flushHeaderAndDictBuffers(
80 const char* const dictDirPath,
81 const BufferWithExtendableBuffer* const headerBuffer) const {
82 // Create temporary directory.
83 const int tmpDirPathBufSize = FileUtils::getFilePathWithSuffixBufSize(
84 dictDirPath,
85 DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE);
86 char tmpDirPath[tmpDirPathBufSize];
87 FileUtils::getFilePathWithSuffix(
88 dictDirPath, DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE,
89 tmpDirPathBufSize, tmpDirPath);
90 if (FileUtils::existsDir(tmpDirPath)) {
91 if (!FileUtils::removeDirAndFiles(tmpDirPath)) {
92 AKLOGE("Existing directory %s cannot be removed.", tmpDirPath);
93 ASSERT(false);
94 return false;
95 }
96 }
97 umask(S_IWGRP | S_IWOTH);
98 if (mkdir(tmpDirPath, S_IRWXU) == -1) {
99 AKLOGE("Cannot create directory: %s. errno: %d.", tmpDirPath, errno);
100 return false;
101 }
102 // Get dictionary base path.
103 const int dictNameBufSize = strlen(dictDirPath) + 1 /* terminator */;
104 char dictName[dictNameBufSize];
105 FileUtils::getBasename(dictDirPath, dictNameBufSize, dictName);
106 const int dictPathBufSize =
107 FileUtils::getFilePathBufSize(tmpDirPath, dictName);
108 char dictPath[dictPathBufSize];
109 FileUtils::getFilePath(tmpDirPath, dictName, dictPathBufSize, dictPath);
110
111 // Write header file.
112 if (!DictFileWritingUtils::flushBufferToFileWithSuffix(
113 dictPath, Ver4DictConstants::HEADER_FILE_EXTENSION, headerBuffer)) {
114 AKLOGE("Dictionary header file %s%s cannot be written.", tmpDirPath,
115 Ver4DictConstants::HEADER_FILE_EXTENSION);
116 return false;
117 }
118
119 // Write body file.
120 const int bodyFilePathBufSize = FileUtils::getFilePathWithSuffixBufSize(
121 dictPath, Ver4DictConstants::BODY_FILE_EXTENSION);
122 char bodyFilePath[bodyFilePathBufSize];
123 FileUtils::getFilePathWithSuffix(dictPath,
124 Ver4DictConstants::BODY_FILE_EXTENSION,
125 bodyFilePathBufSize, bodyFilePath);
126
127 const int fd =
128 open(bodyFilePath, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
129 if (fd == -1) {
130 AKLOGE("File %s cannot be opened. errno: %d", bodyFilePath, errno);
131 ASSERT(false);
132 return false;
133 }
134 FILE* const file = fdopen(fd, "wb");
135 if (!file) {
136 AKLOGE("fdopen failed for the file %s. errno: %d", bodyFilePath, errno);
137 ASSERT(false);
138 return false;
139 }
140
141 if (!flushDictBuffers(file)) {
142 fclose(file);
143 return false;
144 }
145 fclose(file);
146 // Remove existing dictionary.
147 if (!FileUtils::removeDirAndFiles(dictDirPath)) {
148 AKLOGE("Existing directory %s cannot be removed.", dictDirPath);
149 ASSERT(false);
150 return false;
151 }
152 // Rename temporary directory.
153 if (rename(tmpDirPath, dictDirPath) != 0) {
154 AKLOGE("%s cannot be renamed to %s", tmpDirPath, dictDirPath);
155 ASSERT(false);
156 return false;
157 }
158 return true;
159 }
160
161 bool Ver4DictBuffers::flushDictBuffers(FILE* const file) const {
162 // Write trie.
163 if (!DictFileWritingUtils::writeBufferToFileTail(file,
164 &mExpandableTrieBuffer)) {
165 AKLOGE("Trie cannot be written.");
166 return false;
167 }
168 // Write terminal position lookup table.
169 if (!mTerminalPositionLookupTable.flushToFile(file)) {
170 AKLOGE("Terminal position lookup table cannot be written.");
171 return false;
172 }
173 // Write language model content.
174 if (!mLanguageModelDictContent.save(file)) {
175 AKLOGE("Language model dict content cannot be written.");
176 return false;
177 }
178 // Write bigram dict content.
179 if (!mBigramDictContent.flushToFile(file)) {
180 AKLOGE("Bigram dict content cannot be written.");
181 return false;
182 }
183 // Write shortcut dict content.
184 if (!mShortcutDictContent.flushToFile(file)) {
185 AKLOGE("Shortcut dict content cannot be written.");
186 return false;
187 }
188 return true;
189 }
190
191 Ver4DictBuffers::Ver4DictBuffers(
192 MmappedBuffer::MmappedBufferPtr&& headerBuffer,
193 MmappedBuffer::MmappedBufferPtr&& bodyBuffer,
194 const FormatUtils::FORMAT_VERSION formatVersion,
195 const std::vector<uint8_t*>& contentBuffers,
196 const std::vector<int>& contentBufferSizes)
197 : mHeaderBuffer(std::move(headerBuffer)),
198 mDictBuffer(std::move(bodyBuffer)),
199 mHeaderPolicy(mHeaderBuffer->getReadOnlyByteArrayView().data(),
200 formatVersion),
201 mExpandableHeaderBuffer(
202 mHeaderBuffer->getReadWriteByteArrayView(),
203 BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
204 mExpandableTrieBuffer(
205 ReadWriteByteArrayView(
206 contentBuffers[Ver4DictConstants::TRIE_BUFFER_INDEX],
207 contentBufferSizes[Ver4DictConstants::TRIE_BUFFER_INDEX]),
208 BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
209 mTerminalPositionLookupTable(
210 contentBuffers
211 [Ver4DictConstants::TERMINAL_ADDRESS_LOOKUP_TABLE_BUFFER_INDEX],
212 contentBufferSizes
213 [Ver4DictConstants::TERMINAL_ADDRESS_LOOKUP_TABLE_BUFFER_INDEX]),
214 mLanguageModelDictContent(
215 ReadWriteByteArrayView(
216 contentBuffers[Ver4DictConstants::LANGUAGE_MODEL_BUFFER_INDEX],
217 contentBufferSizes
218 [Ver4DictConstants::LANGUAGE_MODEL_BUFFER_INDEX]),
219 mHeaderPolicy.hasHistoricalInfoOfWords()),
220 mBigramDictContent(
221 &contentBuffers[Ver4DictConstants::BIGRAM_BUFFERS_INDEX],
222 &contentBufferSizes[Ver4DictConstants::BIGRAM_BUFFERS_INDEX],
223 mHeaderPolicy.hasHistoricalInfoOfWords()),
224 mShortcutDictContent(
225 &contentBuffers[Ver4DictConstants::SHORTCUT_BUFFERS_INDEX],
226 &contentBufferSizes[Ver4DictConstants::SHORTCUT_BUFFERS_INDEX]),
227 mIsUpdatable(mDictBuffer->isUpdatable()) {
228 }
229
230 Ver4DictBuffers::Ver4DictBuffers(const HeaderPolicy* const headerPolicy,
231 const int maxTrieSize)
232 : mHeaderBuffer(nullptr),
233 mDictBuffer(nullptr),
234 mHeaderPolicy(headerPolicy),
235 mExpandableHeaderBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
236 mExpandableTrieBuffer(maxTrieSize),
237 mTerminalPositionLookupTable(),
238 mLanguageModelDictContent(headerPolicy->hasHistoricalInfoOfWords()),
239 mBigramDictContent(headerPolicy->hasHistoricalInfoOfWords()),
240 mShortcutDictContent(),
241 mIsUpdatable(true) {
242 }
243
244 } // namespace latinime
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698