mini_phone 1.0.6 → 1.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f7c87533de0643b9af5d9394d62a238208c34fa34e16effbb9064e9fd3578d7
4
- data.tar.gz: 5868d8b76184925da0ba875fa0a5df7c3bb61f920b51f5d9391fd2d742335ddc
3
+ metadata.gz: 89fa88b742202101e6bb0204bad2fd20545946a19447d227f61312dd1f9e251c
4
+ data.tar.gz: 49a1d96d9a61aa00c24b88c7e6d3b51dab2929f9ec12043ce2508fc6af374da2
5
5
  SHA512:
6
- metadata.gz: 6bdb02eee2405855e49defd3e27d9eccd8934ec1bc1c02977b69d17026d32500969b443b053b1eece4ca7f72294a2d57349c19cfe14f6993c02dab6d21ec9d21
7
- data.tar.gz: e57f59c8c2b75a1e4983d8a7fc3941fa1c641bd1c55eb13185bc9c8b35347b39a3ce301e65e021887f5bfc403ee8b0b5e5bad60d20e3604900418c0b6d46511e
6
+ metadata.gz: 5e719bb7cade41a127cd601f06ca5f2529dae2994112c89bf56ace37202230a2c4a3fae7c0738632d78d032cae0f6b7d1e20365a48f57f0ff046bc0241b2f023
7
+ data.tar.gz: f4ba0f376645bea9b1c25c94f5ba696d744988a1e11a44ff4081af0435165b7a573e24f3101b12dd652add2dccf2e23596bf75ed21b43a5e2fd0a44b1772ef35
@@ -0,0 +1,9 @@
1
+ FROM ruby:2.7-alpine
2
+
3
+ WORKDiR /app
4
+
5
+ # RUN apt-get update -y && apt-get install -y valgrind libphonenumber
6
+ RUN apk add --no-cache libphonenumber-dev valgrind git make libffi-dev build-base
7
+ COPY Gemfile Gemfile.lock mini_phone.gemspec ./
8
+ COPY lib/mini_phone/version.rb ./lib/mini_phone/version.rb
9
+ RUN bundle install -j4
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ gemspec
7
7
 
8
8
  gem 'rake', require: false
9
9
  # https://github.com/rake-compiler/rake-compiler/pull/166
10
+ gem 'get_process_mem', require: false
10
11
  gem 'rake-compiler', github: 'larskanis/rake-compiler', branch: 'fix-native-version'
11
12
  gem 'rspec', '~> 3.0', require: false
12
13
  gem 'rspec-github', require: false
data/Rakefile CHANGED
@@ -76,3 +76,21 @@ namespace :publish do
76
76
  push_to_github_registry(g)
77
77
  end
78
78
  end
79
+
80
+ desc 'Run valgrind test'
81
+
82
+ namespace :debug do
83
+ desc 'Plot memory'
84
+ task :memory do
85
+ sh 'debug/memory_plot/plot.sh'
86
+ end
87
+
88
+ task :valgrind do
89
+ sh 'docker build --tag mini_phone_dev -f Dockerfile.dev .'
90
+ args = '--tool=memcheck --num-callers=15 --partial-loads-ok=yes --undef-value-errors=no'
91
+ script = 'ruby debug/memory_plot/memory.rb --once'
92
+ cmd = "docker run -it --rm -v #{Dir.pwd}:/app -w /app mini_phone_dev valgrind #{args} #{script}"
93
+ puts cmd
94
+ system cmd
95
+ end
96
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'mini_phone'
5
+ require 'get_process_mem'
6
+
7
+ 10.times do
8
+ GC.start
9
+ GC.compact
10
+ end
11
+
12
+ $stdout.sync = true
13
+
14
+ loop do
15
+ 10_000.times do
16
+ pn = MiniPhone::PhoneNumber.new('+1 404 388 1299')
17
+ pn.e164
18
+ pn.valid?
19
+ pn.possible?
20
+ pn.raw_national
21
+ pn.international
22
+ pn.country_code
23
+ pn.area_code
24
+ end
25
+
26
+ 4.times { GC.start }
27
+
28
+ memory_mb = GetProcessMem.new.mb
29
+
30
+ $stdout.puts memory_mb
31
+
32
+ break if ARGV.first == '--once'
33
+ end
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ bundle exec rake compile
6
+ exec ruby "$(dirname "$0")/memory.rb" | ttyplot
@@ -14,10 +14,29 @@ static VALUE rb_cPhoneNumber;
14
14
  static RepeatedPtrField<NumberFormat> raw_national_format;
