bigram_list_read_write_utils.cpp revision 3225b6fe66a84ed7f499daf84d085141a66bb346
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 "suggest/policyimpl/dictionary/structure/pt_common/bigram/bigram_list_read_write_utils.h"
18
19#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h"
20#include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h"
21
22namespace latinime {
23
24const BigramListReadWriteUtils::BigramFlags BigramListReadWriteUtils::MASK_ATTRIBUTE_ADDRESS_TYPE =
25        0x30;
26const BigramListReadWriteUtils::BigramFlags
27        BigramListReadWriteUtils::FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE = 0x10;
28const BigramListReadWriteUtils::BigramFlags
29        BigramListReadWriteUtils::FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES = 0x20;
30const BigramListReadWriteUtils::BigramFlags
31        BigramListReadWriteUtils::FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES = 0x30;
32const BigramListReadWriteUtils::BigramFlags
33        BigramListReadWriteUtils::FLAG_ATTRIBUTE_OFFSET_NEGATIVE = 0x40;
34// Flag for presence of more attributes
35const BigramListReadWriteUtils::BigramFlags BigramListReadWriteUtils::FLAG_ATTRIBUTE_HAS_NEXT =
36        0x80;
37// Mask for attribute probability, stored on 4 bits inside the flags byte.
38const BigramListReadWriteUtils::BigramFlags
39        BigramListReadWriteUtils::MASK_ATTRIBUTE_PROBABILITY = 0x0F;
40
41/* static */ bool BigramListReadWriteUtils::getBigramEntryPropertiesAndAdvancePosition(
42        const uint8_t *const bigramsBuf, const int bufSize, BigramFlags *const outBigramFlags,
43        int *const outTargetPtNodePos, int *const bigramEntryPos) {
44    if (bufSize <= *bigramEntryPos) {
45        AKLOGE("Read invalid pos in getBigramEntryPropertiesAndAdvancePosition(). bufSize: %d, "
46                "bigramEntryPos: %d.", bufSize, *bigramEntryPos);
47        return false;
48    }
49    const BigramFlags bigramFlags = ByteArrayUtils::readUint8AndAdvancePosition(bigramsBuf,
50            bigramEntryPos);
51    if (outBigramFlags) {
52        *outBigramFlags = bigramFlags;
53    }
54    const int targetPos = getBigramAddressAndAdvancePosition(bigramsBuf, bigramFlags,
55            bigramEntryPos);
56    if (outTargetPtNodePos) {
57        *outTargetPtNodePos = targetPos;
58    }
59    return true;
60}
61
62/* static */ bool BigramListReadWriteUtils::skipExistingBigrams(const uint8_t *const bigramsBuf,
63        const int bufSize, int *const bigramListPos) {
64    BigramFlags flags;
65    do {
66        if (!getBigramEntryPropertiesAndAdvancePosition(bigramsBuf, bufSize, &flags,
67                0 /* outTargetPtNodePos */, bigramListPos)) {
68            return false;
69        }
70    } while(hasNext(flags));
71    return true;
72}
73
74/* static */ int BigramListReadWriteUtils::getBigramAddressAndAdvancePosition(
75        const uint8_t *const bigramsBuf, const BigramFlags flags, int *const pos) {
76    int offset = 0;
77    const int origin = *pos;
78    switch (MASK_ATTRIBUTE_ADDRESS_TYPE & flags) {
79        case FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE:
80            offset = ByteArrayUtils::readUint8AndAdvancePosition(bigramsBuf, pos);
81            break;
82        case FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES:
83            offset = ByteArrayUtils::readUint16AndAdvancePosition(bigramsBuf, pos);
84            break;
85        case FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES:
86            offset = ByteArrayUtils::readUint24AndAdvancePosition(bigramsBuf, pos);
87            break;
88    }
89    if (isOffsetNegative(flags)) {
90        return origin - offset;
91    } else {
92        return origin + offset;
93    }
94}
95
96} // namespace latinime
97