12fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/*
22fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Copyright (C) 2013 The Android Open Source Project
32fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *
42fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Licensed under the Apache License, Version 2.0 (the "License");
52fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * you may not use this file except in compliance with the License.
62fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * You may obtain a copy of the License at
72fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *
82fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *      http://www.apache.org/licenses/LICENSE-2.0
92fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa *
102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * Unless required by applicable law or agreed to in writing, software
112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * distributed under the License is distributed on an "AS IS" BASIS,
122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * See the License for the specific language governing permissions and
142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * limitations under the License.
152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa */
162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/dictionary_structure_with_buffer_policy_factory.h"
182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include <climits>
202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa#include "defines.h"
2288bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/backward/v402/ver4_dict_buffers.h"
2388bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/backward/v402/ver4_dict_constants.h"
2488bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/backward/v402/ver4_patricia_trie_policy.h"
2588bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/pt_common/dynamic_pt_writing_utils.h"
2688bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v2/patricia_trie_policy.h"
2788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/ver4_dict_buffers.h"
2888bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/ver4_dict_constants.h"
2988bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/structure/v4/ver4_patricia_trie_policy.h"
3088bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/dict_file_writing_utils.h"
3188bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/file_utils.h"
3288bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/format_utils.h"
3388bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/mmapped_buffer.h"
34c0c674cdc0721a374e140ad5ee1409c0498b3262Keisuke Kuroyanagi#include "utils/byte_array_view.h"
352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasanamespace latinime {
372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr
39903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        DictionaryStructureWithBufferPolicyFactory::newPolicyForExistingDictFile(
40903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi                const char *const path, const int bufOffset, const int size,
41903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi                const bool isUpdatable) {
422fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    if (FileUtils::existsDir(path)) {
432fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // Given path represents a directory.
44903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        return newPolicyForDirectoryDict(path, isUpdatable);
452fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    } else {
462fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        if (isUpdatable) {
472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            AKLOGE("One file dictionaries don't support updating. path: %s", path);
482fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            ASSERT(false);
497116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            return nullptr;
502fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
51903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        return newPolicyForFileDict(path, bufOffset, size);
522fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
542fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr
56903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        DictionaryStructureWithBufferPolicyFactory:: newPolicyForOnMemoryDict(
57903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi                const int formatVersion, const std::vector<int> &locale,
58903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi                const DictionaryHeaderStructurePolicy::AttributeMap *const attributeMap) {
59455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi    FormatUtils::FORMAT_VERSION dictFormatVersion = FormatUtils::getFormatVersion(formatVersion);
60455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi    switch (dictFormatVersion) {
61ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi        case FormatUtils::VERSION_402: {
6207e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi            return newPolicyForOnMemoryV4Dict<backward::v402::Ver4DictConstants,
6307e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi                    backward::v402::Ver4DictBuffers,
6407e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi                    backward::v402::Ver4DictBuffers::Ver4DictBuffersPtr,
6507e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi                    backward::v402::Ver4PatriciaTriePolicy>(
667116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                            dictFormatVersion, locale, attributeMap);
677116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        }
687116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
69ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi        case FormatUtils::VERSION_403: {
707116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            return newPolicyForOnMemoryV4Dict<Ver4DictConstants, Ver4DictBuffers,
717116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                    Ver4DictBuffers::Ver4DictBuffersPtr, Ver4PatriciaTriePolicy>(
727116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                            dictFormatVersion, locale, attributeMap);
73903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        }
74903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        default:
75903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi            AKLOGE("DICT: dictionary format %d is not supported for on memory dictionary",
76903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi                    formatVersion);
77903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi            break;
78903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi    }
797116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    return nullptr;
807116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi}
817116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi
827116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagitemplate<class DictConstants, class DictBuffers, class DictBuffersPtr, class StructurePolicy>
837116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr
847116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        DictionaryStructureWithBufferPolicyFactory::newPolicyForOnMemoryV4Dict(
857116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                const FormatUtils::FORMAT_VERSION formatVersion,
867116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                const std::vector<int> &locale,
877116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                const DictionaryHeaderStructurePolicy::AttributeMap *const attributeMap) {
887116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    HeaderPolicy headerPolicy(formatVersion, locale, attributeMap);
897116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    DictBuffersPtr dictBuffers = DictBuffers::createVer4DictBuffers(&headerPolicy,
907116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            DictConstants::MAX_DICT_EXTENDED_REGION_SIZE);
917116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    if (!DynamicPtWritingUtils::writeEmptyDictionary(
927116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            dictBuffers->getWritableTrieBuffer(), 0 /* rootPos */)) {
937116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        AKLOGE("Empty ver4 dictionary structure cannot be created on memory.");
947116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        return nullptr;
957116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    }
967116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(
977116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            new StructurePolicy(std::move(dictBuffers)));
98903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi}
99903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi
100903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr
101903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        DictionaryStructureWithBufferPolicyFactory::newPolicyForDirectoryDict(
1022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                const char *const path, const bool isUpdatable) {
1032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int headerFilePathBufSize = PATH_MAX + 1 /* terminator */;
1042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    char headerFilePath[headerFilePathBufSize];
1052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    getHeaderFilePathInDictDir(path, headerFilePathBufSize, headerFilePath);
1062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of
1072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // MmappedBufferPtr if the instance has the responsibility.
1087116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    MmappedBuffer::MmappedBufferPtr mmappedBuffer =
1097116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            MmappedBuffer::openBuffer(headerFilePath, isUpdatable);
1104ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi    if (!mmappedBuffer) {
1117116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        return nullptr;
1122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
113455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi    const FormatUtils::FORMAT_VERSION formatVersion = FormatUtils::detectFormatVersion(
1144fbb2148ee149ef647f3f43c615911455228f3afKeisuke Kuroyanagi            mmappedBuffer->getReadOnlyByteArrayView());
115455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi    switch (formatVersion) {
1162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        case FormatUtils::VERSION_2:
117fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto        case FormatUtils::VERSION_201:
1187c87859d4c16c9cf19b095b865d7000ebc3cdaa9Adrian Velicu        case FormatUtils::VERSION_202:
1197c87859d4c16c9cf19b095b865d7000ebc3cdaa9Adrian Velicu            AKLOGE("Given path is a directory but the format is version 2xx. path: %s", path);
1202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            break;
121ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi        case FormatUtils::VERSION_402: {
12207e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi            return newPolicyForV4Dict<backward::v402::Ver4DictConstants,
12307e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi                    backward::v402::Ver4DictBuffers,
12407e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi                    backward::v402::Ver4DictBuffers::Ver4DictBuffersPtr,
12507e14126318f7661f76fdce421d723d64e7ea8deKeisuke Kuroyanagi                    backward::v402::Ver4PatriciaTriePolicy>(
1267116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                            headerFilePath, formatVersion, std::move(mmappedBuffer));
1277116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        }
1287116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
129ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi        case FormatUtils::VERSION_403: {
1307116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            return newPolicyForV4Dict<Ver4DictConstants, Ver4DictBuffers,
1317116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                    Ver4DictBuffers::Ver4DictBuffersPtr, Ver4PatriciaTriePolicy>(
1327116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                            headerFilePath, formatVersion, std::move(mmappedBuffer));
1332fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        }
1342fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        default:
1352fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            AKLOGE("DICT: dictionary format is unknown, bad magic number. path: %s", path);
1362fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            break;
1372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    ASSERT(false);
1397116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    return nullptr;
1407116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi}
1417116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi
1427116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagitemplate<class DictConstants, class DictBuffers, class DictBuffersPtr, class StructurePolicy>
1437116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr
1447116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        DictionaryStructureWithBufferPolicyFactory::newPolicyForV4Dict(
1457116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                const char *const headerFilePath, const FormatUtils::FORMAT_VERSION formatVersion,
1467116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi                MmappedBuffer::MmappedBufferPtr &&mmappedBuffer) {
1477116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    const int dictDirPathBufSize = strlen(headerFilePath) + 1 /* terminator */;
1487116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    char dictPath[dictDirPathBufSize];
1497116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    if (!FileUtils::getFilePathWithoutSuffix(headerFilePath,
1507116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            DictConstants::HEADER_FILE_EXTENSION, dictDirPathBufSize, dictPath)) {
1519f8c9a0161924f515c5ff9617db2317cdc1d01e2Keisuke Kuroyanagi        AKLOGE("Dictionary file name is not valid as a ver4 dictionary. header path: %s",
1529f8c9a0161924f515c5ff9617db2317cdc1d01e2Keisuke Kuroyanagi                headerFilePath);
1537116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        ASSERT(false);
1547116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        return nullptr;
1557116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    }
1567116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    DictBuffersPtr dictBuffers =
1577116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            DictBuffers::openVer4DictBuffers(dictPath, std::move(mmappedBuffer), formatVersion);
1587116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    if (!dictBuffers || !dictBuffers->isValid()) {
1597116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        AKLOGE("DICT: The dictionary doesn't satisfy ver4 format requirements. path: %s",
1609f8c9a0161924f515c5ff9617db2317cdc1d01e2Keisuke Kuroyanagi                dictPath);
1617116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        ASSERT(false);
1627116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        return nullptr;
1637116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    }
1647116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(
1657116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi            new StructurePolicy(std::move(dictBuffers)));
1662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1672fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1682fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr
169903be5bbd33b664c7e691d8bee0dd4d6376947bcKeisuke Kuroyanagi        DictionaryStructureWithBufferPolicyFactory::newPolicyForFileDict(
1702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa                const char *const path, const int bufOffset, const int size) {
1712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of
1722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    // MmappedBufferPtr if the instance has the responsibility.
1734ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi    MmappedBuffer::MmappedBufferPtr mmappedBuffer(
1744ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi            MmappedBuffer::openBuffer(path, bufOffset, size, false /* isUpdatable */));
1754ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi    if (!mmappedBuffer) {
1767116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi        return nullptr;
1772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1784fbb2148ee149ef647f3f43c615911455228f3afKeisuke Kuroyanagi    switch (FormatUtils::detectFormatVersion(mmappedBuffer->getReadOnlyByteArrayView())) {
1792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        case FormatUtils::VERSION_2:
180fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto        case FormatUtils::VERSION_201:
1817c87859d4c16c9cf19b095b865d7000ebc3cdaa9Adrian Velicu            AKLOGE("Dictionary versions 2 and 201 are incompatible with this version");
1827c87859d4c16c9cf19b095b865d7000ebc3cdaa9Adrian Velicu            break;
1837c87859d4c16c9cf19b095b865d7000ebc3cdaa9Adrian Velicu        case FormatUtils::VERSION_202:
1842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(
1854ce480d5ce2d47f607448ce439aaf2cefba1bdd8Keisuke Kuroyanagi                    new PatriciaTriePolicy(std::move(mmappedBuffer)));
186455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi        case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
187ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi        case FormatUtils::VERSION_402:
188ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi        case FormatUtils::VERSION_403:
1892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            AKLOGE("Given path is a file but the format is version 4. path: %s", path);
1902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            break;
1912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        default:
1922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            AKLOGE("DICT: dictionary format is unknown, bad magic number. path: %s", path);
1932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            break;
1942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    }
1952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    ASSERT(false);
1967116ea98f4002b79b517a695e37e01a78c84e97eKeisuke Kuroyanagi    return nullptr;
1972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
1982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
1992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa/* static */ void DictionaryStructureWithBufferPolicyFactory::getHeaderFilePathInDictDir(
2002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        const char *const dictDirPath, const int outHeaderFileBufSize,
2012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        char *const outHeaderFilePath) {
2022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    const int dictNameBufSize = strlen(dictDirPath) + 1 /* terminator */;
2032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    char dictName[dictNameBufSize];
2042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    FileUtils::getBasename(dictDirPath, dictNameBufSize, dictName);
2052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa    snprintf(outHeaderFilePath, outHeaderFileBufSize, "%s/%s%s", dictDirPath,
2062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa            dictName, Ver4DictConstants::HEADER_FILE_EXTENSION);
2072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa}
2082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa
2092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa} // namespace latinime
210