OLD | NEW |
(Empty) | |
| 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 "third_party/prediction/suggest/policyimpl/dictionary/header/header_rea
d_write_utils.h" |
| 18 |
| 19 #include <cctype> |
| 20 #include <cstdio> |
| 21 #include <vector> |
| 22 |
| 23 #include "third_party/prediction/defines.h" |
| 24 #include "third_party/prediction/suggest/policyimpl/dictionary/utils/buffer_with
_extendable_buffer.h" |
| 25 #include "third_party/prediction/suggest/policyimpl/dictionary/utils/byte_array_
utils.h" |
| 26 |
| 27 namespace latinime { |
| 28 |
| 29 // Number of base-10 digits in the largest integer + 1 to leave room for a zero |
| 30 // terminator. |
| 31 // As such, this is the maximum number of characters will be needed to represent |
| 32 // an int as a |
| 33 // string, including the terminator; this is used as the size of a string buffer |
| 34 // large enough to |
| 35 // hold any value that is intended to fit in an integer, e.g. in the code that |
| 36 // reads the header |
| 37 // of the binary dictionary where a {key,value} string pair scheme is used. |
| 38 const int HeaderReadWriteUtils::LARGEST_INT_DIGIT_COUNT = 11; |
| 39 |
| 40 const int HeaderReadWriteUtils::MAX_ATTRIBUTE_KEY_LENGTH = 256; |
| 41 const int HeaderReadWriteUtils::MAX_ATTRIBUTE_VALUE_LENGTH = 256; |
| 42 |
| 43 const int HeaderReadWriteUtils::HEADER_MAGIC_NUMBER_SIZE = 4; |
| 44 const int HeaderReadWriteUtils::HEADER_DICTIONARY_VERSION_SIZE = 2; |
| 45 const int HeaderReadWriteUtils::HEADER_FLAG_SIZE = 2; |
| 46 const int HeaderReadWriteUtils::HEADER_SIZE_FIELD_SIZE = 4; |
| 47 |
| 48 const HeaderReadWriteUtils::DictionaryFlags HeaderReadWriteUtils::NO_FLAGS = 0; |
| 49 |
| 50 typedef DictionaryHeaderStructurePolicy::AttributeMap AttributeMap; |
| 51 |
| 52 /* static */ int HeaderReadWriteUtils::getHeaderSize( |
| 53 const uint8_t* const dictBuf) { |
| 54 // See the format of the header in the comment in |
| 55 // BinaryDictionaryFormatUtils::detectFormatVersion() |
| 56 return ByteArrayUtils::readUint32( |
| 57 dictBuf, HEADER_MAGIC_NUMBER_SIZE + HEADER_DICTIONARY_VERSION_SIZE + |
| 58 HEADER_FLAG_SIZE); |
| 59 } |
| 60 |
| 61 /* static */ HeaderReadWriteUtils::DictionaryFlags |
| 62 HeaderReadWriteUtils::getFlags(const uint8_t* const dictBuf) { |
| 63 return ByteArrayUtils::readUint16( |
| 64 dictBuf, HEADER_MAGIC_NUMBER_SIZE + HEADER_DICTIONARY_VERSION_SIZE); |
| 65 } |
| 66 |
| 67 /* static */ HeaderReadWriteUtils::DictionaryFlags |
| 68 HeaderReadWriteUtils::createAndGetDictionaryFlagsUsingAttributeMap( |
| 69 const AttributeMap* const attributeMap) { |
| 70 return NO_FLAGS; |
| 71 } |
| 72 |
| 73 /* static */ void HeaderReadWriteUtils::fetchAllHeaderAttributes( |
| 74 const uint8_t* const dictBuf, |
| 75 AttributeMap* const headerAttributes) { |
| 76 const int headerSize = getHeaderSize(dictBuf); |
| 77 int pos = getHeaderOptionsPosition(); |
| 78 if (pos == NOT_A_DICT_POS) { |
| 79 // The header doesn't have header options. |
| 80 return; |
| 81 } |
| 82 int keyBuffer[MAX_ATTRIBUTE_KEY_LENGTH]; |
| 83 int valueBuffer[MAX_ATTRIBUTE_VALUE_LENGTH]; |
| 84 while (pos < headerSize) { |
| 85 const int keyLength = ByteArrayUtils::readStringAndAdvancePosition( |
| 86 dictBuf, MAX_ATTRIBUTE_KEY_LENGTH, keyBuffer, &pos); |
| 87 std::vector<int> key; |
| 88 key.insert(key.end(), keyBuffer, keyBuffer + keyLength); |
| 89 const int valueLength = ByteArrayUtils::readStringAndAdvancePosition( |
| 90 dictBuf, MAX_ATTRIBUTE_VALUE_LENGTH, valueBuffer, &pos); |
| 91 std::vector<int> value; |
| 92 value.insert(value.end(), valueBuffer, valueBuffer + valueLength); |
| 93 headerAttributes->insert(AttributeMap::value_type(key, value)); |
| 94 } |
| 95 } |
| 96 |
| 97 /* static */ bool HeaderReadWriteUtils::writeDictionaryVersion( |
| 98 BufferWithExtendableBuffer* const buffer, |
| 99 const FormatUtils::FORMAT_VERSION version, |
| 100 int* const writingPos) { |
| 101 if (!buffer->writeUintAndAdvancePosition( |
| 102 FormatUtils::MAGIC_NUMBER, HEADER_MAGIC_NUMBER_SIZE, writingPos)) { |
| 103 return false; |
| 104 } |
| 105 switch (version) { |
| 106 case FormatUtils::VERSION_2: |
| 107 // Version 2 dictionary writing is not supported. |
| 108 return false; |
| 109 case FormatUtils::VERSION_4_ONLY_FOR_TESTING: |
| 110 case FormatUtils::VERSION_4: |
| 111 case FormatUtils::VERSION_4_DEV: |
| 112 return buffer->writeUintAndAdvancePosition( |
| 113 version /* data */, HEADER_DICTIONARY_VERSION_SIZE, writingPos); |
| 114 default: |
| 115 return false; |
| 116 } |
| 117 } |
| 118 |
| 119 /* static */ bool HeaderReadWriteUtils::writeDictionaryFlags( |
| 120 BufferWithExtendableBuffer* const buffer, |
| 121 const DictionaryFlags flags, |
| 122 int* const writingPos) { |
| 123 return buffer->writeUintAndAdvancePosition(flags, HEADER_FLAG_SIZE, |
| 124 writingPos); |
| 125 } |
| 126 |
| 127 /* static */ bool HeaderReadWriteUtils::writeDictionaryHeaderSize( |
| 128 BufferWithExtendableBuffer* const buffer, |
| 129 const int size, |
| 130 int* const writingPos) { |
| 131 return buffer->writeUintAndAdvancePosition(size, HEADER_SIZE_FIELD_SIZE, |
| 132 writingPos); |
| 133 } |
| 134 |
| 135 /* static */ bool HeaderReadWriteUtils::writeHeaderAttributes( |
| 136 BufferWithExtendableBuffer* const buffer, |
| 137 const AttributeMap* const headerAttributes, |
| 138 int* const writingPos) { |
| 139 for (AttributeMap::const_iterator it = headerAttributes->begin(); |
| 140 it != headerAttributes->end(); ++it) { |
| 141 if (it->first.empty() || it->second.empty()) { |
| 142 continue; |
| 143 } |
| 144 // Write a key. |
| 145 if (!buffer->writeCodePointsAndAdvancePosition( |
| 146 &(it->first.at(0)), it->first.size(), true /* writesTerminator */, |
| 147 writingPos)) { |
| 148 return false; |
| 149 } |
| 150 // Write a value. |
| 151 if (!buffer->writeCodePointsAndAdvancePosition( |
| 152 &(it->second.at(0)), it->second.size(), true /* writesTerminator */, |
| 153 writingPos)) { |
| 154 return false; |
| 155 } |
| 156 } |
| 157 return true; |
| 158 } |
| 159 |
| 160 /* static */ void HeaderReadWriteUtils::setCodePointVectorAttribute( |
| 161 AttributeMap* const headerAttributes, |
| 162 const char* const key, |
| 163 const std::vector<int> value) { |
| 164 AttributeMap::key_type keyVector; |
| 165 insertCharactersIntoVector(key, &keyVector); |
| 166 (*headerAttributes)[keyVector] = value; |
| 167 } |
| 168 |
| 169 /* static */ void HeaderReadWriteUtils::setBoolAttribute( |
| 170 AttributeMap* const headerAttributes, |
| 171 const char* const key, |
| 172 const bool value) { |
| 173 setIntAttribute(headerAttributes, key, value ? 1 : 0); |
| 174 } |
| 175 |
| 176 /* static */ void HeaderReadWriteUtils::setIntAttribute( |
| 177 AttributeMap* const headerAttributes, |
| 178 const char* const key, |
| 179 const int value) { |
| 180 AttributeMap::key_type keyVector; |
| 181 insertCharactersIntoVector(key, &keyVector); |
| 182 setIntAttributeInner(headerAttributes, &keyVector, value); |
| 183 } |
| 184 |
| 185 /* static */ void HeaderReadWriteUtils::setIntAttributeInner( |
| 186 AttributeMap* const headerAttributes, |
| 187 const AttributeMap::key_type* const key, |
| 188 const int value) { |
| 189 AttributeMap::mapped_type valueVector; |
| 190 char charBuf[LARGEST_INT_DIGIT_COUNT]; |
| 191 snprintf(charBuf, sizeof(charBuf), "%d", value); |
| 192 insertCharactersIntoVector(charBuf, &valueVector); |
| 193 (*headerAttributes)[*key] = valueVector; |
| 194 } |
| 195 |
| 196 /* static */ const std::vector<int> |
| 197 HeaderReadWriteUtils::readCodePointVectorAttributeValue( |
| 198 const AttributeMap* const headerAttributes, |
| 199 const char* const key) { |
| 200 AttributeMap::key_type keyVector; |
| 201 insertCharactersIntoVector(key, &keyVector); |
| 202 AttributeMap::const_iterator it = headerAttributes->find(keyVector); |
| 203 if (it == headerAttributes->end()) { |
| 204 return std::vector<int>(); |
| 205 } else { |
| 206 return it->second; |
| 207 } |
| 208 } |
| 209 |
| 210 /* static */ bool HeaderReadWriteUtils::readBoolAttributeValue( |
| 211 const AttributeMap* const headerAttributes, |
| 212 const char* const key, |
| 213 const bool defaultValue) { |
| 214 const int intDefaultValue = defaultValue ? 1 : 0; |
| 215 const int intValue = |
| 216 readIntAttributeValue(headerAttributes, key, intDefaultValue); |
| 217 return intValue != 0; |
| 218 } |
| 219 |
| 220 /* static */ int HeaderReadWriteUtils::readIntAttributeValue( |
| 221 const AttributeMap* const headerAttributes, |
| 222 const char* const key, |
| 223 const int defaultValue) { |
| 224 AttributeMap::key_type keyVector; |
| 225 insertCharactersIntoVector(key, &keyVector); |
| 226 return readIntAttributeValueInner(headerAttributes, &keyVector, defaultValue); |
| 227 } |
| 228 |
| 229 /* static */ int HeaderReadWriteUtils::readIntAttributeValueInner( |
| 230 const AttributeMap* const headerAttributes, |
| 231 const AttributeMap::key_type* const key, |
| 232 const int defaultValue) { |
| 233 AttributeMap::const_iterator it = headerAttributes->find(*key); |
| 234 if (it != headerAttributes->end()) { |
| 235 int value = 0; |
| 236 bool isNegative = false; |
| 237 for (size_t i = 0; i < it->second.size(); ++i) { |
| 238 if (i == 0 && it->second.at(i) == '-') { |
| 239 isNegative = true; |
| 240 } else { |
| 241 if (!isdigit(it->second.at(i))) { |
| 242 // If not a number. |
| 243 return defaultValue; |
| 244 } |
| 245 value *= 10; |
| 246 value += it->second.at(i) - '0'; |
| 247 } |
| 248 } |
| 249 return isNegative ? -value : value; |
| 250 } |
| 251 return defaultValue; |
| 252 } |
| 253 |
| 254 /* static */ void HeaderReadWriteUtils::insertCharactersIntoVector( |
| 255 const char* const characters, |
| 256 std::vector<int>* const vector) { |
| 257 for (int i = 0; characters[i]; ++i) { |
| 258 vector->push_back(characters[i]); |
| 259 } |
| 260 } |
| 261 |
| 262 } // namespace latinime |
OLD | NEW |