1bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi/* 2bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * Copyright (C) 2013, The Android Open Source Project 3bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * 4bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * Licensed under the Apache License, Version 2.0 (the "License"); 5bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * you may not use this file except in compliance with the License. 6bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * You may obtain a copy of the License at 7bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * 8bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * http://www.apache.org/licenses/LICENSE-2.0 9bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * 10bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * Unless required by applicable law or agreed to in writing, software 11bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * distributed under the License is distributed on an "AS IS" BASIS, 12bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * See the License for the specific language governing permissions and 14bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi * limitations under the License. 15bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi */ 16bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 1788bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/header/header_read_write_utils.h" 18bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 19989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi#include <cctype> 20989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi#include <cstdio> 21fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto#include <memory> 225754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi#include <vector> 23bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 24bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi#include "defines.h" 2588bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/buffer_with_extendable_buffer.h" 2688bc312ad34321fb3e81be2dc939a889d065f4a7Keisuke Kuroyanagi#include "dictionary/utils/byte_array_utils.h" 27bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 28bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynaginamespace latinime { 29bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 30fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa// Number of base-10 digits in the largest integer + 1 to leave room for a zero terminator. 31fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa// As such, this is the maximum number of characters will be needed to represent an int as a 32fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa// string, including the terminator; this is used as the size of a string buffer large enough to 33fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa// hold any value that is intended to fit in an integer, e.g. in the code that reads the header 34fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa// of the binary dictionary where a {key,value} string pair scheme is used. 35fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasaconst int HeaderReadWriteUtils::LARGEST_INT_DIGIT_COUNT = 11; 36fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa 37484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst int HeaderReadWriteUtils::MAX_ATTRIBUTE_KEY_LENGTH = 256; 38fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimotoconst int HeaderReadWriteUtils::MAX_ATTRIBUTE_VALUE_LENGTH = 2048; 39bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 40484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst int HeaderReadWriteUtils::HEADER_MAGIC_NUMBER_SIZE = 4; 41484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst int HeaderReadWriteUtils::HEADER_DICTIONARY_VERSION_SIZE = 2; 42484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst int HeaderReadWriteUtils::HEADER_FLAG_SIZE = 2; 43484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst int HeaderReadWriteUtils::HEADER_SIZE_FIELD_SIZE = 4; 44fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimotoconst char *const HeaderReadWriteUtils::CODE_POINT_TABLE_KEY = "codePointTable"; 4576e579c7caf2ef04f440be21c27377fe0b4150ffKeisuke Kuroyanagi 46484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagiconst HeaderReadWriteUtils::DictionaryFlags HeaderReadWriteUtils::NO_FLAGS = 0; 47989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi 48fc9ca59cc1dccc8353528c42a7eb710ad6d90e14Keisuke Kuroyanagitypedef DictionaryHeaderStructurePolicy::AttributeMap AttributeMap; 49fc9ca59cc1dccc8353528c42a7eb710ad6d90e14Keisuke Kuroyanagi 50484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi/* static */ int HeaderReadWriteUtils::getHeaderSize(const uint8_t *const dictBuf) { 5199007de979e006b6b08bf381f2d394377264de85Keisuke Kuroyanagi // See the format of the header in the comment in 5299007de979e006b6b08bf381f2d394377264de85Keisuke Kuroyanagi // BinaryDictionaryFormatUtils::detectFormatVersion() 5376e579c7caf2ef04f440be21c27377fe0b4150ffKeisuke Kuroyanagi return ByteArrayUtils::readUint32(dictBuf, HEADER_MAGIC_NUMBER_SIZE 5476e579c7caf2ef04f440be21c27377fe0b4150ffKeisuke Kuroyanagi + HEADER_DICTIONARY_VERSION_SIZE + HEADER_FLAG_SIZE); 55bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi} 56bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 57484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi/* static */ HeaderReadWriteUtils::DictionaryFlags 58484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi HeaderReadWriteUtils::getFlags(const uint8_t *const dictBuf) { 5976e579c7caf2ef04f440be21c27377fe0b4150ffKeisuke Kuroyanagi return ByteArrayUtils::readUint16(dictBuf, 6076e579c7caf2ef04f440be21c27377fe0b4150ffKeisuke Kuroyanagi HEADER_MAGIC_NUMBER_SIZE + HEADER_DICTIONARY_VERSION_SIZE); 61bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi} 62bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 63989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi/* static */ HeaderReadWriteUtils::DictionaryFlags 64989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi HeaderReadWriteUtils::createAndGetDictionaryFlagsUsingAttributeMap( 65fc9ca59cc1dccc8353528c42a7eb710ad6d90e14Keisuke Kuroyanagi const AttributeMap *const attributeMap) { 662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return NO_FLAGS; 67989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi} 68989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi 69484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi/* static */ void HeaderReadWriteUtils::fetchAllHeaderAttributes(const uint8_t *const dictBuf, 705754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi AttributeMap *const headerAttributes) { 7199007de979e006b6b08bf381f2d394377264de85Keisuke Kuroyanagi const int headerSize = getHeaderSize(dictBuf); 7299007de979e006b6b08bf381f2d394377264de85Keisuke Kuroyanagi int pos = getHeaderOptionsPosition(); 735ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi if (pos == NOT_A_DICT_POS) { 745ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi // The header doesn't have header options. 755754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi return; 765ae8722bd52b0f70ab7cd3bd888585422bef9563Keisuke Kuroynagi } 775754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi int keyBuffer[MAX_ATTRIBUTE_KEY_LENGTH]; 78fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto std::unique_ptr<int[]> valueBuffer(new int[MAX_ATTRIBUTE_VALUE_LENGTH]); 79bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi while (pos < headerSize) { 80fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto // The values in the header don't use the code point table for their encoding. 815754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi const int keyLength = ByteArrayUtils::readStringAndAdvancePosition(dictBuf, 82fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto MAX_ATTRIBUTE_KEY_LENGTH, nullptr /* codePointTable */, keyBuffer, &pos); 835754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi std::vector<int> key; 845754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi key.insert(key.end(), keyBuffer, keyBuffer + keyLength); 855754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi const int valueLength = ByteArrayUtils::readStringAndAdvancePosition(dictBuf, 86fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto MAX_ATTRIBUTE_VALUE_LENGTH, nullptr /* codePointTable */, valueBuffer.get(), &pos); 875754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi std::vector<int> value; 88fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto value.insert(value.end(), valueBuffer.get(), valueBuffer.get() + valueLength); 895754817a5e2e804f5ced54e601d4c08087d75b44Keisuke Kuroyanagi headerAttributes->insert(AttributeMap::value_type(key, value)); 90bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi } 91bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi} 92bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi 93fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto/* static */ const int *HeaderReadWriteUtils::readCodePointTable( 94fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto AttributeMap *const headerAttributes) { 95fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto AttributeMap::key_type keyVector; 96fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto insertCharactersIntoVector(CODE_POINT_TABLE_KEY, &keyVector); 97fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto AttributeMap::const_iterator it = headerAttributes->find(keyVector); 98fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto if (it == headerAttributes->end()) { 99fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto return nullptr; 100fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto } 101fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto return it->second.data(); 102fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto} 103fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto 104484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi/* static */ bool HeaderReadWriteUtils::writeDictionaryVersion( 105484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi BufferWithExtendableBuffer *const buffer, const FormatUtils::FORMAT_VERSION version, 106484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi int *const writingPos) { 107484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi if (!buffer->writeUintAndAdvancePosition(FormatUtils::MAGIC_NUMBER, HEADER_MAGIC_NUMBER_SIZE, 108484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi writingPos)) { 109484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return false; 110484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi } 111484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi switch (version) { 112484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi case FormatUtils::VERSION_2: 113fb2bde5a688d93aa946e3dd923aa1e99588777fcAkifumi Yoshimoto case FormatUtils::VERSION_201: 1147c87859d4c16c9cf19b095b865d7000ebc3cdaa9Adrian Velicu case FormatUtils::VERSION_202: 1157c87859d4c16c9cf19b095b865d7000ebc3cdaa9Adrian Velicu // None of the static dictionaries (v2x) support writing 116484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return false; 117455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi case FormatUtils::VERSION_4_ONLY_FOR_TESTING: 118ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi case FormatUtils::VERSION_402: 119ea468cc9de468b6574f98b3a7614decfcb7e456eKeisuke Kuroyanagi case FormatUtils::VERSION_403: 120455dc84cf2c6526329b535f30000ea45b7d4d4d7Keisuke Kuroyanagi return buffer->writeUintAndAdvancePosition(version /* data */, 121484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi HEADER_DICTIONARY_VERSION_SIZE, writingPos); 122484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi default: 123484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return false; 124484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi } 125484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi} 126484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi 127484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi/* static */ bool HeaderReadWriteUtils::writeDictionaryFlags( 128484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi BufferWithExtendableBuffer *const buffer, const DictionaryFlags flags, 129484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi int *const writingPos) { 130484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return buffer->writeUintAndAdvancePosition(flags, HEADER_FLAG_SIZE, writingPos); 131484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi} 132484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi 133484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi/* static */ bool HeaderReadWriteUtils::writeDictionaryHeaderSize( 134484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi BufferWithExtendableBuffer *const buffer, const int size, int *const writingPos) { 135484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return buffer->writeUintAndAdvancePosition(size, HEADER_SIZE_FIELD_SIZE, writingPos); 136484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi} 137484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi 138484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi/* static */ bool HeaderReadWriteUtils::writeHeaderAttributes( 139484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi BufferWithExtendableBuffer *const buffer, const AttributeMap *const headerAttributes, 140484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi int *const writingPos) { 141484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi for (AttributeMap::const_iterator it = headerAttributes->begin(); 142484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi it != headerAttributes->end(); ++it) { 1439cb1e78a44f4136d05df8368816e12725cbf5861Keisuke Kuroyanagi if (it->first.empty() || it->second.empty()) { 1449cb1e78a44f4136d05df8368816e12725cbf5861Keisuke Kuroyanagi continue; 1459cb1e78a44f4136d05df8368816e12725cbf5861Keisuke Kuroyanagi } 146484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi // Write a key. 147484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi if (!buffer->writeCodePointsAndAdvancePosition(&(it->first.at(0)), it->first.size(), 148484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi true /* writesTerminator */, writingPos)) { 149484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return false; 150484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi } 151484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi // Write a value. 152484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi if (!buffer->writeCodePointsAndAdvancePosition(&(it->second.at(0)), it->second.size(), 153484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi true /* writesTerminator */, writingPos)) { 154484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return false; 155484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi } 156484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi } 157484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi return true; 158484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi} 159484fa7b59cb0659ac18fa68da5c7b641d9255be8Keisuke Kuroyanagi 16043cf9076b2d053c554941e55f6073b8f586c510bJean Chalard/* static */ void HeaderReadWriteUtils::setCodePointVectorAttribute( 161fbddeedff617d101b7617995bdf7c9c7ce7eaf24Keisuke Kuroyanagi AttributeMap *const headerAttributes, const char *const key, 162fbddeedff617d101b7617995bdf7c9c7ce7eaf24Keisuke Kuroyanagi const std::vector<int> &value) { 16343cf9076b2d053c554941e55f6073b8f586c510bJean Chalard AttributeMap::key_type keyVector; 16443cf9076b2d053c554941e55f6073b8f586c510bJean Chalard insertCharactersIntoVector(key, &keyVector); 16543cf9076b2d053c554941e55f6073b8f586c510bJean Chalard (*headerAttributes)[keyVector] = value; 16643cf9076b2d053c554941e55f6073b8f586c510bJean Chalard} 16743cf9076b2d053c554941e55f6073b8f586c510bJean Chalard 168989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi/* static */ void HeaderReadWriteUtils::setBoolAttribute(AttributeMap *const headerAttributes, 16931097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi const char *const key, const bool value) { 170989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi setIntAttribute(headerAttributes, key, value ? 1 : 0); 171989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi} 172989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi 173989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi/* static */ void HeaderReadWriteUtils::setIntAttribute(AttributeMap *const headerAttributes, 17431097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi const char *const key, const int value) { 17531097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi AttributeMap::key_type keyVector; 17631097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi insertCharactersIntoVector(key, &keyVector); 17731097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi setIntAttributeInner(headerAttributes, &keyVector, value); 17831097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi} 17931097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi 18031097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi/* static */ void HeaderReadWriteUtils::setIntAttributeInner(AttributeMap *const headerAttributes, 181989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi const AttributeMap::key_type *const key, const int value) { 182989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi AttributeMap::mapped_type valueVector; 183fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa char charBuf[LARGEST_INT_DIGIT_COUNT]; 184fc2858c55bf64ef96b1b60f19db23de4b0c62c9cKen Wakasa snprintf(charBuf, sizeof(charBuf), "%d", value); 185989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi insertCharactersIntoVector(charBuf, &valueVector); 186989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi (*headerAttributes)[*key] = valueVector; 187989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi} 188989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi 18943cf9076b2d053c554941e55f6073b8f586c510bJean Chalard/* static */ const std::vector<int> HeaderReadWriteUtils::readCodePointVectorAttributeValue( 19043cf9076b2d053c554941e55f6073b8f586c510bJean Chalard const AttributeMap *const headerAttributes, const char *const key) { 19143cf9076b2d053c554941e55f6073b8f586c510bJean Chalard AttributeMap::key_type keyVector; 19243cf9076b2d053c554941e55f6073b8f586c510bJean Chalard insertCharactersIntoVector(key, &keyVector); 19343cf9076b2d053c554941e55f6073b8f586c510bJean Chalard AttributeMap::const_iterator it = headerAttributes->find(keyVector); 19443cf9076b2d053c554941e55f6073b8f586c510bJean Chalard if (it == headerAttributes->end()) { 19543cf9076b2d053c554941e55f6073b8f586c510bJean Chalard return std::vector<int>(); 19643cf9076b2d053c554941e55f6073b8f586c510bJean Chalard } else { 19743cf9076b2d053c554941e55f6073b8f586c510bJean Chalard return it->second; 19843cf9076b2d053c554941e55f6073b8f586c510bJean Chalard } 19943cf9076b2d053c554941e55f6073b8f586c510bJean Chalard} 20043cf9076b2d053c554941e55f6073b8f586c510bJean Chalard 201989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi/* static */ bool HeaderReadWriteUtils::readBoolAttributeValue( 20231097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi const AttributeMap *const headerAttributes, const char *const key, 203989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi const bool defaultValue) { 204989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi const int intDefaultValue = defaultValue ? 1 : 0; 205989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi const int intValue = readIntAttributeValue(headerAttributes, key, intDefaultValue); 206989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi return intValue != 0; 207989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi} 208989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi 209989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi/* static */ int HeaderReadWriteUtils::readIntAttributeValue( 21031097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi const AttributeMap *const headerAttributes, const char *const key, 21131097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi const int defaultValue) { 21231097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi AttributeMap::key_type keyVector; 21331097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi insertCharactersIntoVector(key, &keyVector); 21431097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi return readIntAttributeValueInner(headerAttributes, &keyVector, defaultValue); 21531097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi} 21631097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi 21731097a57cc6f8022abc0ea56f27147399f41b630Keisuke Kuroyanagi/* static */ int HeaderReadWriteUtils::readIntAttributeValueInner( 218989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi const AttributeMap *const headerAttributes, const AttributeMap::key_type *const key, 219989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi const int defaultValue) { 220989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi AttributeMap::const_iterator it = headerAttributes->find(*key); 221989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi if (it != headerAttributes->end()) { 222989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi int value = 0; 223989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi bool isNegative = false; 224989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi for (size_t i = 0; i < it->second.size(); ++i) { 225989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi if (i == 0 && it->second.at(i) == '-') { 226989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi isNegative = true; 227989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi } else { 228989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi if (!isdigit(it->second.at(i))) { 229989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi // If not a number. 230989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi return defaultValue; 231989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi } 232989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi value *= 10; 233989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi value += it->second.at(i) - '0'; 234989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi } 235989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi } 236989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi return isNegative ? -value : value; 237989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi } 238989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi return defaultValue; 239989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi} 240989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi 241989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi/* static */ void HeaderReadWriteUtils::insertCharactersIntoVector(const char *const characters, 242989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi std::vector<int> *const vector) { 243989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi for (int i = 0; characters[i]; ++i) { 244989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi vector->push_back(characters[i]); 245989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi } 246989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi} 247989596844e05b551d8fc6bb64c343677da0e4f7fKeisuke Kuroyanagi 248bd0d1afdb28a28e2ddac1409208c59ba64350399Keisuke Kuroynagi} // namespace latinime 249