12f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi/* 22f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * Copyright (C) 2013 The Android Open Source Project 32f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * 42f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License"); 52f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * you may not use this file except in compliance with the License. 62f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * You may obtain a copy of the License at 72f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * 82f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * http://www.apache.org/licenses/LICENSE-2.0 92f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * 102f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software 112f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS, 122f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * See the License for the specific language governing permissions and 142f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * limitations under the License. 152f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi */ 162f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 172f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi#ifndef LATINIME_DYNAMIC_SHORTCUT_LIST_POLICY_H 182f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi#define LATINIME_DYNAMIC_SHORTCUT_LIST_POLICY_H 192f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 202f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi#include <stdint.h> 212f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 222f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi#include "defines.h" 232f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi#include "suggest/core/policy/dictionary_shortcuts_structure_policy.h" 242f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi#include "suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h" 252660f83a123b54af02a829cf941a0348194aa3c5Keisuke Kuroyanagi#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h" 262f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 272f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanaginamespace latinime { 282f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 292f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi/* 302f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi * This is a dynamic version of ShortcutListPolicy and supports an additional buffer. 312f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi */ 322f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagiclass DynamicShortcutListPolicy : public DictionaryShortcutsStructurePolicy { 332f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi public: 34b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi explicit DynamicShortcutListPolicy(const BufferWithExtendableBuffer *const buffer) 353e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi : mBuffer(buffer) {} 362f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 372f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi ~DynamicShortcutListPolicy() {} 382f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 392f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi int getStartPos(const int pos) const { 402f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi if (pos == NOT_A_DICT_POS) { 412f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi return NOT_A_DICT_POS; 422f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 432f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi return pos + ShortcutListReadingUtils::getShortcutListSizeFieldSize(); 442f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 452f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 462f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi void getNextShortcut(const int maxCodePointCount, int *const outCodePoint, 472f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi int *const outCodePointCount, bool *const outIsWhitelist, bool *const outHasNext, 482f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi int *const pos) const { 493e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*pos); 503e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer); 512f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi if (usesAdditionalBuffer) { 523e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi *pos -= mBuffer->getOriginalBufferSize(); 532f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 542f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi const ShortcutListReadingUtils::ShortcutFlags flags = 552f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi ShortcutListReadingUtils::getFlagsAndForwardPointer(buffer, pos); 562f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi if (outHasNext) { 572f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi *outHasNext = ShortcutListReadingUtils::hasNext(flags); 582f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 592f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi if (outIsWhitelist) { 602f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi *outIsWhitelist = ShortcutListReadingUtils::isWhitelist(flags); 612f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 622f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi if (outCodePoint) { 632f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi *outCodePointCount = ShortcutListReadingUtils::readShortcutTarget( 642f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi buffer, maxCodePointCount, outCodePoint, pos); 652f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 662f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi if (usesAdditionalBuffer) { 673e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi *pos += mBuffer->getOriginalBufferSize(); 682f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 692f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 702f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 712f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi void skipAllShortcuts(int *const pos) const { 723e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*pos); 733e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer); 743e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi if (usesAdditionalBuffer) { 753e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi *pos -= mBuffer->getOriginalBufferSize(); 763e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi } 773e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi const int shortcutListSize = ShortcutListReadingUtils 783e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi ::getShortcutListSizeAndForwardPointer(buffer, pos); 793e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi *pos += shortcutListSize; 803e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi if (usesAdditionalBuffer) { 813e76487c6c95ccec49622b9d7e0b45efff97f937Keisuke Kuroyanagi *pos += mBuffer->getOriginalBufferSize(); 822f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 832f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi } 842f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 85b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi // Copy shortcuts from the shortcut list that starts at fromPos in mBuffer to toPos in 86b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi // bufferToWrite and advance these positions after the shortcut lists. This returns whether 87b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi // the copy was succeeded or not. 88b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi bool copyAllShortcutsAndReturnIfSucceededOrNot(BufferWithExtendableBuffer *const bufferToWrite, 89b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi int *const fromPos, int *const toPos) const { 909e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*fromPos); 919e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi if (usesAdditionalBuffer) { 929e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi *fromPos -= mBuffer->getOriginalBufferSize(); 939e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi } 949e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi const int shortcutListSize = ShortcutListReadingUtils 95b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi ::getShortcutListSizeAndForwardPointer(mBuffer->getBuffer(usesAdditionalBuffer), 96b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi fromPos); 979e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi // Copy shortcut list size. 98b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi if (!bufferToWrite->writeUintAndAdvancePosition( 999e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi shortcutListSize + ShortcutListReadingUtils::getShortcutListSizeFieldSize(), 100c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi ShortcutListReadingUtils::getShortcutListSizeFieldSize(), toPos)) { 101c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi return false; 102c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi } 103c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi // Copy shortcut list. 1049e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi for (int i = 0; i < shortcutListSize; ++i) { 105c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi const uint8_t data = ByteArrayUtils::readUint8AndAdvancePosition( 106c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi mBuffer->getBuffer(usesAdditionalBuffer), fromPos); 107b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi if (!bufferToWrite->writeUintAndAdvancePosition(data, 1 /* size */, toPos)) { 108c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi return false; 109c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi } 1109e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi } 1119e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi if (usesAdditionalBuffer) { 1129e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi *fromPos += mBuffer->getOriginalBufferSize(); 1139e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi } 114c987120cbcb94f8ab2d4994d548af0dbbb04a4d5Keisuke Kuroyanagi return true; 1159e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi } 1169e3082e0168ff40ec532d5fef162d93426b550a1Keisuke Kuroyanagi 1172f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi private: 1182f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicShortcutListPolicy); 1192f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi 120b7e8a9abf585181345b32631e4c02747ee60a1a0Keisuke Kuroyanagi const BufferWithExtendableBuffer *const mBuffer; 1212f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi}; 1222f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi} // namespace latinime 1232f0c1253e288d0670416bf8fc45b77962e68e250Keisuke Kuroyanagi#endif // LATINIME_DYNAMIC_SHORTCUT_LIST_POLICY_H 124