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 #ifndef LATINIME_DYNAMIC_SHORTCUT_LIST_POLICY_H 18 #define LATINIME_DYNAMIC_SHORTCUT_LIST_POLICY_H 19 20 #include <stdint.h> 21 22 #include "defines.h" 23 #include "suggest/core/policy/dictionary_shortcuts_structure_policy.h" 24 #include "suggest/policyimpl/dictionary/shortcut/shortcut_list_reading_utils.h" 25 #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h" 26 27 namespace latinime { 28 29 /* 30 * This is a dynamic version of ShortcutListPolicy and supports an additional buffer. 31 */ 32 class DynamicShortcutListPolicy : public DictionaryShortcutsStructurePolicy { 33 public: 34 explicit DynamicShortcutListPolicy(const BufferWithExtendableBuffer *const buffer) 35 : mBuffer(buffer) {} 36 37 ~DynamicShortcutListPolicy() {} 38 39 int getStartPos(const int pos) const { 40 if (pos == NOT_A_DICT_POS) { 41 return NOT_A_DICT_POS; 42 } 43 return pos + ShortcutListReadingUtils::getShortcutListSizeFieldSize(); 44 } 45 46 void getNextShortcut(const int maxCodePointCount, int *const outCodePoint, 47 int *const outCodePointCount, bool *const outIsWhitelist, bool *const outHasNext, 48 int *const pos) const { 49 const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*pos); 50 const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer); 51 if (usesAdditionalBuffer) { 52 *pos -= mBuffer->getOriginalBufferSize(); 53 } 54 const ShortcutListReadingUtils::ShortcutFlags flags = 55 ShortcutListReadingUtils::getFlagsAndForwardPointer(buffer, pos); 56 if (outHasNext) { 57 *outHasNext = ShortcutListReadingUtils::hasNext(flags); 58 } 59 if (outIsWhitelist) { 60 *outIsWhitelist = ShortcutListReadingUtils::isWhitelist(flags); 61 } 62 if (outCodePoint) { 63 *outCodePointCount = ShortcutListReadingUtils::readShortcutTarget( 64 buffer, maxCodePointCount, outCodePoint, pos); 65 } 66 if (usesAdditionalBuffer) { 67 *pos += mBuffer->getOriginalBufferSize(); 68 } 69 } 70 71 void skipAllShortcuts(int *const pos) const { 72 const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*pos); 73 const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer); 74 if (usesAdditionalBuffer) { 75 *pos -= mBuffer->getOriginalBufferSize(); 76 } 77 const int shortcutListSize = ShortcutListReadingUtils 78 ::getShortcutListSizeAndForwardPointer(buffer, pos); 79 *pos += shortcutListSize; 80 if (usesAdditionalBuffer) { 81 *pos += mBuffer->getOriginalBufferSize(); 82 } 83 } 84 85 // Copy shortcuts from the shortcut list that starts at fromPos in mBuffer to toPos in 86 // bufferToWrite and advance these positions after the shortcut lists. This returns whether 87 // the copy was succeeded or not. 88 bool copyAllShortcutsAndReturnIfSucceededOrNot(BufferWithExtendableBuffer *const bufferToWrite, 89 int *const fromPos, int *const toPos) const { 90 const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*fromPos); 91 if (usesAdditionalBuffer) { 92 *fromPos -= mBuffer->getOriginalBufferSize(); 93 } 94 const int shortcutListSize = ShortcutListReadingUtils 95 ::getShortcutListSizeAndForwardPointer(mBuffer->getBuffer(usesAdditionalBuffer), 96 fromPos); 97 // Copy shortcut list size. 98 if (!bufferToWrite->writeUintAndAdvancePosition( 99 shortcutListSize + ShortcutListReadingUtils::getShortcutListSizeFieldSize(), 100 ShortcutListReadingUtils::getShortcutListSizeFieldSize(), toPos)) { 101 return false; 102 } 103 // Copy shortcut list. 104 for (int i = 0; i < shortcutListSize; ++i) { 105 const uint8_t data = ByteArrayUtils::readUint8AndAdvancePosition( 106 mBuffer->getBuffer(usesAdditionalBuffer), fromPos); 107 if (!bufferToWrite->writeUintAndAdvancePosition(data, 1 /* size */, toPos)) { 108 return false; 109 } 110 } 111 if (usesAdditionalBuffer) { 112 *fromPos += mBuffer->getOriginalBufferSize(); 113 } 114 return true; 115 } 116 117 private: 118 DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicShortcutListPolicy); 119 120 const BufferWithExtendableBuffer *const mBuffer; 121 }; 122 } // namespace latinime 123 #endif // LATINIME_DYNAMIC_SHORTCUT_LIST_POLICY_H 124