12dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// Copyright (C) 2012 The Libphonenumber Authors
22dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com//
32dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// Licensed under the Apache License, Version 2.0 (the "License");
42dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// you may not use this file except in compliance with the License.
52dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// You may obtain a copy of the License at
62dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com//
72dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// http://www.apache.org/licenses/LICENSE-2.0
82dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com//
92dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// Unless required by applicable law or agreed to in writing, software
102dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// distributed under the License is distributed on an "AS IS" BASIS,
112dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// See the License for the specific language governing permissions and
132dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// limitations under the License.
142dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com//
152dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com// Author: Patrick Mezard
162dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
172dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com#include "phonenumbers/geocoding/area_code_map.h"
182dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
192dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com#include <cstddef>
202dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
212dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com#include "phonenumbers/geocoding/default_map_storage.h"
222dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com#include "phonenumbers/phonenumber.pb.h"
232dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com#include "phonenumbers/phonenumberutil.h"
242dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com#include "phonenumbers/stringutil.h"
252dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
262dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.comnamespace i18n {
272dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.comnamespace phonenumbers {
282dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
292dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.comAreaCodeMap::AreaCodeMap()
302dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  : phone_util_(*PhoneNumberUtil::GetInstance()) {
312dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com}
322dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
332dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.comAreaCodeMap::~AreaCodeMap() {
342dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com}
352dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
36b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.pengvoid AreaCodeMap::ReadAreaCodeMap(const PrefixDescriptions* descriptions) {
37b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng  DefaultMapStorage* storage = new DefaultMapStorage();
38b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng  storage->ReadFromMap(descriptions);
392dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  storage_.reset(storage);
402dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com}
412dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
42b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.pengconst char* AreaCodeMap::Lookup(const PhoneNumber& number) const {
432dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  const int entries = storage_->GetNumOfEntries();
442dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  if (!entries) {
452dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    return NULL;
462dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  }
472dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
482dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  string national_number;
492dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  phone_util_.GetNationalSignificantNumber(number, &national_number);
502dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  int64 phone_prefix;
512dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  safe_strto64(SimpleItoa(number.country_code()) + national_number,
522dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com               &phone_prefix);
532dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
54b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng  const int* const lengths = storage_->GetPossibleLengths();
55b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng  const int lengths_size = storage_->GetPossibleLengthsSize();
562dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  int current_index = entries - 1;
57b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng  for (int lengths_index = lengths_size - 1; lengths_index >= 0;
58b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng       --lengths_index) {
59b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng    const int possible_length = lengths[lengths_index];
602dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    string phone_prefix_str = SimpleItoa(phone_prefix);
612dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    if (static_cast<int>(phone_prefix_str.length()) > possible_length) {
622dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com      safe_strto64(phone_prefix_str.substr(0, possible_length), &phone_prefix);
632dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    }
642dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    current_index = BinarySearch(0, current_index, phone_prefix);
652dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    if (current_index < 0) {
662dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com      return NULL;
672dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    }
68b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng    const int32 current_prefix = storage_->GetPrefix(current_index);
692dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    if (phone_prefix == current_prefix) {
70b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng      return storage_->GetDescription(current_index);
712dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    }
722dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  }
732dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  return NULL;
742dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com}
752dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
762dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.comint AreaCodeMap::BinarySearch(int start, int end, int64 value) const {
772dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  int current = 0;
782dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  while (start <= end) {
792dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    current = (start + end) / 2;
80b32eeb5f079c0b91bc073455657cfc3003df2608jia.shao.peng    int32 current_value = storage_->GetPrefix(current);
812dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    if (current_value == value) {
822dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com      return current;
832dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    } else if (current_value > value) {
842dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com      --current;
852dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com      end = current;
862dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    } else {
872dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com      start = current + 1;
882dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com    }
892dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  }
902dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com  return current;
912dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com}
922dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com
932dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com}  // namespace phonenumbers
942dbe1d8526f8d057898bc02ed3185a84f82cbb9aphilip.liard@gmail.com}  // namespace i18n
95