15
15
  static RepeatedPtrField<NumberFormat> dasherized_national_format;
16
16
 
17
- extern "C" struct PhoneNumberInfo {
18
- PhoneNumber phone_number;
19
- std::string raw_phone_number;
20
- std::string raw_country_code;
17
+ extern "C" struct PhoneNumberInfo { PhoneNumber *phone_number; };
18
+
19
+ extern "C" size_t phone_number_info_size(const void *data) { return sizeof(PhoneNumberInfo) + sizeof(PhoneNumber); }
20
+
21
+ extern "C" void phone_number_info_free(void *data) {
22
+ PhoneNumberInfo *phone_number_info = static_cast<PhoneNumberInfo *>(data);
23
+ phone_number_info->phone_number->~PhoneNumber();
24
+ xfree(phone_number_info->phone_number);
25
+ phone_number_info->~PhoneNumberInfo();
26
+ xfree(data);
27
+ }
28
+
29
+ extern "C" const rb_data_type_t phone_number_info_type = {
30
+ .wrap_struct_name = "MiniPhone/PhoneNumberInfo",
31
+ .function =
32
+ {
33
+ .dmark = NULL,
34
+ .dfree = phone_number_info_free,
35
+ .dsize = phone_number_info_size,
36
+ },
37
+ .parent = NULL,
38
+ .data = NULL,
39
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
21
40
  };
22
41
 
23
42
  static inline VALUE is_phone_number_valid(VALUE self, VALUE str, VALUE cc) {
@@ -107,17 +126,18 @@ extern "C" VALUE rb_set_default_country(VALUE self, VALUE str_code) {
107
126
 
108
127
  extern "C" VALUE rb_get_default_country(VALUE self) { return rb_iv_get(self, "@default_country"); }
109
128
 
110
- extern "C" void rb_phone_number_dealloc(PhoneNumberInfo *phone_number_info) { delete phone_number_info; }
111
-
112
129
  extern "C" VALUE rb_phone_number_parse(int argc, VALUE *argv, VALUE self) {
113
130
  return rb_class_new_instance(argc, argv, rb_cPhoneNumber);
114
131
  }
115
132
 
116
133
  extern "C" VALUE rb_phone_number_alloc(VALUE self) {
117
- PhoneNumberInfo *phone_number_info = new PhoneNumberInfo();
134
+ void *phone_number_data = ALLOC(PhoneNumber);
135
+ void *data = ALLOC(PhoneNumberInfo);
136
+ PhoneNumberInfo *phone_number_info = new (data) PhoneNumberInfo();
137
+ PhoneNumber *phone_number = new (phone_number_data) PhoneNumber();
138
+ phone_number_info->phone_number = phone_number;
118
139
 
119
- /* wrap */
120
- return Data_Wrap_Struct(self, NULL, &rb_phone_number_dealloc, phone_number_info);
140
+ return TypedData_Wrap_Struct(self, &phone_number_info_type, phone_number_info);
121
141
  }
122
142
 
123
143
  static inline VALUE rb_phone_number_nullify_ivars(VALUE self) {
@@ -160,7 +180,7 @@ extern "C" VALUE rb_phone_number_initialize(int argc, VALUE *argv, VALUE self) {
160
180
  PhoneNumberInfo *phone_number_info;
161
181
  PhoneNumber parsed_number;
162
182
 
163
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
183
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
164
184
 
165
185
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
166
186
 
@@ -172,7 +192,7 @@ extern "C" VALUE rb_phone_number_initialize(int argc, VALUE *argv, VALUE self) {
172
192
  if (result != PhoneNumberUtil::NO_PARSING_ERROR) {
173
193
  rb_phone_number_nullify_ivars(self);
174
194
  } else {
175
- phone_number_info->phone_number = parsed_number;
195
+ phone_number_info->phone_number->Swap(&parsed_number);
176
196
  }
177
197
 
178
198
  return self;
@@ -181,11 +201,11 @@ extern "C" VALUE rb_phone_number_initialize(int argc, VALUE *argv, VALUE self) {
181
201
  static inline VALUE rb_phone_number_format(VALUE self, PhoneNumberUtil::PhoneNumberFormat fmt) {
182
202
  std::string formatted_number;
183
203
  PhoneNumberInfo *phone_number_info;
184
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
204
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
185
205
 
186
206
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
187
- PhoneNumber parsed_number = phone_number_info->phone_number;
188
- phone_util.Format(parsed_number, fmt, &formatted_number);
207
+ PhoneNumber *parsed_number = phone_number_info->phone_number;
208
+ phone_util.Format(*parsed_number, fmt, &formatted_number);
189
209
 
190
210
  return rb_str_new(formatted_number.c_str(), formatted_number.size());
191
211
  }
@@ -227,9 +247,9 @@ VALUE format_by_pattern_national(VALUE self, RepeatedPtrField<NumberFormat> form
227
247
  std::string formatted_number;
228
248
  PhoneNumberInfo *phone_number_info;
229
249
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
230
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
250
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
231
251
 
232
- phone_util.FormatByPattern(phone_number_info->phone_number, PhoneNumberUtil::NATIONAL, format, &formatted_number);
252
+ phone_util.FormatByPattern(*phone_number_info->phone_number, PhoneNumberUtil::NATIONAL, format, &formatted_number);
233
253
 
234
254
  return rb_str_new(formatted_number.c_str(), formatted_number.size());
235
255
  }
@@ -260,9 +280,9 @@ extern "C" VALUE rb_phone_number_country_code(VALUE self) {
260
280
  }
261
281
 
262
282
  PhoneNumberInfo *phone_number_info;
263
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
283
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
264
284
 
265
- int code = phone_number_info->phone_number.country_code();
285
+ int code = phone_number_info->phone_number->country_code();
266
286
 
267
287
  VALUE result = INT2NUM(code);
268
288
 
@@ -302,11 +322,11 @@ extern "C" VALUE rb_phone_number_valid_eh(VALUE self) {
302
322
 
303
323
  std::string formatted_number;
304
324
  PhoneNumberInfo *phone_number_info;
305
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
325
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
306
326
 
307
327
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
308
328
 
309
- if (phone_util.IsValidNumber(phone_number_info->phone_number)) {
329
+ if (phone_util.IsValidNumber(*phone_number_info->phone_number)) {
310
330
  return rb_iv_set(self, "@valid", Qtrue);
311
331
  } else {
312
332
  return rb_iv_set(self, "@valid", Qfalse);
@@ -324,11 +344,11 @@ extern "C" VALUE rb_phone_number_possible_eh(VALUE self) {
324
344
 
325
345
  std::string formatted_number;
326
346
  PhoneNumberInfo *phone_number_info;
327
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
347
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
328
348
 
329
349
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
330
350
 
331
- if (phone_util.IsPossibleNumber(phone_number_info->phone_number)) {
351
+ if (phone_util.IsPossibleNumber(*phone_number_info->phone_number)) {
332
352
  return rb_iv_set(self, "@possible", Qtrue);
333
353
  } else {
334
354
  return rb_iv_set(self, "@possible", Qfalse);
@@ -346,10 +366,10 @@ extern "C" VALUE rb_phone_number_region_code(VALUE self) {
346
366
 
347
367
  PhoneNumberInfo *phone_number_info;
348
368
  std::string code;
349
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
369
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
350
370
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
351
371
 
352
- phone_util.GetRegionCodeForCountryCode(phone_number_info->phone_number.country_code(), &code);
372
+ phone_util.GetRegionCodeForCountryCode(phone_number_info->phone_number->country_code(), &code);
353
373
 
354
374
  VALUE result = rb_str_new(code.c_str(), code.size());
355
375
 
@@ -364,11 +384,12 @@ extern "C" VALUE rb_phone_number_eql_eh(VALUE self, VALUE other) {
364
384
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
365
385
 
366
386
  PhoneNumberInfo *self_phone_number_info;
367
- Data_Get_Struct(self, PhoneNumberInfo, self_phone_number_info);
387
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, self_phone_number_info);
368
388
 
369
389
  PhoneNumberInfo *other_phone_number_info;
370
- Data_Get_Struct(other, PhoneNumberInfo, other_phone_number_info);
371
- if (phone_util.IsNumberMatch(other_phone_number_info->phone_number, self_phone_number_info->phone_number)) {
390
+ TypedData_Get_Struct(other, PhoneNumberInfo, &phone_number_info_type, other_phone_number_info);
391
+
392
+ if (phone_util.IsNumberMatch(*other_phone_number_info->phone_number, *self_phone_number_info->phone_number)) {
372
393
  return Qtrue;
373
394
  } else {
374
395
  return Qfalse;
@@ -381,14 +402,14 @@ extern "C" VALUE rb_phone_number_type(VALUE self) {
381
402
  }
382
403
 
383
404
  PhoneNumberInfo *phone_number_info;
384
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
405
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
385
406
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
386
407
 
387
408
  VALUE result;
388
409
 
389
410
  // @see
390
411
  // https://github.com/google/libphonenumber/blob/4e9954edea7cf263532c5dd3861a801104c3f012/cpp/src/phonenumbers/phonenumberutil.h#L91
391
- switch (phone_util.GetNumberType(phone_number_info->phone_number)) {
412
+ switch (phone_util.GetNumberType(*phone_number_info->phone_number)) {
392
413
  case PhoneNumberUtil::PREMIUM_RATE:
393
414
  result = rb_intern("premium_rate");
394
415
  break;
@@ -437,15 +458,15 @@ extern "C" VALUE rb_phone_number_area_code(VALUE self) {
437
458
 
438
459
  const PhoneNumberUtil &phone_util(*PhoneNumberUtil::GetInstance());
439
460
  PhoneNumberInfo *phone_number_info;
440
- Data_Get_Struct(self, PhoneNumberInfo, phone_number_info);
461
+ TypedData_Get_Struct(self, PhoneNumberInfo, &phone_number_info_type, phone_number_info);
441
462
 
442
- PhoneNumber number = phone_number_info->phone_number;
463
+ PhoneNumber *number = phone_number_info->phone_number;
443
464
  string national_significant_number;
444
- phone_util.GetNationalSignificantNumber(number, &national_significant_number);
465
+ phone_util.GetNationalSignificantNumber(*number, &national_significant_number);
445
466
  string area_code;
446
467
  string subscriber_number;
447
468
 
448
- int area_code_length = phone_util.GetLengthOfGeographicalAreaCode(number);
469
+ int area_code_length = phone_util.GetLengthOfGeographicalAreaCode(*number);
449
470
  if (area_code_length > 0) {
450
471
  area_code = national_significant_number.substr(0, area_code_length);
451
472
  subscriber_number = national_significant_number.substr(area_code_length, string::npos);
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniPhone
4
- VERSION = '1.0.6'
4
+ VERSION = '1.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_phone
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Ker-Seymer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-11 00:00:00.000000000 Z
11
+ date: 2021-01-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Plugs directly in the the Google's native C++ [libphonenumber](https://github.com/google/libphonenumber)
14
14
  for extemely _fast_ and _robust_ phone number parsing, validation, and formatting.
@@ -22,10 +22,13 @@ extra_rdoc_files: []
22
22
  files:
23
23
  - CHANGELOG.md
24
24
  - CODE_OF_CONDUCT.md
25
+ - Dockerfile.dev
25
26
  - Gemfile
26
27
  - LICENSE.txt
27
28
  - README.md
28
29
  - Rakefile
30
+ - debug/memory_plot/memory.rb
31
+ - debug/memory_plot/plot.sh
29
32
  - ext/mini_phone/extconf.rb
30
33
  - ext/mini_phone/mini_phone.cc
31
34
  - ext/mini_phone/mini_phone.h