1/* 2 * Copyright (C) 2014, 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 "dictionary/structure/v4/ver4_pt_node_array_reader.h" 18 19#include "dictionary/structure/pt_common/dynamic_pt_reading_utils.h" 20#include "dictionary/structure/pt_common/patricia_trie_reading_utils.h" 21#include "dictionary/utils/buffer_with_extendable_buffer.h" 22 23namespace latinime { 24 25bool Ver4PtNodeArrayReader::readPtNodeArrayInfoAndReturnIfValid(const int ptNodeArrayPos, 26 int *const outPtNodeCount, int *const outFirstPtNodePos) const { 27 if (ptNodeArrayPos < 0 || ptNodeArrayPos >= mBuffer->getTailPosition()) { 28 // Reading invalid position because of a bug or a broken dictionary. 29 AKLOGE("Reading PtNode array info from invalid dictionary position: %d, dict size: %d", 30 ptNodeArrayPos, mBuffer->getTailPosition()); 31 ASSERT(false); 32 return false; 33 } 34 const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(ptNodeArrayPos); 35 const uint8_t *const dictBuf = mBuffer->getBuffer(usesAdditionalBuffer); 36 int readingPos = ptNodeArrayPos; 37 if (usesAdditionalBuffer) { 38 readingPos -= mBuffer->getOriginalBufferSize(); 39 } 40 const int ptNodeCountInArray = PatriciaTrieReadingUtils::getPtNodeArraySizeAndAdvancePosition( 41 dictBuf, &readingPos); 42 if (usesAdditionalBuffer) { 43 readingPos += mBuffer->getOriginalBufferSize(); 44 } 45 if (ptNodeCountInArray < 0) { 46 AKLOGE("Invalid PtNode count in an array: %d.", ptNodeCountInArray); 47 return false; 48 } 49 *outPtNodeCount = ptNodeCountInArray; 50 *outFirstPtNodePos = readingPos; 51 return true; 52} 53 54bool Ver4PtNodeArrayReader::readForwardLinkAndReturnIfValid(const int forwordLinkPos, 55 int *const outNextPtNodeArrayPos) const { 56 if (forwordLinkPos < 0 || forwordLinkPos >= mBuffer->getTailPosition()) { 57 // Reading invalid position because of bug or broken dictionary. 58 AKLOGE("Reading forward link from invalid dictionary position: %d, dict size: %d", 59 forwordLinkPos, mBuffer->getTailPosition()); 60 ASSERT(false); 61 return false; 62 } 63 const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(forwordLinkPos); 64 const uint8_t *const dictBuf = mBuffer->getBuffer(usesAdditionalBuffer); 65 int readingPos = forwordLinkPos; 66 if (usesAdditionalBuffer) { 67 readingPos -= mBuffer->getOriginalBufferSize(); 68 } 69 const int nextPtNodeArrayOffset = 70 DynamicPtReadingUtils::getForwardLinkPosition(dictBuf, readingPos); 71 if (DynamicPtReadingUtils::isValidForwardLinkPosition(nextPtNodeArrayOffset)) { 72 *outNextPtNodeArrayPos = forwordLinkPos + nextPtNodeArrayOffset; 73 } else { 74 *outNextPtNodeArrayPos = NOT_A_DICT_POS; 75 } 76 return true; 77} 78 79} // namespace latinime 80