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 "dictionary/utils/format_utils.h" 18 19 #include "dictionary/utils/byte_array_utils.h" 20 21 namespace latinime { 22 23 const uint32_t FormatUtils::MAGIC_NUMBER = 0x9BC13AFE; 24 25 // Magic number (4 bytes), version (2 bytes), flags (2 bytes), header size (4 bytes) = 12 26 const size_t FormatUtils::DICTIONARY_MINIMUM_SIZE = 12; 27 28 /* static */ FormatUtils::FORMAT_VERSION FormatUtils::getFormatVersion(const int formatVersion) { 29 switch (formatVersion) { 30 case VERSION_2: 31 case VERSION_201: 32 AKLOGE("Dictionary versions 2 and 201 are incompatible with this version"); 33 return UNKNOWN_VERSION; 34 case VERSION_202: 35 return VERSION_202; 36 case VERSION_4_ONLY_FOR_TESTING: 37 return VERSION_4_ONLY_FOR_TESTING; 38 case VERSION_402: 39 return VERSION_402; 40 case VERSION_403: 41 return VERSION_403; 42 default: 43 return UNKNOWN_VERSION; 44 } 45 } 46 /* static */ FormatUtils::FORMAT_VERSION FormatUtils::detectFormatVersion( 47 const ReadOnlyByteArrayView dictBuffer) { 48 // The magic number is stored big-endian. 49 // If the dictionary is less than 4 bytes, we can't even read the magic number, so we don't 50 // understand this format. 51 if (dictBuffer.size() < DICTIONARY_MINIMUM_SIZE) { 52 return UNKNOWN_VERSION; 53 } 54 const uint32_t magicNumber = ByteArrayUtils::readUint32(dictBuffer.data(), 0); 55 switch (magicNumber) { 56 case MAGIC_NUMBER: 57 // The layout of the header is as follows: 58 // Magic number (4 bytes) 0x9B 0xC1 0x3A 0xFE 59 // Dictionary format version number (2 bytes) 60 // Options (2 bytes) 61 // Header size (4 bytes) : integer, big endian 62 // Conceptually this converts the hardcoded value of the bytes in the file into 63 // the symbolic value we use in the code. But we want the constants to be the 64 // same so we use them for both here. 65 return getFormatVersion(ByteArrayUtils::readUint16(dictBuffer.data(), 4)); 66 default: 67 return UNKNOWN_VERSION; 68 } 69 } 70 71 } // namespace latinime 72