1 // Copyright (C) 2012 The Libphonenumber Authors
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 // Author: Patrick Mezard
17 #include "phonenumbers/geocoding/area_code_map.h"
23 #include "phonenumbers/geocoding/area_code_map_storage_strategy.h"
24 #include "phonenumbers/geocoding/default_map_storage.h"
25 #include "phonenumbers/phonenumber.pb.h"
26 #include "phonenumbers/phonenumberutil.h"
27 #include "phonenumbers/stringutil.h"
30 namespace phonenumbers {
32 AreaCodeMap::AreaCodeMap()
33 : phone_util_(*PhoneNumberUtil::GetInstance()) {
36 AreaCodeMap::~AreaCodeMap() {
39 AreaCodeMapStorageStrategy* AreaCodeMap::CreateDefaultMapStorage() const {
40 return new DefaultMapStorage();
43 void AreaCodeMap::ReadAreaCodeMap(const map<int, string>& area_codes) {
44 AreaCodeMapStorageStrategy* storage = CreateDefaultMapStorage();
45 storage->ReadFromMap(area_codes);
46 storage_.reset(storage);
49 const string* AreaCodeMap::Lookup(const PhoneNumber& number) const {
50 const int entries = storage_->GetNumOfEntries();
55 string national_number;
56 phone_util_.GetNationalSignificantNumber(number, &national_number);
58 safe_strto64(SimpleItoa(number.country_code()) + national_number,
61 const set<int>& lengths = storage_->GetPossibleLengths();
62 int current_index = entries - 1;
63 for (set<int>::const_reverse_iterator lengths_it = lengths.rbegin();
64 lengths_it != lengths.rend(); ++lengths_it) {
65 const int possible_length = *lengths_it;
66 string phone_prefix_str = SimpleItoa(phone_prefix);
67 if (static_cast<int>(phone_prefix_str.length()) > possible_length) {
68 safe_strto64(phone_prefix_str.substr(0, possible_length), &phone_prefix);
70 current_index = BinarySearch(0, current_index, phone_prefix);
71 if (current_index < 0) {
74 const int current_prefix = storage_->GetPrefix(current_index);
75 if (phone_prefix == current_prefix) {
76 return &storage_->GetDescription(current_index);
82 int AreaCodeMap::BinarySearch(int start, int end, int64 value) const {
84 while (start <= end) {
85 current = (start + end) / 2;
86 int current_value = storage_->GetPrefix(current);
87 if (current_value == value) {
89 } else if (current_value > value) {
99 } // namespace phonenumbers