pico_phone 0.6.2-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/THIRD_PARTY_LICENSES.txt +353 -0
- data/ext/pico_phone/carrier_data.cc +68763 -0
- data/ext/pico_phone/carrier_mapper.cc +127 -0
- data/ext/pico_phone/carrier_mapper.h +88 -0
- data/ext/pico_phone/extconf.rb +129 -0
- data/ext/pico_phone/pico_phone.cpp +1059 -0
- data/ext/pico_phone/timezone_data.cc +6648 -0
- data/ext/pico_phone/timezone_data.h +25 -0
- data/ext/pico_phone/timezone_mapper.cc +54 -0
- data/ext/pico_phone/timezone_mapper.h +49 -0
- data/ext/pico_phone/vendor_headers/phonenumbers/geocoding/area_code_map.h +92 -0
- data/ext/pico_phone/vendor_headers/phonenumbers/geocoding/carrier_data.h +52 -0
- data/ext/pico_phone/vendor_headers/phonenumbers/geocoding/geocoding_data.h +93 -0
- data/ext/pico_phone/vendor_headers/phonenumbers/geocoding/mapping_file_provider.h +89 -0
- data/lib/pico_phone/3.1/pico_phone.so +0 -0
- data/lib/pico_phone/3.2/pico_phone.so +0 -0
- data/lib/pico_phone/3.3/pico_phone.so +0 -0
- data/lib/pico_phone/3.4/pico_phone.so +0 -0
- data/lib/pico_phone/4.0/pico_phone.so +0 -0
- data/lib/pico_phone/phone_number.rb +294 -0
- data/lib/pico_phone/version.rb +5 -0
- data/lib/pico_phone.rb +29 -0
- metadata +128 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// First-party pico_phone file. See carrier_mapper.h.
|
|
2
|
+
|
|
3
|
+
#include "carrier_mapper.h"
|
|
4
|
+
|
|
5
|
+
#include <algorithm>
|
|
6
|
+
#include <cstring>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
#include "phonenumbers/geocoding/area_code_map.h"
|
|
10
|
+
#include "phonenumbers/geocoding/carrier_data.h"
|
|
11
|
+
#include "phonenumbers/geocoding/mapping_file_provider.h"
|
|
12
|
+
#include "phonenumbers/phonenumber.pb.h"
|
|
13
|
+
|
|
14
|
+
#include "absl/synchronization/mutex.h"
|
|
15
|
+
|
|
16
|
+
namespace i18n {
|
|
17
|
+
namespace phonenumbers {
|
|
18
|
+
|
|
19
|
+
using std::string;
|
|
20
|
+
|
|
21
|
+
namespace {
|
|
22
|
+
|
|
23
|
+
// Returns true if s1 comes strictly before s2 in lexicographic order.
|
|
24
|
+
bool IsLowerThan(const char* s1, const char* s2) {
|
|
25
|
+
return strcmp(s1, s2) < 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
} // namespace
|
|
29
|
+
|
|
30
|
+
PhoneNumberCarrierMapper::PhoneNumberCarrierMapper() {
|
|
31
|
+
provider_.reset(new MappingFileProvider(get_carrier_country_calling_codes(),
|
|
32
|
+
get_carrier_country_calling_codes_size(),
|
|
33
|
+
get_carrier_country_languages));
|
|
34
|
+
prefix_language_code_pairs_ = get_carrier_prefix_language_code_pairs();
|
|
35
|
+
prefix_language_code_pairs_size_ = get_carrier_prefix_language_code_pairs_size();
|
|
36
|
+
get_prefix_descriptions_ = get_carrier_prefix_descriptions;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
PhoneNumberCarrierMapper::~PhoneNumberCarrierMapper() {
|
|
40
|
+
// Pointer-taking constructor, not the reference-taking one: this file
|
|
41
|
+
// compiles against two different Abseil versions depending on build path
|
|
42
|
+
// (vendored 20260526.0 for the static/native build, whatever Debian/Ubuntu
|
|
43
|
+
// packages for the dynamic/apt-linked build), and only the older
|
|
44
|
+
// pointer-taking overload exists in both. The vendored geocoder itself hit
|
|
45
|
+
// the same tension in the other direction (see build_deps.sh's
|
|
46
|
+
// absl::MutexLock patch) -- there it's a -Werror'd deprecation inside
|
|
47
|
+
// libphonenumber's own CMake build; here it's just a harmless warning
|
|
48
|
+
// since pico_phone's own extension build doesn't set -Werror.
|
|
49
|
+
absl::MutexLock l(&mu_);
|
|
50
|
+
for (AreaCodeMaps::const_iterator it = available_maps_.begin();
|
|
51
|
+
it != available_maps_.end(); ++it) {
|
|
52
|
+
delete it->second;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const AreaCodeMap* PhoneNumberCarrierMapper::GetPhonePrefixDescriptions(
|
|
57
|
+
int prefix, const string& language, const string& script,
|
|
58
|
+
const string& region) const {
|
|
59
|
+
string filename;
|
|
60
|
+
provider_->GetFileName(prefix, language, script, region, &filename);
|
|
61
|
+
if (filename.empty()) {
|
|
62
|
+
return NULL;
|
|
63
|
+
}
|
|
64
|
+
AreaCodeMaps::const_iterator it = available_maps_.find(filename);
|
|
65
|
+
if (it == available_maps_.end()) {
|
|
66
|
+
return LoadAreaCodeMapFromFile(filename);
|
|
67
|
+
}
|
|
68
|
+
return it->second;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const AreaCodeMap* PhoneNumberCarrierMapper::LoadAreaCodeMapFromFile(
|
|
72
|
+
const string& filename) const {
|
|
73
|
+
const char** const prefix_language_code_pairs_end =
|
|
74
|
+
prefix_language_code_pairs_ + prefix_language_code_pairs_size_;
|
|
75
|
+
const char** const prefix_language_code_pair =
|
|
76
|
+
std::lower_bound(prefix_language_code_pairs_,
|
|
77
|
+
prefix_language_code_pairs_end,
|
|
78
|
+
filename.c_str(), IsLowerThan);
|
|
79
|
+
if (prefix_language_code_pair != prefix_language_code_pairs_end &&
|
|
80
|
+
filename.compare(*prefix_language_code_pair) == 0) {
|
|
81
|
+
AreaCodeMap* const m = new AreaCodeMap();
|
|
82
|
+
m->ReadAreaCodeMap(get_prefix_descriptions_(
|
|
83
|
+
prefix_language_code_pair - prefix_language_code_pairs_));
|
|
84
|
+
return available_maps_.insert(AreaCodeMaps::value_type(filename, m))
|
|
85
|
+
.first->second;
|
|
86
|
+
}
|
|
87
|
+
return NULL;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const char* PhoneNumberCarrierMapper::GetAreaDescription(
|
|
91
|
+
const PhoneNumber& number, const string& lang, const string& script,
|
|
92
|
+
const string& region) const {
|
|
93
|
+
const int country_calling_code = number.country_code();
|
|
94
|
+
// NANPA area is not split in C++ code (matches PhoneNumberOfflineGeocoder).
|
|
95
|
+
const int phone_prefix = country_calling_code;
|
|
96
|
+
absl::MutexLock l(&mu_);
|
|
97
|
+
const AreaCodeMap* const descriptions = GetPhonePrefixDescriptions(
|
|
98
|
+
phone_prefix, lang, script, region);
|
|
99
|
+
const char* description = descriptions ? descriptions->Lookup(number) : NULL;
|
|
100
|
+
// When a carrier name is not available in the requested language, fall
|
|
101
|
+
// back to English.
|
|
102
|
+
if ((!description || *description == '\0') && MayFallBackToEnglish(lang)) {
|
|
103
|
+
const AreaCodeMap* default_descriptions = GetPhonePrefixDescriptions(
|
|
104
|
+
phone_prefix, "en", "", "");
|
|
105
|
+
if (!default_descriptions) {
|
|
106
|
+
return "";
|
|
107
|
+
}
|
|
108
|
+
description = default_descriptions->Lookup(number);
|
|
109
|
+
}
|
|
110
|
+
return description ? description : "";
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Don't fall back to English if the requested language is among the following:
|
|
114
|
+
// - Chinese
|
|
115
|
+
// - Japanese
|
|
116
|
+
// - Korean
|
|
117
|
+
bool PhoneNumberCarrierMapper::MayFallBackToEnglish(const string& lang) const {
|
|
118
|
+
return lang.compare("zh") && lang.compare("ja") && lang.compare("ko");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
string PhoneNumberCarrierMapper::GetNameForNumber(
|
|
122
|
+
const PhoneNumber& number, const string& lang) const {
|
|
123
|
+
return GetAreaDescription(number, lang, "", "");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
} // namespace phonenumbers
|
|
127
|
+
} // namespace i18n
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// First-party pico_phone file. A trimmed mirror of libphonenumber's
|
|
2
|
+
// PhoneNumberOfflineGeocoder (phonenumbers/geocoding/
|
|
3
|
+
// phonenumber_offline_geocoder.h in the vendored source), reusing the same
|
|
4
|
+
// AreaCodeMap/MappingFileProvider machinery -- lazy per (country calling
|
|
5
|
+
// code, language) file loading, cached for the life of the process -- but
|
|
6
|
+
// backed by carrier_data.cc instead of geocoding_data.cc, and with the
|
|
7
|
+
// ICU-based country-name fallback removed: carrier data has no natural
|
|
8
|
+
// "fall back to the country name" concept (unlike geocoding), so an
|
|
9
|
+
// unmapped prefix returns an empty string, matching phonelib's carrier
|
|
10
|
+
// semantics. This also means, unlike the geocoder, this class has no ICU
|
|
11
|
+
// dependency at all.
|
|
12
|
+
|
|
13
|
+
#ifndef PICO_PHONE_CARRIER_MAPPER_H_
|
|
14
|
+
#define PICO_PHONE_CARRIER_MAPPER_H_
|
|
15
|
+
|
|
16
|
+
#include <map>
|
|
17
|
+
#include <string>
|
|
18
|
+
|
|
19
|
+
#include "absl/synchronization/mutex.h"
|
|
20
|
+
#include "phonenumbers/base/memory/scoped_ptr.h"
|
|
21
|
+
|
|
22
|
+
namespace i18n {
|
|
23
|
+
namespace phonenumbers {
|
|
24
|
+
|
|
25
|
+
class AreaCodeMap;
|
|
26
|
+
class MappingFileProvider;
|
|
27
|
+
class PhoneNumber;
|
|
28
|
+
struct CountryLanguages;
|
|
29
|
+
struct PrefixDescriptions;
|
|
30
|
+
|
|
31
|
+
class PhoneNumberCarrierMapper {
|
|
32
|
+
private:
|
|
33
|
+
typedef std::map<std::string, const AreaCodeMap*> AreaCodeMaps;
|
|
34
|
+
|
|
35
|
+
public:
|
|
36
|
+
PhoneNumberCarrierMapper();
|
|
37
|
+
|
|
38
|
+
PhoneNumberCarrierMapper(const PhoneNumberCarrierMapper&) = delete;
|
|
39
|
+
PhoneNumberCarrierMapper& operator=(const PhoneNumberCarrierMapper&) = delete;
|
|
40
|
+
|
|
41
|
+
~PhoneNumberCarrierMapper();
|
|
42
|
+
|
|
43
|
+
// Returns the carrier name for the given phone number in the given
|
|
44
|
+
// language, or an empty string if no carrier mapping is available for
|
|
45
|
+
// this prefix. lang is a two or three-letter lowercase ISO 639 language
|
|
46
|
+
// code, as with PhoneNumberOfflineGeocoder.
|
|
47
|
+
//
|
|
48
|
+
// The carrier name is the one the number was originally allocated to,
|
|
49
|
+
// however if the country supports mobile number portability the number
|
|
50
|
+
// might not belong to the returned carrier anymore (same caveat as
|
|
51
|
+
// upstream's Java-only PhoneNumberToCarrierMapper.getNameForNumber,
|
|
52
|
+
// verbatim -- see java/carrier/src/.../PhoneNumberToCarrierMapper.java
|
|
53
|
+
// in the vendored source tree).
|
|
54
|
+
std::string GetNameForNumber(const PhoneNumber& number,
|
|
55
|
+
const std::string& lang) const;
|
|
56
|
+
|
|
57
|
+
private:
|
|
58
|
+
typedef const PrefixDescriptions* (*prefix_descriptions_getter)(int index);
|
|
59
|
+
|
|
60
|
+
const AreaCodeMap* LoadAreaCodeMapFromFile(
|
|
61
|
+
const std::string& filename) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
|
62
|
+
|
|
63
|
+
const AreaCodeMap* GetPhonePrefixDescriptions(
|
|
64
|
+
int prefix, const std::string& language, const std::string& script,
|
|
65
|
+
const std::string& region) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
|
|
66
|
+
|
|
67
|
+
const char* GetAreaDescription(const PhoneNumber& number,
|
|
68
|
+
const std::string& lang,
|
|
69
|
+
const std::string& script,
|
|
70
|
+
const std::string& region) const
|
|
71
|
+
ABSL_LOCKS_EXCLUDED(mu_);
|
|
72
|
+
|
|
73
|
+
bool MayFallBackToEnglish(const std::string& lang) const;
|
|
74
|
+
|
|
75
|
+
scoped_ptr<const MappingFileProvider> provider_;
|
|
76
|
+
|
|
77
|
+
const char** prefix_language_code_pairs_;
|
|
78
|
+
int prefix_language_code_pairs_size_;
|
|
79
|
+
prefix_descriptions_getter get_prefix_descriptions_;
|
|
80
|
+
|
|
81
|
+
mutable absl::Mutex mu_;
|
|
82
|
+
mutable AreaCodeMaps available_maps_ ABSL_GUARDED_BY(mu_);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
} // namespace phonenumbers
|
|
86
|
+
} // namespace i18n
|
|
87
|
+
|
|
88
|
+
#endif // PICO_PHONE_CARRIER_MAPPER_H_
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require "mkmf-rice"
|
|
2
|
+
|
|
3
|
+
$CXXFLAGS << ' -std=c++17'
|
|
4
|
+
|
|
5
|
+
# carrier_mapper.cc needs AreaCodeMap/MappingFileProvider/the
|
|
6
|
+
# CountryLanguages+PrefixDescriptions structs, none of which libphonenumber
|
|
7
|
+
# installs publicly (only phonenumber_offline_geocoder.h is installed) in
|
|
8
|
+
# either build path below. Headers vendored verbatim under
|
|
9
|
+
# vendor_headers/phonenumbers/geocoding/ -- see that directory's own
|
|
10
|
+
# comments. Needed unconditionally, regardless of NATIVE_BUILD.
|
|
11
|
+
$INCFLAGS << " -I#{File.expand_path("vendor_headers", __dir__)}"
|
|
12
|
+
|
|
13
|
+
VENDOR_INSTALL = File.expand_path("vendor/install", __dir__)
|
|
14
|
+
NATIVE_BUILD = ENV["PICO_PHONE_NATIVE_BUILD"] == "1"
|
|
15
|
+
|
|
16
|
+
if NATIVE_BUILD
|
|
17
|
+
# Static linking against vendored libraries for native gem builds.
|
|
18
|
+
# All five dependencies are baked into the .so — users need nothing installed.
|
|
19
|
+
$INCFLAGS << " -I#{VENDOR_INSTALL}/include"
|
|
20
|
+
|
|
21
|
+
static_libs = []
|
|
22
|
+
# geocoding depends on symbols from phonenumber, so it must precede it in
|
|
23
|
+
# the static link order.
|
|
24
|
+
static_libs << "#{VENDOR_INSTALL}/lib/libgeocoding.a"
|
|
25
|
+
static_libs << "#{VENDOR_INSTALL}/lib/libphonenumber.a"
|
|
26
|
+
static_libs << "#{VENDOR_INSTALL}/lib/libprotobuf.a"
|
|
27
|
+
# protobuf's own transitive static deps (UTF-8 validation, upb). Whole-archive
|
|
28
|
+
# linking (below) force-includes every object in libprotobuf.a, including
|
|
29
|
+
# members that reference these, so they must be present even though nothing
|
|
30
|
+
# in our own code calls them directly. libutf8_range and libutf8_validity are
|
|
31
|
+
# two CMake target names for the exact same compiled object (utf8_range.c.o)
|
|
32
|
+
# in this protobuf version — link only one, or whole-archive pulls in both
|
|
33
|
+
# copies and the linker sees duplicate symbols.
|
|
34
|
+
%w[libutf8_range libupb].each do |lib|
|
|
35
|
+
path = "#{VENDOR_INSTALL}/lib/#{lib}.a"
|
|
36
|
+
static_libs << path if File.exist?(path)
|
|
37
|
+
end
|
|
38
|
+
static_libs += Dir["#{VENDOR_INSTALL}/lib/libabsl_*.a"].sort
|
|
39
|
+
|
|
40
|
+
if RUBY_PLATFORM.include?("darwin")
|
|
41
|
+
boost_prefix = `brew --prefix boost 2>/dev/null`.strip
|
|
42
|
+
icu_prefix = `brew --prefix icu4c@78 2>/dev/null`.strip
|
|
43
|
+
|
|
44
|
+
$INCFLAGS << " -I#{icu_prefix}/include"
|
|
45
|
+
|
|
46
|
+
%w[libboost_date_time libboost_thread libboost_atomic].each do |lib|
|
|
47
|
+
static_libs << "#{boost_prefix}/lib/#{lib}.a"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
%w[libicui18n libicuuc libicudata].each do |lib|
|
|
51
|
+
static_libs << "#{icu_prefix}/lib/#{lib}.a"
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
# Linux: libphonenumber was built with USE_BOOST=OFF so no Boost needed.
|
|
55
|
+
# Ubuntu's libicu-dev static archives are not compiled with -fPIC and cannot
|
|
56
|
+
# be linked into a shared object. Link ICU dynamically instead — libicu74 is
|
|
57
|
+
# part of the Ubuntu 24.04 base system and is present in the target environment.
|
|
58
|
+
# ICU headers (for the geocoder) come from the system libicu-dev package.
|
|
59
|
+
$LOCAL_LIBS << " -licui18n -licuuc -licudata -lpthread -ldl"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Adding the geocoder introduces a circular reference among several small
|
|
63
|
+
# Abseil static archives (e.g. synchronization <-> log_internal). A plain
|
|
64
|
+
# left-to-right static link only pulls in archive members that satisfy an
|
|
65
|
+
# already-outstanding undefined symbol, which for a -bundle target isn't
|
|
66
|
+
# even validated until dlopen time — so a missing member surfaces as a
|
|
67
|
+
# runtime "symbol not found in flat namespace" error, not a link failure.
|
|
68
|
+
# Force-load every member of our own vendored archives so nothing gets
|
|
69
|
+
# silently dropped.
|
|
70
|
+
if RUBY_PLATFORM.include?("darwin")
|
|
71
|
+
$LOCAL_LIBS << " -Wl,-all_load " + static_libs.join(" ")
|
|
72
|
+
else
|
|
73
|
+
$LOCAL_LIBS << " -Wl,--whole-archive " + static_libs.join(" ") + " -Wl,--no-whole-archive"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
unless find_header("phonenumbers/phonenumberutil.h")
|
|
77
|
+
abort "Could not find phonenumberutil.h in #{VENDOR_INSTALL}/include — run build_deps.sh first"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
unless find_header("phonenumbers/geocoding/phonenumber_offline_geocoder.h")
|
|
81
|
+
abort "Could not find the geocoding header in #{VENDOR_INSTALL}/include — run build_deps.sh first"
|
|
82
|
+
end
|
|
83
|
+
else
|
|
84
|
+
# Dynamic linking against system/Homebrew libraries (default developer workflow).
|
|
85
|
+
if RUBY_PLATFORM.include?("darwin")
|
|
86
|
+
# icu4c@78 is already a transitive dependency of Homebrew's libphonenumber
|
|
87
|
+
# formula (which itself ships geocoding), so no extra install step needed.
|
|
88
|
+
%w[libphonenumber protobuf abseil icu4c@78].each do |pkg|
|
|
89
|
+
prefix = `brew --prefix #{pkg} 2>/dev/null`.strip
|
|
90
|
+
next if prefix.empty?
|
|
91
|
+
$INCFLAGS << " -I#{prefix}/include"
|
|
92
|
+
$LDFLAGS << " -L#{prefix}/lib"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
$LOCAL_LIBS << " -lphonenumber -lgeocoding"
|
|
97
|
+
|
|
98
|
+
unless find_header("phonenumbers/phonenumberutil.h")
|
|
99
|
+
abort <<~MSG
|
|
100
|
+
|
|
101
|
+
Could not find libphonenumber. Please install it before installing this gem:
|
|
102
|
+
macOS: brew install libphonenumber
|
|
103
|
+
Ubuntu: sudo apt-get install libphonenumber-dev libicu-dev
|
|
104
|
+
Fedora: sudo dnf install libphonenumber-devel
|
|
105
|
+
MSG
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
unless find_header("phonenumbers/geocoding/phonenumber_offline_geocoder.h")
|
|
109
|
+
abort <<~MSG
|
|
110
|
+
|
|
111
|
+
Found libphonenumber but not its geocoding headers/library. On Debian/Ubuntu
|
|
112
|
+
this also needs ICU development headers:
|
|
113
|
+
sudo apt-get install libphonenumber-dev libicu-dev
|
|
114
|
+
MSG
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Ruby builds with --enable-shared (used by ruby/setup-ruby, official Docker images, Homebrew, and
|
|
119
|
+
# most system packages) make mkmf hard-link every extension against a build-specific libruby.so/
|
|
120
|
+
# .dylib via LIBRUBYARG_SHARED, on top of -Wl,-undefined,dynamic_lookup which alone is already
|
|
121
|
+
# sufficient for symbol resolution at load time. On macOS that dependency is an absolute path tied
|
|
122
|
+
# to wherever that particular Ruby happened to be installed -- which cannot exist on any other
|
|
123
|
+
# machine, breaking every precompiled native gem once it's moved off the machine that built it,
|
|
124
|
+
# regardless of Ruby version. Drop it so the compiled extension only depends on libraries it
|
|
125
|
+
# actually needs.
|
|
126
|
+
$LIBRUBYARG_SHARED = ""
|
|
127
|
+
$LIBRUBYARG = ""
|
|
128
|
+
|
|
129
|
+
create_makefile("pico_phone/pico_phone")
|