10ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi/* 20ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * Copyright (C) 2013 The Android Open Source Project 30ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * 40ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License"); 50ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * you may not use this file except in compliance with the License. 60ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * You may obtain a copy of the License at 70ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * 80ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * http://www.apache.org/licenses/LICENSE-2.0 90ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * 100ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software 110ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS, 120ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * See the License for the specific language governing permissions and 140ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi * limitations under the License. 150ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi */ 160ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi 1790619ae02b1861e644db6a0d72d0e5f9c195ef3eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/utils/format_utils.h" 180ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi 1990619ae02b1861e644db6a0d72d0e5f9c195ef3eKeisuke Kuroyanagi#include "suggest/policyimpl/dictionary/utils/byte_array_utils.h" 2099007de979e006b6b08bf381f2d394377264de85Keisuke Kuroyanagi 210ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanaginamespace latinime { 220ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi 23484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst uint32_t FormatUtils::MAGIC_NUMBER = 0x9BC13AFE; 240ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi 25484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi// Magic number (4 bytes), version (2 bytes), flags (2 bytes), header size (4 bytes) = 12 26484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst int FormatUtils::DICTIONARY_MINIMUM_SIZE = 12; 270ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi 2890619ae02b1861e644db6a0d72d0e5f9c195ef3eKeisuke Kuroyanagi/* static */ FormatUtils::FORMAT_VERSION FormatUtils::detectFormatVersion( 2990619ae02b1861e644db6a0d72d0e5f9c195ef3eKeisuke Kuroyanagi const uint8_t *const dict, const int dictSize) { 300ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi // The magic number is stored big-endian. 310ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi // If the dictionary is less than 4 bytes, we can't even read the magic number, so we don't 320ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi // understand this format. 330ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi if (dictSize < DICTIONARY_MINIMUM_SIZE) { 340ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi return UNKNOWN_VERSION; 350ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi } 360ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi const uint32_t magicNumber = ByteArrayUtils::readUint32(dict, 0); 370ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi switch (magicNumber) { 38484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi case MAGIC_NUMBER: 395ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi // Version 2 header is as follows: 405ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi // Magic number (4 bytes) 0x9B 0xC1 0x3A 0xFE 41484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi // Dictionary format version number (2 bytes) 425ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi // Options (2 bytes) 435ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi // Header size (4 bytes) : integer, big endian 445ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi if (ByteArrayUtils::readUint16(dict, 4) == 2) { 455ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi return VERSION_2; 465ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi } else if (ByteArrayUtils::readUint16(dict, 4) == 3) { 4760eb250194f05a944447e8bdee94c35a01911870Keisuke Kuroyanagi return VERSION_3; 485ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi } else { 495ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi return UNKNOWN_VERSION; 505ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi } 515ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi default: 520ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi return UNKNOWN_VERSION; 530ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi } 540ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi} 550ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi 560ecfb9424754341d7ee41557fc1f913cb6ca79c2Keisuke Kuroyanagi} // namespace latinime 57